summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-driver-samsung-laptop19
-rw-r--r--Documentation/ABI/testing/sysfs-platform-asus-wmi31
-rw-r--r--Documentation/ABI/testing/sysfs-platform-eeepc-wmi10
-rw-r--r--Documentation/laptops/sony-laptop.txt37
-rw-r--r--MAINTAINERS30
-rw-r--r--Makefile4
-rw-r--r--arch/alpha/Kconfig2
-rw-r--r--arch/alpha/kernel/irq.c67
-rw-r--r--arch/alpha/kernel/irq_alpha.c2
-rw-r--r--arch/alpha/kernel/irq_i8259.c2
-rw-r--r--arch/alpha/kernel/irq_pyxis.c2
-rw-r--r--arch/alpha/kernel/irq_srm.c2
-rw-r--r--arch/alpha/kernel/sys_alcor.c2
-rw-r--r--arch/alpha/kernel/sys_cabriolet.c4
-rw-r--r--arch/alpha/kernel/sys_dp264.c2
-rw-r--r--arch/alpha/kernel/sys_eb64p.c2
-rw-r--r--arch/alpha/kernel/sys_eiger.c2
-rw-r--r--arch/alpha/kernel/sys_jensen.c10
-rw-r--r--arch/alpha/kernel/sys_marvel.c8
-rw-r--r--arch/alpha/kernel/sys_mikasa.c3
-rw-r--r--arch/alpha/kernel/sys_noritake.c3
-rw-r--r--arch/alpha/kernel/sys_rawhide.c3
-rw-r--r--arch/alpha/kernel/sys_rx164.c2
-rw-r--r--arch/alpha/kernel/sys_sable.c4
-rw-r--r--arch/alpha/kernel/sys_takara.c3
-rw-r--r--arch/alpha/kernel/sys_titan.c2
-rw-r--r--arch/alpha/kernel/sys_wildfire.c12
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/boot/compressed/head.S10
-rw-r--r--arch/arm/boot/compressed/misc.c12
-rw-r--r--arch/arm/common/gic.c15
-rw-r--r--arch/arm/common/it8152.c4
-rw-r--r--arch/arm/common/locomo.c17
-rw-r--r--arch/arm/common/sa1111.c24
-rw-r--r--arch/arm/common/vic.c6
-rw-r--r--arch/arm/include/asm/hw_irq.h8
-rw-r--r--arch/arm/include/asm/mach/udc_pxa2xx.h2
-rw-r--r--arch/arm/kernel/bios32.c25
-rw-r--r--arch/arm/kernel/debug.S19
-rw-r--r--arch/arm/kernel/ecard.c6
-rw-r--r--arch/arm/kernel/etm.c4
-rw-r--r--arch/arm/kernel/irq.c70
-rw-r--r--arch/arm/kernel/kprobes-decode.c10
-rw-r--r--arch/arm/kernel/perf_event.c33
-rw-r--r--arch/arm/kernel/perf_event_v6.c2
-rw-r--r--arch/arm/kernel/perf_event_v7.c26
-rw-r--r--arch/arm/kernel/perf_event_xscale.c4
-rw-r--r--arch/arm/kernel/sleep.S14
-rw-r--r--arch/arm/mach-at91/at91cap9_devices.c6
-rw-r--r--arch/arm/mach-at91/gpio.c43
-rw-r--r--arch/arm/mach-at91/include/mach/at572d940hf.h2
-rw-r--r--arch/arm/mach-at91/irq.c3
-rw-r--r--arch/arm/mach-bcmring/irq.c10
-rw-r--r--arch/arm/mach-clps711x/irq.c8
-rw-r--r--arch/arm/mach-davinci/cp_intc.c4
-rw-r--r--arch/arm/mach-davinci/gpio.c49
-rw-r--r--arch/arm/mach-davinci/irq.c6
-rw-r--r--arch/arm/mach-dove/include/mach/dove.h2
-rw-r--r--arch/arm/mach-dove/irq.c20
-rw-r--r--arch/arm/mach-dove/mpp.c3
-rw-r--r--arch/arm/mach-ebsa110/core.c4
-rw-r--r--arch/arm/mach-ep93xx/gpio.c52
-rw-r--r--arch/arm/mach-exynos4/Kconfig7
-rw-r--r--arch/arm/mach-exynos4/Makefile2
-rw-r--r--arch/arm/mach-exynos4/include/mach/debug-macro.S4
-rw-r--r--arch/arm/mach-exynos4/irq-combiner.c13
-rw-r--r--arch/arm/mach-exynos4/irq-eint.c15
-rw-r--r--arch/arm/mach-exynos4/mach-smdkc210.c2
-rw-r--r--arch/arm/mach-exynos4/mach-smdkv310.c2
-rw-r--r--arch/arm/mach-footbridge/common.c3
-rw-r--r--arch/arm/mach-footbridge/dc21285-timer.c2
-rw-r--r--arch/arm/mach-footbridge/isa-irq.c10
-rw-r--r--arch/arm/mach-gemini/gpio.c14
-rw-r--r--arch/arm/mach-gemini/irq.c6
-rw-r--r--arch/arm/mach-h720x/common.c22
-rw-r--r--arch/arm/mach-h720x/cpu-h7202.c17
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c8
-rw-r--r--arch/arm/mach-iop13xx/irq.c10
-rw-r--r--arch/arm/mach-iop13xx/msi.c6
-rw-r--r--arch/arm/mach-iop32x/irq.c3
-rw-r--r--arch/arm/mach-iop33x/irq.c5
-rw-r--r--arch/arm/mach-ixp2000/core.c20
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x00.c6
-rw-r--r--arch/arm/mach-ixp2000/ixdp2x01.c6
-rw-r--r--arch/arm/mach-ixp23xx/core.c14
-rw-r--r--arch/arm/mach-ixp23xx/ixdp2351.c12
-rw-r--r--arch/arm/mach-ixp23xx/roadrunner.c4
-rw-r--r--arch/arm/mach-ixp4xx/avila-pci.c8
-rw-r--r--arch/arm/mach-ixp4xx/common.c4
-rw-r--r--arch/arm/mach-ixp4xx/coyote-pci.c4
-rw-r--r--arch/arm/mach-ixp4xx/dsmg600-pci.c12
-rw-r--r--arch/arm/mach-ixp4xx/fsg-pci.c6
-rw-r--r--arch/arm/mach-ixp4xx/gateway7001-pci.c4
-rw-r--r--arch/arm/mach-ixp4xx/goramo_mlr.c12
-rw-r--r--arch/arm/mach-ixp4xx/gtwx5715-pci.c4
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-pci.c8
-rw-r--r--arch/arm/mach-ixp4xx/ixdpg425-pci.c4
-rw-r--r--arch/arm/mach-ixp4xx/nas100d-pci.c10
-rw-r--r--arch/arm/mach-ixp4xx/nslu2-pci.c6
-rw-r--r--arch/arm/mach-ixp4xx/vulcan-pci.c4
-rw-r--r--arch/arm/mach-ixp4xx/wg302v2-pci.c4
-rw-r--r--arch/arm/mach-kirkwood/irq.c15
-rw-r--r--arch/arm/mach-kirkwood/sheevaplug-setup.c7
-rw-r--r--arch/arm/mach-ks8695/gpio.c2
-rw-r--r--arch/arm/mach-ks8695/irq.c18
-rw-r--r--arch/arm/mach-lpc32xx/irq.c10
-rw-r--r--arch/arm/mach-mmp/irq-mmp2.c18
-rw-r--r--arch/arm/mach-mmp/irq-pxa168.c3
-rw-r--r--arch/arm/mach-msm/board-msm8960.c2
-rw-r--r--arch/arm/mach-msm/board-msm8x60.c2
-rw-r--r--arch/arm/mach-msm/board-trout-gpio.c10
-rw-r--r--arch/arm/mach-msm/board-trout-mmc.c2
-rw-r--r--arch/arm/mach-msm/gpio-v2.c49
-rw-r--r--arch/arm/mach-msm/gpio.c18
-rw-r--r--arch/arm/mach-msm/irq-vic.c7
-rw-r--r--arch/arm/mach-msm/irq.c7
-rw-r--r--arch/arm/mach-msm/sirc.c11
-rw-r--r--arch/arm/mach-mv78xx0/irq.c8
-rw-r--r--arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c14
-rw-r--r--arch/arm/mach-mx3/mach-mx31ads.c7
-rw-r--r--arch/arm/mach-mx3/mach-pcm043.c12
-rw-r--r--arch/arm/mach-mx5/Kconfig1
-rw-r--r--arch/arm/mach-mx5/Makefile2
-rw-r--r--arch/arm/mach-mx5/board-mx51_babbage.c5
-rw-r--r--arch/arm/mach-mx5/board-mx53_evk.c9
-rw-r--r--arch/arm/mach-mx5/board-mx53_loco.c25
-rw-r--r--arch/arm/mach-mx5/clock-mx51-mx53.c9
-rw-r--r--arch/arm/mach-mx5/cpu.c59
-rw-r--r--arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c2
-rw-r--r--arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c4
-rw-r--r--arch/arm/mach-mx5/mx51_efika.c7
-rw-r--r--arch/arm/mach-mx5/system.c84
-rw-r--r--arch/arm/mach-mxs/Kconfig2
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c15
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c18
-rw-r--r--arch/arm/mach-mxs/devices-mx23.h4
-rw-r--r--arch/arm/mach-mxs/devices-mx28.h4
-rw-r--r--arch/arm/mach-mxs/devices/Kconfig3
-rw-r--r--arch/arm/mach-mxs/devices/Makefile1
-rw-r--r--arch/arm/mach-mxs/devices/platform-mxs-mmc.c73
-rw-r--r--arch/arm/mach-mxs/gpio.c10
-rw-r--r--arch/arm/mach-mxs/icoll.c3
-rw-r--r--arch/arm/mach-mxs/include/mach/devices-common.h13
-rw-r--r--arch/arm/mach-mxs/mach-mx23evk.c44
-rw-r--r--arch/arm/mach-mxs/mach-mx28evk.c89
-rw-r--r--arch/arm/mach-mxs/module-tx28.c41
-rw-r--r--arch/arm/mach-mxs/module-tx28.h1
-rw-r--r--arch/arm/mach-netx/generic.c6
-rw-r--r--arch/arm/mach-ns9xxx/board-a9m9750dev.c8
-rw-r--r--arch/arm/mach-ns9xxx/include/mach/board.h2
-rw-r--r--arch/arm/mach-ns9xxx/include/mach/module.h5
-rw-r--r--arch/arm/mach-ns9xxx/irq.c59
-rw-r--r--arch/arm/mach-nuc93x/irq.c4
-rw-r--r--arch/arm/mach-omap1/board-osk.c6
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c8
-rw-r--r--arch/arm/mach-omap1/board-voiceblue.c8
-rw-r--r--arch/arm/mach-omap1/fpga.c10
-rw-r--r--arch/arm/mach-omap1/irq.c4
-rw-r--r--arch/arm/mach-omap2/gpmc.c2
-rw-r--r--arch/arm/mach-omap2/irq.c3
-rw-r--r--arch/arm/mach-orion5x/db88f5281-setup.c4
-rw-r--r--arch/arm/mach-orion5x/irq.c8
-rw-r--r--arch/arm/mach-orion5x/rd88f5182-setup.c4
-rw-r--r--arch/arm/mach-orion5x/terastation_pro2-setup.c2
-rw-r--r--arch/arm/mach-orion5x/ts209-setup.c4
-rw-r--r--arch/arm/mach-orion5x/ts78xx-setup.c18
-rw-r--r--arch/arm/mach-pnx4008/irq.c10
-rw-r--r--arch/arm/mach-pxa/am200epd.c8
-rw-r--r--arch/arm/mach-pxa/am300epd.c13
-rw-r--r--arch/arm/mach-pxa/balloon3.c10
-rw-r--r--arch/arm/mach-pxa/cm-x2xx-pci.c5
-rw-r--r--arch/arm/mach-pxa/cm-x2xx.c2
-rw-r--r--arch/arm/mach-pxa/cm-x300.c4
-rw-r--r--arch/arm/mach-pxa/colibri-pxa270-income.c2
-rw-r--r--arch/arm/mach-pxa/colibri-pxa3xx.c2
-rw-r--r--arch/arm/mach-pxa/corgi.c1
-rw-r--r--arch/arm/mach-pxa/devices.c9
-rw-r--r--arch/arm/mach-pxa/em-x270.c2
-rw-r--r--arch/arm/mach-pxa/eseries.c36
-rw-r--r--arch/arm/mach-pxa/ezx.c12
-rw-r--r--arch/arm/mach-pxa/gumstix.c13
-rw-r--r--arch/arm/mach-pxa/idp.c2
-rw-r--r--arch/arm/mach-pxa/include/mach/palmz72.h5
-rw-r--r--arch/arm/mach-pxa/include/mach/pxafb.h4
-rw-r--r--arch/arm/mach-pxa/include/mach/z2.h3
-rw-r--r--arch/arm/mach-pxa/irq.c12
-rw-r--r--arch/arm/mach-pxa/littleton.c2
-rw-r--r--arch/arm/mach-pxa/lpd270.c10
-rw-r--r--arch/arm/mach-pxa/lubbock.c10
-rw-r--r--arch/arm/mach-pxa/magician.c2
-rw-r--r--arch/arm/mach-pxa/mainstone.c10
-rw-r--r--arch/arm/mach-pxa/mioa701.c2
-rw-r--r--arch/arm/mach-pxa/palm27x.c5
-rw-r--r--arch/arm/mach-pxa/palmtc.c2
-rw-r--r--arch/arm/mach-pxa/palmte2.c33
-rw-r--r--arch/arm/mach-pxa/palmz72.c127
-rw-r--r--arch/arm/mach-pxa/pcm990-baseboard.c10
-rw-r--r--arch/arm/mach-pxa/poodle.c3
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c4
-rw-r--r--arch/arm/mach-pxa/raumfeld.c2
-rw-r--r--arch/arm/mach-pxa/saar.c2
-rw-r--r--arch/arm/mach-pxa/spitz.c2
-rw-r--r--arch/arm/mach-pxa/tavorevb.c2
-rw-r--r--arch/arm/mach-pxa/time.c5
-rw-r--r--arch/arm/mach-pxa/tosa.c13
-rw-r--r--arch/arm/mach-pxa/trizeps4.c4
-rw-r--r--arch/arm/mach-pxa/viper.c10
-rw-r--r--arch/arm/mach-pxa/vpac270.c2
-rw-r--r--arch/arm/mach-pxa/z2.c77
-rw-r--r--arch/arm/mach-pxa/zeus.c21
-rw-r--r--arch/arm/mach-pxa/zylonite.c4
-rw-r--r--arch/arm/mach-realview/realview_eb.c2
-rw-r--r--arch/arm/mach-rpc/irq.c14
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c6
-rw-r--r--arch/arm/mach-s3c2412/irq.c12
-rw-r--r--arch/arm/mach-s3c2416/irq.c8
-rw-r--r--arch/arm/mach-s3c2440/irq.c10
-rw-r--r--arch/arm/mach-s3c2440/s3c244x-irq.c14
-rw-r--r--arch/arm/mach-s3c2443/irq.c8
-rw-r--r--arch/arm/mach-s3c64xx/irq-eint.c13
-rw-r--r--arch/arm/mach-s5p64x0/cpu.c2
-rw-r--r--arch/arm/mach-s5pv210/include/mach/irqs.h6
-rw-r--r--arch/arm/mach-s5pv210/mach-smdkv210.c1
-rw-r--r--arch/arm/mach-sa1100/cerf.c2
-rw-r--r--arch/arm/mach-sa1100/irq.c16
-rw-r--r--arch/arm/mach-sa1100/neponset.c8
-rw-r--r--arch/arm/mach-sa1100/pleb.c2
-rw-r--r--arch/arm/mach-shark/irq.c3
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c10
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c6
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c14
-rw-r--r--arch/arm/mach-shmobile/intc-sh7367.c6
-rw-r--r--arch/arm/mach-shmobile/intc-sh7372.c6
-rw-r--r--arch/arm/mach-shmobile/intc-sh7377.c6
-rw-r--r--arch/arm/mach-tcc8k/irq.c6
-rw-r--r--arch/arm/mach-tegra/gpio.c39
-rw-r--r--arch/arm/mach-tegra/irq.c5
-rw-r--r--arch/arm/mach-ux500/Kconfig1
-rw-r--r--arch/arm/mach-ux500/board-mop500-regulators.c201
-rw-r--r--arch/arm/mach-ux500/board-mop500-regulators.h3
-rw-r--r--arch/arm/mach-ux500/board-mop500.c50
-rw-r--r--arch/arm/mach-ux500/board-mop500.h4
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-board-mop500.h15
-rw-r--r--arch/arm/mach-ux500/modem-irq-db5500.c3
-rw-r--r--arch/arm/mach-vt8500/irq.c14
-rw-r--r--arch/arm/mach-w90x900/irq.c4
-rw-r--r--arch/arm/plat-mxc/3ds_debugboard.c14
-rw-r--r--arch/arm/plat-mxc/avic.c4
-rw-r--r--arch/arm/plat-mxc/devices/platform-fec.c2
-rw-r--r--arch/arm/plat-mxc/devices/platform-imxdi_rtc.c2
-rw-r--r--arch/arm/plat-mxc/gpio.c24
-rw-r--r--arch/arm/plat-mxc/include/mach/audmux.h10
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx2x.h12
-rw-r--r--arch/arm/plat-mxc/include/mach/mx50.h4
-rw-r--r--arch/arm/plat-mxc/include/mach/mx51.h1
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h23
-rw-r--r--arch/arm/plat-mxc/include/mach/system.h6
-rw-r--r--arch/arm/plat-mxc/irq-common.c4
-rw-r--r--arch/arm/plat-mxc/time.c25
-rw-r--r--arch/arm/plat-mxc/tzic.c4
-rw-r--r--arch/arm/plat-nomadik/gpio.c57
-rw-r--r--arch/arm/plat-omap/gpio.c31
-rw-r--r--arch/arm/plat-orion/gpio.c31
-rw-r--r--arch/arm/plat-orion/irq.c8
-rw-r--r--arch/arm/plat-pxa/gpio.c6
-rw-r--r--arch/arm/plat-s3c24xx/irq.c43
-rw-r--r--arch/arm/plat-s5p/cpu.c8
-rw-r--r--arch/arm/plat-s5p/irq-eint.c7
-rw-r--r--arch/arm/plat-s5p/irq-gpioint.c22
-rw-r--r--arch/arm/plat-samsung/init.c2
-rw-r--r--arch/arm/plat-samsung/irq-uart.c10
-rw-r--r--arch/arm/plat-samsung/irq-vic-timer.c11
-rw-r--r--arch/arm/plat-samsung/wakeup-mask.c8
-rw-r--r--arch/arm/plat-spear/shirq.c12
-rw-r--r--arch/arm/plat-stmp3xxx/irq.c3
-rw-r--r--arch/arm/plat-stmp3xxx/pinmux.c13
-rw-r--r--arch/arm/plat-versatile/fpga-irq.c12
-rw-r--r--arch/avr32/Kconfig1
-rw-r--r--arch/avr32/mach-at32ap/pio.c2
-rw-r--r--arch/blackfin/Kconfig1
-rw-r--r--arch/blackfin/configs/BF527-AD7160-EVAL_defconfig1
-rw-r--r--arch/blackfin/configs/BF538-EZKIT_defconfig1
-rw-r--r--arch/blackfin/configs/BF561-ACVILON_defconfig1
-rw-r--r--arch/blackfin/configs/BlackStamp_defconfig1
-rw-r--r--arch/blackfin/configs/CM-BF527_defconfig1
-rw-r--r--arch/blackfin/configs/CM-BF533_defconfig1
-rw-r--r--arch/blackfin/configs/CM-BF548_defconfig1
-rw-r--r--arch/blackfin/configs/DNP5370_defconfig1
-rw-r--r--arch/blackfin/configs/H8606_defconfig1
-rw-r--r--arch/blackfin/configs/SRV1_defconfig1
-rw-r--r--arch/blackfin/include/asm/bitops.h4
-rw-r--r--arch/blackfin/kernel/irqchip.c2
-rw-r--r--arch/blackfin/kernel/module.c45
-rw-r--r--arch/blackfin/kernel/trace.c7
-rw-r--r--arch/blackfin/mach-bf561/smp.c6
-rw-r--r--arch/blackfin/mach-common/ints-priority.c43
-rw-r--r--arch/cris/Kconfig4
-rw-r--r--arch/cris/arch-v10/drivers/pcf8563.c2
-rw-r--r--arch/cris/arch-v10/kernel/signal.c2
-rw-r--r--arch/cris/arch-v32/drivers/Makefile1
-rw-r--r--arch/cris/arch-v32/drivers/pcf8563.c377
-rw-r--r--arch/frv/Kconfig2
-rw-r--r--arch/frv/include/asm/system.h9
-rw-r--r--arch/frv/include/asm/thread_info.h4
-rw-r--r--arch/frv/kernel/irq-mb93091.c30
-rw-r--r--arch/frv/kernel/irq-mb93093.c31
-rw-r--r--arch/frv/kernel/irq-mb93493.c25
-rw-r--r--arch/frv/kernel/irq.c80
-rw-r--r--arch/h8300/Kconfig1
-rw-r--r--arch/ia64/Kconfig1
-rw-r--r--arch/ia64/hp/sim/hpsim_irq.c31
-rw-r--r--arch/ia64/include/asm/hw_irq.h3
-rw-r--r--arch/ia64/kernel/iosapic.c119
-rw-r--r--arch/ia64/kernel/irq.c73
-rw-r--r--arch/ia64/kernel/irq_ia64.c10
-rw-r--r--arch/ia64/kernel/irq_lsapic.c23
-rw-r--r--arch/ia64/kernel/mca.c4
-rw-r--r--arch/ia64/kernel/msi_ia64.c49
-rw-r--r--arch/ia64/kernel/smpboot.c14
-rw-r--r--arch/ia64/sn/kernel/irq.c97
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c32
-rw-r--r--arch/ia64/sn/kernel/sn2/sn_proc_fs.c42
-rw-r--r--arch/ia64/xen/irq_xen.c4
-rw-r--r--arch/m32r/Kconfig1
-rw-r--r--arch/m68k/Kconfig1
-rw-r--r--arch/m68k/kernel/irq.c2
-rw-r--r--arch/m68k/platform/5249/intc2.c4
-rw-r--r--arch/m68k/platform/5272/intc.c12
-rw-r--r--arch/m68k/platform/68328/ints.c4
-rw-r--r--arch/m68k/platform/68360/ints.c4
-rw-r--r--arch/m68k/platform/coldfire/intc-2.c10
-rw-r--r--arch/m68k/platform/coldfire/intc-simr.c10
-rw-r--r--arch/m68k/platform/coldfire/intc.c6
-rw-r--r--arch/microblaze/Kconfig2
-rw-r--r--arch/microblaze/kernel/intc.c6
-rw-r--r--arch/microblaze/kernel/irq.c42
-rw-r--r--arch/microblaze/pci/pci-common.c2
-rw-r--r--arch/mips/alchemy/devboards/bcsr.c6
-rw-r--r--arch/mips/alchemy/devboards/db1200/setup.c15
-rw-r--r--arch/mips/alchemy/devboards/db1x00/board_setup.c50
-rw-r--r--arch/mips/alchemy/devboards/pb1000/board_setup.c2
-rw-r--r--arch/mips/alchemy/devboards/pb1100/board_setup.c8
-rw-r--r--arch/mips/alchemy/devboards/pb1200/board_setup.c2
-rw-r--r--arch/mips/alchemy/devboards/pb1500/board_setup.c16
-rw-r--r--arch/mips/alchemy/devboards/pb1550/board_setup.c6
-rw-r--r--arch/mips/alchemy/mtx-1/board_setup.c10
-rw-r--r--arch/mips/alchemy/xxs1500/board_setup.c24
-rw-r--r--arch/mips/ar7/irq.c4
-rw-r--r--arch/mips/ath79/irq.c4
-rw-r--r--arch/mips/bcm63xx/irq.c4
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c1389
-rw-r--r--arch/mips/cavium-octeon/setup.c12
-rw-r--r--arch/mips/cavium-octeon/smp.c39
-rw-r--r--arch/mips/dec/ioasic-irq.c4
-rw-r--r--arch/mips/dec/kn02-irq.c2
-rw-r--r--arch/mips/emma/markeins/irq.c6
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/irq.h243
-rw-r--r--arch/mips/include/asm/octeon/octeon.h2
-rw-r--r--arch/mips/include/asm/unistd.h2
-rw-r--r--arch/mips/jazz/irq.c2
-rw-r--r--arch/mips/jz4740/gpio.c14
-rw-r--r--arch/mips/jz4740/irq.c4
-rw-r--r--arch/mips/kernel/i8259.c6
-rw-r--r--arch/mips/kernel/irq-gic.c2
-rw-r--r--arch/mips/kernel/irq-gt641xx.c4
-rw-r--r--arch/mips/kernel/irq-msc01.c12
-rw-r--r--arch/mips/kernel/irq-rm7000.c2
-rw-r--r--arch/mips/kernel/irq-rm9000.c4
-rw-r--r--arch/mips/kernel/irq.c2
-rw-r--r--arch/mips/kernel/irq_cpu.c4
-rw-r--r--arch/mips/kernel/irq_txx9.c4
-rw-r--r--arch/mips/kernel/smtc.c2
-rw-r--r--arch/mips/lasat/interrupt.c2
-rw-r--r--arch/mips/loongson/common/bonito-irq.c3
-rw-r--r--arch/mips/mti-malta/malta-int.c2
-rw-r--r--arch/mips/mti-malta/malta-time.c2
-rw-r--r--arch/mips/pci/msi-octeon.c24
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c2
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c2
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_smp.c2
-rw-r--r--arch/mips/pnx833x/common/interrupts.c6
-rw-r--r--arch/mips/pnx8550/common/int.c10
-rw-r--r--arch/mips/powertv/asic/irq_asic.c2
-rw-r--r--arch/mips/rb532/irq.c4
-rw-r--r--arch/mips/sgi-ip22/ip22-int.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c2
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c2
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c40
-rw-r--r--arch/mips/sibyte/bcm1480/irq.c3
-rw-r--r--arch/mips/sibyte/sb1250/irq.c3
-rw-r--r--arch/mips/sni/a20r.c2
-rw-r--r--arch/mips/sni/pcimt.c2
-rw-r--r--arch/mips/sni/pcit.c4
-rw-r--r--arch/mips/sni/rm200.c4
-rw-r--r--arch/mips/txx9/generic/irq_tx4927.c2
-rw-r--r--arch/mips/txx9/generic/irq_tx4938.c2
-rw-r--r--arch/mips/txx9/generic/irq_tx4939.c6
-rw-r--r--arch/mips/txx9/jmr3927/irq.c5
-rw-r--r--arch/mips/txx9/rbtx4927/irq.c6
-rw-r--r--arch/mips/txx9/rbtx4938/irq.c6
-rw-r--r--arch/mips/txx9/rbtx4939/irq.c4
-rw-r--r--arch/mips/vr41xx/common/icu.c4
-rw-r--r--arch/mips/vr41xx/common/irq.c2
-rw-r--r--arch/mn10300/Kconfig2
-rw-r--r--arch/mn10300/kernel/irq.c85
-rw-r--r--arch/mn10300/kernel/mn10300-serial.c2
-rw-r--r--arch/mn10300/kernel/smp.c12
-rw-r--r--arch/mn10300/unit-asb2364/irq-fpga.c3
-rw-r--r--arch/parisc/Kconfig1
-rw-r--r--arch/parisc/kernel/irq.c32
-rw-r--r--arch/powerpc/Kconfig3
-rw-r--r--arch/powerpc/configs/44x/warp_defconfig1
-rw-r--r--arch/powerpc/configs/52xx/motionpro_defconfig1
-rw-r--r--arch/powerpc/configs/86xx/gef_ppc9a_defconfig1
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc310_defconfig1
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc610_defconfig1
-rw-r--r--arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig1
-rw-r--r--arch/powerpc/configs/e55xx_smp_defconfig1
-rw-r--r--arch/powerpc/configs/linkstation_defconfig1
-rw-r--r--arch/powerpc/configs/mpc512x_defconfig1
-rw-r--r--arch/powerpc/configs/mpc5200_defconfig1
-rw-r--r--arch/powerpc/configs/mpc85xx_defconfig1
-rw-r--r--arch/powerpc/configs/mpc85xx_smp_defconfig1
-rw-r--r--arch/powerpc/configs/mpc86xx_defconfig1
-rw-r--r--arch/powerpc/configs/pasemi_defconfig1
-rw-r--r--arch/powerpc/configs/ppc6xx_defconfig1
-rw-r--r--arch/powerpc/configs/pseries_defconfig3
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h6
-rw-r--r--arch/powerpc/include/asm/machdep.h3
-rw-r--r--arch/powerpc/include/asm/mmu-hash64.h2
-rw-r--r--arch/powerpc/include/asm/page.h2
-rw-r--r--arch/powerpc/include/asm/qe_ic.h16
-rw-r--r--arch/powerpc/include/asm/reg_booke.h2
-rw-r--r--arch/powerpc/include/asm/smp.h5
-rw-r--r--arch/powerpc/include/asm/systbl.h4
-rw-r--r--arch/powerpc/include/asm/unistd.h6
-rw-r--r--arch/powerpc/kernel/dma.c18
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S28
-rw-r--r--arch/powerpc/kernel/head_32.S9
-rw-r--r--arch/powerpc/kernel/head_64.S7
-rw-r--r--arch/powerpc/kernel/idle_power4.S21
-rw-r--r--arch/powerpc/kernel/irq.c84
-rw-r--r--arch/powerpc/kernel/machine_kexec.c6
-rw-r--r--arch/powerpc/kernel/pci-common.c2
-rw-r--r--arch/powerpc/kernel/smp.c153
-rw-r--r--arch/powerpc/kernel/time.c17
-rw-r--r--arch/powerpc/mm/dma-noncoherent.c20
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads_cpld.c6
-rw-r--r--arch/powerpc/platforms/52xx/media5200.c19
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c10
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c6
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c16
-rw-r--r--arch/powerpc/platforms/85xx/ksi8560.c4
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c4
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ds.c4
-rw-r--r--arch/powerpc/platforms/85xx/sbc8560.c4
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c12
-rw-r--r--arch/powerpc/platforms/85xx/stx_gp3.c4
-rw-r--r--arch/powerpc/platforms/85xx/tqm85xx.c4
-rw-r--r--arch/powerpc/platforms/86xx/gef_pic.c8
-rw-r--r--arch/powerpc/platforms/86xx/pic.c4
-rw-r--r--arch/powerpc/platforms/8xx/m8xx_setup.c6
-rw-r--r--arch/powerpc/platforms/cell/Kconfig1
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c14
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.c5
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c64
-rw-r--r--arch/powerpc/platforms/cell/setup.c8
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c21
-rw-r--r--arch/powerpc/platforms/chrp/setup.c4
-rw-r--r--arch/powerpc/platforms/embedded6xx/flipper-pic.c10
-rw-r--r--arch/powerpc/platforms/embedded6xx/hlwd-pic.c20
-rw-r--r--arch/powerpc/platforms/embedded6xx/holly.c4
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c4
-rw-r--r--arch/powerpc/platforms/iseries/irq.c4
-rw-r--r--arch/powerpc/platforms/maple/pci.c2
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c2
-rw-r--r--arch/powerpc/platforms/powermac/pci.c2
-rw-r--r--arch/powerpc/platforms/powermac/pic.c17
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h1
-rw-r--r--arch/powerpc/platforms/powermac/setup.c56
-rw-r--r--arch/powerpc/platforms/powermac/smp.c154
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c14
-rw-r--r--arch/powerpc/platforms/pseries/msi.c4
-rw-r--r--arch/powerpc/platforms/pseries/nvram.c24
-rw-r--r--arch/powerpc/platforms/pseries/offline_states.h2
-rw-r--r--arch/powerpc/platforms/pseries/setup.c4
-rw-r--r--arch/powerpc/platforms/pseries/smp.c4
-rw-r--r--arch/powerpc/platforms/pseries/xics.c79
-rw-r--r--arch/powerpc/sysdev/cpm1.c4
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c47
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c43
-rw-r--r--arch/powerpc/sysdev/i8259.c8
-rw-r--r--arch/powerpc/sysdev/ipic.c22
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c11
-rw-r--r--arch/powerpc/sysdev/mpc8xxx_gpio.c12
-rw-r--r--arch/powerpc/sysdev/mpic.c43
-rw-r--r--arch/powerpc/sysdev/mpic_pasemi_msi.c8
-rw-r--r--arch/powerpc/sysdev/mpic_u3msi.c8
-rw-r--r--arch/powerpc/sysdev/mv64x60_pic.c5
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c16
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c6
-rw-r--r--arch/powerpc/sysdev/uic.c41
-rw-r--r--arch/powerpc/sysdev/xilinx_intc.c20
-rw-r--r--arch/score/Kconfig1
-rw-r--r--arch/score/include/asm/irqflags.h2
-rw-r--r--arch/score/kernel/irq.c53
-rw-r--r--arch/sh/Kconfig1
-rw-r--r--arch/sh/boards/board-magicpanelr2.c12
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c6
-rw-r--r--arch/sh/boards/mach-cayman/irq.c4
-rw-r--r--arch/sh/boards/mach-dreamcast/irq.c3
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c14
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c4
-rw-r--r--arch/sh/boards/mach-microdev/irq.c2
-rw-r--r--arch/sh/boards/mach-migor/setup.c4
-rw-r--r--arch/sh/boards/mach-se/7206/irq.c5
-rw-r--r--arch/sh/boards/mach-se/7343/irq.c23
-rw-r--r--arch/sh/boards/mach-se/7722/irq.c15
-rw-r--r--arch/sh/boards/mach-se/7724/irq.c15
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c6
-rw-r--r--arch/sh/boards/mach-x3proto/gpio.c8
-rw-r--r--arch/sh/cchips/hd6446x/hd64461.c6
-rw-r--r--arch/sh/kernel/cpu/irq/imask.c4
-rw-r--r--arch/sh/kernel/cpu/irq/intc-sh5.c2
-rw-r--r--arch/sh/kernel/cpu/irq/ipr.c6
-rw-r--r--arch/sparc/Kconfig3
-rw-r--r--arch/sparc/include/asm/unistd.h3
-rw-r--r--arch/sparc/kernel/auxio_64.c2
-rw-r--r--arch/sparc/kernel/central.c4
-rw-r--r--arch/sparc/kernel/ds.c2
-rw-r--r--arch/sparc/kernel/entry.S2
-rw-r--r--arch/sparc/kernel/irq_64.c123
-rw-r--r--arch/sparc/kernel/mdesc.c2
-rw-r--r--arch/sparc/kernel/pci.c2
-rw-r--r--arch/sparc/kernel/pci_fire.c2
-rw-r--r--arch/sparc/kernel/pci_msi.c15
-rw-r--r--arch/sparc/kernel/pci_psycho.c2
-rw-r--r--arch/sparc/kernel/pci_sabre.c2
-rw-r--r--arch/sparc/kernel/pci_schizo.c2
-rw-r--r--arch/sparc/kernel/pci_sun4v.c2
-rw-r--r--arch/sparc/kernel/power.c2
-rw-r--r--arch/sparc/kernel/systbls_32.S2
-rw-r--r--arch/sparc/kernel/systbls_64.S2
-rw-r--r--arch/sparc/kernel/time_64.c6
-rw-r--r--arch/tile/Kconfig2
-rw-r--r--arch/tile/kernel/irq.c45
-rw-r--r--arch/um/Kconfig.common1
-rw-r--r--arch/unicore32/Kconfig2
-rw-r--r--arch/unicore32/kernel/irq.c58
-rw-r--r--arch/x86/crypto/aesni-intel_asm.S5
-rw-r--r--arch/x86/crypto/aesni-intel_glue.c14
-rw-r--r--arch/x86/kernel/apb_timer.c2
-rw-r--r--arch/x86/xen/p2m.c10
-rw-r--r--arch/xtensa/Kconfig1
-rw-r--r--drivers/acpi/video.c6
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c2
-rw-r--r--drivers/ata/pata_palmld.c43
-rw-r--r--drivers/ata/pata_rb532_cf.c4
-rw-r--r--drivers/atm/solos-pci.c39
-rw-r--r--drivers/block/drbd/drbd_bitmap.c14
-rw-r--r--drivers/char/tpm/tpm.c2
-rw-r--r--drivers/connector/cn_queue.c58
-rw-r--r--drivers/connector/connector.c47
-rw-r--r--drivers/dma/ipu/ipu_irq.c58
-rw-r--r--drivers/edac/amd64_edac.c2
-rw-r--r--drivers/gpio/Kconfig5
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/ab8500-gpio.c522
-rw-r--r--drivers/hwmon/gpio-fan.c2
-rw-r--r--drivers/input/keyboard/lm8323.c4
-rw-r--r--drivers/input/serio/ams_delta_serio.c2
-rw-r--r--drivers/input/touchscreen/mainstone-wm97xx.c2
-rw-r--r--drivers/input/touchscreen/zylonite-wm97xx.c2
-rw-r--r--drivers/macintosh/therm_pm72.c60
-rw-r--r--drivers/md/md.c8
-rw-r--r--drivers/memstick/host/r592.c6
-rw-r--r--drivers/mfd/Kconfig16
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/ab8500-core.c14
-rw-r--r--drivers/mfd/ab8500-i2c.c2
-rw-r--r--drivers/misc/sgi-gru/grufile.c2
-rw-r--r--drivers/mmc/card/mmc_test.c3
-rw-r--r--drivers/mmc/core/sd_ops.c14
-rw-r--r--drivers/mmc/host/Kconfig14
-rw-r--r--drivers/mmc/host/Makefile8
-rw-r--r--drivers/mmc/host/dw_mmc.c4
-rw-r--r--drivers/mmc/host/mmci.c13
-rw-r--r--drivers/mmc/host/of_mmc_spi.c2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c86
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h3
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c3
-rw-r--r--drivers/mmc/host/sdhci-pci.c6
-rw-r--r--drivers/mmc/host/sdhci-pltfm.h2
-rw-r--r--drivers/mmc/host/sdhci-spear.c2
-rw-r--r--drivers/mmc/host/sdhci.h1
-rw-r--r--drivers/mmc/host/sh_mobile_sdhi.c (renamed from drivers/mfd/sh_mobile_sdhi.c)95
-rw-r--r--drivers/mmc/host/tmio_mmc.c1285
-rw-r--r--drivers/mmc/host/tmio_mmc.h123
-rw-r--r--drivers/mmc/host/tmio_mmc_dma.c317
-rw-r--r--drivers/mmc/host/tmio_mmc_pio.c897
-rw-r--r--drivers/mmc/host/via-sdmmc.c5
-rw-r--r--drivers/net/atlx/atl2.c22
-rw-r--r--drivers/net/bfin_mac.c13
-rw-r--r--drivers/net/bnx2.c2
-rw-r--r--drivers/net/bonding/bond_alb.h2
-rw-r--r--drivers/net/can/c_can/c_can.c16
-rw-r--r--drivers/net/can/c_can/c_can_platform.c9
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c14
-rw-r--r--drivers/net/dm9000.c8
-rw-r--r--drivers/net/irda/via-ircc.c94
-rw-r--r--drivers/net/jme.c30
-rw-r--r--drivers/net/ksz884x.c2
-rw-r--r--drivers/net/mlx4/en_netdev.c3
-rw-r--r--drivers/net/mlx4/eq.c4
-rw-r--r--drivers/net/mlx4/mcg.c3
-rw-r--r--drivers/net/myri10ge/myri10ge.c37
-rw-r--r--drivers/net/netxen/netxen_nic_ethtool.c2
-rw-r--r--drivers/net/phy/phy_device.c8
-rw-r--r--drivers/net/qlcnic/qlcnic_ethtool.c2
-rw-r--r--drivers/net/s2io.c2
-rw-r--r--drivers/net/tg3.c6
-rw-r--r--drivers/net/usb/Kconfig15
-rw-r--r--drivers/net/usb/Makefile1
-rw-r--r--drivers/net/usb/cdc_ether.c21
-rw-r--r--drivers/net/usb/lg-vl600.c346
-rw-r--r--drivers/net/usb/usbnet.c10
-rw-r--r--drivers/net/vmxnet3/vmxnet3_ethtool.c4
-rw-r--r--drivers/net/vxge/vxge-ethtool.c4
-rw-r--r--drivers/net/wireless/p54/p54spi.c3
-rw-r--r--drivers/net/wireless/wl1251/sdio.c2
-rw-r--r--drivers/net/wireless/wl1251/spi.c2
-rw-r--r--drivers/parisc/eisa.c2
-rw-r--r--drivers/parisc/gsc.c4
-rw-r--r--drivers/parisc/superio.c3
-rw-r--r--drivers/pci/dmar.c12
-rw-r--r--drivers/pci/htirq.c16
-rw-r--r--drivers/pci/intel-iommu.c2
-rw-r--r--drivers/pci/intr_remapping.c2
-rw-r--r--drivers/pci/msi.c10
-rw-r--r--drivers/pcmcia/bfin_cf_pcmcia.c2
-rw-r--r--drivers/pcmcia/db1xxx_ss.c2
-rw-r--r--drivers/pcmcia/pxa2xx_colibri.c133
-rw-r--r--drivers/pcmcia/pxa2xx_palmld.c42
-rw-r--r--drivers/pcmcia/pxa2xx_palmtc.c75
-rw-r--r--drivers/pcmcia/pxa2xx_palmtx.c57
-rw-r--r--drivers/pcmcia/pxa2xx_vpac270.c110
-rw-r--r--drivers/pcmcia/sa1100_nanoengine.c2
-rw-r--r--drivers/pcmcia/soc_common.c14
-rw-r--r--drivers/pcmcia/xxs1500_ss.c2
-rw-r--r--drivers/platform/x86/Kconfig90
-rw-r--r--drivers/platform/x86/Makefile9
-rw-r--r--drivers/platform/x86/acer-wmi.c127
-rw-r--r--drivers/platform/x86/asus-laptop.c182
-rw-r--r--drivers/platform/x86/asus-nb-wmi.c98
-rw-r--r--drivers/platform/x86/asus-wmi.c1656
-rw-r--r--drivers/platform/x86/asus-wmi.h58
-rw-r--r--drivers/platform/x86/compal-laptop.c8
-rw-r--r--drivers/platform/x86/dell-wmi-aio.c171
-rw-r--r--drivers/platform/x86/eeepc-laptop.c2
-rw-r--r--drivers/platform/x86/eeepc-wmi.c912
-rw-r--r--drivers/platform/x86/hp-wmi.c312
-rw-r--r--drivers/platform/x86/ideapad-laptop.c2
-rw-r--r--drivers/platform/x86/intel_ips.c2
-rw-r--r--drivers/platform/x86/intel_mid_powerbtn.c148
-rw-r--r--drivers/platform/x86/intel_mid_thermal.c576
-rw-r--r--drivers/platform/x86/intel_pmic_gpio.c8
-rw-r--r--drivers/platform/x86/intel_rar_register.c2
-rw-r--r--drivers/platform/x86/intel_scu_ipc.c2
-rw-r--r--drivers/platform/x86/msi-laptop.c95
-rw-r--r--drivers/platform/x86/samsung-laptop.c832
-rw-r--r--drivers/platform/x86/sony-laptop.c501
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c4
-rw-r--r--drivers/platform/x86/xo15-ebook.c180
-rw-r--r--drivers/power/z2_battery.c4
-rw-r--r--drivers/regulator/Kconfig2
-rw-r--r--drivers/regulator/ab3100.c51
-rw-r--r--drivers/regulator/ab8500.c270
-rw-r--r--drivers/regulator/core.c116
-rw-r--r--drivers/regulator/max8997.c1
-rw-r--r--drivers/regulator/max8998.c1
-rw-r--r--drivers/regulator/tps6524x-regulator.c2
-rw-r--r--drivers/regulator/wm831x-dcdc.c32
-rw-r--r--drivers/regulator/wm831x-isink.c8
-rw-r--r--drivers/regulator/wm831x-ldo.c17
-rw-r--r--drivers/rtc/rtc-sh.c6
-rw-r--r--drivers/sh/intc/core.c23
-rw-r--r--drivers/sh/intc/internals.h4
-rw-r--r--drivers/sh/intc/virq.c12
-rw-r--r--drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c4
-rw-r--r--drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c2
-rw-r--r--drivers/tty/hvc/hvc_xen.c2
-rw-r--r--drivers/tty/serial/Kconfig2
-rw-r--r--drivers/tty/serial/apbuart.c34
-rw-r--r--drivers/tty/serial/msm_serial_hs.c4
-rw-r--r--drivers/usb/gadget/pxa25x_udc.c76
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c2
-rw-r--r--drivers/usb/musb/tusb6010.c2
-rw-r--r--drivers/video/pxafb.c136
-rw-r--r--drivers/video/pxafb.h3
-rw-r--r--drivers/vlynq/vlynq.c64
-rw-r--r--drivers/w1/masters/ds1wm.c4
-rw-r--r--drivers/watchdog/davinci_wdt.c22
-rw-r--r--drivers/watchdog/max63xx_wdt.c20
-rw-r--r--drivers/watchdog/nv_tco.c2
-rw-r--r--drivers/watchdog/pnx4008_wdt.c28
-rw-r--r--drivers/watchdog/s3c2410_wdt.c19
-rw-r--r--drivers/watchdog/softdog.c16
-rw-r--r--drivers/watchdog/sp5100_tco.c16
-rw-r--r--drivers/xen/events.c26
-rw-r--r--drivers/xen/gntdev.c6
-rw-r--r--fs/btrfs/btrfs_inode.h3
-rw-r--r--fs/btrfs/compression.c17
-rw-r--r--fs/btrfs/ctree.c159
-rw-r--r--fs/btrfs/ctree.h19
-rw-r--r--fs/btrfs/delayed-ref.c6
-rw-r--r--fs/btrfs/dir-item.c45
-rw-r--r--fs/btrfs/disk-io.c132
-rw-r--r--fs/btrfs/extent-tree.c229
-rw-r--r--fs/btrfs/extent_io.c3
-rw-r--r--fs/btrfs/extent_io.h1
-rw-r--r--fs/btrfs/file-item.c5
-rw-r--r--fs/btrfs/file.c388
-rw-r--r--fs/btrfs/free-space-cache.c510
-rw-r--r--fs/btrfs/free-space-cache.h2
-rw-r--r--fs/btrfs/inode-map.c3
-rw-r--r--fs/btrfs/inode.c366
-rw-r--r--fs/btrfs/ioctl.c100
-rw-r--r--fs/btrfs/ordered-data.c8
-rw-r--r--fs/btrfs/relocation.c8
-rw-r--r--fs/btrfs/root-tree.c6
-rw-r--r--fs/btrfs/super.c5
-rw-r--r--fs/btrfs/transaction.c14
-rw-r--r--fs/btrfs/tree-log.c57
-rw-r--r--fs/btrfs/volumes.c164
-rw-r--r--fs/btrfs/volumes.h12
-rw-r--r--fs/btrfs/xattr.c2
-rw-r--r--fs/ceph/addr.c2
-rw-r--r--fs/ceph/mds_client.c6
-rw-r--r--fs/ceph/snap.c4
-rw-r--r--fs/ceph/super.c2
-rw-r--r--fs/ecryptfs/crypto.c2
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h30
-rw-r--r--fs/ecryptfs/file.c9
-rw-r--r--fs/ecryptfs/inode.c24
-rw-r--r--fs/ecryptfs/keystore.c272
-rw-r--r--fs/ecryptfs/main.c10
-rw-r--r--fs/ecryptfs/mmap.c61
-rw-r--r--fs/ecryptfs/read_write.c12
-rw-r--r--fs/ecryptfs/super.c3
-rw-r--r--fs/nfs/namespace.c4
-rw-r--r--fs/nfs/nfs4state.c3
-rw-r--r--fs/nfs/pagelist.c4
-rw-r--r--fs/nfs/write.c13
-rw-r--r--fs/nilfs2/file.c11
-rw-r--r--fs/nilfs2/nilfs.h14
-rw-r--r--fs/nilfs2/page.c4
-rw-r--r--fs/ocfs2/acl.c1
-rw-r--r--fs/ocfs2/alloc.c214
-rw-r--r--fs/ocfs2/aops.c82
-rw-r--r--fs/ocfs2/buffer_head_io.c49
-rw-r--r--fs/ocfs2/cluster/heartbeat.c3
-rw-r--r--fs/ocfs2/cluster/masklog.c20
-rw-r--r--fs/ocfs2/cluster/masklog.h105
-rw-r--r--fs/ocfs2/cluster/tcp.c10
-rw-r--r--fs/ocfs2/dcache.c45
-rw-r--r--fs/ocfs2/dir.c121
-rw-r--r--fs/ocfs2/dlm/dlmconvert.c6
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c36
-rw-r--r--fs/ocfs2/dlm/dlmlock.c10
-rw-r--r--fs/ocfs2/dlm/dlmmaster.c6
-rw-r--r--fs/ocfs2/dlm/dlmrecovery.c9
-rw-r--r--fs/ocfs2/dlm/dlmunlock.c4
-rw-r--r--fs/ocfs2/dlmglue.c246
-rw-r--r--fs/ocfs2/export.c47
-rw-r--r--fs/ocfs2/extent_map.c10
-rw-r--r--fs/ocfs2/file.c220
-rw-r--r--fs/ocfs2/heartbeat.c4
-rw-r--r--fs/ocfs2/inode.c134
-rw-r--r--fs/ocfs2/ioctl.c41
-rw-r--r--fs/ocfs2/journal.c168
-rw-r--r--fs/ocfs2/localalloc.c109
-rw-r--r--fs/ocfs2/locks.c1
-rw-r--r--fs/ocfs2/mmap.c7
-rw-r--r--fs/ocfs2/namei.c175
-rw-r--r--fs/ocfs2/ocfs2.h23
-rw-r--r--fs/ocfs2/ocfs2_trace.h2739
-rw-r--r--fs/ocfs2/quota_global.c45
-rw-r--r--fs/ocfs2/quota_local.c16
-rw-r--r--fs/ocfs2/refcounttree.c158
-rw-r--r--fs/ocfs2/reservations.c57
-rw-r--r--fs/ocfs2/resize.c23
-rw-r--r--fs/ocfs2/slot_map.c16
-rw-r--r--fs/ocfs2/suballoc.c189
-rw-r--r--fs/ocfs2/super.c89
-rw-r--r--fs/ocfs2/symlink.c14
-rw-r--r--fs/ocfs2/sysfile.c1
-rw-r--r--fs/ocfs2/uptodate.c73
-rw-r--r--fs/ocfs2/xattr.c155
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c344
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h40
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c6
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c4
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c36
-rw-r--r--fs/xfs/linux-2.6/xfs_sync.c30
-rw-r--r--fs/xfs/xfs_inode.c2
-rw-r--r--fs/xfs/xfs_inode_item.c6
-rw-r--r--fs/xfs/xfs_trans_buf.c3
-rw-r--r--fs/xfs/xfs_vnodeops.c3
-rw-r--r--fs/xfs/xfs_vnodeops.h1
-rw-r--r--include/keys/ceph-type.h8
-rw-r--r--include/linux/atmdev.h1
-rw-r--r--include/linux/can/core.h9
-rw-r--r--include/linux/ceph/auth.h4
-rw-r--r--include/linux/ceph/libceph.h2
-rw-r--r--include/linux/connector.h16
-rw-r--r--include/linux/ethtool.h1
-rw-r--r--include/linux/fs.h2
-rw-r--r--include/linux/input.h7
-rw-r--r--include/linux/interrupt.h8
-rw-r--r--include/linux/irq.h187
-rw-r--r--include/linux/irqdesc.h60
-rw-r--r--include/linux/kexec.h1
-rw-r--r--include/linux/mfd/ab8500.h47
-rw-r--r--include/linux/mfd/ab8500/gpio.h21
-rw-r--r--include/linux/mmc/sh_mobile_sdhi.h (renamed from include/linux/mfd/sh_mobile_sdhi.h)0
-rw-r--r--include/linux/mmc/tmio.h63
-rw-r--r--include/linux/nfs_page.h1
-rw-r--r--include/linux/regulator/ab8500.h51
-rw-r--r--include/linux/regulator/consumer.h2
-rw-r--r--include/linux/regulator/driver.h11
-rw-r--r--include/linux/regulator/machine.h1
-rw-r--r--include/linux/skbuff.h8
-rw-r--r--include/linux/sonypi.h1
-rw-r--r--include/linux/usb/usbnet.h3
-rw-r--r--include/linux/vmalloc.h32
-rw-r--r--include/net/dst.h2
-rw-r--r--include/net/if_inet6.h16
-rw-r--r--include/net/ip.h8
-rw-r--r--include/net/rose.h8
-rw-r--r--include/net/xfrm.h22
-rw-r--r--include/trace/events/btrfs.h667
-rw-r--r--kernel/irq/Kconfig11
-rw-r--r--kernel/irq/autoprobe.c4
-rw-r--r--kernel/irq/chip.c283
-rw-r--r--kernel/irq/compat.h72
-rw-r--r--kernel/irq/debug.h12
-rw-r--r--kernel/irq/dummychip.c9
-rw-r--r--kernel/irq/handle.c19
-rw-r--r--kernel/irq/internals.h16
-rw-r--r--kernel/irq/irqdesc.c3
-rw-r--r--kernel/irq/manage.c102
-rw-r--r--kernel/irq/migration.c15
-rw-r--r--kernel/irq/proc.c8
-rw-r--r--kernel/irq/resend.c1
-rw-r--r--kernel/irq/settings.h55
-rw-r--r--kernel/irq/spurious.c11
-rw-r--r--kernel/kexec.c5
-rw-r--r--kernel/signal.c4
-rw-r--r--mm/nommu.c52
-rw-r--r--mm/percpu.c3
-rw-r--r--net/appletalk/ddp.c11
-rw-r--r--net/atm/common.c1
-rw-r--r--net/bridge/br_if.c6
-rw-r--r--net/bridge/br_multicast.c2
-rw-r--r--net/bridge/br_private.h2
-rw-r--r--net/bridge/br_stp_if.c11
-rw-r--r--net/can/af_can.c9
-rw-r--r--net/can/bcm.c4
-rw-r--r--net/can/raw.c4
-rw-r--r--net/ceph/Kconfig1
-rw-r--r--net/ceph/auth.c8
-rw-r--r--net/ceph/auth_x.c8
-rw-r--r--net/ceph/ceph_common.c112
-rw-r--r--net/ceph/crypto.c73
-rw-r--r--net/ceph/crypto.h4
-rw-r--r--net/ceph/mon_client.c2
-rw-r--r--net/ceph/osd_client.c12
-rw-r--r--net/core/dev.c79
-rw-r--r--net/core/ethtool.c17
-rw-r--r--net/ipv4/arp.c3
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/fib_trie.c4
-rw-r--r--net/ipv4/ip_options.c6
-rw-r--r--net/ipv4/raw.c1
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/ndisc.c2
-rw-r--r--net/irda/iriap.c6
-rw-r--r--net/irda/irnet/irnet_ppp.c3
-rw-r--r--net/rose/af_rose.c8
-rw-r--r--net/rose/rose_loopback.c13
-rw-r--r--net/rose/rose_route.c20
-rw-r--r--net/rose/rose_subr.c101
-rw-r--r--net/sctp/protocol.c4
-rw-r--r--net/sunrpc/sched.c4
-rw-r--r--net/xfrm/xfrm_input.c4
-rw-r--r--net/xfrm/xfrm_output.c4
-rw-r--r--net/xfrm/xfrm_replay.c17
-rw-r--r--net/xfrm/xfrm_state.c6
-rw-r--r--net/xfrm/xfrm_user.c24
-rw-r--r--security/selinux/ss/services.c2
-rw-r--r--sound/soc/soc-jack.c2
903 files changed, 20286 insertions, 11843 deletions
diff --git a/Documentation/ABI/testing/sysfs-driver-samsung-laptop b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
new file mode 100644
index 00000000000..0a810231aad
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-driver-samsung-laptop
@@ -0,0 +1,19 @@
+What: /sys/devices/platform/samsung/performance_level
+Date: January 1, 2010
+KernelVersion: 2.6.33
+Contact: Greg Kroah-Hartman <gregkh@suse.de>
+Description: Some Samsung laptops have different "performance levels"
+ that are can be modified by a function key, and by this
+ sysfs file. These values don't always make a whole lot
+ of sense, but some users like to modify them to keep
+ their fans quiet at all costs. Reading from this file
+ will show the current performance level. Writing to the
+ file can change this value.
+ Valid options:
+ "silent"
+ "normal"
+ "overclock"
+ Note that not all laptops support all of these options.
+ Specifically, not all support the "overclock" option,
+ and it's still unknown if this value even changes
+ anything, other than making the user feel a bit better.
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-wmi b/Documentation/ABI/testing/sysfs-platform-asus-wmi
new file mode 100644
index 00000000000..2e7df91620d
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-platform-asus-wmi
@@ -0,0 +1,31 @@
+What: /sys/devices/platform/<platform>/cpufv
+Date: Oct 2010
+KernelVersion: 2.6.37
+Contact: "Corentin Chary" <corentincj@iksaif.net>
+Description:
+ Change CPU clock configuration (write-only).
+ There are three available clock configuration:
+ * 0 -> Super Performance Mode
+ * 1 -> High Performance Mode
+ * 2 -> Power Saving Mode
+
+What: /sys/devices/platform/<platform>/camera
+Date: Jan 2010
+KernelVersion: 2.6.39
+Contact: "Corentin Chary" <corentincj@iksaif.net>
+Description:
+ Control the camera. 1 means on, 0 means off.
+
+What: /sys/devices/platform/<platform>/cardr
+Date: Jan 2010
+KernelVersion: 2.6.39
+Contact: "Corentin Chary" <corentincj@iksaif.net>
+Description:
+ Control the card reader. 1 means on, 0 means off.
+
+What: /sys/devices/platform/<platform>/touchpad
+Date: Jan 2010
+KernelVersion: 2.6.39
+Contact: "Corentin Chary" <corentincj@iksaif.net>
+Description:
+ Control the card touchpad. 1 means on, 0 means off.
diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
deleted file mode 100644
index e4b5fef5fad..00000000000
--- a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi
+++ /dev/null
@@ -1,10 +0,0 @@
-What: /sys/devices/platform/eeepc-wmi/cpufv
-Date: Oct 2010
-KernelVersion: 2.6.37
-Contact: "Corentin Chary" <corentincj@iksaif.net>
-Description:
- Change CPU clock configuration (write-only).
- There are three available clock configuration:
- * 0 -> Super Performance Mode
- * 1 -> High Performance Mode
- * 2 -> Power Saving Mode
diff --git a/Documentation/laptops/sony-laptop.txt b/Documentation/laptops/sony-laptop.txt
index 23ce7d350d1..2bd4e82e5d9 100644
--- a/Documentation/laptops/sony-laptop.txt
+++ b/Documentation/laptops/sony-laptop.txt
@@ -14,7 +14,8 @@ Some models report hotkeys through the SNC or SPIC devices, such events are
reported both through the ACPI subsystem as acpi events and through the INPUT
subsystem. See the logs of acpid or /proc/acpi/event and
/proc/bus/input/devices to find out what those events are and which input
-devices are created by the driver.
+devices are created by the driver. Additionally, loading the driver with the
+debug option will report all events in the kernel log.
Backlight control:
------------------
@@ -64,6 +65,16 @@ powers off the sound card,
# echo "1" > /sys/devices/platform/sony-laptop/audiopower
powers on the sound card.
+
+RFkill control:
+---------------
+More recent Vaio models expose a consistent set of ACPI methods to
+control radio frequency emitting devices. If you are a lucky owner of
+such a laptop you will find the necessary rfkill devices under
+/sys/class/rfkill. Check those starting with sony-* in
+ # grep . /sys/class/rfkill/*/{state,name}
+
+
Development:
------------
@@ -75,8 +86,21 @@ pass the option 'debug=1'.
REPEAT: DON'T DO THIS IF YOU DON'T LIKE RISKY BUSINESS.
In your kernel logs you will find the list of all ACPI methods
-the SNC device has on your laptop. You can see the GCDP/GCDP methods
-used to pwer on/off the CD drive, but there are others.
+the SNC device has on your laptop.
+
+* For new models you will see a long list of meaningless method names,
+reading the DSDT table source should reveal that:
+(1) the SNC device uses an internal capability lookup table
+(2) SN00 is used to find values in the lookup table
+(3) SN06 and SN07 are used to call into the real methods based on
+ offsets you can obtain iterating the table using SN00
+(4) SN02 used to enable events.
+Some values in the capability lookup table are more or less known, see
+the code for all sony_call_snc_handle calls, others are more obscure.
+
+* For old models you can see the GCDP/GCDP methods used to pwer on/off
+the CD drive, but there are others and they are usually different from
+model to model.
I HAVE NO IDEA WHAT THOSE METHODS DO.
@@ -108,9 +132,8 @@ Bugs/Limitations:
laptop, including permanent damage.
* The sony-laptop and sonypi drivers do not interact at all. In the
- future, sonypi could use sony-laptop to do (part of) its business.
+ future, sonypi will be removed and replaced by sony-laptop.
* spicctrl, which is the userspace tool used to communicate with the
- sonypi driver (through /dev/sonypi) does not try to use the
- sony-laptop driver. In the future, spicctrl could try sonypi first,
- and if it isn't present, try sony-laptop instead.
+ sonypi driver (through /dev/sonypi) is deprecated as well since all
+ its features are now available under the sysfs tree via sony-laptop.
diff --git a/MAINTAINERS b/MAINTAINERS
index 8aa1cacddbc..6b4b9cdec37 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1157,14 +1157,14 @@ S: Maintained
F: Documentation/hwmon/asc7621
F: drivers/hwmon/asc7621.c
-ASUS ACPI EXTRAS DRIVER
+ASUS NOTEBOOKS AND EEEPC ACPI/WMI EXTRAS DRIVERS
M: Corentin Chary <corentincj@iksaif.net>
-M: Karol Kozimor <sziwan@users.sourceforge.net>
L: acpi4asus-user@lists.sourceforge.net
L: platform-driver-x86@vger.kernel.org
W: http://acpi4asus.sf.net
S: Maintained
-F: drivers/platform/x86/asus_acpi.c
+F: drivers/platform/x86/asus*.c
+F: drivers/platform/x86/eeepc*.c
ASUS ASB100 HARDWARE MONITOR DRIVER
M: "Mark M. Hoffman" <mhoffman@lightlink.com>
@@ -1172,14 +1172,6 @@ L: lm-sensors@lm-sensors.org
S: Maintained
F: drivers/hwmon/asb100.c
-ASUS LAPTOP EXTRAS DRIVER
-M: Corentin Chary <corentincj@iksaif.net>
-L: acpi4asus-user@lists.sourceforge.net
-L: platform-driver-x86@vger.kernel.org
-W: http://acpi4asus.sf.net
-S: Maintained
-F: drivers/platform/x86/asus-laptop.c
-
ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API
M: Dan Williams <dan.j.williams@intel.com>
W: http://sourceforge.net/projects/xscaleiop
@@ -2414,22 +2406,6 @@ T: git git://git.alsa-project.org/alsa-kernel.git
S: Maintained
F: sound/usb/misc/ua101.c
-EEEPC LAPTOP EXTRAS DRIVER
-M: Corentin Chary <corentincj@iksaif.net>
-L: acpi4asus-user@lists.sourceforge.net
-L: platform-driver-x86@vger.kernel.org
-W: http://acpi4asus.sf.net
-S: Maintained
-F: drivers/platform/x86/eeepc-laptop.c
-
-EEEPC WMI EXTRAS DRIVER
-M: Corentin Chary <corentincj@iksaif.net>
-L: acpi4asus-user@lists.sourceforge.net
-L: platform-driver-x86@vger.kernel.org
-W: http://acpi4asus.sf.net
-S: Maintained
-F: drivers/platform/x86/eeepc-wmi.c
-
EFIFB FRAMEBUFFER DRIVER
L: linux-fbdev@vger.kernel.org
M: Peter Jones <pjones@redhat.com>
diff --git a/Makefile b/Makefile
index 7d4e9c8da72..ba7a55ccd89 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 2
PATCHLEVEL = 6
-SUBLEVEL = 38
-EXTRAVERSION =
+SUBLEVEL = 39
+EXTRAVERSION = -rc1
NAME = Flesh-Eating Bats with Fangs
# *DOCUMENTATION*
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index cc31bec2e31..9808998cc07 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -11,7 +11,7 @@ config ALPHA
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select AUTO_IRQ_AFFINITY if SMP
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ select GENERIC_IRQ_SHOW
help
The Alpha is a 64-bit general-purpose processor designed and
marketed by the Digital Equipment Corporation of blessed memory,
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index a19d6008229..381431a2d6d 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -67,68 +67,21 @@ int irq_select_affinity(unsigned int irq)
}
#endif /* CONFIG_SMP */
-int
-show_interrupts(struct seq_file *p, void *v)
+int arch_show_interrupts(struct seq_file *p, int prec)
{
int j;
- int irq = *(loff_t *) v;
- struct irqaction * action;
- struct irq_desc *desc;
- unsigned long flags;
#ifdef CONFIG_SMP
- if (irq == 0) {
- seq_puts(p, " ");
- for_each_online_cpu(j)
- seq_printf(p, "CPU%d ", j);
- seq_putc(p, '\n');
- }
-#endif
-
- if (irq < ACTUAL_NR_IRQS) {
- desc = irq_to_desc(irq);
-
- if (!desc)
- return 0;
-
- raw_spin_lock_irqsave(&desc->lock, flags);
- action = desc->action;
- if (!action)
- goto unlock;
- seq_printf(p, "%3d: ", irq);
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(irq));
-#else
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_irqs_cpu(irq, j));
+ seq_puts(p, "IPI: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10lu ", cpu_data[j].ipi_count);
+ seq_putc(p, '\n');
#endif
- seq_printf(p, " %14s", get_irq_desc_chip(desc)->name);
- seq_printf(p, " %c%s",
- (action->flags & IRQF_DISABLED)?'+':' ',
- action->name);
-
- for (action=action->next; action; action = action->next) {
- seq_printf(p, ", %c%s",
- (action->flags & IRQF_DISABLED)?'+':' ',
- action->name);
- }
-
- seq_putc(p, '\n');
-unlock:
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- } else if (irq == ACTUAL_NR_IRQS) {
-#ifdef CONFIG_SMP
- seq_puts(p, "IPI: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10lu ", cpu_data[j].ipi_count);
- seq_putc(p, '\n');
-#endif
- seq_puts(p, "PMI: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10lu ", per_cpu(irq_pmi_count, j));
- seq_puts(p, " Performance Monitoring\n");
- seq_printf(p, "ERR: %10lu\n", irq_err_count);
- }
+ seq_puts(p, "PMI: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10lu ", per_cpu(irq_pmi_count, j));
+ seq_puts(p, " Performance Monitoring\n");
+ seq_printf(p, "ERR: %10lu\n", irq_err_count);
return 0;
}
diff --git a/arch/alpha/kernel/irq_alpha.c b/arch/alpha/kernel/irq_alpha.c
index 411ca11d0a1..1479dc6ebd9 100644
--- a/arch/alpha/kernel/irq_alpha.c
+++ b/arch/alpha/kernel/irq_alpha.c
@@ -228,7 +228,7 @@ struct irqaction timer_irqaction = {
void __init
init_rtc_irq(void)
{
- set_irq_chip_and_handler_name(RTC_IRQ, &no_irq_chip,
+ irq_set_chip_and_handler_name(RTC_IRQ, &no_irq_chip,
handle_simple_irq, "RTC");
setup_irq(RTC_IRQ, &timer_irqaction);
}
diff --git a/arch/alpha/kernel/irq_i8259.c b/arch/alpha/kernel/irq_i8259.c
index c7cc9813e45..e1861c77dab 100644
--- a/arch/alpha/kernel/irq_i8259.c
+++ b/arch/alpha/kernel/irq_i8259.c
@@ -92,7 +92,7 @@ init_i8259a_irqs(void)
outb(0xff, 0xA1); /* mask all of 8259A-2 */
for (i = 0; i < 16; i++) {
- set_irq_chip_and_handler(i, &i8259a_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &i8259a_irq_type, handle_level_irq);
}
setup_irq(2, &cascade);
diff --git a/arch/alpha/kernel/irq_pyxis.c b/arch/alpha/kernel/irq_pyxis.c
index b30227fa7f5..13c97a5b31e 100644
--- a/arch/alpha/kernel/irq_pyxis.c
+++ b/arch/alpha/kernel/irq_pyxis.c
@@ -102,7 +102,7 @@ init_pyxis_irqs(unsigned long ignore_mask)
for (i = 16; i < 48; ++i) {
if ((ignore_mask >> i) & 1)
continue;
- set_irq_chip_and_handler(i, &pyxis_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &pyxis_irq_type, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/alpha/kernel/irq_srm.c b/arch/alpha/kernel/irq_srm.c
index 82a47bba41c..a79fa30e755 100644
--- a/arch/alpha/kernel/irq_srm.c
+++ b/arch/alpha/kernel/irq_srm.c
@@ -51,7 +51,7 @@ init_srm_irqs(long max, unsigned long ignore_mask)
for (i = 16; i < max; ++i) {
if (i < 64 && ((ignore_mask >> i) & 1))
continue;
- set_irq_chip_and_handler(i, &srm_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &srm_irq_type, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
}
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index 88d95e872f5..0e1439904cd 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -125,7 +125,7 @@ alcor_init_irq(void)
on while IRQ probing. */
if (i >= 16+20 && i <= 16+30)
continue;
- set_irq_chip_and_handler(i, &alcor_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &alcor_irq_type, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
i8259a_irq_type.irq_ack = alcor_isa_mask_and_ack_irq;
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index 57eb6307bc2..c8c112d5158 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -105,8 +105,8 @@ common_init_irq(void (*srm_dev_int)(unsigned long v))
outb(0xff, 0x806);
for (i = 16; i < 35; ++i) {
- set_irq_chip_and_handler(i, &cabriolet_irq_type,
- handle_level_irq);
+ irq_set_chip_and_handler(i, &cabriolet_irq_type,
+ handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
}
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 481df4ecb65..5ac00fd4cd0 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -270,7 +270,7 @@ init_tsunami_irqs(struct irq_chip * ops, int imin, int imax)
{
long i;
for (i = imin; i <= imax; ++i) {
- set_irq_chip_and_handler(i, ops, handle_level_irq);
+ irq_set_chip_and_handler(i, ops, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
}
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
index 402e908ffb3..a7a23b40eec 100644
--- a/arch/alpha/kernel/sys_eb64p.c
+++ b/arch/alpha/kernel/sys_eb64p.c
@@ -118,7 +118,7 @@ eb64p_init_irq(void)
init_i8259a_irqs();
for (i = 16; i < 32; ++i) {
- set_irq_chip_and_handler(i, &eb64p_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &eb64p_irq_type, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
index 0b44a54c152..a60cd5b2621 100644
--- a/arch/alpha/kernel/sys_eiger.c
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -138,7 +138,7 @@ eiger_init_irq(void)
init_i8259a_irqs();
for (i = 16; i < 128; ++i) {
- set_irq_chip_and_handler(i, &eiger_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &eiger_irq_type, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
}
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 00341b75c8b..7f1a87f176e 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -171,11 +171,11 @@ jensen_init_irq(void)
{
init_i8259a_irqs();
- set_irq_chip_and_handler(1, &jensen_local_irq_type, handle_level_irq);
- set_irq_chip_and_handler(4, &jensen_local_irq_type, handle_level_irq);
- set_irq_chip_and_handler(3, &jensen_local_irq_type, handle_level_irq);
- set_irq_chip_and_handler(7, &jensen_local_irq_type, handle_level_irq);
- set_irq_chip_and_handler(9, &jensen_local_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(1, &jensen_local_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(4, &jensen_local_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(3, &jensen_local_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(7, &jensen_local_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(9, &jensen_local_irq_type, handle_level_irq);
common_init_isa_dma();
}
diff --git a/arch/alpha/kernel/sys_marvel.c b/arch/alpha/kernel/sys_marvel.c
index e61910734e4..388b99d1779 100644
--- a/arch/alpha/kernel/sys_marvel.c
+++ b/arch/alpha/kernel/sys_marvel.c
@@ -276,7 +276,7 @@ init_io7_irqs(struct io7 *io7,
/* Set up the lsi irqs. */
for (i = 0; i < 128; ++i) {
- set_irq_chip_and_handler(base + i, lsi_ops, handle_level_irq);
+ irq_set_chip_and_handler(base + i, lsi_ops, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
@@ -290,7 +290,7 @@ init_io7_irqs(struct io7 *io7,
/* Set up the msi irqs. */
for (i = 128; i < (128 + 512); ++i) {
- set_irq_chip_and_handler(base + i, msi_ops, handle_level_irq);
+ irq_set_chip_and_handler(base + i, msi_ops, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
@@ -308,8 +308,8 @@ marvel_init_irq(void)
/* Reserve the legacy irqs. */
for (i = 0; i < 16; ++i) {
- set_irq_chip_and_handler(i, &marvel_legacy_irq_type,
- handle_level_irq);
+ irq_set_chip_and_handler(i, &marvel_legacy_irq_type,
+ handle_level_irq);
}
/* Init the io7 irqs. */
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index cf7f43dd314..0e6e4697a02 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -98,7 +98,8 @@ mikasa_init_irq(void)
mikasa_update_irq_hw(0);
for (i = 16; i < 32; ++i) {
- set_irq_chip_and_handler(i, &mikasa_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &mikasa_irq_type,
+ handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index 92bc188e94a..a00ac708716 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -127,7 +127,8 @@ noritake_init_irq(void)
outw(0, 0x54c);
for (i = 16; i < 48; ++i) {
- set_irq_chip_and_handler(i, &noritake_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &noritake_irq_type,
+ handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index 936d4140ed5..7f52161f3d8 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -180,7 +180,8 @@ rawhide_init_irq(void)
}
for (i = 16; i < 128; ++i) {
- set_irq_chip_and_handler(i, &rawhide_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &rawhide_irq_type,
+ handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index cea22a62913..216d94d9c0c 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -99,7 +99,7 @@ rx164_init_irq(void)
rx164_update_irq_hw(0);
for (i = 16; i < 40; ++i) {
- set_irq_chip_and_handler(i, &rx164_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &rx164_irq_type, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index a349538aabc..da714e427c5 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -518,8 +518,8 @@ sable_lynx_init_irq(int nr_of_irqs)
long i;
for (i = 0; i < nr_of_irqs; ++i) {
- set_irq_chip_and_handler(i, &sable_lynx_irq_type,
- handle_level_irq);
+ irq_set_chip_and_handler(i, &sable_lynx_irq_type,
+ handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index 42a5331f13c..a31f8cd9bd6 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -138,7 +138,8 @@ takara_init_irq(void)
takara_update_irq_hw(i, -1);
for (i = 16; i < 128; ++i) {
- set_irq_chip_and_handler(i, &takara_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &takara_irq_type,
+ handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/alpha/kernel/sys_titan.c b/arch/alpha/kernel/sys_titan.c
index 8c13a0c7783..fea0e462099 100644
--- a/arch/alpha/kernel/sys_titan.c
+++ b/arch/alpha/kernel/sys_titan.c
@@ -179,7 +179,7 @@ init_titan_irqs(struct irq_chip * ops, int imin, int imax)
{
long i;
for (i = imin; i <= imax; ++i) {
- set_irq_chip_and_handler(i, ops, handle_level_irq);
+ irq_set_chip_and_handler(i, ops, handle_level_irq);
irq_set_status_flags(i, IRQ_LEVEL);
}
}
diff --git a/arch/alpha/kernel/sys_wildfire.c b/arch/alpha/kernel/sys_wildfire.c
index ca60a387ef0..d3cb28bb8eb 100644
--- a/arch/alpha/kernel/sys_wildfire.c
+++ b/arch/alpha/kernel/sys_wildfire.c
@@ -183,17 +183,17 @@ wildfire_init_irq_per_pca(int qbbno, int pcano)
for (i = 0; i < 16; ++i) {
if (i == 2)
continue;
- set_irq_chip_and_handler(i+irq_bias, &wildfire_irq_type,
- handle_level_irq);
+ irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type,
+ handle_level_irq);
irq_set_status_flags(i + irq_bias, IRQ_LEVEL);
}
- set_irq_chip_and_handler(36+irq_bias, &wildfire_irq_type,
- handle_level_irq);
+ irq_set_chip_and_handler(36 + irq_bias, &wildfire_irq_type,
+ handle_level_irq);
irq_set_status_flags(36 + irq_bias, IRQ_LEVEL);
for (i = 40; i < 64; ++i) {
- set_irq_chip_and_handler(i+irq_bias, &wildfire_irq_type,
- handle_level_irq);
+ irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type,
+ handle_level_irq);
irq_set_status_flags(i + irq_bias, IRQ_LEVEL);
}
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 93d595a7477..5b9f78b570e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -28,6 +28,7 @@ config ARM
select HAVE_C_RECORDMCOUNT
select HAVE_GENERIC_HARDIRQS
select HAVE_SPARSE_IRQ
+ select GENERIC_IRQ_SHOW
help
The ARM series is a line of low-power-consumption RISC chip designs
licensed by ARM Ltd and targeted at embedded applications and
@@ -365,6 +366,7 @@ config ARCH_MXC
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
+ select HAVE_SCHED_CLOCK
help
Support for Freescale MXC/iMX-based family of processors
@@ -2009,6 +2011,7 @@ menu "Power management options"
source "kernel/power/Kconfig"
config ARCH_SUSPEND_POSSIBLE
+ depends on !ARCH_S5P64X0 && !ARCH_S5P6442
def_bool y
endmenu
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 84ac4d65631..adf583cd0c3 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -21,20 +21,12 @@
#if defined(CONFIG_DEBUG_ICEDCC)
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
.macro loadsp, rb, tmp
.endm
.macro writeb, ch, rb
mcr p14, 0, \ch, c0, c5, 0
.endm
-#elif defined(CONFIG_CPU_V7)
- .macro loadsp, rb, tmp
- .endm
- .macro writeb, ch, rb
-wait: mrc p14, 0, pc, c0, c1, 0
- bcs wait
- mcr p14, 0, \ch, c0, c5, 0
- .endm
#elif defined(CONFIG_CPU_XSCALE)
.macro loadsp, rb, tmp
.endm
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 4657e877bf8..2df38263124 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -36,7 +36,7 @@ extern void error(char *x);
#ifdef CONFIG_DEBUG_ICEDCC
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
static void icedcc_putc(int ch)
{
@@ -52,16 +52,6 @@ static void icedcc_putc(int ch)
asm("mcr p14, 0, %0, c0, c5, 0" : : "r" (ch));
}
-#elif defined(CONFIG_CPU_V7)
-
-static void icedcc_putc(int ch)
-{
- asm(
- "wait: mrc p14, 0, pc, c0, c1, 0 \n\
- bcs wait \n\
- mcr p14, 0, %0, c0, c5, 0 "
- : : "r" (ch));
-}
#elif defined(CONFIG_CPU_XSCALE)
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index cb6b041c39d..f70ec7dadeb 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -213,8 +213,8 @@ static int gic_set_wake(struct irq_data *d, unsigned int on)
static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
{
- struct gic_chip_data *chip_data = get_irq_data(irq);
- struct irq_chip *chip = get_irq_chip(irq);
+ struct gic_chip_data *chip_data = irq_get_handler_data(irq);
+ struct irq_chip *chip = irq_get_chip(irq);
unsigned int cascade_irq, gic_irq;
unsigned long status;
@@ -257,9 +257,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
{
if (gic_nr >= MAX_GIC_NR)
BUG();
- if (set_irq_data(irq, &gic_data[gic_nr]) != 0)
+ if (irq_set_handler_data(irq, &gic_data[gic_nr]) != 0)
BUG();
- set_irq_chained_handler(irq, gic_handle_cascade_irq);
+ irq_set_chained_handler(irq, gic_handle_cascade_irq);
}
static void __init gic_dist_init(struct gic_chip_data *gic,
@@ -319,9 +319,8 @@ static void __init gic_dist_init(struct gic_chip_data *gic,
* Setup the Linux IRQ subsystem.
*/
for (i = irq_start; i < irq_limit; i++) {
- set_irq_chip(i, &gic_chip);
- set_irq_chip_data(i, gic);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &gic_chip, handle_level_irq);
+ irq_set_chip_data(i, gic);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
@@ -382,7 +381,7 @@ void __cpuinit gic_enable_ppi(unsigned int irq)
unsigned long flags;
local_irq_save(flags);
- irq_to_desc(irq)->status |= IRQ_NOPROBE;
+ irq_set_status_flags(irq, IRQ_NOPROBE);
gic_unmask_irq(irq_get_irq_data(irq));
local_irq_restore(flags);
}
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index fcddd48fe9d..7a21927c52e 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -88,8 +88,8 @@ void it8152_init_irq(void)
__raw_writel((0), IT8152_INTC_LDCNIRR);
for (irq = IT8152_IRQ(0); irq <= IT8152_LAST_IRQ; irq++) {
- set_irq_chip(irq, &it8152_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &it8152_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index a026a6bf489..b55c3625d7e 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -140,7 +140,7 @@ static struct locomo_dev_info locomo_devices[] = {
static void locomo_handler(unsigned int irq, struct irq_desc *desc)
{
- struct locomo *lchip = get_irq_chip_data(irq);
+ struct locomo *lchip = irq_get_chip_data(irq);
int req, i;
/* Acknowledge the parent IRQ */
@@ -197,15 +197,14 @@ static void locomo_setup_irq(struct locomo *lchip)
/*
* Install handler for IRQ_LOCOMO_HW.
*/
- set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
- set_irq_chip_data(lchip->irq, lchip);
- set_irq_chained_handler(lchip->irq, locomo_handler);
+ irq_set_irq_type(lchip->irq, IRQ_TYPE_EDGE_FALLING);
+ irq_set_chip_data(lchip->irq, lchip);
+ irq_set_chained_handler(lchip->irq, locomo_handler);
/* Install handlers for IRQ_LOCOMO_* */
for ( ; irq <= lchip->irq_base + 3; irq++) {
- set_irq_chip(irq, &locomo_chip);
- set_irq_chip_data(irq, lchip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &locomo_chip, handle_level_irq);
+ irq_set_chip_data(irq, lchip);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
@@ -476,8 +475,8 @@ static void __locomo_remove(struct locomo *lchip)
device_for_each_child(lchip->dev, NULL, locomo_remove_child);
if (lchip->irq != NO_IRQ) {
- set_irq_chained_handler(lchip->irq, NULL);
- set_irq_data(lchip->irq, NULL);
+ irq_set_chained_handler(lchip->irq, NULL);
+ irq_set_handler_data(lchip->irq, NULL);
}
iounmap(lchip->base);
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
index eb9796b0dab..a12b33c0dc4 100644
--- a/arch/arm/common/sa1111.c
+++ b/arch/arm/common/sa1111.c
@@ -202,7 +202,7 @@ static void
sa1111_irq_handler(unsigned int irq, struct irq_desc *desc)
{
unsigned int stat0, stat1, i;
- struct sa1111 *sachip = get_irq_data(irq);
+ struct sa1111 *sachip = irq_get_handler_data(irq);
void __iomem *mapbase = sachip->base + SA1111_INTC;
stat0 = sa1111_readl(mapbase + SA1111_INTSTATCLR0);
@@ -472,25 +472,25 @@ static void sa1111_setup_irq(struct sa1111 *sachip)
sa1111_writel(~0, irqbase + SA1111_INTSTATCLR1);
for (irq = IRQ_GPAIN0; irq <= SSPROR; irq++) {
- set_irq_chip(irq, &sa1111_low_chip);
- set_irq_chip_data(irq, sachip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &sa1111_low_chip,
+ handle_edge_irq);
+ irq_set_chip_data(irq, sachip);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
for (irq = AUDXMTDMADONEA; irq <= IRQ_S1_BVD1_STSCHG; irq++) {
- set_irq_chip(irq, &sa1111_high_chip);
- set_irq_chip_data(irq, sachip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &sa1111_high_chip,
+ handle_edge_irq);
+ irq_set_chip_data(irq, sachip);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
/*
* Register SA1111 interrupt
*/
- set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
- set_irq_data(sachip->irq, sachip);
- set_irq_chained_handler(sachip->irq, sa1111_irq_handler);
+ irq_set_irq_type(sachip->irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_handler_data(sachip->irq, sachip);
+ irq_set_chained_handler(sachip->irq, sa1111_irq_handler);
}
/*
@@ -815,8 +815,8 @@ static void __sa1111_remove(struct sa1111 *sachip)
clk_disable(sachip->clk);
if (sachip->irq != NO_IRQ) {
- set_irq_chained_handler(sachip->irq, NULL);
- set_irq_data(sachip->irq, NULL);
+ irq_set_chained_handler(sachip->irq, NULL);
+ irq_set_handler_data(sachip->irq, NULL);
release_mem_region(sachip->phys + SA1111_INTC, 512);
}
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index ae5fe7292e0..113085a7712 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -305,9 +305,9 @@ static void __init vic_set_irq_sources(void __iomem *base,
if (vic_sources & (1 << i)) {
unsigned int irq = irq_start + i;
- set_irq_chip(irq, &vic_chip);
- set_irq_chip_data(irq, base);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &vic_chip,
+ handle_level_irq);
+ irq_set_chip_data(irq, base);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
diff --git a/arch/arm/include/asm/hw_irq.h b/arch/arm/include/asm/hw_irq.h
index 5586b7c8ef6..a71b417b185 100644
--- a/arch/arm/include/asm/hw_irq.h
+++ b/arch/arm/include/asm/hw_irq.h
@@ -10,14 +10,6 @@ static inline void ack_bad_irq(int irq)
irq_err_count++;
}
-/*
- * Obsolete inline function for calling irq descriptor handlers.
- */
-static inline void desc_handle_irq(unsigned int irq, struct irq_desc *desc)
-{
- desc->handle_irq(irq, desc);
-}
-
void set_irq_flags(unsigned int irq, unsigned int flags);
#define IRQF_VALID (1 << 0)
diff --git a/arch/arm/include/asm/mach/udc_pxa2xx.h b/arch/arm/include/asm/mach/udc_pxa2xx.h
index 833306ee9e7..ea297ac70bc 100644
--- a/arch/arm/include/asm/mach/udc_pxa2xx.h
+++ b/arch/arm/include/asm/mach/udc_pxa2xx.h
@@ -20,8 +20,6 @@ struct pxa2xx_udc_mach_info {
* VBUS IRQ and omit the methods above. Store the GPIO number
* here. Note that sometimes the signals go through inverters...
*/
- bool gpio_vbus_inverted;
- int gpio_vbus; /* high == vbus present */
bool gpio_pullup_inverted;
int gpio_pullup; /* high == pullup activated */
};
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index d86fcd44b22..e4ee050aad7 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -159,31 +159,6 @@ static void __devinit pci_fixup_dec21285(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, pci_fixup_dec21285);
/*
- * Same as above. The PrPMC800 carrier board for the PrPMC1100
- * card maps the host-bridge @ 00:01:00 for some reason and it
- * ends up getting scanned. Note that we only want to do this
- * fixup when we find the IXP4xx on a PrPMC system, which is why
- * we check the machine type. We could be running on a board
- * with an IXP4xx target device and we don't want to kill the
- * resources in that case.
- */
-static void __devinit pci_fixup_prpmc1100(struct pci_dev *dev)
-{
- int i;
-
- if (machine_is_prpmc1100()) {
- dev->class &= 0xff;
- dev->class |= PCI_CLASS_BRIDGE_HOST << 8;
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- dev->resource[i].start = 0;
- dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
- }
- }
-}
-DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IXP4XX, pci_fixup_prpmc1100);
-
-/*
* PCI IDE controllers use non-standard I/O port decoding, respect it.
*/
static void __devinit pci_fixup_ide_bases(struct pci_dev *dev)
diff --git a/arch/arm/kernel/debug.S b/arch/arm/kernel/debug.S
index d2d983be096..bcd66e00bdb 100644
--- a/arch/arm/kernel/debug.S
+++ b/arch/arm/kernel/debug.S
@@ -25,7 +25,7 @@
.macro addruart, rp, rv
.endm
-#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K)
+#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) || defined(CONFIG_CPU_V7)
.macro senduart, rd, rx
mcr p14, 0, \rd, c0, c5, 0
@@ -49,23 +49,6 @@
1002:
.endm
-#elif defined(CONFIG_CPU_V7)
-
- .macro senduart, rd, rx
- mcr p14, 0, \rd, c0, c5, 0
- .endm
-
- .macro busyuart, rd, rx
-busy: mrc p14, 0, pc, c0, c1, 0
- bcs busy
- .endm
-
- .macro waituart, rd, rx
-wait: mrc p14, 0, pc, c0, c1, 0
- bcs wait
-
- .endm
-
#elif defined(CONFIG_CPU_XSCALE)
.macro senduart, rd, rx
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 2ad62df3773..d16500110ee 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -1043,8 +1043,8 @@ ecard_probe(int slot, card_type_t type)
*/
if (slot < 8) {
ec->irq = 32 + slot;
- set_irq_chip(ec->irq, &ecard_chip);
- set_irq_handler(ec->irq, handle_level_irq);
+ irq_set_chip_and_handler(ec->irq, &ecard_chip,
+ handle_level_irq);
set_irq_flags(ec->irq, IRQF_VALID);
}
@@ -1103,7 +1103,7 @@ static int __init ecard_init(void)
irqhw = ecard_probeirqhw();
- set_irq_chained_handler(IRQ_EXPANSIONCARD,
+ irq_set_chained_handler(IRQ_EXPANSIONCARD,
irqhw ? ecard_irqexp_handler : ecard_irq_handler);
ecard_proc_init();
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c
index 052b509e2d5..1bec8b5f22f 100644
--- a/arch/arm/kernel/etm.c
+++ b/arch/arm/kernel/etm.c
@@ -338,7 +338,7 @@ static struct miscdevice etb_miscdev = {
.fops = &etb_fops,
};
-static int __init etb_probe(struct amba_device *dev, const struct amba_id *id)
+static int __devinit etb_probe(struct amba_device *dev, const struct amba_id *id)
{
struct tracectx *t = &tracer;
int ret = 0;
@@ -530,7 +530,7 @@ static ssize_t trace_mode_store(struct kobject *kobj,
static struct kobj_attribute trace_mode_attr =
__ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store);
-static int __init etm_probe(struct amba_device *dev, const struct amba_id *id)
+static int __devinit etm_probe(struct amba_device *dev, const struct amba_id *id)
{
struct tracectx *t = &tracer;
int ret = 0;
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 3535d3793e6..83bbad03fcc 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -51,63 +51,18 @@
unsigned long irq_err_count;
-int show_interrupts(struct seq_file *p, void *v)
+int arch_show_interrupts(struct seq_file *p, int prec)
{
- int i = *(loff_t *) v, cpu;
- struct irq_desc *desc;
- struct irqaction * action;
- unsigned long flags;
- int prec, n;
-
- for (prec = 3, n = 1000; prec < 10 && n <= nr_irqs; prec++)
- n *= 10;
-
-#ifdef CONFIG_SMP
- if (prec < 4)
- prec = 4;
-#endif
-
- if (i == 0) {
- char cpuname[12];
-
- seq_printf(p, "%*s ", prec, "");
- for_each_present_cpu(cpu) {
- sprintf(cpuname, "CPU%d", cpu);
- seq_printf(p, " %10s", cpuname);
- }
- seq_putc(p, '\n');
- }
-
- if (i < nr_irqs) {
- desc = irq_to_desc(i);
- raw_spin_lock_irqsave(&desc->lock, flags);
- action = desc->action;
- if (!action)
- goto unlock;
-
- seq_printf(p, "%*d: ", prec, i);
- for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
- seq_printf(p, " %10s", desc->irq_data.chip->name ? : "-");
- seq_printf(p, " %s", action->name);
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
-unlock:
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- } else if (i == nr_irqs) {
#ifdef CONFIG_FIQ
- show_fiq_list(p, prec);
+ show_fiq_list(p, prec);
#endif
#ifdef CONFIG_SMP
- show_ipi_list(p, prec);
+ show_ipi_list(p, prec);
#endif
#ifdef CONFIG_LOCAL_TIMERS
- show_local_irqs(p, prec);
+ show_local_irqs(p, prec);
#endif
- seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
- }
+ seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
return 0;
}
@@ -144,24 +99,21 @@ asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
void set_irq_flags(unsigned int irq, unsigned int iflags)
{
- struct irq_desc *desc;
- unsigned long flags;
+ unsigned long clr = 0, set = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
if (irq >= nr_irqs) {
printk(KERN_ERR "Trying to set irq flags for IRQ%d\n", irq);
return;
}
- desc = irq_to_desc(irq);
- raw_spin_lock_irqsave(&desc->lock, flags);
- desc->status |= IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN;
if (iflags & IRQF_VALID)
- desc->status &= ~IRQ_NOREQUEST;
+ clr |= IRQ_NOREQUEST;
if (iflags & IRQF_PROBE)
- desc->status &= ~IRQ_NOPROBE;
+ clr |= IRQ_NOPROBE;
if (!(iflags & IRQF_NOAUTOEN))
- desc->status &= ~IRQ_NOAUTOEN;
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ clr |= IRQ_NOAUTOEN;
+ /* Order is clear bits in "clr" then set bits in "set" */
+ irq_modify_status(irq, clr, set & ~clr);
}
void __init init_IRQ(void)
diff --git a/arch/arm/kernel/kprobes-decode.c b/arch/arm/kernel/kprobes-decode.c
index 8f6ed43861f..23891317dc4 100644
--- a/arch/arm/kernel/kprobes-decode.c
+++ b/arch/arm/kernel/kprobes-decode.c
@@ -594,7 +594,8 @@ static void __kprobes emulate_ldr(struct kprobe *p, struct pt_regs *regs)
long cpsr = regs->ARM_cpsr;
fnr.dr = insnslot_llret_3arg_rflags(rnv, 0, rmv, cpsr, i_fn);
- regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */
+ if (rn != 15)
+ regs->uregs[rn] = fnr.r0; /* Save Rn in case of writeback. */
rdv = fnr.r1;
if (rd == 15) {
@@ -622,10 +623,11 @@ static void __kprobes emulate_str(struct kprobe *p, struct pt_regs *regs)
long rdv = (rd == 15) ? iaddr + str_pc_offset : regs->uregs[rd];
long rnv = (rn == 15) ? iaddr + 8 : regs->uregs[rn];
long rmv = regs->uregs[rm]; /* rm/rmv may be invalid, don't care. */
+ long rnv_wb;
- /* Save Rn in case of writeback. */
- regs->uregs[rn] =
- insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
+ rnv_wb = insnslot_3arg_rflags(rnv, rdv, rmv, regs->ARM_cpsr, i_fn);
+ if (rn != 15)
+ regs->uregs[rn] = rnv_wb; /* Save Rn in case of writeback. */
}
static void __kprobes emulate_mrrc(struct kprobe *p, struct pt_regs *regs)
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index 22e194eb853..69cfee0fe00 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -79,6 +79,7 @@ struct arm_pmu {
void (*write_counter)(int idx, u32 val);
void (*start)(void);
void (*stop)(void);
+ void (*reset)(void *);
const unsigned (*cache_map)[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
[PERF_COUNT_HW_CACHE_RESULT_MAX];
@@ -204,11 +205,9 @@ armpmu_event_set_period(struct perf_event *event,
static u64
armpmu_event_update(struct perf_event *event,
struct hw_perf_event *hwc,
- int idx)
+ int idx, int overflow)
{
- int shift = 64 - 32;
- s64 prev_raw_count, new_raw_count;
- u64 delta;
+ u64 delta, prev_raw_count, new_raw_count;
again:
prev_raw_count = local64_read(&hwc->prev_count);
@@ -218,8 +217,13 @@ again:
new_raw_count) != prev_raw_count)
goto again;
- delta = (new_raw_count << shift) - (prev_raw_count << shift);
- delta >>= shift;
+ new_raw_count &= armpmu->max_period;
+ prev_raw_count &= armpmu->max_period;
+
+ if (overflow)
+ delta = armpmu->max_period - prev_raw_count + new_raw_count;
+ else
+ delta = new_raw_count - prev_raw_count;
local64_add(delta, &event->count);
local64_sub(delta, &hwc->period_left);
@@ -236,7 +240,7 @@ armpmu_read(struct perf_event *event)
if (hwc->idx < 0)
return;
- armpmu_event_update(event, hwc, hwc->idx);
+ armpmu_event_update(event, hwc, hwc->idx, 0);
}
static void
@@ -254,7 +258,7 @@ armpmu_stop(struct perf_event *event, int flags)
if (!(hwc->state & PERF_HES_STOPPED)) {
armpmu->disable(hwc, hwc->idx);
barrier(); /* why? */
- armpmu_event_update(event, hwc, hwc->idx);
+ armpmu_event_update(event, hwc, hwc->idx, 0);
hwc->state |= PERF_HES_STOPPED | PERF_HES_UPTODATE;
}
}
@@ -624,6 +628,19 @@ static struct pmu pmu = {
#include "perf_event_v6.c"
#include "perf_event_v7.c"
+/*
+ * Ensure the PMU has sane values out of reset.
+ * This requires SMP to be available, so exists as a separate initcall.
+ */
+static int __init
+armpmu_reset(void)
+{
+ if (armpmu && armpmu->reset)
+ return on_each_cpu(armpmu->reset, NULL, 1);
+ return 0;
+}
+arch_initcall(armpmu_reset);
+
static int __init
init_hw_perf_events(void)
{
diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index 6fc2d228db5..f1e8dd94afe 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -474,7 +474,7 @@ armv6pmu_handle_irq(int irq_num,
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event, hwc, idx, 1);
data.period = event->hw.last_period;
if (!armpmu_event_set_period(event, hwc, idx))
continue;
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 2e1402556fa..4960686afb5 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -466,6 +466,7 @@ static inline unsigned long armv7_pmnc_read(void)
static inline void armv7_pmnc_write(unsigned long val)
{
val &= ARMV7_PMNC_MASK;
+ isb();
asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
}
@@ -502,6 +503,7 @@ static inline int armv7_pmnc_select_counter(unsigned int idx)
val = (idx - ARMV7_EVENT_CNT_TO_CNTx) & ARMV7_SELECT_MASK;
asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (val));
+ isb();
return idx;
}
@@ -780,7 +782,7 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event, hwc, idx, 1);
data.period = event->hw.last_period;
if (!armpmu_event_set_period(event, hwc, idx))
continue;
@@ -847,6 +849,18 @@ static int armv7pmu_get_event_idx(struct cpu_hw_events *cpuc,
}
}
+static void armv7pmu_reset(void *info)
+{
+ u32 idx, nb_cnt = armpmu->num_events;
+
+ /* The counter and interrupt enable registers are unknown at reset. */
+ for (idx = 1; idx < nb_cnt; ++idx)
+ armv7pmu_disable_event(NULL, idx);
+
+ /* Initialize & Reset PMNC: C and P bits */
+ armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
+}
+
static struct arm_pmu armv7pmu = {
.handle_irq = armv7pmu_handle_irq,
.enable = armv7pmu_enable_event,
@@ -856,17 +870,15 @@ static struct arm_pmu armv7pmu = {
.get_event_idx = armv7pmu_get_event_idx,
.start = armv7pmu_start,
.stop = armv7pmu_stop,
+ .reset = armv7pmu_reset,
.raw_event_mask = 0xFF,
.max_period = (1LLU << 32) - 1,
};
-static u32 __init armv7_reset_read_pmnc(void)
+static u32 __init armv7_read_num_pmnc_events(void)
{
u32 nb_cnt;
- /* Initialize & Reset PMNC: C and P bits */
- armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
-
/* Read the nb of CNTx counters supported from PMNC */
nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK;
@@ -880,7 +892,7 @@ static const struct arm_pmu *__init armv7_a8_pmu_init(void)
armv7pmu.name = "ARMv7 Cortex-A8";
armv7pmu.cache_map = &armv7_a8_perf_cache_map;
armv7pmu.event_map = &armv7_a8_perf_map;
- armv7pmu.num_events = armv7_reset_read_pmnc();
+ armv7pmu.num_events = armv7_read_num_pmnc_events();
return &armv7pmu;
}
@@ -890,7 +902,7 @@ static const struct arm_pmu *__init armv7_a9_pmu_init(void)
armv7pmu.name = "ARMv7 Cortex-A9";
armv7pmu.cache_map = &armv7_a9_perf_cache_map;
armv7pmu.event_map = &armv7_a9_perf_map;
- armv7pmu.num_events = armv7_reset_read_pmnc();
+ armv7pmu.num_events = armv7_read_num_pmnc_events();
return &armv7pmu;
}
#else
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index 28cd3b025bc..39affbe4fdb 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -246,7 +246,7 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event, hwc, idx, 1);
data.period = event->hw.last_period;
if (!armpmu_event_set_period(event, hwc, idx))
continue;
@@ -578,7 +578,7 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
continue;
hwc = &event->hw;
- armpmu_event_update(event, hwc, idx);
+ armpmu_event_update(event, hwc, idx, 1);
data.period = event->hw.last_period;
if (!armpmu_event_set_period(event, hwc, idx))
continue;
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index bfad698a02e..6398ead9d1c 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -119,11 +119,19 @@ ENTRY(cpu_resume)
#else
ldr r0, sleep_save_sp @ stack phys addr
#endif
- msr cpsr_c, #PSR_I_BIT | PSR_F_BIT | SVC_MODE @ set SVC, irqs off
+ setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off
#ifdef MULTI_CPU
- ldmia r0!, {r1, sp, lr, pc} @ load v:p, stack, return fn, resume fn
+ @ load v:p, stack, return fn, resume fn
+ ARM( ldmia r0!, {r1, sp, lr, pc} )
+THUMB( ldmia r0!, {r1, r2, r3, r4} )
+THUMB( mov sp, r2 )
+THUMB( mov lr, r3 )
+THUMB( bx r4 )
#else
- ldmia r0!, {r1, sp, lr} @ load v:p, stack, return fn
+ @ load v:p, stack, return fn
+ ARM( ldmia r0!, {r1, sp, lr} )
+THUMB( ldmia r0!, {r1, r2, lr} )
+THUMB( mov sp, r2 )
b cpu_do_resume
#endif
ENDPROC(cpu_resume)
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
index d1f775e8635..9ffbf3a2dfe 100644
--- a/arch/arm/mach-at91/at91cap9_devices.c
+++ b/arch/arm/mach-at91/at91cap9_devices.c
@@ -72,7 +72,7 @@ void __init at91_add_device_usbh(struct at91_usbh_data *data)
return;
if (cpu_is_at91cap9_revB())
- set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
/* Enable VBus control for UHP ports */
for (i = 0; i < data->ports; i++) {
@@ -157,7 +157,7 @@ static struct platform_device at91_usba_udc_device = {
void __init at91_add_device_usba(struct usba_platform_data *data)
{
if (cpu_is_at91cap9_revB()) {
- set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_irq_type(AT91CAP9_ID_UDPHS, IRQ_TYPE_LEVEL_HIGH);
at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS |
AT91_MATRIX_UDPHS_BYPASS_LOCK);
}
@@ -861,7 +861,7 @@ void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
return;
if (cpu_is_at91cap9_revB())
- set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_irq_type(AT91CAP9_ID_LCDC, IRQ_TYPE_LEVEL_HIGH);
at91_set_A_periph(AT91_PIN_PC1, 0); /* LCDHSYNC */
at91_set_A_periph(AT91_PIN_PC2, 0); /* LCDDOTCK */
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index af818a21587..4615528205c 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -287,7 +287,7 @@ static int gpio_irq_set_wake(struct irq_data *d, unsigned state)
else
wakeups[bank] &= ~mask;
- set_irq_wake(gpio_chip[bank].bank->id, state);
+ irq_set_irq_wake(gpio_chip[bank].bank->id, state);
return 0;
}
@@ -375,6 +375,7 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
static struct irq_chip gpio_irqchip = {
.name = "GPIO",
+ .irq_disable = gpio_irq_mask,
.irq_mask = gpio_irq_mask,
.irq_unmask = gpio_irq_unmask,
.irq_set_type = gpio_irq_type,
@@ -384,16 +385,14 @@ static struct irq_chip gpio_irqchip = {
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
unsigned pin;
- struct irq_desc *gpio;
- struct at91_gpio_chip *at91_gpio;
- void __iomem *pio;
+ struct irq_data *idata = irq_desc_get_irq_data(desc);
+ struct irq_chip *chip = irq_data_get_irq_chip(idata);
+ struct at91_gpio_chip *at91_gpio = irq_data_get_irq_chip_data(idata);
+ void __iomem *pio = at91_gpio->regbase;
u32 isr;
- at91_gpio = get_irq_chip_data(irq);
- pio = at91_gpio->regbase;
-
/* temporarily mask (level sensitive) parent IRQ */
- desc->irq_data.chip->irq_ack(&desc->irq_data);
+ chip->irq_ack(idata);
for (;;) {
/* Reading ISR acks pending (edge triggered) GPIO interrupts.
* When there none are pending, we're finished unless we need
@@ -409,27 +408,15 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
}
pin = at91_gpio->chip.base;
- gpio = &irq_desc[pin];
while (isr) {
- if (isr & 1) {
- if (unlikely(gpio->depth)) {
- /*
- * The core ARM interrupt handler lazily disables IRQs so
- * another IRQ must be generated before it actually gets
- * here to be disabled on the GPIO controller.
- */
- gpio_irq_mask(irq_get_irq_data(pin));
- }
- else
- generic_handle_irq(pin);
- }
+ if (isr & 1)
+ generic_handle_irq(pin);
pin++;
- gpio++;
isr >>= 1;
}
}
- desc->irq_data.chip->irq_unmask(&desc->irq_data);
+ chip->irq_unmask(idata);
/* now it may re-trigger */
}
@@ -518,14 +505,14 @@ void __init at91_gpio_irq_setup(void)
__raw_writel(~0, this->regbase + PIO_IDR);
for (i = 0, pin = this->chip.base; i < 32; i++, pin++) {
- lockdep_set_class(&irq_desc[pin].lock, &gpio_lock_class);
+ irq_set_lockdep_class(pin, &gpio_lock_class);
/*
* Can use the "simple" and not "edge" handler since it's
* shorter, and the AIC handles interrupts sanely.
*/
- set_irq_chip(pin, &gpio_irqchip);
- set_irq_handler(pin, handle_simple_irq);
+ irq_set_chip_and_handler(pin, &gpio_irqchip,
+ handle_simple_irq);
set_irq_flags(pin, IRQF_VALID);
}
@@ -536,8 +523,8 @@ void __init at91_gpio_irq_setup(void)
if (prev && prev->next == this)
continue;
- set_irq_chip_data(id, this);
- set_irq_chained_handler(id, gpio_irq_handler);
+ irq_set_chip_data(id, this);
+ irq_set_chained_handler(id, gpio_irq_handler);
}
pr_info("AT91: %d gpio irqs in %d banks\n", pin - PIN_BASE, gpio_banks);
}
diff --git a/arch/arm/mach-at91/include/mach/at572d940hf.h b/arch/arm/mach-at91/include/mach/at572d940hf.h
index 2d9b0af9c4d..be510cfc56b 100644
--- a/arch/arm/mach-at91/include/mach/at572d940hf.h
+++ b/arch/arm/mach-at91/include/mach/at572d940hf.h
@@ -89,7 +89,7 @@
/*
* System Peripherals (offset from AT91_BASE_SYS)
*/
-#define AT91_SDRAMC (0xffffea00 - AT91_BASE_SYS)
+#define AT91_SDRAMC0 (0xffffea00 - AT91_BASE_SYS)
#define AT91_SMC (0xffffec00 - AT91_BASE_SYS)
#define AT91_MATRIX (0xffffee00 - AT91_BASE_SYS)
#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index b56d6b3a408..9665265ec75 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -143,8 +143,7 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
/* Active Low interrupt, with the specified priority */
at91_sys_write(AT91_AIC_SMR(i), AT91_AIC_SRCTYPE_LOW | priority[i]);
- set_irq_chip(i, &at91_aic_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &at91_aic_chip, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
/* Perform 8 End Of Interrupt Command to make sure AIC will not Lock out nIRQ */
diff --git a/arch/arm/mach-bcmring/irq.c b/arch/arm/mach-bcmring/irq.c
index 84dcda0d1d9..c48feaf4e8e 100644
--- a/arch/arm/mach-bcmring/irq.c
+++ b/arch/arm/mach-bcmring/irq.c
@@ -93,11 +93,11 @@ static void vic_init(void __iomem *base, struct irq_chip *chip,
unsigned int i;
for (i = 0; i < 32; i++) {
unsigned int irq = irq_start + i;
- set_irq_chip(irq, chip);
- set_irq_chip_data(irq, base);
+ irq_set_chip(irq, chip);
+ irq_set_chip_data(irq, base);
if (vic_sources & (1 << i)) {
- set_irq_handler(irq, handle_level_irq);
+ irq_set_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
@@ -119,9 +119,9 @@ void __init bcmring_init_irq(void)
/* special cases */
if (INTCHW_INTC1_GPIO0 & IRQ_INTC1_VALID_MASK) {
- set_irq_handler(IRQ_GPIO0, handle_simple_irq);
+ irq_set_handler(IRQ_GPIO0, handle_simple_irq);
}
if (INTCHW_INTC1_GPIO1 & IRQ_INTC1_VALID_MASK) {
- set_irq_handler(IRQ_GPIO1, handle_simple_irq);
+ irq_set_handler(IRQ_GPIO1, handle_simple_irq);
}
}
diff --git a/arch/arm/mach-clps711x/irq.c b/arch/arm/mach-clps711x/irq.c
index 86da7a1b2bb..c2eceee645e 100644
--- a/arch/arm/mach-clps711x/irq.c
+++ b/arch/arm/mach-clps711x/irq.c
@@ -112,13 +112,13 @@ void __init clps711x_init_irq(void)
for (i = 0; i < NR_IRQS; i++) {
if (INT1_IRQS & (1 << i)) {
- set_irq_handler(i, handle_level_irq);
- set_irq_chip(i, &int1_chip);
+ irq_set_chip_and_handler(i, &int1_chip,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
if (INT2_IRQS & (1 << i)) {
- set_irq_handler(i, handle_level_irq);
- set_irq_chip(i, &int2_chip);
+ irq_set_chip_and_handler(i, &int2_chip,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
}
diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c
index 9abc80a86a2..f83152d643c 100644
--- a/arch/arm/mach-davinci/cp_intc.c
+++ b/arch/arm/mach-davinci/cp_intc.c
@@ -167,9 +167,9 @@ void __init cp_intc_init(void)
/* Set up genirq dispatching for cp_intc */
for (i = 0; i < num_irq; i++) {
- set_irq_chip(i, &cp_intc_irq_chip);
+ irq_set_chip(i, &cp_intc_irq_chip);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
- set_irq_handler(i, handle_edge_irq);
+ irq_set_handler(i, handle_edge_irq);
}
/* Enable global interrupt */
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c
index 20d66e5e466..a0b838894ac 100644
--- a/arch/arm/mach-davinci/gpio.c
+++ b/arch/arm/mach-davinci/gpio.c
@@ -62,7 +62,7 @@ static inline struct davinci_gpio_regs __iomem *irq2regs(int irq)
{
struct davinci_gpio_regs __iomem *g;
- g = (__force struct davinci_gpio_regs __iomem *)get_irq_chip_data(irq);
+ g = (__force struct davinci_gpio_regs __iomem *)irq_get_chip_data(irq);
return g;
}
@@ -208,7 +208,7 @@ pure_initcall(davinci_gpio_setup);
static void gpio_irq_disable(struct irq_data *d)
{
struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
- u32 mask = (u32) irq_data_get_irq_data(d);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
__raw_writel(mask, &g->clr_falling);
__raw_writel(mask, &g->clr_rising);
@@ -217,8 +217,8 @@ static void gpio_irq_disable(struct irq_data *d)
static void gpio_irq_enable(struct irq_data *d)
{
struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
- u32 mask = (u32) irq_data_get_irq_data(d);
- unsigned status = irq_desc[d->irq].status;
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
+ unsigned status = irqd_get_trigger_type(d);
status &= IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING;
if (!status)
@@ -233,21 +233,11 @@ static void gpio_irq_enable(struct irq_data *d)
static int gpio_irq_type(struct irq_data *d, unsigned trigger)
{
struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
- u32 mask = (u32) irq_data_get_irq_data(d);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
return -EINVAL;
- irq_desc[d->irq].status &= ~IRQ_TYPE_SENSE_MASK;
- irq_desc[d->irq].status |= trigger;
-
- /* don't enable the IRQ if it's currently disabled */
- if (irq_desc[d->irq].depth == 0) {
- __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_FALLING)
- ? &g->set_falling : &g->clr_falling);
- __raw_writel(mask, (trigger & IRQ_TYPE_EDGE_RISING)
- ? &g->set_rising : &g->clr_rising);
- }
return 0;
}
@@ -256,6 +246,7 @@ static struct irq_chip gpio_irqchip = {
.irq_enable = gpio_irq_enable,
.irq_disable = gpio_irq_disable,
.irq_set_type = gpio_irq_type,
+ .flags = IRQCHIP_SET_TYPE_MASKED,
};
static void
@@ -285,7 +276,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
status >>= 16;
/* now demux them to the right lowlevel handler */
- n = (int)get_irq_data(irq);
+ n = (int)irq_get_handler_data(irq);
while (status) {
res = ffs(status);
n += res;
@@ -323,7 +314,7 @@ static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
static int gpio_irq_type_unbanked(struct irq_data *d, unsigned trigger)
{
struct davinci_gpio_regs __iomem *g = irq2regs(d->irq);
- u32 mask = (u32) irq_data_get_irq_data(d);
+ u32 mask = (u32) irq_data_get_irq_handler_data(d);
if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
return -EINVAL;
@@ -395,7 +386,7 @@ static int __init davinci_gpio_irq_setup(void)
/* AINTC handles mask/unmask; GPIO handles triggering */
irq = bank_irq;
- gpio_irqchip_unbanked = *get_irq_desc_chip(irq_to_desc(irq));
+ gpio_irqchip_unbanked = *irq_get_chip(irq);
gpio_irqchip_unbanked.name = "GPIO-AINTC";
gpio_irqchip_unbanked.irq_set_type = gpio_irq_type_unbanked;
@@ -406,10 +397,10 @@ static int __init davinci_gpio_irq_setup(void)
/* set the direct IRQs up to use that irqchip */
for (gpio = 0; gpio < soc_info->gpio_unbanked; gpio++, irq++) {
- set_irq_chip(irq, &gpio_irqchip_unbanked);
- set_irq_data(irq, (void *) __gpio_mask(gpio));
- set_irq_chip_data(irq, (__force void *) g);
- irq_desc[irq].status |= IRQ_TYPE_EDGE_BOTH;
+ irq_set_chip(irq, &gpio_irqchip_unbanked);
+ irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
+ irq_set_chip_data(irq, (__force void *)g);
+ irq_set_status_flags(irq, IRQ_TYPE_EDGE_BOTH);
}
goto done;
@@ -430,15 +421,15 @@ static int __init davinci_gpio_irq_setup(void)
__raw_writel(~0, &g->clr_rising);
/* set up all irqs in this bank */
- set_irq_chained_handler(bank_irq, gpio_irq_handler);
- set_irq_chip_data(bank_irq, (__force void *) g);
- set_irq_data(bank_irq, (void *) irq);
+ irq_set_chained_handler(bank_irq, gpio_irq_handler);
+ irq_set_chip_data(bank_irq, (__force void *)g);
+ irq_set_handler_data(bank_irq, (void *)irq);
for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
- set_irq_chip(irq, &gpio_irqchip);
- set_irq_chip_data(irq, (__force void *) g);
- set_irq_data(irq, (void *) __gpio_mask(gpio));
- set_irq_handler(irq, handle_simple_irq);
+ irq_set_chip(irq, &gpio_irqchip);
+ irq_set_chip_data(irq, (__force void *)g);
+ irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
+ irq_set_handler(irq, handle_simple_irq);
set_irq_flags(irq, IRQF_VALID);
}
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c
index 5e05c9b64e1..e6269a6e001 100644
--- a/arch/arm/mach-davinci/irq.c
+++ b/arch/arm/mach-davinci/irq.c
@@ -154,11 +154,11 @@ void __init davinci_irq_init(void)
/* set up genirq dispatch for ARM INTC */
for (i = 0; i < davinci_soc_info.intc_irq_num; i++) {
- set_irq_chip(i, &davinci_irq_chip_0);
+ irq_set_chip(i, &davinci_irq_chip_0);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
if (i != IRQ_TINT1_TINT34)
- set_irq_handler(i, handle_edge_irq);
+ irq_set_handler(i, handle_edge_irq);
else
- set_irq_handler(i, handle_level_irq);
+ irq_set_handler(i, handle_level_irq);
}
}
diff --git a/arch/arm/mach-dove/include/mach/dove.h b/arch/arm/mach-dove/include/mach/dove.h
index e5fcdd3f5bf..b20ec9af788 100644
--- a/arch/arm/mach-dove/include/mach/dove.h
+++ b/arch/arm/mach-dove/include/mach/dove.h
@@ -136,7 +136,7 @@
#define DOVE_MPP_GENERAL_VIRT_BASE (DOVE_SB_REGS_VIRT_BASE | 0xe803c)
#define DOVE_AU1_SPDIFO_GPIO_EN (1 << 1)
#define DOVE_NAND_GPIO_EN (1 << 0)
-#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_VIRT_BASE + 0x40)
+#define DOVE_MPP_CTRL4_VIRT_BASE (DOVE_GPIO_LO_VIRT_BASE + 0x40)
#define DOVE_SPI_GPIO_SEL (1 << 5)
#define DOVE_UART1_GPIO_SEL (1 << 4)
#define DOVE_AU1_GPIO_SEL (1 << 3)
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c
index 101707fa2e2..f07fd16e0c9 100644
--- a/arch/arm/mach-dove/irq.c
+++ b/arch/arm/mach-dove/irq.c
@@ -86,8 +86,7 @@ static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc)
if (!(cause & (1 << irq)))
continue;
irq = pmu_to_irq(irq);
- desc = irq_desc + irq;
- desc_handle_irq(irq, desc);
+ generic_handle_irq(irq);
}
}
@@ -103,14 +102,14 @@ void __init dove_init_irq(void)
*/
orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START);
- set_irq_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
- set_irq_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
- set_irq_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
- set_irq_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler);
orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 32);
- set_irq_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler);
orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0,
IRQ_DOVE_GPIO_START + 64);
@@ -122,10 +121,9 @@ void __init dove_init_irq(void)
writel(0, PMU_INTERRUPT_CAUSE);
for (i = IRQ_DOVE_PMU_START; i < NR_IRQS; i++) {
- set_irq_chip(i, &pmu_irq_chip);
- set_irq_handler(i, handle_level_irq);
- irq_desc[i].status |= IRQ_LEVEL;
+ irq_set_chip_and_handler(i, &pmu_irq_chip, handle_level_irq);
+ irq_set_status_flags(i, IRQ_LEVEL);
set_irq_flags(i, IRQF_VALID);
}
- set_irq_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
+ irq_set_chained_handler(IRQ_DOVE_PMU, pmu_irq_handler);
}
diff --git a/arch/arm/mach-dove/mpp.c b/arch/arm/mach-dove/mpp.c
index 71db2bdf2f2..c66c7634690 100644
--- a/arch/arm/mach-dove/mpp.c
+++ b/arch/arm/mach-dove/mpp.c
@@ -147,9 +147,6 @@ void __init dove_mpp_conf(unsigned int *mpp_list)
u32 pmu_sig_ctrl[PMU_SIG_REGS];
int i;
- /* Initialize gpiolib. */
- orion_gpio_init();
-
for (i = 0; i < MPP_NR_REGS; i++)
mpp_ctrl[i] = readl(MPP_CTRL(i));
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 7df083f37fa..087bc771ac2 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -66,8 +66,8 @@ static void __init ebsa110_init_irq(void)
local_irq_restore(flags);
for (irq = 0; irq < NR_IRQS; irq++) {
- set_irq_chip(irq, &ebsa110_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ebsa110_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
diff --git a/arch/arm/mach-ep93xx/gpio.c b/arch/arm/mach-ep93xx/gpio.c
index 34e071d7976..180b8a9d0d2 100644
--- a/arch/arm/mach-ep93xx/gpio.c
+++ b/arch/arm/mach-ep93xx/gpio.c
@@ -117,7 +117,7 @@ static void ep93xx_gpio_irq_ack(struct irq_data *d)
int port = line >> 3;
int port_mask = 1 << (line & 7);
- if ((irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+ if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
ep93xx_gpio_update_int_params(port);
}
@@ -131,7 +131,7 @@ static void ep93xx_gpio_irq_mask_ack(struct irq_data *d)
int port = line >> 3;
int port_mask = 1 << (line & 7);
- if ((irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH)
+ if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH)
gpio_int_type2[port] ^= port_mask; /* switch edge direction */
gpio_int_unmasked[port] &= ~port_mask;
@@ -165,10 +165,10 @@ static void ep93xx_gpio_irq_unmask(struct irq_data *d)
*/
static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
{
- struct irq_desc *desc = irq_desc + d->irq;
const int gpio = irq_to_gpio(d->irq);
const int port = gpio >> 3;
const int port_mask = 1 << (gpio & 7);
+ irq_flow_handler_t handler;
gpio_direction_input(gpio);
@@ -176,22 +176,22 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
case IRQ_TYPE_EDGE_RISING:
gpio_int_type1[port] |= port_mask;
gpio_int_type2[port] |= port_mask;
- desc->handle_irq = handle_edge_irq;
+ handler = handle_edge_irq;
break;
case IRQ_TYPE_EDGE_FALLING:
gpio_int_type1[port] |= port_mask;
gpio_int_type2[port] &= ~port_mask;
- desc->handle_irq = handle_edge_irq;
+ handler = handle_edge_irq;
break;
case IRQ_TYPE_LEVEL_HIGH:
gpio_int_type1[port] &= ~port_mask;
gpio_int_type2[port] |= port_mask;
- desc->handle_irq = handle_level_irq;
+ handler = handle_level_irq;
break;
case IRQ_TYPE_LEVEL_LOW:
gpio_int_type1[port] &= ~port_mask;
gpio_int_type2[port] &= ~port_mask;
- desc->handle_irq = handle_level_irq;
+ handler = handle_level_irq;
break;
case IRQ_TYPE_EDGE_BOTH:
gpio_int_type1[port] |= port_mask;
@@ -200,17 +200,16 @@ static int ep93xx_gpio_irq_type(struct irq_data *d, unsigned int type)
gpio_int_type2[port] &= ~port_mask; /* falling */
else
gpio_int_type2[port] |= port_mask; /* rising */
- desc->handle_irq = handle_edge_irq;
+ handler = handle_edge_irq;
break;
default:
pr_err("failed to set irq type %d for gpio %d\n", type, gpio);
return -EINVAL;
}
- gpio_int_enabled[port] |= port_mask;
+ __irq_set_handler_locked(d->irq, handler);
- desc->status &= ~IRQ_TYPE_SENSE_MASK;
- desc->status |= type & IRQ_TYPE_SENSE_MASK;
+ gpio_int_enabled[port] |= port_mask;
ep93xx_gpio_update_int_params(port);
@@ -232,20 +231,29 @@ void __init ep93xx_gpio_init_irq(void)
for (gpio_irq = gpio_to_irq(0);
gpio_irq <= gpio_to_irq(EP93XX_GPIO_LINE_MAX_IRQ); ++gpio_irq) {
- set_irq_chip(gpio_irq, &ep93xx_gpio_irq_chip);
- set_irq_handler(gpio_irq, handle_level_irq);
+ irq_set_chip_and_handler(gpio_irq, &ep93xx_gpio_irq_chip,
+ handle_level_irq);
set_irq_flags(gpio_irq, IRQF_VALID);
}
- set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
- set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
- set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
- set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
- set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
- set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
- set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
- set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
- set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO_AB,
+ ep93xx_gpio_ab_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO0MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO1MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO2MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO3MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO4MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO5MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO6MUX,
+ ep93xx_gpio_f_irq_handler);
+ irq_set_chained_handler(IRQ_EP93XX_GPIO7MUX,
+ ep93xx_gpio_f_irq_handler);
}
diff --git a/arch/arm/mach-exynos4/Kconfig b/arch/arm/mach-exynos4/Kconfig
index a021b5240bb..e849f67be47 100644
--- a/arch/arm/mach-exynos4/Kconfig
+++ b/arch/arm/mach-exynos4/Kconfig
@@ -20,6 +20,11 @@ config EXYNOS4_MCT
help
Use MCT (Multi Core Timer) as kernel timers
+config EXYNOS4_DEV_AHCI
+ bool
+ help
+ Compile in platform device definitions for AHCI
+
config EXYNOS4_DEV_PD
bool
help
@@ -134,9 +139,9 @@ config MACH_ARMLEX4210
select S3C_DEV_HSMMC
select S3C_DEV_HSMMC2
select S3C_DEV_HSMMC3
+ select EXYNOS4_DEV_AHCI
select EXYNOS4_DEV_SYSMMU
select EXYNOS4_SETUP_SDHCI
- select SATA_AHCI_PLATFORM
help
Machine support for Samsung ARMLEX4210 based on EXYNOS4210
diff --git a/arch/arm/mach-exynos4/Makefile b/arch/arm/mach-exynos4/Makefile
index b8f0e7d82d7..9be104f63c0 100644
--- a/arch/arm/mach-exynos4/Makefile
+++ b/arch/arm/mach-exynos4/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_MACH_NURI) += mach-nuri.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
@@ -53,4 +54,3 @@ 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_SATA_AHCI_PLATFORM) += dev-ahci.o
diff --git a/arch/arm/mach-exynos4/include/mach/debug-macro.S b/arch/arm/mach-exynos4/include/mach/debug-macro.S
index 58bbd049a6c..a442ef86116 100644
--- a/arch/arm/mach-exynos4/include/mach/debug-macro.S
+++ b/arch/arm/mach-exynos4/include/mach/debug-macro.S
@@ -21,8 +21,8 @@
*/
.macro addruart, rp, rv
- ldreq \rp, = S3C_PA_UART
- ldrne \rv, = S3C_VA_UART
+ 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)
diff --git a/arch/arm/mach-exynos4/irq-combiner.c b/arch/arm/mach-exynos4/irq-combiner.c
index 31618d91ce1..f488b66d680 100644
--- a/arch/arm/mach-exynos4/irq-combiner.c
+++ b/arch/arm/mach-exynos4/irq-combiner.c
@@ -54,8 +54,8 @@ static void combiner_unmask_irq(struct irq_data *data)
static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
{
- struct combiner_chip_data *chip_data = get_irq_data(irq);
- struct irq_chip *chip = get_irq_chip(irq);
+ 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;
@@ -93,9 +93,9 @@ void __init combiner_cascade_irq(unsigned int combiner_nr, unsigned int irq)
{
if (combiner_nr >= MAX_COMBINER_NR)
BUG();
- if (set_irq_data(irq, &combiner_data[combiner_nr]) != 0)
+ if (irq_set_handler_data(irq, &combiner_data[combiner_nr]) != 0)
BUG();
- set_irq_chained_handler(irq, combiner_handle_cascade_irq);
+ irq_set_chained_handler(irq, combiner_handle_cascade_irq);
}
void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
@@ -119,9 +119,8 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base,
for (i = irq_start; i < combiner_data[combiner_nr].irq_offset
+ MAX_IRQ_IN_COMBINER; i++) {
- set_irq_chip(i, &combiner_chip);
- set_irq_chip_data(i, &combiner_data[combiner_nr]);
- set_irq_handler(i, handle_level_irq);
+ 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
index 4f7ad4a796e..9d87d2ac7f6 100644
--- a/arch/arm/mach-exynos4/irq-eint.c
+++ b/arch/arm/mach-exynos4/irq-eint.c
@@ -190,8 +190,8 @@ static void exynos4_irq_demux_eint16_31(unsigned int irq, struct irq_desc *desc)
static void exynos4_irq_eint0_15(unsigned int irq, struct irq_desc *desc)
{
- u32 *irq_data = get_irq_data(irq);
- struct irq_chip *chip = get_irq_chip(irq);
+ u32 *irq_data = irq_get_handler_data(irq);
+ struct irq_chip *chip = irq_get_chip(irq);
chip->irq_mask(&desc->irq_data);
@@ -208,18 +208,19 @@ int __init exynos4_init_irq_eint(void)
int irq;
for (irq = 0 ; irq <= 31 ; irq++) {
- set_irq_chip(IRQ_EINT(irq), &exynos4_irq_eint);
- set_irq_handler(IRQ_EINT(irq), handle_level_irq);
+ irq_set_chip_and_handler(IRQ_EINT(irq), &exynos4_irq_eint,
+ handle_level_irq);
set_irq_flags(IRQ_EINT(irq), IRQF_VALID);
}
- set_irq_chained_handler(IRQ_EINT16_31, exynos4_irq_demux_eint16_31);
+ 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);
- set_irq_data(exynos4_get_irq_nr(irq), &eint0_15_data[irq]);
- set_irq_chained_handler(exynos4_get_irq_nr(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);
}
diff --git a/arch/arm/mach-exynos4/mach-smdkc210.c b/arch/arm/mach-exynos4/mach-smdkc210.c
index 25a25681812..e645f7a955f 100644
--- a/arch/arm/mach-exynos4/mach-smdkc210.c
+++ b/arch/arm/mach-exynos4/mach-smdkc210.c
@@ -125,7 +125,7 @@ static struct resource smdkc210_smsc911x_resources[] = {
};
static struct smsc911x_platform_config smsc9215_config = {
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .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,
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c
index 88e0275143b..152676471b6 100644
--- a/arch/arm/mach-exynos4/mach-smdkv310.c
+++ b/arch/arm/mach-exynos4/mach-smdkv310.c
@@ -127,7 +127,7 @@ static struct resource smdkv310_smsc911x_resources[] = {
};
static struct smsc911x_platform_config smsc9215_config = {
- .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
+ .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,
diff --git a/arch/arm/mach-footbridge/common.c b/arch/arm/mach-footbridge/common.c
index 84c5f258f2d..38a44f9b9da 100644
--- a/arch/arm/mach-footbridge/common.c
+++ b/arch/arm/mach-footbridge/common.c
@@ -102,8 +102,7 @@ static void __init __fb_init_irq(void)
*CSR_FIQ_DISABLE = -1;
for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(20); irq++) {
- set_irq_chip(irq, &fb_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &fb_chip, handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
diff --git a/arch/arm/mach-footbridge/dc21285-timer.c b/arch/arm/mach-footbridge/dc21285-timer.c
index a921fe92b85..5f1f9867fc7 100644
--- a/arch/arm/mach-footbridge/dc21285-timer.c
+++ b/arch/arm/mach-footbridge/dc21285-timer.c
@@ -30,7 +30,7 @@ static int cksrc_dc21285_enable(struct clocksource *cs)
return 0;
}
-static int cksrc_dc21285_disable(struct clocksource *cs)
+static void cksrc_dc21285_disable(struct clocksource *cs)
{
*CSR_TIMER2_CNTL = 0;
}
diff --git a/arch/arm/mach-footbridge/isa-irq.c b/arch/arm/mach-footbridge/isa-irq.c
index de7a5cb5dbe..c3a0abbc904 100644
--- a/arch/arm/mach-footbridge/isa-irq.c
+++ b/arch/arm/mach-footbridge/isa-irq.c
@@ -151,14 +151,14 @@ void __init isa_init_irq(unsigned int host_irq)
if (host_irq != (unsigned int)-1) {
for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
- set_irq_chip(irq, &isa_lo_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &isa_lo_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
- set_irq_chip(irq, &isa_hi_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &isa_hi_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
@@ -166,7 +166,7 @@ void __init isa_init_irq(unsigned int host_irq)
request_resource(&ioport_resource, &pic2_resource);
setup_irq(IRQ_ISA_CASCADE, &irq_cascade);
- set_irq_chained_handler(host_irq, isa_irq_handler);
+ irq_set_chained_handler(host_irq, isa_irq_handler);
/*
* On the NetWinder, don't automatically
diff --git a/arch/arm/mach-gemini/gpio.c b/arch/arm/mach-gemini/gpio.c
index fa3d333f21e..fdc7ef1391d 100644
--- a/arch/arm/mach-gemini/gpio.c
+++ b/arch/arm/mach-gemini/gpio.c
@@ -127,8 +127,8 @@ static int gpio_set_irq_type(struct irq_data *d, unsigned int type)
static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
+ unsigned int port = (unsigned int)irq_desc_get_handler_data(desc);
unsigned int gpio_irq_no, irq_stat;
- unsigned int port = (unsigned int)get_irq_data(irq);
irq_stat = __raw_readl(GPIO_BASE(port) + GPIO_INT_STAT);
@@ -138,9 +138,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
if ((irq_stat & 1) == 0)
continue;
- BUG_ON(!(irq_desc[gpio_irq_no].handle_irq));
- irq_desc[gpio_irq_no].handle_irq(gpio_irq_no,
- &irq_desc[gpio_irq_no]);
+ generic_handle_irq(gpio_irq_no);
}
}
@@ -219,13 +217,13 @@ void __init gemini_gpio_init(void)
for (j = GPIO_IRQ_BASE + i * 32;
j < GPIO_IRQ_BASE + (i + 1) * 32; j++) {
- set_irq_chip(j, &gpio_irq_chip);
- set_irq_handler(j, handle_edge_irq);
+ irq_set_chip_and_handler(j, &gpio_irq_chip,
+ handle_edge_irq);
set_irq_flags(j, IRQF_VALID);
}
- set_irq_chained_handler(IRQ_GPIO(i), gpio_irq_handler);
- set_irq_data(IRQ_GPIO(i), (void *)i);
+ irq_set_chained_handler(IRQ_GPIO(i), gpio_irq_handler);
+ irq_set_handler_data(IRQ_GPIO(i), (void *)i);
}
BUG_ON(gpiochip_add(&gemini_gpio_chip));
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c
index 96bc227dd84..9485a8fdf85 100644
--- a/arch/arm/mach-gemini/irq.c
+++ b/arch/arm/mach-gemini/irq.c
@@ -81,13 +81,13 @@ void __init gemini_init_irq(void)
request_resource(&iomem_resource, &irq_resource);
for (i = 0; i < NR_IRQS; i++) {
- set_irq_chip(i, &gemini_irq_chip);
+ irq_set_chip(i, &gemini_irq_chip);
if((i >= IRQ_TIMER1 && i <= IRQ_TIMER3) || (i >= IRQ_SERIRQ0 && i <= IRQ_SERIRQ1)) {
- set_irq_handler(i, handle_edge_irq);
+ irq_set_handler(i, handle_edge_irq);
mode |= 1 << i;
level |= 1 << i;
} else {
- set_irq_handler(i, handle_level_irq);
+ irq_set_handler(i, handle_level_irq);
}
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index 1f28c90932c..51d4e44ab97 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -199,29 +199,29 @@ void __init h720x_init_irq (void)
/* Initialize global IRQ's, fast path */
for (irq = 0; irq < NR_GLBL_IRQS; irq++) {
- set_irq_chip(irq, &h720x_global_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &h720x_global_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
/* Initialize multiplexed IRQ's, slow path */
for (irq = IRQ_CHAINED_GPIOA(0) ; irq <= IRQ_CHAINED_GPIOD(31); irq++) {
- set_irq_chip(irq, &h720x_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &h720x_gpio_chip,
+ handle_edge_irq);
set_irq_flags(irq, IRQF_VALID );
}
- set_irq_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler);
- set_irq_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler);
- set_irq_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler);
- set_irq_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler);
+ irq_set_chained_handler(IRQ_GPIOA, h720x_gpioa_demux_handler);
+ irq_set_chained_handler(IRQ_GPIOB, h720x_gpiob_demux_handler);
+ irq_set_chained_handler(IRQ_GPIOC, h720x_gpioc_demux_handler);
+ irq_set_chained_handler(IRQ_GPIOD, h720x_gpiod_demux_handler);
#ifdef CONFIG_CPU_H7202
for (irq = IRQ_CHAINED_GPIOE(0) ; irq <= IRQ_CHAINED_GPIOE(31); irq++) {
- set_irq_chip(irq, &h720x_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &h720x_gpio_chip,
+ handle_edge_irq);
set_irq_flags(irq, IRQF_VALID );
}
- set_irq_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler);
+ irq_set_chained_handler(IRQ_GPIOE, h720x_gpioe_demux_handler);
#endif
/* Enable multiplexed irq's */
diff --git a/arch/arm/mach-h720x/cpu-h7202.c b/arch/arm/mach-h720x/cpu-h7202.c
index ac3f9144237..c37d570b852 100644
--- a/arch/arm/mach-h720x/cpu-h7202.c
+++ b/arch/arm/mach-h720x/cpu-h7202.c
@@ -141,13 +141,18 @@ h7202_timer_interrupt(int irq, void *dev_id)
/*
* mask multiplexed timer IRQs
*/
-static void inline mask_timerx_irq(struct irq_data *d)
+static void inline __mask_timerx_irq(unsigned int irq)
{
unsigned int bit;
- bit = 2 << ((d->irq == IRQ_TIMER64B) ? 4 : (d->irq - IRQ_TIMER1));
+ bit = 2 << ((irq == IRQ_TIMER64B) ? 4 : (irq - IRQ_TIMER1));
CPU_REG (TIMER_VIRT, TIMER_TOPCTRL) &= ~bit;
}
+static void inline mask_timerx_irq(struct irq_data *d)
+{
+ __mask_timerx_irq(d->irq);
+}
+
/*
* unmask multiplexed timer IRQs
*/
@@ -196,12 +201,12 @@ void __init h7202_init_irq (void)
for (irq = IRQ_TIMER1;
irq < IRQ_CHAINED_TIMERX(NR_TIMERX_IRQS); irq++) {
- mask_timerx_irq(irq);
- set_irq_chip(irq, &h7202_timerx_chip);
- set_irq_handler(irq, handle_edge_irq);
+ __mask_timerx_irq(irq);
+ irq_set_chip_and_handler(irq, &h7202_timerx_chip,
+ handle_edge_irq);
set_irq_flags(irq, IRQF_VALID );
}
- set_irq_chained_handler(IRQ_TIMERX, h7202_timerx_demux_handler);
+ irq_set_chained_handler(IRQ_TIMERX, h7202_timerx_demux_handler);
h720x_init_irq();
}
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 5eec099e0c7..56b930a1344 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -255,6 +255,7 @@ config MACH_IMX27_VISSTRIM_M10
bool "Vista Silicon i.MX27 Visstrim_m10"
select SOC_IMX27
select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_IMX_SSI
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_MXC_EHCI
diff --git a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
index cb705c28de0..6269053505f 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd25-baseboard.c
@@ -34,6 +34,7 @@
#include <mach/mx25.h>
#include <mach/imx-uart.h>
#include <mach/audmux.h>
+#include <mach/esdhc.h>
#include "devices-imx25.h"
@@ -242,6 +243,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
};
+static struct esdhc_platform_data sd1_pdata = {
+ .cd_gpio = GPIO_SD1CD,
+ .wp_gpio = -EINVAL,
+};
+
/*
* system init for baseboard usage. Will be called by cpuimx25 init.
*
@@ -275,7 +281,7 @@ void __init eukrea_mbimxsd25_baseboard_init(void)
imx25_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
imx25_add_flexcan1(NULL);
- imx25_add_sdhci_esdhc_imx(0, NULL);
+ imx25_add_sdhci_esdhc_imx(0, &sd1_pdata);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
index a233470dd10..bc739701c30 100644
--- a/arch/arm/mach-iop13xx/irq.c
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -224,15 +224,15 @@ void __init iop13xx_init_irq(void)
for(i = 0; i <= IRQ_IOP13XX_HPI; i++) {
if (i < 32)
- set_irq_chip(i, &iop13xx_irqchip1);
+ irq_set_chip(i, &iop13xx_irqchip1);
else if (i < 64)
- set_irq_chip(i, &iop13xx_irqchip2);
+ irq_set_chip(i, &iop13xx_irqchip2);
else if (i < 96)
- set_irq_chip(i, &iop13xx_irqchip3);
+ irq_set_chip(i, &iop13xx_irqchip3);
else
- set_irq_chip(i, &iop13xx_irqchip4);
+ irq_set_chip(i, &iop13xx_irqchip4);
- set_irq_handler(i, handle_level_irq);
+ irq_set_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index c9c02e3698b..560d5b2dec2 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -118,7 +118,7 @@ static void iop13xx_msi_handler(unsigned int irq, struct irq_desc *desc)
void __init iop13xx_msi_init(void)
{
- set_irq_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler);
+ irq_set_chained_handler(IRQ_IOP13XX_INBD_MSI, iop13xx_msi_handler);
}
/*
@@ -178,7 +178,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
if (irq < 0)
return irq;
- set_irq_msi(irq, desc);
+ irq_set_msi_desc(irq, desc);
msg.address_hi = 0x0;
msg.address_lo = IOP13XX_MU_MIMR_PCI;
@@ -187,7 +187,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
msg.data = (id << IOP13XX_MU_MIMR_CORE_SELECT) | (irq & 0x7f);
write_msi_msg(irq, &msg);
- set_irq_chip_and_handler(irq, &iop13xx_msi_chip, handle_simple_irq);
+ irq_set_chip_and_handler(irq, &iop13xx_msi_chip, handle_simple_irq);
return 0;
}
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index d3426a12059..d7ee2789d89 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -68,8 +68,7 @@ void __init iop32x_init_irq(void)
*IOP3XX_PCIIRSR = 0x0f;
for (i = 0; i < NR_IRQS; i++) {
- set_irq_chip(i, &ext_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &ext_chip, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
}
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c
index 0ff2f74363a..f7f5d3e451c 100644
--- a/arch/arm/mach-iop33x/irq.c
+++ b/arch/arm/mach-iop33x/irq.c
@@ -110,8 +110,9 @@ void __init iop33x_init_irq(void)
*IOP3XX_PCIIRSR = 0x0f;
for (i = 0; i < NR_IRQS; i++) {
- set_irq_chip(i, (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i,
+ (i < 32) ? &iop33x_irqchip1 : &iop33x_irqchip2,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
}
diff --git a/arch/arm/mach-ixp2000/core.c b/arch/arm/mach-ixp2000/core.c
index 5fc4e064b65..4068166c899 100644
--- a/arch/arm/mach-ixp2000/core.c
+++ b/arch/arm/mach-ixp2000/core.c
@@ -476,8 +476,8 @@ void __init ixp2000_init_irq(void)
*/
for (irq = IRQ_IXP2000_SOFT_INT; irq <= IRQ_IXP2000_THDB3; irq++) {
if ((1 << irq) & IXP2000_VALID_IRQ_MASK) {
- set_irq_chip(irq, &ixp2000_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ixp2000_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
} else set_irq_flags(irq, 0);
}
@@ -485,21 +485,21 @@ void __init ixp2000_init_irq(void)
for (irq = IRQ_IXP2000_DRAM0_MIN_ERR; irq <= IRQ_IXP2000_SP_INT; irq++) {
if((1 << (irq - IRQ_IXP2000_DRAM0_MIN_ERR)) &
IXP2000_VALID_ERR_IRQ_MASK) {
- set_irq_chip(irq, &ixp2000_err_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ixp2000_err_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
else
set_irq_flags(irq, 0);
}
- set_irq_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler);
+ irq_set_chained_handler(IRQ_IXP2000_ERRSUM, ixp2000_err_irq_handler);
for (irq = IRQ_IXP2000_GPIO0; irq <= IRQ_IXP2000_GPIO7; irq++) {
- set_irq_chip(irq, &ixp2000_GPIO_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ixp2000_GPIO_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
- set_irq_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler);
+ irq_set_chained_handler(IRQ_IXP2000_GPIO, ixp2000_GPIO_irq_handler);
/*
* Enable PCI irqs. The actual PCI[AB] decoding is done in
@@ -508,8 +508,8 @@ void __init ixp2000_init_irq(void)
*/
ixp2000_reg_write(IXP2000_IRQ_ENABLE_SET, (1 << IRQ_IXP2000_PCI));
for (irq = IRQ_IXP2000_PCIA; irq <= IRQ_IXP2000_PCIB; irq++) {
- set_irq_chip(irq, &ixp2000_pci_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ixp2000_pci_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-ixp2000/ixdp2x00.c b/arch/arm/mach-ixp2000/ixdp2x00.c
index 7d90d3f13ee..235638f800e 100644
--- a/arch/arm/mach-ixp2000/ixdp2x00.c
+++ b/arch/arm/mach-ixp2000/ixdp2x00.c
@@ -158,13 +158,13 @@ void __init ixdp2x00_init_irq(volatile unsigned long *stat_reg, volatile unsigne
*board_irq_mask = 0xffffffff;
for(irq = IXP2000_BOARD_IRQ(0); irq < IXP2000_BOARD_IRQ(board_irq_count); irq++) {
- set_irq_chip(irq, &ixdp2x00_cpld_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ixdp2x00_cpld_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
/* Hook into PCI interrupt */
- set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler);
+ irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x00_irq_handler);
}
/*************************************************************************
diff --git a/arch/arm/mach-ixp2000/ixdp2x01.c b/arch/arm/mach-ixp2000/ixdp2x01.c
index 34b1b2af37c..84835b20955 100644
--- a/arch/arm/mach-ixp2000/ixdp2x01.c
+++ b/arch/arm/mach-ixp2000/ixdp2x01.c
@@ -115,8 +115,8 @@ void __init ixdp2x01_init_irq(void)
for (irq = NR_IXP2000_IRQS; irq < NR_IXDP2X01_IRQS; irq++) {
if (irq & valid_irq_mask) {
- set_irq_chip(irq, &ixdp2x01_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ixdp2x01_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
} else {
set_irq_flags(irq, 0);
@@ -124,7 +124,7 @@ void __init ixdp2x01_init_irq(void)
}
/* Hook into PCI interrupts */
- set_irq_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler);
+ irq_set_chained_handler(IRQ_IXP2000_PCIB, ixdp2x01_irq_handler);
}
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index 9c8a3390321..a1bee33d183 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -289,12 +289,12 @@ static void ixp23xx_config_irq(unsigned int irq, enum ixp23xx_irq_type type)
{
switch (type) {
case IXP23XX_IRQ_LEVEL:
- set_irq_chip(irq, &ixp23xx_irq_level_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ixp23xx_irq_level_chip,
+ handle_level_irq);
break;
case IXP23XX_IRQ_EDGE:
- set_irq_chip(irq, &ixp23xx_irq_edge_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &ixp23xx_irq_edge_chip,
+ handle_edge_irq);
break;
}
set_irq_flags(irq, IRQF_VALID);
@@ -324,12 +324,12 @@ void __init ixp23xx_init_irq(void)
}
for (irq = IRQ_IXP23XX_INTA; irq <= IRQ_IXP23XX_INTB; irq++) {
- set_irq_chip(irq, &ixp23xx_pci_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &ixp23xx_pci_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
- set_irq_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler);
+ irq_set_chained_handler(IRQ_IXP23XX_PCI_INT_RPH, pci_handler);
}
diff --git a/arch/arm/mach-ixp23xx/ixdp2351.c b/arch/arm/mach-ixp23xx/ixdp2351.c
index 181116aa659..8dcba17c81e 100644
--- a/arch/arm/mach-ixp23xx/ixdp2351.c
+++ b/arch/arm/mach-ixp23xx/ixdp2351.c
@@ -136,8 +136,8 @@ void __init ixdp2351_init_irq(void)
irq++) {
if (IXDP2351_INTA_IRQ_MASK(irq) & IXDP2351_INTA_IRQ_VALID) {
set_irq_flags(irq, IRQF_VALID);
- set_irq_handler(irq, handle_level_irq);
- set_irq_chip(irq, &ixdp2351_inta_chip);
+ irq_set_chip_and_handler(irq, &ixdp2351_inta_chip,
+ handle_level_irq);
}
}
@@ -147,13 +147,13 @@ void __init ixdp2351_init_irq(void)
irq++) {
if (IXDP2351_INTB_IRQ_MASK(irq) & IXDP2351_INTB_IRQ_VALID) {
set_irq_flags(irq, IRQF_VALID);
- set_irq_handler(irq, handle_level_irq);
- set_irq_chip(irq, &ixdp2351_intb_chip);
+ irq_set_chip_and_handler(irq, &ixdp2351_intb_chip,
+ handle_level_irq);
}
}
- set_irq_chained_handler(IRQ_IXP23XX_INTA, ixdp2351_inta_handler);
- set_irq_chained_handler(IRQ_IXP23XX_INTB, ixdp2351_intb_handler);
+ irq_set_chained_handler(IRQ_IXP23XX_INTA, ixdp2351_inta_handler);
+ irq_set_chained_handler(IRQ_IXP23XX_INTB, ixdp2351_intb_handler);
}
/*
diff --git a/arch/arm/mach-ixp23xx/roadrunner.c b/arch/arm/mach-ixp23xx/roadrunner.c
index 76c61ba7321..8fe0c627326 100644
--- a/arch/arm/mach-ixp23xx/roadrunner.c
+++ b/arch/arm/mach-ixp23xx/roadrunner.c
@@ -110,8 +110,8 @@ static int __init roadrunner_map_irq(struct pci_dev *dev, u8 idsel, u8 pin)
static void __init roadrunner_pci_preinit(void)
{
- set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTC, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_ROADRUNNER_PCI_INTD, IRQ_TYPE_LEVEL_LOW);
ixp23xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/avila-pci.c b/arch/arm/mach-ixp4xx/avila-pci.c
index 845e1b50054..162043ff29f 100644
--- a/arch/arm/mach-ixp4xx/avila-pci.c
+++ b/arch/arm/mach-ixp4xx/avila-pci.c
@@ -39,10 +39,10 @@
void __init avila_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 9fd894271d5..ed19bc31431 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -252,8 +252,8 @@ void __init ixp4xx_init_irq(void)
/* Default to all level triggered */
for(i = 0; i < NR_IRQS; i++) {
- set_irq_chip(i, &ixp4xx_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &ixp4xx_irq_chip,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-ixp4xx/coyote-pci.c b/arch/arm/mach-ixp4xx/coyote-pci.c
index b978ea8bd6f..37fda7d6e83 100644
--- a/arch/arm/mach-ixp4xx/coyote-pci.c
+++ b/arch/arm/mach-ixp4xx/coyote-pci.c
@@ -32,8 +32,8 @@
void __init coyote_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(SLOT0_INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(SLOT1_INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(SLOT0_INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(SLOT1_INTA), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/dsmg600-pci.c b/arch/arm/mach-ixp4xx/dsmg600-pci.c
index fa70fed462b..c7612010b3f 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-pci.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-pci.c
@@ -35,12 +35,12 @@
void __init dsmg600_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTF), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTF), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/fsg-pci.c b/arch/arm/mach-ixp4xx/fsg-pci.c
index 5a810c93062..44ccde9d487 100644
--- a/arch/arm/mach-ixp4xx/fsg-pci.c
+++ b/arch/arm/mach-ixp4xx/fsg-pci.c
@@ -32,9 +32,9 @@
void __init fsg_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/gateway7001-pci.c b/arch/arm/mach-ixp4xx/gateway7001-pci.c
index 7e93a0975c4..fc112416887 100644
--- a/arch/arm/mach-ixp4xx/gateway7001-pci.c
+++ b/arch/arm/mach-ixp4xx/gateway7001-pci.c
@@ -29,8 +29,8 @@
void __init gateway7001_pci_preinit(void)
{
- set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO10, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO11, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/goramo_mlr.c b/arch/arm/mach-ixp4xx/goramo_mlr.c
index d0e4861ac03..3e8c0e33b59 100644
--- a/arch/arm/mach-ixp4xx/goramo_mlr.c
+++ b/arch/arm/mach-ixp4xx/goramo_mlr.c
@@ -420,8 +420,8 @@ static void __init gmlr_init(void)
gpio_line_config(GPIO_HSS1_RTS_N, IXP4XX_GPIO_OUT);
gpio_line_config(GPIO_HSS0_DCD_N, IXP4XX_GPIO_IN);
gpio_line_config(GPIO_HSS1_DCD_N, IXP4XX_GPIO_IN);
- set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
- set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS0_DCD_N), IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_HSS1_DCD_N), IRQ_TYPE_EDGE_BOTH);
set_control(CONTROL_HSS0_DTR_N, 1);
set_control(CONTROL_HSS1_DTR_N, 1);
@@ -441,10 +441,10 @@ static void __init gmlr_init(void)
#ifdef CONFIG_PCI
static void __init gmlr_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_ETHB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_NEC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(GPIO_IRQ_MPCI), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-pci.c b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
index 25d2c333c20..38cc0725dbd 100644
--- a/arch/arm/mach-ixp4xx/gtwx5715-pci.c
+++ b/arch/arm/mach-ixp4xx/gtwx5715-pci.c
@@ -43,8 +43,8 @@
*/
void __init gtwx5715_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
index 1ba165a6eda..58f400417ea 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -36,10 +36,10 @@
void __init ixdp425_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/ixdpg425-pci.c b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
index 4ed7ac61492..e64f6d04148 100644
--- a/arch/arm/mach-ixp4xx/ixdpg425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdpg425-pci.c
@@ -25,8 +25,8 @@
void __init ixdpg425_pci_preinit(void)
{
- set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO6, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO7, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/nas100d-pci.c b/arch/arm/mach-ixp4xx/nas100d-pci.c
index d0cea34cf61..428d1202b79 100644
--- a/arch/arm/mach-ixp4xx/nas100d-pci.c
+++ b/arch/arm/mach-ixp4xx/nas100d-pci.c
@@ -33,11 +33,11 @@
void __init nas100d_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTD), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTE), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/nslu2-pci.c b/arch/arm/mach-ixp4xx/nslu2-pci.c
index 1eb5a90470b..2e85f76b950 100644
--- a/arch/arm/mach-ixp4xx/nslu2-pci.c
+++ b/arch/arm/mach-ixp4xx/nslu2-pci.c
@@ -32,9 +32,9 @@
void __init nslu2_pci_preinit(void)
{
- set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTC), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/vulcan-pci.c b/arch/arm/mach-ixp4xx/vulcan-pci.c
index f3111c6840e..03bdec5140a 100644
--- a/arch/arm/mach-ixp4xx/vulcan-pci.c
+++ b/arch/arm/mach-ixp4xx/vulcan-pci.c
@@ -38,8 +38,8 @@ void __init vulcan_pci_preinit(void)
pr_info("Vulcan PCI: limiting CardBus memory size to %dMB\n",
(int)(pci_cardbus_mem_size >> 20));
#endif
- set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTA), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IXP4XX_GPIO_IRQ(INTB), IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-ixp4xx/wg302v2-pci.c b/arch/arm/mach-ixp4xx/wg302v2-pci.c
index 9b59ed03b15..17f3cf59a31 100644
--- a/arch/arm/mach-ixp4xx/wg302v2-pci.c
+++ b/arch/arm/mach-ixp4xx/wg302v2-pci.c
@@ -29,8 +29,8 @@
void __init wg302v2_pci_preinit(void)
{
- set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW);
- set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO8, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ_IXP4XX_GPIO9, IRQ_TYPE_LEVEL_LOW);
ixp4xx_pci_preinit();
}
diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c
index cbdb5863d13..05d193a25b2 100644
--- a/arch/arm/mach-kirkwood/irq.c
+++ b/arch/arm/mach-kirkwood/irq.c
@@ -35,14 +35,15 @@ void __init kirkwood_init_irq(void)
*/
orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START);
- set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler);
- set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler);
- set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler);
- set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler);
orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0,
IRQ_KIRKWOOD_GPIO_START + 32);
- set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler);
- set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler);
- set_irq_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23,
+ gpio_irq_handler);
}
diff --git a/arch/arm/mach-kirkwood/sheevaplug-setup.c b/arch/arm/mach-kirkwood/sheevaplug-setup.c
index 0a95063f6d3..17de0bf53c0 100644
--- a/arch/arm/mach-kirkwood/sheevaplug-setup.c
+++ b/arch/arm/mach-kirkwood/sheevaplug-setup.c
@@ -58,6 +58,12 @@ static struct mvsdio_platform_data sheeva_esata_mvsdio_data = {
static struct gpio_led sheevaplug_led_pins[] = {
{
+ .name = "plug:red:misc",
+ .default_trigger = "none",
+ .gpio = 46,
+ .active_low = 1,
+ },
+ {
.name = "plug:green:health",
.default_trigger = "default-on",
.gpio = 49,
@@ -80,6 +86,7 @@ static struct platform_device sheevaplug_leds = {
static unsigned int sheevaplug_mpp_config[] __initdata = {
MPP29_GPIO, /* USB Power Enable */
+ MPP46_GPIO, /* LED Red */
MPP49_GPIO, /* LED */
0
};
diff --git a/arch/arm/mach-ks8695/gpio.c b/arch/arm/mach-ks8695/gpio.c
index 55fbf7111a5..31e456508a6 100644
--- a/arch/arm/mach-ks8695/gpio.c
+++ b/arch/arm/mach-ks8695/gpio.c
@@ -80,7 +80,7 @@ int ks8695_gpio_interrupt(unsigned int pin, unsigned int type)
local_irq_restore(flags);
/* Set IRQ triggering type */
- set_irq_type(gpio_irq[pin], type);
+ irq_set_irq_type(gpio_irq[pin], type);
/* enable interrupt mode */
ks8695_gpio_mode(pin, 0);
diff --git a/arch/arm/mach-ks8695/irq.c b/arch/arm/mach-ks8695/irq.c
index 7998ccaa633..a78092dcd6f 100644
--- a/arch/arm/mach-ks8695/irq.c
+++ b/arch/arm/mach-ks8695/irq.c
@@ -115,12 +115,12 @@ static int ks8695_irq_set_type(struct irq_data *d, unsigned int type)
}
if (level_triggered) {
- set_irq_chip(d->irq, &ks8695_irq_level_chip);
- set_irq_handler(d->irq, handle_level_irq);
+ irq_set_chip_and_handler(d->irq, &ks8695_irq_level_chip,
+ handle_level_irq);
}
else {
- set_irq_chip(d->irq, &ks8695_irq_edge_chip);
- set_irq_handler(d->irq, handle_edge_irq);
+ irq_set_chip_and_handler(d->irq, &ks8695_irq_edge_chip,
+ handle_edge_irq);
}
__raw_writel(ctrl, KS8695_GPIO_VA + KS8695_IOPC);
@@ -158,16 +158,18 @@ void __init ks8695_init_irq(void)
case KS8695_IRQ_UART_RX:
case KS8695_IRQ_COMM_TX:
case KS8695_IRQ_COMM_RX:
- set_irq_chip(irq, &ks8695_irq_level_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq,
+ &ks8695_irq_level_chip,
+ handle_level_irq);
break;
/* Edge-triggered interrupts */
default:
/* clear pending bit */
ks8695_irq_ack(irq_get_irq_data(irq));
- set_irq_chip(irq, &ks8695_irq_edge_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq,
+ &ks8695_irq_edge_chip,
+ handle_edge_irq);
}
set_irq_flags(irq, IRQF_VALID);
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
index 316ecbf6c58..4eae566dfdc 100644
--- a/arch/arm/mach-lpc32xx/irq.c
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -290,7 +290,7 @@ static int lpc32xx_set_irq_type(struct irq_data *d, unsigned int type)
}
/* Ok to use the level handler for all types */
- set_irq_handler(d->irq, handle_level_irq);
+ irq_set_handler(d->irq, handle_level_irq);
return 0;
}
@@ -390,8 +390,8 @@ void __init lpc32xx_init_irq(void)
/* Configure supported IRQ's */
for (i = 0; i < NR_IRQS; i++) {
- set_irq_chip(i, &lpc32xx_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &lpc32xx_irq_chip,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
@@ -406,8 +406,8 @@ void __init lpc32xx_init_irq(void)
__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
/* MIC SUBIRQx interrupts will route handling to the chain handlers */
- set_irq_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler);
- set_irq_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler);
+ irq_set_chained_handler(IRQ_LPC32XX_SUB1IRQ, lpc32xx_sic1_handler);
+ irq_set_chained_handler(IRQ_LPC32XX_SUB2IRQ, lpc32xx_sic2_handler);
/* Initially disable all wake events */
__raw_writel(0, LPC32XX_CLKPWR_P01_ER);
diff --git a/arch/arm/mach-mmp/irq-mmp2.c b/arch/arm/mach-mmp/irq-mmp2.c
index fa037038e7b..d21c5441a3d 100644
--- a/arch/arm/mach-mmp/irq-mmp2.c
+++ b/arch/arm/mach-mmp/irq-mmp2.c
@@ -110,9 +110,9 @@ static void init_mux_irq(struct irq_chip *chip, int start, int num)
if (chip->irq_ack)
chip->irq_ack(d);
- set_irq_chip(irq, chip);
+ irq_set_chip(irq, chip);
set_irq_flags(irq, IRQF_VALID);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_handler(irq, handle_level_irq);
}
}
@@ -122,7 +122,7 @@ void __init mmp2_init_icu(void)
for (irq = 0; irq < IRQ_MMP2_MUX_BASE; irq++) {
icu_mask_irq(irq_get_irq_data(irq));
- set_irq_chip(irq, &icu_irq_chip);
+ irq_set_chip(irq, &icu_irq_chip);
set_irq_flags(irq, IRQF_VALID);
switch (irq) {
@@ -133,7 +133,7 @@ void __init mmp2_init_icu(void)
case IRQ_MMP2_SSP_MUX:
break;
default:
- set_irq_handler(irq, handle_level_irq);
+ irq_set_handler(irq, handle_level_irq);
break;
}
}
@@ -149,9 +149,9 @@ void __init mmp2_init_icu(void)
init_mux_irq(&misc_irq_chip, IRQ_MMP2_MISC_BASE, 15);
init_mux_irq(&ssp_irq_chip, IRQ_MMP2_SSP_BASE, 2);
- set_irq_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux);
- set_irq_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux);
- set_irq_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux);
- set_irq_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux);
- set_irq_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_PMIC_MUX, pmic_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_RTC_MUX, rtc_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_TWSI_MUX, twsi_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_MISC_MUX, misc_irq_demux);
+ irq_set_chained_handler(IRQ_MMP2_SSP_MUX, ssp_irq_demux);
}
diff --git a/arch/arm/mach-mmp/irq-pxa168.c b/arch/arm/mach-mmp/irq-pxa168.c
index f86b450cb93..89706a0d08f 100644
--- a/arch/arm/mach-mmp/irq-pxa168.c
+++ b/arch/arm/mach-mmp/irq-pxa168.c
@@ -48,8 +48,7 @@ void __init icu_init_irq(void)
for (irq = 0; irq < 64; irq++) {
icu_mask_irq(irq_get_irq_data(irq));
- set_irq_chip(irq, &icu_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &icu_irq_chip, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index 1993721d472..35c7ceeb3f2 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -53,7 +53,7 @@ static void __init msm8960_init_irq(void)
*/
for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
- set_irq_handler(i, handle_percpu_irq);
+ irq_set_handler(i, handle_percpu_irq);
}
}
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index b3c55f138fc..1163b6fd05d 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -56,7 +56,7 @@ static void __init msm8x60_init_irq(void)
*/
for (i = GIC_PPI_START; i < GIC_SPI_START; i++) {
if (i != AVS_SVICINT && i != AVS_SVICINTSWDONE)
- set_irq_handler(i, handle_percpu_irq);
+ irq_set_handler(i, handle_percpu_irq);
}
}
diff --git a/arch/arm/mach-msm/board-trout-gpio.c b/arch/arm/mach-msm/board-trout-gpio.c
index 31117a4499c..87e1d01edec 100644
--- a/arch/arm/mach-msm/board-trout-gpio.c
+++ b/arch/arm/mach-msm/board-trout-gpio.c
@@ -214,17 +214,17 @@ int __init trout_init_gpio(void)
{
int i;
for(i = TROUT_INT_START; i <= TROUT_INT_END; i++) {
- set_irq_chip(i, &trout_gpio_irq_chip);
- set_irq_handler(i, handle_edge_irq);
+ irq_set_chip_and_handler(i, &trout_gpio_irq_chip,
+ handle_edge_irq);
set_irq_flags(i, IRQF_VALID);
}
for (i = 0; i < ARRAY_SIZE(msm_gpio_banks); i++)
gpiochip_add(&msm_gpio_banks[i].chip);
- set_irq_type(MSM_GPIO_TO_INT(17), IRQF_TRIGGER_HIGH);
- set_irq_chained_handler(MSM_GPIO_TO_INT(17), trout_gpio_irq_handler);
- set_irq_wake(MSM_GPIO_TO_INT(17), 1);
+ irq_set_irq_type(MSM_GPIO_TO_INT(17), IRQF_TRIGGER_HIGH);
+ irq_set_chained_handler(MSM_GPIO_TO_INT(17), trout_gpio_irq_handler);
+ irq_set_irq_wake(MSM_GPIO_TO_INT(17), 1);
return 0;
}
diff --git a/arch/arm/mach-msm/board-trout-mmc.c b/arch/arm/mach-msm/board-trout-mmc.c
index 44be8464657..f7a9724788b 100644
--- a/arch/arm/mach-msm/board-trout-mmc.c
+++ b/arch/arm/mach-msm/board-trout-mmc.c
@@ -174,7 +174,7 @@ int __init trout_init_mmc(unsigned int sys_rev)
if (IS_ERR(vreg_sdslot))
return PTR_ERR(vreg_sdslot);
- set_irq_wake(TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 1);
+ irq_set_irq_wake(TROUT_GPIO_TO_INT(TROUT_GPIO_SDMC_CD_N), 1);
if (!opt_disable_sdcard)
msm_add_sdcc(2, &trout_sdslot_data,
diff --git a/arch/arm/mach-msm/gpio-v2.c b/arch/arm/mach-msm/gpio-v2.c
index 0de19ec74e3..56a964e52ad 100644
--- a/arch/arm/mach-msm/gpio-v2.c
+++ b/arch/arm/mach-msm/gpio-v2.c
@@ -230,18 +230,18 @@ static void msm_gpio_update_dual_edge_pos(unsigned gpio)
val, val2);
}
-static void msm_gpio_irq_ack(unsigned int irq)
+static void msm_gpio_irq_ack(struct irq_data *d)
{
- int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
writel(BIT(INTR_STATUS), GPIO_INTR_STATUS(gpio));
if (test_bit(gpio, msm_gpio.dual_edge_irqs))
msm_gpio_update_dual_edge_pos(gpio);
}
-static void msm_gpio_irq_mask(unsigned int irq)
+static void msm_gpio_irq_mask(struct irq_data *d)
{
- int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
unsigned long irq_flags;
spin_lock_irqsave(&tlmm_lock, irq_flags);
@@ -251,9 +251,9 @@ static void msm_gpio_irq_mask(unsigned int irq)
spin_unlock_irqrestore(&tlmm_lock, irq_flags);
}
-static void msm_gpio_irq_unmask(unsigned int irq)
+static void msm_gpio_irq_unmask(struct irq_data *d)
{
- int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
unsigned long irq_flags;
spin_lock_irqsave(&tlmm_lock, irq_flags);
@@ -263,9 +263,9 @@ static void msm_gpio_irq_unmask(unsigned int irq)
spin_unlock_irqrestore(&tlmm_lock, irq_flags);
}
-static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
+static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
{
- int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
unsigned long irq_flags;
uint32_t bits;
@@ -275,14 +275,14 @@ static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
if (flow_type & IRQ_TYPE_EDGE_BOTH) {
bits |= BIT(INTR_DECT_CTL);
- irq_desc[irq].handle_irq = handle_edge_irq;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH)
__set_bit(gpio, msm_gpio.dual_edge_irqs);
else
__clear_bit(gpio, msm_gpio.dual_edge_irqs);
} else {
bits &= ~BIT(INTR_DECT_CTL);
- irq_desc[irq].handle_irq = handle_level_irq;
+ __irq_set_handler_locked(d->irq, handle_level_irq);
__clear_bit(gpio, msm_gpio.dual_edge_irqs);
}
@@ -309,6 +309,7 @@ static int msm_gpio_irq_set_type(unsigned int irq, unsigned int flow_type)
*/
static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
{
+ struct irq_data *data = irq_desc_get_irq_data(desc);
unsigned long i;
for (i = find_first_bit(msm_gpio.enabled_irqs, NR_GPIO_IRQS);
@@ -318,21 +319,21 @@ static void msm_summary_irq_handler(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(msm_gpio_to_irq(&msm_gpio.gpio_chip,
i));
}
- desc->chip->ack(irq);
+ data->chip->irq_ack(data);
}
-static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
+static int msm_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{
- int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, irq);
+ int gpio = msm_irq_to_gpio(&msm_gpio.gpio_chip, d->irq);
if (on) {
if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
- set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
+ irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 1);
set_bit(gpio, msm_gpio.wake_irqs);
} else {
clear_bit(gpio, msm_gpio.wake_irqs);
if (bitmap_empty(msm_gpio.wake_irqs, NR_GPIO_IRQS))
- set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
+ irq_set_irq_wake(TLMM_SCSS_SUMMARY_IRQ, 0);
}
return 0;
@@ -340,11 +341,11 @@ static int msm_gpio_irq_set_wake(unsigned int irq, unsigned int on)
static struct irq_chip msm_gpio_irq_chip = {
.name = "msmgpio",
- .mask = msm_gpio_irq_mask,
- .unmask = msm_gpio_irq_unmask,
- .ack = msm_gpio_irq_ack,
- .set_type = msm_gpio_irq_set_type,
- .set_wake = msm_gpio_irq_set_wake,
+ .irq_mask = msm_gpio_irq_mask,
+ .irq_unmask = msm_gpio_irq_unmask,
+ .irq_ack = msm_gpio_irq_ack,
+ .irq_set_type = msm_gpio_irq_set_type,
+ .irq_set_wake = msm_gpio_irq_set_wake,
};
static int __devinit msm_gpio_probe(struct platform_device *dev)
@@ -361,12 +362,12 @@ static int __devinit msm_gpio_probe(struct platform_device *dev)
for (i = 0; i < msm_gpio.gpio_chip.ngpio; ++i) {
irq = msm_gpio_to_irq(&msm_gpio.gpio_chip, i);
- set_irq_chip(irq, &msm_gpio_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &msm_gpio_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
- set_irq_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
+ irq_set_chained_handler(TLMM_SCSS_SUMMARY_IRQ,
msm_summary_irq_handler);
return 0;
}
@@ -378,7 +379,7 @@ static int __devexit msm_gpio_remove(struct platform_device *dev)
if (ret < 0)
return ret;
- set_irq_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
+ irq_set_handler(TLMM_SCSS_SUMMARY_IRQ, NULL);
return 0;
}
diff --git a/arch/arm/mach-msm/gpio.c b/arch/arm/mach-msm/gpio.c
index 176af9dcb8e..5ea273b00da 100644
--- a/arch/arm/mach-msm/gpio.c
+++ b/arch/arm/mach-msm/gpio.c
@@ -293,10 +293,10 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
val = readl(msm_chip->regs.int_edge);
if (flow_type & IRQ_TYPE_EDGE_BOTH) {
writel(val | mask, msm_chip->regs.int_edge);
- irq_desc[d->irq].handle_irq = handle_edge_irq;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
} else {
writel(val & ~mask, msm_chip->regs.int_edge);
- irq_desc[d->irq].handle_irq = handle_level_irq;
+ __irq_set_handler_locked(d->irq, handle_level_irq);
}
if ((flow_type & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
msm_chip->both_edge_detect |= mask;
@@ -354,9 +354,9 @@ static int __init msm_init_gpio(void)
msm_gpio_chips[j].chip.base +
msm_gpio_chips[j].chip.ngpio)
j++;
- set_irq_chip_data(i, &msm_gpio_chips[j]);
- set_irq_chip(i, &msm_gpio_irq_chip);
- set_irq_handler(i, handle_edge_irq);
+ irq_set_chip_data(i, &msm_gpio_chips[j]);
+ irq_set_chip_and_handler(i, &msm_gpio_irq_chip,
+ handle_edge_irq);
set_irq_flags(i, IRQF_VALID);
}
@@ -366,10 +366,10 @@ static int __init msm_init_gpio(void)
gpiochip_add(&msm_gpio_chips[i].chip);
}
- set_irq_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler);
- set_irq_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler);
- set_irq_wake(INT_GPIO_GROUP1, 1);
- set_irq_wake(INT_GPIO_GROUP2, 2);
+ irq_set_chained_handler(INT_GPIO_GROUP1, msm_gpio_irq_handler);
+ irq_set_chained_handler(INT_GPIO_GROUP2, msm_gpio_irq_handler);
+ irq_set_irq_wake(INT_GPIO_GROUP1, 1);
+ irq_set_irq_wake(INT_GPIO_GROUP2, 2);
return 0;
}
diff --git a/arch/arm/mach-msm/irq-vic.c b/arch/arm/mach-msm/irq-vic.c
index 68c28bbdc96..1b54f807c2d 100644
--- a/arch/arm/mach-msm/irq-vic.c
+++ b/arch/arm/mach-msm/irq-vic.c
@@ -313,11 +313,11 @@ static int msm_irq_set_type(struct irq_data *d, unsigned int flow_type)
type = msm_irq_shadow_reg[index].int_type;
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
type |= b;
- irq_desc[d->irq].handle_irq = handle_edge_irq;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
}
if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
type &= ~b;
- irq_desc[d->irq].handle_irq = handle_level_irq;
+ __irq_set_handler_locked(d->irq, handle_level_irq);
}
writel(type, treg);
msm_irq_shadow_reg[index].int_type = type;
@@ -357,8 +357,7 @@ void __init msm_init_irq(void)
writel(3, VIC_INT_MASTEREN);
for (n = 0; n < NR_MSM_IRQS; n++) {
- set_irq_chip(n, &msm_irq_chip);
- set_irq_handler(n, handle_level_irq);
+ irq_set_chip_and_handler(n, &msm_irq_chip, handle_level_irq);
set_irq_flags(n, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-msm/irq.c b/arch/arm/mach-msm/irq.c
index 0b27d899f40..ea514be390c 100644
--- a/arch/arm/mach-msm/irq.c
+++ b/arch/arm/mach-msm/irq.c
@@ -100,11 +100,11 @@ static int msm_irq_set_type(struct irq_data *d, unsigned int flow_type)
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
writel(readl(treg) | b, treg);
- irq_desc[d->irq].handle_irq = handle_edge_irq;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
}
if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) {
writel(readl(treg) & (~b), treg);
- irq_desc[d->irq].handle_irq = handle_level_irq;
+ __irq_set_handler_locked(d->irq, handle_level_irq);
}
return 0;
}
@@ -145,8 +145,7 @@ void __init msm_init_irq(void)
writel(1, VIC_INT_MASTEREN);
for (n = 0; n < NR_MSM_IRQS; n++) {
- set_irq_chip(n, &msm_irq_chip);
- set_irq_handler(n, handle_level_irq);
+ irq_set_chip_and_handler(n, &msm_irq_chip, handle_level_irq);
set_irq_flags(n, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-msm/sirc.c b/arch/arm/mach-msm/sirc.c
index 11b54c7aeb0..689e78c95f3 100644
--- a/arch/arm/mach-msm/sirc.c
+++ b/arch/arm/mach-msm/sirc.c
@@ -105,10 +105,10 @@ static int sirc_irq_set_type(struct irq_data *d, unsigned int flow_type)
val = readl(sirc_regs.int_type);
if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
val |= mask;
- irq_desc[d->irq].handle_irq = handle_edge_irq;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
} else {
val &= ~mask;
- irq_desc[d->irq].handle_irq = handle_level_irq;
+ __irq_set_handler_locked(d->irq, handle_level_irq);
}
writel(val, sirc_regs.int_type);
@@ -158,15 +158,14 @@ void __init msm_init_sirc(void)
wake_enable = 0;
for (i = FIRST_SIRC_IRQ; i < LAST_SIRC_IRQ; i++) {
- set_irq_chip(i, &sirc_irq_chip);
- set_irq_handler(i, handle_edge_irq);
+ irq_set_chip_and_handler(i, &sirc_irq_chip, handle_edge_irq);
set_irq_flags(i, IRQF_VALID);
}
for (i = 0; i < ARRAY_SIZE(sirc_reg_table); i++) {
- set_irq_chained_handler(sirc_reg_table[i].cascade_irq,
+ irq_set_chained_handler(sirc_reg_table[i].cascade_irq,
sirc_irq_handler);
- set_irq_wake(sirc_reg_table[i].cascade_irq, 1);
+ irq_set_irq_wake(sirc_reg_table[i].cascade_irq, 1);
}
return;
}
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c
index 08da497c39c..3e24431bb5e 100644
--- a/arch/arm/mach-mv78xx0/irq.c
+++ b/arch/arm/mach-mv78xx0/irq.c
@@ -38,8 +38,8 @@ void __init mv78xx0_init_irq(void)
orion_gpio_init(0, 32, GPIO_VIRT_BASE,
mv78xx0_core_index() ? 0x18 : 0,
IRQ_MV78XX0_GPIO_START);
- set_irq_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler);
- set_irq_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler);
- set_irq_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler);
- set_irq_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler);
}
diff --git a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
index 80761474c0f..2e288b38b4a 100644
--- a/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx3/eukrea_mbimxsd-baseboard.c
@@ -43,6 +43,7 @@
#include <mach/ipu.h>
#include <mach/mx3fb.h>
#include <mach/audmux.h>
+#include <mach/esdhc.h>
#include "devices-imx35.h"
#include "devices.h"
@@ -163,11 +164,14 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+ /* SD1 CD */
+ MX35_PAD_LD18__GPIO3_24,
};
#define GPIO_LED1 IMX_GPIO_NR(3, 29)
#define GPIO_SWITCH1 IMX_GPIO_NR(3, 25)
-#define GPIO_LCDPWR (4)
+#define GPIO_LCDPWR IMX_GPIO_NR(1, 4)
+#define GPIO_SD1CD IMX_GPIO_NR(3, 24)
static void eukrea_mbimxsd_lcd_power_set(struct plat_lcd_data *pd,
unsigned int power)
@@ -254,6 +258,11 @@ struct imx_ssi_platform_data eukrea_mbimxsd_ssi_pdata __initconst = {
.flags = IMX_SSI_SYN | IMX_SSI_NET | IMX_SSI_USE_I2S_SLAVE,
};
+static struct esdhc_platform_data sd1_pdata = {
+ .cd_gpio = GPIO_SD1CD,
+ .wp_gpio = -EINVAL,
+};
+
/*
* system init for baseboard usage. Will be called by cpuimx35 init.
*
@@ -289,7 +298,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
imx35_add_flexcan1(NULL);
- imx35_add_sdhci_esdhc_imx(0, NULL);
+ imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
gpio_request(GPIO_LED1, "LED1");
gpio_direction_output(GPIO_LED1, 1);
@@ -301,7 +310,6 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
gpio_request(GPIO_LCDPWR, "LCDPWR");
gpio_direction_output(GPIO_LCDPWR, 1);
- gpio_free(GPIO_LCDPWR);
i2c_register_board_info(0, eukrea_mbimxsd_i2c_devices,
ARRAY_SIZE(eukrea_mbimxsd_i2c_devices));
diff --git a/arch/arm/mach-mx3/mach-mx31ads.c b/arch/arm/mach-mx3/mach-mx31ads.c
index 4e4b780c481..3d095d69bc6 100644
--- a/arch/arm/mach-mx3/mach-mx31ads.c
+++ b/arch/arm/mach-mx3/mach-mx31ads.c
@@ -199,12 +199,11 @@ static void __init mx31ads_init_expio(void)
__raw_writew(0xFFFF, PBC_INTSTATUS_REG);
for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
i++) {
- set_irq_chip(i, &expio_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
- set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
- set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
+ irq_set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
}
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c
index b3ecfb22d24..036ba1a4704 100644
--- a/arch/arm/mach-mx3/mach-pcm043.c
+++ b/arch/arm/mach-mx3/mach-pcm043.c
@@ -40,6 +40,7 @@
#include <mach/mx3fb.h>
#include <mach/ulpi.h>
#include <mach/audmux.h>
+#include <mach/esdhc.h>
#include "devices-imx35.h"
#include "devices.h"
@@ -217,11 +218,15 @@ static iomux_v3_cfg_t pcm043_pads[] = {
MX35_PAD_SD1_DATA1__ESDHC1_DAT1,
MX35_PAD_SD1_DATA2__ESDHC1_DAT2,
MX35_PAD_SD1_DATA3__ESDHC1_DAT3,
+ MX35_PAD_ATA_DATA10__GPIO2_23, /* WriteProtect */
+ MX35_PAD_ATA_DATA11__GPIO2_24, /* CardDetect */
};
#define AC97_GPIO_TXFS IMX_GPIO_NR(2, 31)
#define AC97_GPIO_TXD IMX_GPIO_NR(2, 28)
#define AC97_GPIO_RESET IMX_GPIO_NR(2, 0)
+#define SD1_GPIO_WP IMX_GPIO_NR(2, 23)
+#define SD1_GPIO_CD IMX_GPIO_NR(2, 24)
static void pcm043_ac97_warm_reset(struct snd_ac97 *ac97)
{
@@ -346,6 +351,11 @@ static int __init pcm043_otg_mode(char *options)
}
__setup("otg_mode=", pcm043_otg_mode);
+static struct esdhc_platform_data sd1_pdata = {
+ .wp_gpio = SD1_GPIO_WP,
+ .cd_gpio = SD1_GPIO_CD,
+};
+
/*
* Board specific initialization.
*/
@@ -395,7 +405,7 @@ static void __init pcm043_init(void)
imx35_add_fsl_usb2_udc(&otg_device_pdata);
imx35_add_flexcan1(NULL);
- imx35_add_sdhci_esdhc_imx(0, NULL);
+ imx35_add_sdhci_esdhc_imx(0, &sd1_pdata);
}
static void __init pcm043_timer_init(void)
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index 83ee08847d4..159340da919 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -165,6 +165,7 @@ config MACH_MX53_LOCO
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_UART
select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_GPIO_KEYS
help
Include support for MX53 LOCO platform. This includes specific
configurations for the board and its peripherals.
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index 4f63048be3c..0b9338cec51 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -3,7 +3,7 @@
#
# Object file lists.
-obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o
+obj-y := cpu.o mm.o clock-mx51-mx53.o devices.o ehci.o system.o
obj-$(CONFIG_SOC_IMX50) += mm-mx50.o
obj-$(CONFIG_CPU_FREQ_IMX) += cpu_op-mx51.o
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index b2ecd194e76..bea4e4135f9 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -228,13 +228,12 @@ static inline void babbage_fec_reset(void)
int ret;
/* reset FEC PHY */
- ret = gpio_request(BABBAGE_FEC_PHY_RESET, "fec-phy-reset");
+ ret = gpio_request_one(BABBAGE_FEC_PHY_RESET,
+ GPIOF_OUT_INIT_LOW, "fec-phy-reset");
if (ret) {
printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
return;
}
- gpio_direction_output(BABBAGE_FEC_PHY_RESET, 0);
- gpio_set_value(BABBAGE_FEC_PHY_RESET, 0);
msleep(1);
gpio_set_value(BABBAGE_FEC_PHY_RESET, 1);
}
diff --git a/arch/arm/mach-mx5/board-mx53_evk.c b/arch/arm/mach-mx5/board-mx53_evk.c
index 7b5735c5ea5..2af3f43f74d 100644
--- a/arch/arm/mach-mx5/board-mx53_evk.c
+++ b/arch/arm/mach-mx5/board-mx53_evk.c
@@ -34,7 +34,7 @@
#include <mach/imx-uart.h>
#include <mach/iomux-mx53.h>
-#define SMD_FEC_PHY_RST IMX_GPIO_NR(7, 6)
+#define MX53_EVK_FEC_PHY_RST IMX_GPIO_NR(7, 6)
#define EVK_ECSPI1_CS0 IMX_GPIO_NR(2, 30)
#define EVK_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
@@ -82,15 +82,14 @@ static inline void mx53_evk_fec_reset(void)
int ret;
/* reset FEC PHY */
- ret = gpio_request(SMD_FEC_PHY_RST, "fec-phy-reset");
+ ret = gpio_request_one(MX53_EVK_FEC_PHY_RST, GPIOF_OUT_INIT_LOW,
+ "fec-phy-reset");
if (ret) {
printk(KERN_ERR"failed to get GPIO_FEC_PHY_RESET: %d\n", ret);
return;
}
- gpio_direction_output(SMD_FEC_PHY_RST, 0);
- gpio_set_value(SMD_FEC_PHY_RST, 0);
msleep(1);
- gpio_set_value(SMD_FEC_PHY_RST, 1);
+ gpio_set_value(MX53_EVK_FEC_PHY_RST, 1);
}
static struct fec_platform_data mx53_evk_fec_pdata = {
diff --git a/arch/arm/mach-mx5/board-mx53_loco.c b/arch/arm/mach-mx5/board-mx53_loco.c
index 0a18f8d23eb..10a1bea1054 100644
--- a/arch/arm/mach-mx5/board-mx53_loco.c
+++ b/arch/arm/mach-mx5/board-mx53_loco.c
@@ -36,6 +36,9 @@
#include "crm_regs.h"
#include "devices-imx53.h"
+#define MX53_LOCO_POWER IMX_GPIO_NR(1, 8)
+#define MX53_LOCO_UI1 IMX_GPIO_NR(2, 14)
+#define MX53_LOCO_UI2 IMX_GPIO_NR(2, 15)
#define LOCO_FEC_PHY_RST IMX_GPIO_NR(7, 6)
static iomux_v3_cfg_t mx53_loco_pads[] = {
@@ -180,6 +183,27 @@ static iomux_v3_cfg_t mx53_loco_pads[] = {
MX53_PAD_GPIO_8__GPIO1_8,
};
+#define GPIO_BUTTON(gpio_num, ev_code, act_low, descr, wake) \
+{ \
+ .gpio = gpio_num, \
+ .type = EV_KEY, \
+ .code = ev_code, \
+ .active_low = act_low, \
+ .desc = "btn " descr, \
+ .wakeup = wake, \
+}
+
+static const struct gpio_keys_button loco_buttons[] __initconst = {
+ GPIO_BUTTON(MX53_LOCO_POWER, KEY_POWER, 1, "power", 0),
+ GPIO_BUTTON(MX53_LOCO_UI1, KEY_VOLUMEUP, 1, "volume-up", 0),
+ GPIO_BUTTON(MX53_LOCO_UI2, KEY_VOLUMEDOWN, 1, "volume-down", 0),
+};
+
+static const struct gpio_keys_platform_data loco_button_data __initconst = {
+ .buttons = loco_buttons,
+ .nbuttons = ARRAY_SIZE(loco_buttons),
+};
+
static inline void mx53_loco_fec_reset(void)
{
int ret;
@@ -215,6 +239,7 @@ static void __init mx53_loco_board_init(void)
imx53_add_imx_i2c(1, &mx53_loco_i2c_data);
imx53_add_sdhci_esdhc_imx(0, NULL);
imx53_add_sdhci_esdhc_imx(2, NULL);
+ imx_add_gpio_keys(&loco_button_data);
}
static void __init mx53_loco_timer_init(void)
diff --git a/arch/arm/mach-mx5/clock-mx51-mx53.c b/arch/arm/mach-mx5/clock-mx51-mx53.c
index 652ace41382..fdbc05ed551 100644
--- a/arch/arm/mach-mx5/clock-mx51-mx53.c
+++ b/arch/arm/mach-mx5/clock-mx51-mx53.c
@@ -865,6 +865,13 @@ static struct clk aips_tz2_clk = {
.disable = _clk_ccgr_disable_inwait,
};
+static struct clk gpc_dvfs_clk = {
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+ .enable = _clk_ccgr_enable,
+ .disable = _clk_ccgr_disable,
+};
+
static struct clk gpt_32k_clk = {
.id = 0,
.parent = &ckil_clk,
@@ -1448,6 +1455,7 @@ static struct clk_lookup mx51_lookups[] = {
_REGISTER_CLOCK("imx-ipuv3", NULL, ipu_clk)
_REGISTER_CLOCK("imx-ipuv3", "di0", ipu_di0_clk)
_REGISTER_CLOCK("imx-ipuv3", "di1", ipu_di1_clk)
+ _REGISTER_CLOCK(NULL, "gpc_dvfs", gpc_dvfs_clk)
};
static struct clk_lookup mx53_lookups[] = {
@@ -1511,6 +1519,7 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
clk_enable(&iim_clk);
mx51_revision();
clk_disable(&iim_clk);
+ mx51_display_revision();
/* move usb_phy_clk to 24MHz */
clk_set_parent(&usb_phy1_clk, &osc_clk);
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
index df46b5e6085..472bdfab2e5 100644
--- a/arch/arm/mach-mx5/cpu.c
+++ b/arch/arm/mach-mx5/cpu.c
@@ -21,6 +21,7 @@
static int cpu_silicon_rev = -1;
#define IIM_SREV 0x24
+#define MX50_HW_ADADIG_DIGPROG 0xB0
static int get_mx51_srev(void)
{
@@ -51,6 +52,26 @@ int mx51_revision(void)
}
EXPORT_SYMBOL(mx51_revision);
+void mx51_display_revision(void)
+{
+ int rev;
+ char *srev;
+ rev = mx51_revision();
+
+ switch (rev) {
+ case IMX_CHIP_REVISION_2_0:
+ srev = IMX_CHIP_REVISION_2_0_STRING;
+ break;
+ case IMX_CHIP_REVISION_3_0:
+ srev = IMX_CHIP_REVISION_3_0_STRING;
+ break;
+ default:
+ srev = IMX_CHIP_REVISION_UNKNOWN_STRING;
+ }
+ printk(KERN_INFO "CPU identified as i.MX51, silicon rev %s\n", srev);
+}
+EXPORT_SYMBOL(mx51_display_revision);
+
#ifdef CONFIG_NEON
/*
@@ -107,6 +128,44 @@ int mx53_revision(void)
}
EXPORT_SYMBOL(mx53_revision);
+static int get_mx50_srev(void)
+{
+ void __iomem *anatop = ioremap(MX50_ANATOP_BASE_ADDR, SZ_8K);
+ u32 rev;
+
+ if (!anatop) {
+ cpu_silicon_rev = -EINVAL;
+ return 0;
+ }
+
+ rev = readl(anatop + MX50_HW_ADADIG_DIGPROG);
+ rev &= 0xff;
+
+ iounmap(anatop);
+ if (rev == 0x0)
+ return IMX_CHIP_REVISION_1_0;
+ else if (rev == 0x1)
+ return IMX_CHIP_REVISION_1_1;
+ return 0;
+}
+
+/*
+ * Returns:
+ * the silicon revision of the cpu
+ * -EINVAL - not a mx50
+ */
+int mx50_revision(void)
+{
+ if (!cpu_is_mx50())
+ return -EINVAL;
+
+ if (cpu_silicon_rev == -1)
+ cpu_silicon_rev = get_mx50_srev();
+
+ return cpu_silicon_rev;
+}
+EXPORT_SYMBOL(mx50_revision);
+
static int __init post_cpu_init(void)
{
unsigned int reg;
diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
index e83ffadb65f..4a8550529b0 100644
--- a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
@@ -212,7 +212,7 @@ void __init eukrea_mbimx51_baseboard_init(void)
gpio_request(MBIMX51_TSC2007_GPIO, "tsc2007_irq");
gpio_direction_input(MBIMX51_TSC2007_GPIO);
- set_irq_type(MBIMX51_TSC2007_IRQ, IRQF_TRIGGER_FALLING);
+ irq_set_irq_type(MBIMX51_TSC2007_IRQ, IRQF_TRIGGER_FALLING);
i2c_register_board_info(1, mbimx51_i2c_devices,
ARRAY_SIZE(mbimx51_i2c_devices));
diff --git a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
index c372a437369..e6c1119c20a 100644
--- a/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimxsd-baseboard.c
@@ -67,6 +67,10 @@ static iomux_v3_cfg_t eukrea_mbimxsd_pads[] = {
MX51_PAD_SD1_DATA1__SD1_DATA1,
MX51_PAD_SD1_DATA2__SD1_DATA2,
MX51_PAD_SD1_DATA3__SD1_DATA3,
+ /* SD1 CD */
+ _MX51_PAD_GPIO1_0__SD1_CD | MUX_PAD_CTRL(PAD_CTL_PUS_22K_UP |
+ PAD_CTL_PKE | PAD_CTL_SRE_FAST |
+ PAD_CTL_DSE_HIGH | PAD_CTL_PUE | PAD_CTL_HYS),
};
#define GPIO_LED1 IMX_GPIO_NR(3, 30)
diff --git a/arch/arm/mach-mx5/mx51_efika.c b/arch/arm/mach-mx5/mx51_efika.c
index 51a67fc7f0e..d0c7075937c 100644
--- a/arch/arm/mach-mx5/mx51_efika.c
+++ b/arch/arm/mach-mx5/mx51_efika.c
@@ -42,7 +42,6 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
-#include <asm/mach-types.h>
#include "devices-imx51.h"
#include "devices.h"
@@ -572,8 +571,10 @@ static struct mc13xxx_regulator_init_data mx51_efika_regulators[] = {
static struct mc13xxx_platform_data mx51_efika_mc13892_data = {
.flags = MC13XXX_USE_RTC | MC13XXX_USE_REGULATOR,
- .num_regulators = ARRAY_SIZE(mx51_efika_regulators),
- .regulators = mx51_efika_regulators,
+ .regulators = {
+ .num_regulators = ARRAY_SIZE(mx51_efika_regulators),
+ .regulators = mx51_efika_regulators,
+ },
};
static struct spi_board_info mx51_efika_spi_board_info[] __initdata = {
diff --git a/arch/arm/mach-mx5/system.c b/arch/arm/mach-mx5/system.c
new file mode 100644
index 00000000000..76ae8dc33e0
--- /dev/null
+++ b/arch/arm/mach-mx5/system.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "crm_regs.h"
+
+/* set cpu low power mode before WFI instruction. This function is called
+ * mx5 because it can be used for mx50, mx51, and mx53.*/
+void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+ u32 plat_lpc, arm_srpgcr, ccm_clpcr;
+ u32 empgc0, empgc1;
+ int stop_mode = 0;
+
+ /* always allow platform to issue a deep sleep mode request */
+ plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
+ ~(MXC_CORTEXA8_PLAT_LPC_DSM);
+ ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+ arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
+ empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
+ empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);
+
+ switch (mode) {
+ case WAIT_CLOCKED:
+ break;
+ case WAIT_UNCLOCKED:
+ ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+ break;
+ case WAIT_UNCLOCKED_POWER_OFF:
+ case STOP_POWER_OFF:
+ plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
+ | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
+ if (mode == WAIT_UNCLOCKED_POWER_OFF) {
+ ccm_clpcr |= 0x1 << MXC_CCM_CLPCR_LPM_OFFSET;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr &= ~MXC_CCM_CLPCR_SBYOS;
+ stop_mode = 0;
+ } else {
+ ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+ ccm_clpcr |= 0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET;
+ ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+ stop_mode = 1;
+ }
+ arm_srpgcr |= MXC_SRPGCR_PCR;
+
+ if (tzic_enable_wake(1) != 0)
+ return;
+ break;
+ case STOP_POWER_ON:
+ ccm_clpcr |= 0x2 << MXC_CCM_CLPCR_LPM_OFFSET;
+ break;
+ default:
+ printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+ return;
+ }
+
+ __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
+ __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+ __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
+
+ /* Enable NEON SRPG for all but MX50TO1.0. */
+ if (mx50_revision() != IMX_CHIP_REVISION_1_0)
+ __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
+
+ if (stop_mode) {
+ empgc0 |= MXC_SRPGCR_PCR;
+ empgc1 |= MXC_SRPGCR_PCR;
+
+ __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
+ }
+}
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
index 4f6f174af6c..4522fbb235d 100644
--- a/arch/arm/mach-mxs/Kconfig
+++ b/arch/arm/mach-mxs/Kconfig
@@ -22,6 +22,7 @@ config MACH_MX23EVK
select SOC_IMX23
select MXS_HAVE_AMBA_DUART
select MXS_HAVE_PLATFORM_AUART
+ select MXS_HAVE_PLATFORM_MXS_MMC
select MXS_HAVE_PLATFORM_MXSFB
default y
help
@@ -35,6 +36,7 @@ config MACH_MX28EVK
select MXS_HAVE_PLATFORM_AUART
select MXS_HAVE_PLATFORM_FEC
select MXS_HAVE_PLATFORM_FLEXCAN
+ select MXS_HAVE_PLATFORM_MXS_MMC
select MXS_HAVE_PLATFORM_MXSFB
select MXS_OCOTP
default y
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index d133c7f3094..c3577ea789a 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -521,6 +521,15 @@ static int clk_misc_init(void)
__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+ /*
+ * 480 MHz seems too high to be ssp clock source directly,
+ * so set frac to get a 288 MHz ref_io.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ reg &= ~BM_CLKCTRL_FRAC_IOFRAC;
+ reg |= 30 << BP_CLKCTRL_FRAC_IOFRAC;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+
return 0;
}
@@ -528,6 +537,12 @@ int __init mx23_clocks_init(void)
{
clk_misc_init();
+ /*
+ * source ssp clock from ref_io than ref_xtal,
+ * as ref_xtal only provides 24 MHz as maximum.
+ */
+ clk_set_parent(&ssp_clk, &ref_io_clk);
+
clk_enable(&cpu_clk);
clk_enable(&hbus_clk);
clk_enable(&xbus_clk);
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 5e489a2b202..1ad97fed1e9 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -618,6 +618,8 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("pll2", NULL, pll2_clk)
_REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
_REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+ _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
+ _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -737,6 +739,15 @@ static int clk_misc_init(void)
reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+ /*
+ * 480 MHz seems too high to be ssp clock source directly,
+ * so set frac0 to get a 288 MHz ref_io0.
+ */
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+ reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
+ reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+
return 0;
}
@@ -744,6 +755,13 @@ int __init mx28_clocks_init(void)
{
clk_misc_init();
+ /*
+ * source ssp clock from ref_io0 than ref_xtal,
+ * as ref_xtal only provides 24 MHz as maximum.
+ */
+ clk_set_parent(&ssp0_clk, &ref_io0_clk);
+ clk_set_parent(&ssp1_clk, &ref_io0_clk);
+
clk_enable(&cpu_clk);
clk_enable(&hbus_clk);
clk_enable(&xbus_clk);
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
index c7e14f4e366..c6f345febd3 100644
--- a/arch/arm/mach-mxs/devices-mx23.h
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -21,6 +21,10 @@ extern const struct mxs_auart_data mx23_auart_data[] __initconst;
#define mx23_add_auart0() mx23_add_auart(0)
#define mx23_add_auart1() mx23_add_auart(1)
+extern const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst;
+#define mx23_add_mxs_mmc(id, pdata) \
+ mxs_add_mxs_mmc(&mx23_mxs_mmc_data[id], pdata)
+
#define mx23_add_mxs_pwm(id) mxs_add_mxs_pwm(MX23_PWM_BASE_ADDR, id)
struct platform_device *__init mx23_add_mxsfb(
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 9d08555c4cf..c473eddce8c 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -37,6 +37,10 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;
extern const struct mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
#define mx28_add_mxs_i2c(id) mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id])
+extern const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst;
+#define mx28_add_mxs_mmc(id, pdata) \
+ mxs_add_mxs_mmc(&mx28_mxs_mmc_data[id], pdata)
+
#define mx28_add_mxs_pwm(id) mxs_add_mxs_pwm(MX28_PWM_BASE_ADDR, id)
struct platform_device *__init mx28_add_mxsfb(
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
index 1451ad060d8..acf9eea124c 100644
--- a/arch/arm/mach-mxs/devices/Kconfig
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -15,6 +15,9 @@ config MXS_HAVE_PLATFORM_FLEXCAN
config MXS_HAVE_PLATFORM_MXS_I2C
bool
+config MXS_HAVE_PLATFORM_MXS_MMC
+ bool
+
config MXS_HAVE_PLATFORM_MXS_PWM
bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
index 0d9bea30b0a..324f2824d38 100644
--- a/arch/arm/mach-mxs/devices/Makefile
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -4,5 +4,6 @@ obj-y += platform-dma.o
obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
obj-$(CONFIG_MXS_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_I2C) += platform-mxs-i2c.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_MMC) += platform-mxs-mmc.o
obj-$(CONFIG_MXS_HAVE_PLATFORM_MXS_PWM) += platform-mxs-pwm.o
obj-$(CONFIG_MXS_HAVE_PLATFORM_MXSFB) += platform-mxsfb.o
diff --git a/arch/arm/mach-mxs/devices/platform-mxs-mmc.c b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
new file mode 100644
index 00000000000..382dacbeca2
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-mxs-mmc.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2011 Freescale Semiconductor, Inc. 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/compiler.h>
+#include <linux/err.h>
+#include <linux/init.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_mxs_mmc_data_entry_single(soc, _id, hwid) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _SSP ## hwid ## _BASE_ADDR, \
+ .dma = soc ## _DMA_SSP ## hwid, \
+ .irq_err = soc ## _INT_SSP ## hwid ## _ERROR, \
+ .irq_dma = soc ## _INT_SSP ## hwid ## _DMA, \
+ }
+
+#define mxs_mxs_mmc_data_entry(soc, _id, hwid) \
+ [_id] = mxs_mxs_mmc_data_entry_single(soc, _id, hwid)
+
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_mxs_mmc_data mx23_mxs_mmc_data[] __initconst = {
+ mxs_mxs_mmc_data_entry(MX23, 0, 1),
+ mxs_mxs_mmc_data_entry(MX23, 1, 2),
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_mxs_mmc_data mx28_mxs_mmc_data[] __initconst = {
+ mxs_mxs_mmc_data_entry(MX28, 0, 0),
+ mxs_mxs_mmc_data_entry(MX28, 1, 1),
+};
+#endif
+
+struct platform_device *__init mxs_add_mxs_mmc(
+ const struct mxs_mxs_mmc_data *data,
+ const struct mxs_mmc_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->dma,
+ .end = data->dma,
+ .flags = IORESOURCE_DMA,
+ }, {
+ .start = data->irq_err,
+ .end = data->irq_err,
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = data->irq_dma,
+ .end = data->irq_dma,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("mxs-mmc", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
index 56fa2ed1522..2c950fef71a 100644
--- a/arch/arm/mach-mxs/gpio.c
+++ b/arch/arm/mach-mxs/gpio.c
@@ -136,7 +136,7 @@ static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{
u32 irq_stat;
- struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
+ struct mxs_gpio_port *port = (struct mxs_gpio_port *)irq_get_handler_data(irq);
u32 gpio_irq_no_base = port->virtual_irq_start;
desc->irq_data.chip->irq_ack(&desc->irq_data);
@@ -265,14 +265,14 @@ int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
for (j = port[i].virtual_irq_start;
j < port[i].virtual_irq_start + 32; j++) {
- set_irq_chip(j, &gpio_irq_chip);
- set_irq_handler(j, handle_level_irq);
+ irq_set_chip_and_handler(j, &gpio_irq_chip,
+ handle_level_irq);
set_irq_flags(j, IRQF_VALID);
}
/* setup one handler for each entry */
- set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
- set_irq_data(port[i].irq, &port[i]);
+ irq_set_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+ irq_set_handler_data(port[i].irq, &port[i]);
/* register gpio chip */
port[i].chip.direction_input = mxs_gpio_direction_input;
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
index 0f4c120fc16..23ca9d083b2 100644
--- a/arch/arm/mach-mxs/icoll.c
+++ b/arch/arm/mach-mxs/icoll.c
@@ -74,8 +74,7 @@ void __init icoll_init_irq(void)
mxs_reset_block(icoll_base + HW_ICOLL_CTRL);
for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
- set_irq_chip(i, &mxs_icoll_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &mxs_icoll_chip, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 71f24484b04..c5137f14c36 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -73,6 +73,19 @@ struct mxs_i2c_data {
};
struct platform_device * __init mxs_add_mxs_i2c(const struct mxs_i2c_data *data);
+/* mmc */
+#include <mach/mmc.h>
+struct mxs_mxs_mmc_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t dma;
+ resource_size_t irq_err;
+ resource_size_t irq_dma;
+};
+struct platform_device *__init mxs_add_mxs_mmc(
+ const struct mxs_mxs_mmc_data *data,
+ const struct mxs_mmc_platform_data *pdata);
+
/* pwm */
struct platform_device *__init mxs_add_mxs_pwm(
resource_size_t iobase, int id);
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
index a66994f0518..214e5b641bb 100644
--- a/arch/arm/mach-mxs/mach-mx23evk.c
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -28,6 +28,8 @@
#define MX23EVK_LCD_ENABLE MXS_GPIO_NR(1, 18)
#define MX23EVK_BL_ENABLE MXS_GPIO_NR(1, 28)
+#define MX23EVK_MMC0_WRITE_PROTECT MXS_GPIO_NR(1, 30)
+#define MX23EVK_MMC0_SLOT_POWER MXS_GPIO_NR(1, 29)
static const iomux_cfg_t mx23evk_pads[] __initconst = {
/* duart */
@@ -73,6 +75,36 @@ static const iomux_cfg_t mx23evk_pads[] __initconst = {
MX23_PAD_LCD_RESET__GPIO_1_18 | MXS_PAD_CTRL,
/* backlight control */
MX23_PAD_PWM2__GPIO_1_28 | MXS_PAD_CTRL,
+
+ /* mmc */
+ MX23_PAD_SSP1_DATA0__SSP1_DATA0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA1__SSP1_DATA1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA2__SSP1_DATA2 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DATA3__SSP1_DATA3 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_GPMI_D08__SSP1_DATA4 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_GPMI_D09__SSP1_DATA5 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_GPMI_D10__SSP1_DATA6 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_GPMI_D11__SSP1_DATA7 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_CMD__SSP1_CMD |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX23_PAD_SSP1_DETECT__SSP1_DETECT |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX23_PAD_SSP1_SCK__SSP1_SCK |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* write protect */
+ MX23_PAD_PWM4__GPIO_1_30 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* slot power enable */
+ MX23_PAD_PWM3__GPIO_1_29 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
};
/* mxsfb (lcdif) */
@@ -101,6 +133,11 @@ static const struct mxsfb_platform_data mx23evk_mxsfb_pdata __initconst = {
.ld_intf_width = STMLCDIF_24BIT,
};
+static struct mxs_mmc_platform_data mx23evk_mmc_pdata __initdata = {
+ .wp_gpio = MX23EVK_MMC0_WRITE_PROTECT,
+ .flags = SLOTF_8_BIT_CAPABLE,
+};
+
static void __init mx23evk_init(void)
{
int ret;
@@ -110,6 +147,13 @@ static void __init mx23evk_init(void)
mx23_add_duart();
mx23_add_auart0();
+ /* power on mmc slot by writing 0 to the gpio */
+ ret = gpio_request_one(MX23EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT,
+ "mmc0-slot-power");
+ if (ret)
+ pr_warn("failed to request gpio mmc0-slot-power: %d\n", ret);
+ mx23_add_mxs_mmc(0, &mx23evk_mmc_pdata);
+
ret = gpio_request_one(MX23EVK_LCD_ENABLE, GPIOF_DIR_OUT, "lcd-enable");
if (ret)
pr_warn("failed to request gpio lcd-enable: %d\n", ret);
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index 08002d02267..bb329b9a260 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -34,6 +34,11 @@
#define MX28EVK_LCD_ENABLE MXS_GPIO_NR(3, 30)
#define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
+#define MX28EVK_MMC0_WRITE_PROTECT MXS_GPIO_NR(2, 12)
+#define MX28EVK_MMC1_WRITE_PROTECT MXS_GPIO_NR(0, 28)
+#define MX28EVK_MMC0_SLOT_POWER MXS_GPIO_NR(3, 28)
+#define MX28EVK_MMC1_SLOT_POWER MXS_GPIO_NR(3, 29)
+
static const iomux_cfg_t mx28evk_pads[] __initconst = {
/* duart */
MX28_PAD_PWM0__DUART_RX | MXS_PAD_CTRL,
@@ -115,6 +120,65 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
MX28_PAD_LCD_RESET__GPIO_3_30 | MXS_PAD_CTRL,
/* backlight control */
MX28_PAD_PWM2__GPIO_3_18 | MXS_PAD_CTRL,
+ /* mmc0 */
+ MX28_PAD_SSP0_DATA0__SSP0_D0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA1__SSP0_D1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA2__SSP0_D2 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA3__SSP0_D3 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA4__SSP0_D4 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA5__SSP0_D5 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA6__SSP0_D6 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DATA7__SSP0_D7 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_CMD__SSP0_CMD |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX28_PAD_SSP0_SCK__SSP0_SCK |
+ (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* write protect */
+ MX28_PAD_SSP1_SCK__GPIO_2_12 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* slot power enable */
+ MX28_PAD_PWM3__GPIO_3_28 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+
+ /* mmc1 */
+ MX28_PAD_GPMI_D00__SSP1_D0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D01__SSP1_D1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D02__SSP1_D2 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D03__SSP1_D3 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D04__SSP1_D4 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D05__SSP1_D5 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D06__SSP1_D6 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_D07__SSP1_D7 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_RDY1__SSP1_CMD |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_GPMI_RDY0__SSP1_CARD_DETECT |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ MX28_PAD_GPMI_WRN__SSP1_SCK |
+ (MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* write protect */
+ MX28_PAD_GPMI_RESETN__GPIO_0_28 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
+ /* slot power enable */
+ MX28_PAD_PWM4__GPIO_3_29 |
+ (MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
};
/* fec */
@@ -258,6 +322,18 @@ static const struct mxsfb_platform_data mx28evk_mxsfb_pdata __initconst = {
.ld_intf_width = STMLCDIF_24BIT,
};
+static struct mxs_mmc_platform_data mx28evk_mmc_pdata[] __initdata = {
+ {
+ /* mmc0 */
+ .wp_gpio = MX28EVK_MMC0_WRITE_PROTECT,
+ .flags = SLOTF_8_BIT_CAPABLE,
+ }, {
+ /* mmc1 */
+ .wp_gpio = MX28EVK_MMC1_WRITE_PROTECT,
+ .flags = SLOTF_8_BIT_CAPABLE,
+ },
+};
+
static void __init mx28evk_init(void)
{
int ret;
@@ -297,6 +373,19 @@ static void __init mx28evk_init(void)
gpio_set_value(MX28EVK_BL_ENABLE, 1);
mx28_add_mxsfb(&mx28evk_mxsfb_pdata);
+
+ /* power on mmc slot by writing 0 to the gpio */
+ ret = gpio_request_one(MX28EVK_MMC0_SLOT_POWER, GPIOF_DIR_OUT,
+ "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]);
+
+ ret = gpio_request_one(MX28EVK_MMC1_SLOT_POWER, GPIOF_DIR_OUT,
+ "mmc1-slot-power");
+ if (ret)
+ pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret);
+ mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
}
static void __init mx28evk_timer_init(void)
diff --git a/arch/arm/mach-mxs/module-tx28.c b/arch/arm/mach-mxs/module-tx28.c
index fa0b154da67..0fcff47009c 100644
--- a/arch/arm/mach-mxs/module-tx28.c
+++ b/arch/arm/mach-mxs/module-tx28.c
@@ -45,7 +45,7 @@ static const iomux_cfg_t tx28_fec_gpio_pads[] __initconst = {
};
#define FEC_MODE (MXS_PAD_8MA | MXS_PAD_PULLUP | MXS_PAD_3V3)
-static const iomux_cfg_t tx28_fec_pads[] __initconst = {
+static const iomux_cfg_t tx28_fec0_pads[] __initconst = {
MX28_PAD_ENET0_MDC__ENET0_MDC | FEC_MODE,
MX28_PAD_ENET0_MDIO__ENET0_MDIO | FEC_MODE,
MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | FEC_MODE,
@@ -57,7 +57,20 @@ static const iomux_cfg_t tx28_fec_pads[] __initconst = {
MX28_PAD_ENET_CLK__CLKCTRL_ENET | FEC_MODE,
};
-static const struct fec_platform_data tx28_fec_data __initconst = {
+static const iomux_cfg_t tx28_fec1_pads[] __initconst = {
+ MX28_PAD_ENET0_RXD2__ENET1_RXD0,
+ MX28_PAD_ENET0_RXD3__ENET1_RXD1,
+ MX28_PAD_ENET0_TXD2__ENET1_TXD0,
+ MX28_PAD_ENET0_TXD3__ENET1_TXD1,
+ MX28_PAD_ENET0_COL__ENET1_TX_EN,
+ MX28_PAD_ENET0_CRS__ENET1_RX_EN,
+};
+
+static struct fec_platform_data tx28_fec0_data = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static struct fec_platform_data tx28_fec1_data = {
.phy = PHY_INTERFACE_MODE_RMII,
};
@@ -108,15 +121,15 @@ int __init tx28_add_fec0(void)
pr_debug("%s: Deasserting FEC PHY RESET\n", __func__);
gpio_set_value(TX28_FEC_PHY_RESET, 1);
- ret = mxs_iomux_setup_multiple_pads(tx28_fec_pads,
- ARRAY_SIZE(tx28_fec_pads));
+ ret = mxs_iomux_setup_multiple_pads(tx28_fec0_pads,
+ ARRAY_SIZE(tx28_fec0_pads));
if (ret) {
pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
__func__, ret);
goto free_gpios;
}
- pr_debug("%s: Registering FEC device\n", __func__);
- mx28_add_fec(0, &tx28_fec_data);
+ pr_debug("%s: Registering FEC0 device\n", __func__);
+ mx28_add_fec(0, &tx28_fec0_data);
return 0;
free_gpios:
@@ -129,3 +142,19 @@ free_gpios:
return ret;
}
+
+int __init tx28_add_fec1(void)
+{
+ int ret;
+
+ ret = mxs_iomux_setup_multiple_pads(tx28_fec1_pads,
+ ARRAY_SIZE(tx28_fec1_pads));
+ if (ret) {
+ pr_debug("%s: mxs_iomux_setup_multiple_pads() failed with rc: %d\n",
+ __func__, ret);
+ return ret;
+ }
+ pr_debug("%s: Registering FEC1 device\n", __func__);
+ mx28_add_fec(1, &tx28_fec1_data);
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/module-tx28.h b/arch/arm/mach-mxs/module-tx28.h
index df9e1b6e81b..8ed425457d3 100644
--- a/arch/arm/mach-mxs/module-tx28.h
+++ b/arch/arm/mach-mxs/module-tx28.h
@@ -7,3 +7,4 @@
* Free Software Foundation.
*/
int __init tx28_add_fec0(void);
+int __init tx28_add_fec1(void);
diff --git a/arch/arm/mach-netx/generic.c b/arch/arm/mach-netx/generic.c
index 29ffa750fbe..00023b5cf12 100644
--- a/arch/arm/mach-netx/generic.c
+++ b/arch/arm/mach-netx/generic.c
@@ -171,13 +171,13 @@ void __init netx_init_irq(void)
vic_init(__io(io_p2v(NETX_PA_VIC)), 0, ~0, 0);
for (irq = NETX_IRQ_HIF_CHAINED(0); irq <= NETX_IRQ_HIF_LAST; irq++) {
- set_irq_chip(irq, &netx_hif_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &netx_hif_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
writel(NETX_DPMAS_INT_EN_GLB_EN, NETX_DPMAS_INT_EN);
- set_irq_chained_handler(NETX_IRQ_HIF, netx_hif_demux_handler);
+ irq_set_chained_handler(NETX_IRQ_HIF, netx_hif_demux_handler);
}
static int __init netx_init(void)
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
index 0c0d5248c36..e27687d5350 100644
--- a/arch/arm/mach-ns9xxx/board-a9m9750dev.c
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -107,8 +107,8 @@ void __init board_a9m9750dev_init_irq(void)
__func__);
for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
- set_irq_chip(i, &a9m9750dev_fpga_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &a9m9750dev_fpga_chip,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
@@ -118,8 +118,8 @@ void __init board_a9m9750dev_init_irq(void)
REGSET(eic, SYS_EIC, LVEDG, LEVEL);
__raw_writel(eic, SYS_EIC(2));
- set_irq_chained_handler(IRQ_NS9XXX_EXT2,
- a9m9750dev_fpga_demux_handler);
+ irq_set_chained_handler(IRQ_NS9XXX_EXT2,
+ a9m9750dev_fpga_demux_handler);
}
void __init board_a9m9750dev_init_machine(void)
diff --git a/arch/arm/mach-ns9xxx/include/mach/board.h b/arch/arm/mach-ns9xxx/include/mach/board.h
index f7e9196eb9a..19ca6de46a4 100644
--- a/arch/arm/mach-ns9xxx/include/mach/board.h
+++ b/arch/arm/mach-ns9xxx/include/mach/board.h
@@ -14,12 +14,10 @@
#include <asm/mach-types.h>
#define board_is_a9m9750dev() (0 \
- || machine_is_cc9p9360dev() \
|| machine_is_cc9p9750dev() \
)
#define board_is_a9mvali() (0 \
- || machine_is_cc9p9360val() \
|| machine_is_cc9p9750val() \
)
diff --git a/arch/arm/mach-ns9xxx/include/mach/module.h b/arch/arm/mach-ns9xxx/include/mach/module.h
index f851a6b7da6..628e9752589 100644
--- a/arch/arm/mach-ns9xxx/include/mach/module.h
+++ b/arch/arm/mach-ns9xxx/include/mach/module.h
@@ -18,7 +18,6 @@
)
#define module_is_cc9c() (0 \
- || machine_is_cc9c() \
)
#define module_is_cc9p9210() (0 \
@@ -32,21 +31,17 @@
)
#define module_is_cc9p9360() (0 \
- || machine_is_a9m9360() \
|| machine_is_cc9p9360dev() \
|| machine_is_cc9p9360js() \
- || machine_is_cc9p9360val() \
)
#define module_is_cc9p9750() (0 \
|| machine_is_a9m9750() \
- || machine_is_cc9p9750dev() \
|| machine_is_cc9p9750js() \
|| machine_is_cc9p9750val() \
)
#define module_is_ccw9c() (0 \
- || machine_is_ccw9c() \
)
#define module_is_inc20otter() (0 \
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
index 389fa5c669d..37ab0a2b83a 100644
--- a/arch/arm/mach-ns9xxx/irq.c
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -31,17 +31,11 @@ static void ns9xxx_mask_irq(struct irq_data *d)
__raw_writel(ic, SYS_IC(prio / 4));
}
-static void ns9xxx_ack_irq(struct irq_data *d)
+static void ns9xxx_eoi_irq(struct irq_data *d)
{
__raw_writel(0, SYS_ISRADDR);
}
-static void ns9xxx_maskack_irq(struct irq_data *d)
-{
- ns9xxx_mask_irq(d);
- ns9xxx_ack_irq(d);
-}
-
static void ns9xxx_unmask_irq(struct irq_data *d)
{
/* XXX: better use cpp symbols */
@@ -52,56 +46,11 @@ static void ns9xxx_unmask_irq(struct irq_data *d)
}
static struct irq_chip ns9xxx_chip = {
- .irq_ack = ns9xxx_ack_irq,
+ .irq_eoi = ns9xxx_eoi_irq,
.irq_mask = ns9xxx_mask_irq,
- .irq_mask_ack = ns9xxx_maskack_irq,
.irq_unmask = ns9xxx_unmask_irq,
};
-#if 0
-#define handle_irq handle_level_irq
-#else
-static void handle_prio_irq(unsigned int irq, struct irq_desc *desc)
-{
- struct irqaction *action;
- irqreturn_t action_ret;
-
- raw_spin_lock(&desc->lock);
-
- BUG_ON(desc->status & IRQ_INPROGRESS);
-
- desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
- kstat_incr_irqs_this_cpu(irq, desc);
-
- action = desc->action;
- if (unlikely(!action || (desc->status & IRQ_DISABLED)))
- goto out_mask;
-
- desc->status |= IRQ_INPROGRESS;
- raw_spin_unlock(&desc->lock);
-
- action_ret = handle_IRQ_event(irq, action);
-
- /* XXX: There is no direct way to access noirqdebug, so check
- * unconditionally for spurious irqs...
- * Maybe this function should go to kernel/irq/chip.c? */
- note_interrupt(irq, desc, action_ret);
-
- raw_spin_lock(&desc->lock);
- desc->status &= ~IRQ_INPROGRESS;
-
- if (desc->status & IRQ_DISABLED)
-out_mask:
- desc->irq_data.chip->irq_mask(&desc->irq_data);
-
- /* ack unconditionally to unmask lower prio irqs */
- desc->irq_data.chip->irq_ack(&desc->irq_data);
-
- raw_spin_unlock(&desc->lock);
-}
-#define handle_irq handle_prio_irq
-#endif
-
void __init ns9xxx_init_irq(void)
{
int i;
@@ -118,8 +67,8 @@ void __init ns9xxx_init_irq(void)
__raw_writel(prio2irq(i), SYS_IVA(i));
for (i = 0; i <= 31; ++i) {
- set_irq_chip(i, &ns9xxx_chip);
- set_irq_handler(i, handle_irq);
+ irq_set_chip_and_handler(i, &ns9xxx_chip, handle_fasteoi_irq);
set_irq_flags(i, IRQF_VALID);
+ irq_set_status_flags(i, IRQ_LEVEL);
}
}
diff --git a/arch/arm/mach-nuc93x/irq.c b/arch/arm/mach-nuc93x/irq.c
index 1f8a05a2283..aa279f23e34 100644
--- a/arch/arm/mach-nuc93x/irq.c
+++ b/arch/arm/mach-nuc93x/irq.c
@@ -59,8 +59,8 @@ void __init nuc93x_init_irq(void)
__raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
for (irqno = IRQ_WDT; irqno <= NR_IRQS; irqno++) {
- set_irq_chip(irqno, &nuc93x_irq_chip);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &nuc93x_irq_chip,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-omap1/board-osk.c b/arch/arm/mach-omap1/board-osk.c
index 7c5e2112c77..e68dfde1918 100644
--- a/arch/arm/mach-omap1/board-osk.c
+++ b/arch/arm/mach-omap1/board-osk.c
@@ -276,7 +276,7 @@ static void __init osk_init_cf(void)
return;
}
/* the CF I/O IRQ is really active-low */
- set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(gpio_to_irq(62), IRQ_TYPE_EDGE_FALLING);
}
static void __init osk_init_irq(void)
@@ -482,7 +482,7 @@ static void __init osk_mistral_init(void)
omap_cfg_reg(P20_1610_GPIO4); /* PENIRQ */
gpio_request(4, "ts_int");
gpio_direction_input(4);
- set_irq_type(gpio_to_irq(4), IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(gpio_to_irq(4), IRQ_TYPE_EDGE_FALLING);
spi_register_board_info(mistral_boardinfo,
ARRAY_SIZE(mistral_boardinfo));
@@ -500,7 +500,7 @@ static void __init osk_mistral_init(void)
int irq = gpio_to_irq(OMAP_MPUIO(2));
gpio_direction_input(OMAP_MPUIO(2));
- set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
#ifdef CONFIG_PM
/* share the IRQ in case someone wants to use the
* button for more than wakeup from system sleep.
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index d7bbbe721a7..45f01d2c3a7 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -256,12 +256,12 @@ palmz71_powercable(int irq, void *dev_id)
{
if (gpio_get_value(PALMZ71_USBDETECT_GPIO)) {
printk(KERN_INFO "PM: Power cable connected\n");
- set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
- IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
+ IRQ_TYPE_EDGE_FALLING);
} else {
printk(KERN_INFO "PM: Power cable disconnected\n");
- set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
- IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
+ IRQ_TYPE_EDGE_RISING);
}
return IRQ_HANDLED;
}
diff --git a/arch/arm/mach-omap1/board-voiceblue.c b/arch/arm/mach-omap1/board-voiceblue.c
index bdc0ac8dc21..65d24204937 100644
--- a/arch/arm/mach-omap1/board-voiceblue.c
+++ b/arch/arm/mach-omap1/board-voiceblue.c
@@ -279,10 +279,10 @@ static void __init voiceblue_init(void)
gpio_request(13, "16C554 irq");
gpio_request(14, "16C554 irq");
gpio_request(15, "16C554 irq");
- set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING);
- set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
- set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING);
- set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(12), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(14), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(15), IRQ_TYPE_EDGE_RISING);
platform_add_devices(voiceblue_devices, ARRAY_SIZE(voiceblue_devices));
omap_board_config = voiceblue_config;
diff --git a/arch/arm/mach-omap1/fpga.c b/arch/arm/mach-omap1/fpga.c
index 0ace7998aaa..cddbf8b089c 100644
--- a/arch/arm/mach-omap1/fpga.c
+++ b/arch/arm/mach-omap1/fpga.c
@@ -156,17 +156,17 @@ void omap1510_fpga_init_irq(void)
* The touchscreen interrupt is level-sensitive, so
* we'll use the regular mask_ack routine for it.
*/
- set_irq_chip(i, &omap_fpga_irq_ack);
+ irq_set_chip(i, &omap_fpga_irq_ack);
}
else {
/*
* All FPGA interrupts except the touchscreen are
* edge-sensitive, so we won't mask them.
*/
- set_irq_chip(i, &omap_fpga_irq);
+ irq_set_chip(i, &omap_fpga_irq);
}
- set_irq_handler(i, handle_edge_irq);
+ irq_set_handler(i, handle_edge_irq);
set_irq_flags(i, IRQF_VALID);
}
@@ -183,6 +183,6 @@ void omap1510_fpga_init_irq(void)
return;
}
gpio_direction_input(13);
- set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
- set_irq_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
+ irq_set_irq_type(gpio_to_irq(13), IRQ_TYPE_EDGE_RISING);
+ irq_set_chained_handler(OMAP1510_INT_FPGA, innovator_fpga_IRQ_demux);
}
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 731dd33bff5..5d3da7a63af 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -230,8 +230,8 @@ void __init omap_init_irq(void)
irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j);
omap_irq_set_cfg(j, 0, 0, irq_trigger);
- set_irq_chip(j, &omap_irq_chip);
- set_irq_handler(j, handle_level_irq);
+ irq_set_chip_and_handler(j, &omap_irq_chip,
+ handle_level_irq);
set_irq_flags(j, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c
index 493505c3b2f..130034bf01d 100644
--- a/arch/arm/mach-omap2/gpmc.c
+++ b/arch/arm/mach-omap2/gpmc.c
@@ -743,7 +743,7 @@ static int __init gpmc_init(void)
/* initalize the irq_chained */
irq = OMAP_GPMC_IRQ_BASE;
for (cs = 0; cs < GPMC_CS_NUM; cs++) {
- set_irq_chip_and_handler(irq, &dummy_irq_chip,
+ irq_set_chip_and_handler(irq, &dummy_irq_chip,
handle_simple_irq);
set_irq_flags(irq, IRQF_VALID);
irq++;
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c
index bc524b94fd5..237e4530abf 100644
--- a/arch/arm/mach-omap2/irq.c
+++ b/arch/arm/mach-omap2/irq.c
@@ -223,8 +223,7 @@ void __init omap_init_irq(void)
nr_of_irqs, nr_banks, nr_banks > 1 ? "s" : "");
for (i = 0; i < nr_of_irqs; i++) {
- set_irq_chip(i, &omap_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &omap_irq_chip, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c
index c10a1171537..b7d4591214e 100644
--- a/arch/arm/mach-orion5x/db88f5281-setup.c
+++ b/arch/arm/mach-orion5x/db88f5281-setup.c
@@ -213,7 +213,7 @@ void __init db88f5281_pci_preinit(void)
pin = DB88F5281_PCI_SLOT0_IRQ_PIN;
if (gpio_request(pin, "PCI Int1") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "db88f5281_pci_preinit faield to "
"set_irq_type pin %d\n", pin);
@@ -226,7 +226,7 @@ void __init db88f5281_pci_preinit(void)
pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN;
if (gpio_request(pin, "PCI Int2") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "db88f5281_pci_preinit faield "
"to set_irq_type pin %d\n", pin);
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index ed85891f869..43cf8bc9767 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -34,8 +34,8 @@ void __init orion5x_init_irq(void)
* Initialize gpiolib for GPIOs 0-31.
*/
orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0, IRQ_ORION5X_GPIO_START);
- set_irq_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler);
- set_irq_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler);
- set_irq_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler);
- set_irq_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler);
+ irq_set_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler);
}
diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c
index 67ec6959b26..4fc46772a08 100644
--- a/arch/arm/mach-orion5x/rd88f5182-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5182-setup.c
@@ -148,7 +148,7 @@ void __init rd88f5182_pci_preinit(void)
pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
if (gpio_request(pin, "PCI IntA") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "rd88f5182_pci_preinit faield to "
"set_irq_type pin %d\n", pin);
@@ -161,7 +161,7 @@ void __init rd88f5182_pci_preinit(void)
pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
if (gpio_request(pin, "PCI IntB") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "rd88f5182_pci_preinit faield to "
"set_irq_type pin %d\n", pin);
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
index 5653ee6c71d..61600414391 100644
--- a/arch/arm/mach-orion5x/terastation_pro2-setup.c
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -88,7 +88,7 @@ void __init tsp2_pci_preinit(void)
pin = TSP2_PCI_SLOT0_IRQ_PIN;
if (gpio_request(pin, "PCI Int1") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "tsp2_pci_preinit failed "
"to set_irq_type pin %d\n", pin);
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
index 8bbd27ea673..f0f43e13ac8 100644
--- a/arch/arm/mach-orion5x/ts209-setup.c
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -117,7 +117,7 @@ void __init qnap_ts209_pci_preinit(void)
pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
if (gpio_request(pin, "PCI Int1") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
"set_irq_type pin %d\n", pin);
@@ -131,7 +131,7 @@ void __init qnap_ts209_pci_preinit(void)
pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
if (gpio_request(pin, "PCI Int2") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "qnap_ts209_pci_preinit failed "
"to set_irq_type pin %d\n", pin);
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c
index 8554707d20a..edb1dd2d161 100644
--- a/arch/arm/mach-orion5x/ts78xx-setup.c
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -402,7 +402,7 @@ static void ts78xx_fpga_supports(void)
/* enable devices if magic matches */
switch ((ts78xx_fpga.id >> 8) & 0xffffff) {
case TS7800_FPGA_MAGIC:
- printk(KERN_WARNING "TS-7800 FPGA: unrecognized revision 0x%.2x\n",
+ pr_warning("TS-7800 FPGA: unrecognized revision 0x%.2x\n",
ts78xx_fpga.id & 0xff);
ts78xx_fpga.supports.ts_rtc.present = 1;
ts78xx_fpga.supports.ts_nand.present = 1;
@@ -423,7 +423,7 @@ static int ts78xx_fpga_load_devices(void)
if (ts78xx_fpga.supports.ts_rtc.present == 1) {
tmp = ts78xx_ts_rtc_load();
if (tmp) {
- printk(KERN_INFO "TS-78xx: RTC not registered\n");
+ pr_info("TS-78xx: RTC not registered\n");
ts78xx_fpga.supports.ts_rtc.present = 0;
}
ret |= tmp;
@@ -431,7 +431,7 @@ static int ts78xx_fpga_load_devices(void)
if (ts78xx_fpga.supports.ts_nand.present == 1) {
tmp = ts78xx_ts_nand_load();
if (tmp) {
- printk(KERN_INFO "TS-78xx: NAND not registered\n");
+ pr_info("TS-78xx: NAND not registered\n");
ts78xx_fpga.supports.ts_nand.present = 0;
}
ret |= tmp;
@@ -439,7 +439,7 @@ static int ts78xx_fpga_load_devices(void)
if (ts78xx_fpga.supports.ts_rng.present == 1) {
tmp = ts78xx_ts_rng_load();
if (tmp) {
- printk(KERN_INFO "TS-78xx: RNG not registered\n");
+ pr_info("TS-78xx: RNG not registered\n");
ts78xx_fpga.supports.ts_rng.present = 0;
}
ret |= tmp;
@@ -466,7 +466,7 @@ static int ts78xx_fpga_load(void)
{
ts78xx_fpga.id = readl(TS78XX_FPGA_REGS_VIRT_BASE);
- printk(KERN_INFO "TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
+ pr_info("TS-78xx FPGA: magic=0x%.6x, rev=0x%.2x\n",
(ts78xx_fpga.id >> 8) & 0xffffff,
ts78xx_fpga.id & 0xff);
@@ -494,7 +494,7 @@ static int ts78xx_fpga_unload(void)
* UrJTAG SVN since r1381 can be used to reprogram the FPGA
*/
if (ts78xx_fpga.id != fpga_id) {
- printk(KERN_ERR "TS-78xx FPGA: magic/rev mismatch\n"
+ pr_err("TS-78xx FPGA: magic/rev mismatch\n"
"TS-78xx FPGA: was 0x%.6x/%.2x but now 0x%.6x/%.2x\n",
(ts78xx_fpga.id >> 8) & 0xffffff, ts78xx_fpga.id & 0xff,
(fpga_id >> 8) & 0xffffff, fpga_id & 0xff);
@@ -525,7 +525,7 @@ static ssize_t ts78xx_fpga_store(struct kobject *kobj,
int value, ret;
if (ts78xx_fpga.state < 0) {
- printk(KERN_ERR "TS-78xx FPGA: borked, you must powercycle asap\n");
+ pr_err("TS-78xx FPGA: borked, you must powercycle asap\n");
return -EBUSY;
}
@@ -534,7 +534,7 @@ static ssize_t ts78xx_fpga_store(struct kobject *kobj,
else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0)
value = 0;
else {
- printk(KERN_ERR "ts78xx_fpga_store: Invalid value\n");
+ pr_err("ts78xx_fpga_store: Invalid value\n");
return -EINVAL;
}
@@ -616,7 +616,7 @@ static void __init ts78xx_init(void)
ret = ts78xx_fpga_load();
ret = sysfs_create_file(power_kobj, &ts78xx_fpga_attr.attr);
if (ret)
- printk(KERN_ERR "sysfs_create_file failed: %d\n", ret);
+ pr_err("sysfs_create_file failed: %d\n", ret);
}
MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
diff --git a/arch/arm/mach-pnx4008/irq.c b/arch/arm/mach-pnx4008/irq.c
index c69c180aec7..7608c7a288c 100644
--- a/arch/arm/mach-pnx4008/irq.c
+++ b/arch/arm/mach-pnx4008/irq.c
@@ -58,22 +58,22 @@ static int pnx4008_set_irq_type(struct irq_data *d, unsigned int type)
case IRQ_TYPE_EDGE_RISING:
__raw_writel(__raw_readl(INTC_ATR(d->irq)) | INTC_BIT(d->irq), INTC_ATR(d->irq)); /*edge sensitive */
__raw_writel(__raw_readl(INTC_APR(d->irq)) | INTC_BIT(d->irq), INTC_APR(d->irq)); /*rising edge */
- set_irq_handler(d->irq, handle_edge_irq);
+ irq_set_handler(d->irq, handle_edge_irq);
break;
case IRQ_TYPE_EDGE_FALLING:
__raw_writel(__raw_readl(INTC_ATR(d->irq)) | INTC_BIT(d->irq), INTC_ATR(d->irq)); /*edge sensitive */
__raw_writel(__raw_readl(INTC_APR(d->irq)) & ~INTC_BIT(d->irq), INTC_APR(d->irq)); /*falling edge */
- set_irq_handler(d->irq, handle_edge_irq);
+ irq_set_handler(d->irq, handle_edge_irq);
break;
case IRQ_TYPE_LEVEL_LOW:
__raw_writel(__raw_readl(INTC_ATR(d->irq)) & ~INTC_BIT(d->irq), INTC_ATR(d->irq)); /*level sensitive */
__raw_writel(__raw_readl(INTC_APR(d->irq)) & ~INTC_BIT(d->irq), INTC_APR(d->irq)); /*low level */
- set_irq_handler(d->irq, handle_level_irq);
+ irq_set_handler(d->irq, handle_level_irq);
break;
case IRQ_TYPE_LEVEL_HIGH:
__raw_writel(__raw_readl(INTC_ATR(d->irq)) & ~INTC_BIT(d->irq), INTC_ATR(d->irq)); /*level sensitive */
__raw_writel(__raw_readl(INTC_APR(d->irq)) | INTC_BIT(d->irq), INTC_APR(d->irq)); /* high level */
- set_irq_handler(d->irq, handle_level_irq);
+ irq_set_handler(d->irq, handle_level_irq);
break;
/* IRQ_TYPE_EDGE_BOTH is not supported */
@@ -98,7 +98,7 @@ void __init pnx4008_init_irq(void)
/* configure IRQ's */
for (i = 0; i < NR_IRQS; i++) {
set_irq_flags(i, IRQF_VALID);
- set_irq_chip(i, &pnx4008_irq_chip);
+ irq_set_chip(i, &pnx4008_irq_chip);
pnx4008_set_irq_type(irq_get_irq_data(i), pnx4008_irq_type[i]);
}
diff --git a/arch/arm/mach-pxa/am200epd.c b/arch/arm/mach-pxa/am200epd.c
index 3499fada73a..4cb069fd9af 100644
--- a/arch/arm/mach-pxa/am200epd.c
+++ b/arch/arm/mach-pxa/am200epd.c
@@ -128,8 +128,8 @@ static int am200_init_gpio_regs(struct metronomefb_par *par)
return 0;
err_req_gpio:
- while (i > 0)
- gpio_free(gpios[i--]);
+ while (--i >= 0)
+ gpio_free(gpios[i]);
return err;
}
@@ -194,7 +194,7 @@ static struct notifier_block am200_fb_notif = {
};
/* this gets called as part of our init. these steps must be done now so
- * that we can use set_pxa_fb_info */
+ * that we can use pxa_set_fb_info */
static void __init am200_presetup_fb(void)
{
int fw;
@@ -249,7 +249,7 @@ static void __init am200_presetup_fb(void)
/* we divide since we told the LCD controller we're 16bpp */
am200_fb_info.modes->xres /= 2;
- set_pxa_fb_info(&am200_fb_info);
+ pxa_set_fb_info(NULL, &am200_fb_info);
}
diff --git a/arch/arm/mach-pxa/am300epd.c b/arch/arm/mach-pxa/am300epd.c
index 993d75e6639..fa8bad235d9 100644
--- a/arch/arm/mach-pxa/am300epd.c
+++ b/arch/arm/mach-pxa/am300epd.c
@@ -125,10 +125,7 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par)
if (err) {
dev_err(&am300_device->dev, "failed requesting "
"gpio %d, err=%d\n", i, err);
- while (i >= DB0_GPIO_PIN)
- gpio_free(i--);
- i = ARRAY_SIZE(gpios) - 1;
- goto err_req_gpio;
+ goto err_req_gpio2;
}
}
@@ -159,9 +156,13 @@ static int am300_init_gpio_regs(struct broadsheetfb_par *par)
return 0;
+err_req_gpio2:
+ while (--i >= DB0_GPIO_PIN)
+ gpio_free(i);
+ i = ARRAY_SIZE(gpios);
err_req_gpio:
- while (i > 0)
- gpio_free(gpios[i--]);
+ while (--i >= 0)
+ gpio_free(gpios[i]);
return err;
}
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c
index d2af73321da..bfbecec6d05 100644
--- a/arch/arm/mach-pxa/balloon3.c
+++ b/arch/arm/mach-pxa/balloon3.c
@@ -263,7 +263,7 @@ static void __init balloon3_lcd_init(void)
}
balloon3_lcd_screen.pxafb_backlight_power = balloon3_backlight_power;
- set_pxa_fb_info(&balloon3_lcd_screen);
+ pxa_set_fb_info(NULL, &balloon3_lcd_screen);
return;
err2:
@@ -527,13 +527,13 @@ static void __init balloon3_init_irq(void)
pxa27x_init_irq();
/* setup extra Balloon3 irqs */
for (irq = BALLOON3_IRQ(0); irq <= BALLOON3_IRQ(7); irq++) {
- set_irq_chip(irq, &balloon3_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &balloon3_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
- set_irq_chained_handler(BALLOON3_AUX_NIRQ, balloon3_irq_handler);
- set_irq_type(BALLOON3_AUX_NIRQ, IRQ_TYPE_EDGE_FALLING);
+ irq_set_chained_handler(BALLOON3_AUX_NIRQ, balloon3_irq_handler);
+ irq_set_irq_type(BALLOON3_AUX_NIRQ, IRQ_TYPE_EDGE_FALLING);
pr_debug("%s: chained handler installed - irq %d automatically "
"enabled\n", __func__, BALLOON3_AUX_NIRQ);
diff --git a/arch/arm/mach-pxa/cm-x2xx-pci.c b/arch/arm/mach-pxa/cm-x2xx-pci.c
index a2380cd76f8..8b1a30959fa 100644
--- a/arch/arm/mach-pxa/cm-x2xx-pci.c
+++ b/arch/arm/mach-pxa/cm-x2xx-pci.c
@@ -70,9 +70,10 @@ void __cmx2xx_pci_init_irq(int irq_gpio)
cmx2xx_it8152_irq_gpio = irq_gpio;
- set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(irq_gpio), IRQ_TYPE_EDGE_RISING);
- set_irq_chained_handler(gpio_to_irq(irq_gpio), cmx2xx_it8152_irq_demux);
+ irq_set_chained_handler(gpio_to_irq(irq_gpio),
+ cmx2xx_it8152_irq_demux);
}
#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/cm-x2xx.c b/arch/arm/mach-pxa/cm-x2xx.c
index b734d846816..8225e2e58c6 100644
--- a/arch/arm/mach-pxa/cm-x2xx.c
+++ b/arch/arm/mach-pxa/cm-x2xx.c
@@ -379,7 +379,7 @@ __setup("monitor=", cmx2xx_set_display);
static void __init cmx2xx_init_display(void)
{
- set_pxa_fb_info(cmx2xx_display);
+ pxa_set_fb_info(NULL, cmx2xx_display);
}
#else
static inline void cmx2xx_init_display(void) {}
diff --git a/arch/arm/mach-pxa/cm-x300.c b/arch/arm/mach-pxa/cm-x300.c
index bfca7ed2fea..b2248e76ec8 100644
--- a/arch/arm/mach-pxa/cm-x300.c
+++ b/arch/arm/mach-pxa/cm-x300.c
@@ -296,7 +296,7 @@ static struct pxafb_mach_info cm_x300_lcd = {
static void __init cm_x300_init_lcd(void)
{
- set_pxa_fb_info(&cm_x300_lcd);
+ pxa_set_fb_info(NULL, &cm_x300_lcd);
}
#else
static inline void cm_x300_init_lcd(void) {}
@@ -765,7 +765,7 @@ static void __init cm_x300_init_da9030(void)
{
pxa3xx_set_i2c_power_info(&cm_x300_pwr_i2c_info);
i2c_register_board_info(1, &cm_x300_pmic_info, 1);
- set_irq_wake(IRQ_WAKEUP0, 1);
+ irq_set_irq_wake(IRQ_WAKEUP0, 1);
}
static void __init cm_x300_init_wi2wi(void)
diff --git a/arch/arm/mach-pxa/colibri-pxa270-income.c b/arch/arm/mach-pxa/colibri-pxa270-income.c
index ee797397dc5..44c1b77ece6 100644
--- a/arch/arm/mach-pxa/colibri-pxa270-income.c
+++ b/arch/arm/mach-pxa/colibri-pxa270-income.c
@@ -175,7 +175,7 @@ static struct pxafb_mach_info income_lcd_screen = {
static void __init income_lcd_init(void)
{
- set_pxa_fb_info(&income_lcd_screen);
+ pxa_set_fb_info(NULL, &income_lcd_screen);
}
#else
static inline void income_lcd_init(void) {}
diff --git a/arch/arm/mach-pxa/colibri-pxa3xx.c b/arch/arm/mach-pxa/colibri-pxa3xx.c
index 96b2d9fbfef..3f9be419959 100644
--- a/arch/arm/mach-pxa/colibri-pxa3xx.c
+++ b/arch/arm/mach-pxa/colibri-pxa3xx.c
@@ -105,7 +105,7 @@ void __init colibri_pxa3xx_init_lcd(int bl_pin)
lcd_bl_pin = bl_pin;
gpio_request(bl_pin, "lcd backlight");
gpio_direction_output(bl_pin, 0);
- set_pxa_fb_info(&sharp_lq43_info);
+ pxa_set_fb_info(NULL, &sharp_lq43_info);
}
#endif
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index d4e705caefe..3a5507e3191 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -462,7 +462,6 @@ static struct pxaficp_platform_data corgi_ficp_platform_data = {
* USB Device Controller
*/
static struct pxa2xx_udc_mach_info udc_info __initdata = {
- .gpio_vbus = -1,
/* no connect GPIO; corgi can't tell connection status */
.gpio_pullup = CORGI_GPIO_USB_PULLUP,
};
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index c4bf08b3eb6..2e0425404de 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -90,7 +90,6 @@ void __init pxa_set_mci_info(struct pxamci_platform_data *info)
static struct pxa2xx_udc_mach_info pxa_udc_info = {
.gpio_pullup = -1,
- .gpio_vbus = -1,
};
void __init pxa_set_udc_info(struct pxa2xx_udc_mach_info *info)
@@ -188,16 +187,12 @@ struct platform_device pxa_device_fb = {
.resource = pxafb_resources,
};
-void __init set_pxa_fb_info(struct pxafb_mach_info *info)
+void __init pxa_set_fb_info(struct device *parent, struct pxafb_mach_info *info)
{
+ pxa_device_fb.dev.parent = parent;
pxa_register_device(&pxa_device_fb, info);
}
-void __init set_pxa_fb_parent(struct device *parent_dev)
-{
- pxa_device_fb.dev.parent = parent_dev;
-}
-
static struct resource pxa_resource_ffuart[] = {
{
.start = 0x40100000,
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index b411d7cbf5a..f8a6e9d79a3 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -689,7 +689,7 @@ static struct pxafb_mach_info em_x270_lcd = {
static void __init em_x270_init_lcd(void)
{
- set_pxa_fb_info(&em_x270_lcd);
+ pxa_set_fb_info(NULL, &em_x270_lcd);
}
#else
static inline void em_x270_init_lcd(void) {}
diff --git a/arch/arm/mach-pxa/eseries.c b/arch/arm/mach-pxa/eseries.c
index edca0a04329..2e3970fdde0 100644
--- a/arch/arm/mach-pxa/eseries.c
+++ b/arch/arm/mach-pxa/eseries.c
@@ -20,6 +20,7 @@
#include <linux/mfd/t7l66xb.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/usb/gpio_vbus.h>
#include <video/w100fb.h>
@@ -51,12 +52,20 @@ void __init eseries_fixup(struct machine_desc *desc,
mi->bank[0].size = (64*1024*1024);
}
-struct pxa2xx_udc_mach_info e7xx_udc_mach_info = {
+struct gpio_vbus_mach_info e7xx_udc_info = {
.gpio_vbus = GPIO_E7XX_USB_DISC,
.gpio_pullup = GPIO_E7XX_USB_PULLUP,
.gpio_pullup_inverted = 1
};
+static struct platform_device e7xx_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &e7xx_udc_info,
+ },
+};
+
struct pxaficp_platform_data e7xx_ficp_platform_data = {
.gpio_pwdown = GPIO_E7XX_IR_OFF,
.transceiver_cap = IR_SIRMODE | IR_OFF,
@@ -165,6 +174,7 @@ static struct platform_device e330_tc6387xb_device = {
static struct platform_device *e330_devices[] __initdata = {
&e330_tc6387xb_device,
+ &e7xx_gpio_vbus,
};
static void __init e330_init(void)
@@ -175,7 +185,6 @@ static void __init e330_init(void)
eseries_register_clks();
eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e330_devices));
- pxa_set_udc_info(&e7xx_udc_mach_info);
}
MACHINE_START(E330, "Toshiba e330")
@@ -214,6 +223,7 @@ static struct platform_device e350_t7l66xb_device = {
static struct platform_device *e350_devices[] __initdata = {
&e350_t7l66xb_device,
+ &e7xx_gpio_vbus,
};
static void __init e350_init(void)
@@ -224,7 +234,6 @@ static void __init e350_init(void)
eseries_register_clks();
eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e350_devices));
- pxa_set_udc_info(&e7xx_udc_mach_info);
}
MACHINE_START(E350, "Toshiba e350")
@@ -333,6 +342,7 @@ static struct platform_device e400_t7l66xb_device = {
static struct platform_device *e400_devices[] __initdata = {
&e400_t7l66xb_device,
+ &e7xx_gpio_vbus,
};
static void __init e400_init(void)
@@ -344,9 +354,8 @@ static void __init e400_init(void)
/* Fixme - e400 may have a switched clock */
eseries_register_clks();
eseries_get_tmio_gpios();
- set_pxa_fb_info(&e400_pxafb_mach_info);
+ pxa_set_fb_info(NULL, &e400_pxafb_mach_info);
platform_add_devices(ARRAY_AND_SIZE(e400_devices));
- pxa_set_udc_info(&e7xx_udc_mach_info);
}
MACHINE_START(E400, "Toshiba e400")
@@ -519,6 +528,7 @@ static struct platform_device e740_t7l66xb_device = {
static struct platform_device *e740_devices[] __initdata = {
&e740_fb_device,
&e740_t7l66xb_device,
+ &e7xx_gpio_vbus,
};
static void __init e740_init(void)
@@ -532,7 +542,6 @@ static void __init e740_init(void)
"UDCCLK", &pxa25x_device_udc.dev),
eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e740_devices));
- pxa_set_udc_info(&e7xx_udc_mach_info);
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&e7xx_ficp_platform_data);
}
@@ -711,6 +720,7 @@ static struct platform_device e750_tc6393xb_device = {
static struct platform_device *e750_devices[] __initdata = {
&e750_fb_device,
&e750_tc6393xb_device,
+ &e7xx_gpio_vbus,
};
static void __init e750_init(void)
@@ -723,7 +733,6 @@ static void __init e750_init(void)
"GPIO11_CLK", NULL),
eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e750_devices));
- pxa_set_udc_info(&e7xx_udc_mach_info);
pxa_set_ac97_info(NULL);
pxa_set_ficp_info(&e7xx_ficp_platform_data);
}
@@ -873,12 +882,21 @@ static struct platform_device e800_fb_device = {
/* --------------------------- UDC definitions --------------------------- */
-static struct pxa2xx_udc_mach_info e800_udc_mach_info = {
+static struct gpio_vbus_mach_info e800_udc_info = {
.gpio_vbus = GPIO_E800_USB_DISC,
.gpio_pullup = GPIO_E800_USB_PULLUP,
.gpio_pullup_inverted = 1
};
+static struct platform_device e800_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &e800_udc_info,
+ },
+};
+
+
/* ----------------- e800 tc6393xb parameters ------------------ */
static struct tc6393xb_platform_data e800_tc6393xb_info = {
@@ -907,6 +925,7 @@ static struct platform_device e800_tc6393xb_device = {
static struct platform_device *e800_devices[] __initdata = {
&e800_fb_device,
&e800_tc6393xb_device,
+ &e800_gpio_vbus,
};
static void __init e800_init(void)
@@ -919,7 +938,6 @@ static void __init e800_init(void)
"GPIO11_CLK", NULL),
eseries_get_tmio_gpios();
platform_add_devices(ARRAY_AND_SIZE(e800_devices));
- pxa_set_udc_info(&e800_udc_mach_info);
pxa_set_ac97_info(NULL);
}
diff --git a/arch/arm/mach-pxa/ezx.c b/arch/arm/mach-pxa/ezx.c
index 93f05e02431..d88aed8fbe1 100644
--- a/arch/arm/mach-pxa/ezx.c
+++ b/arch/arm/mach-pxa/ezx.c
@@ -783,7 +783,7 @@ static void __init a780_init(void)
pxa_set_i2c_info(NULL);
- set_pxa_fb_info(&ezx_fb_info_1);
+ pxa_set_fb_info(NULL, &ezx_fb_info_1);
pxa_set_keypad_info(&a780_keypad_platform_data);
@@ -853,7 +853,7 @@ static void __init e680_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(e680_i2c_board_info));
- set_pxa_fb_info(&ezx_fb_info_1);
+ pxa_set_fb_info(NULL, &ezx_fb_info_1);
pxa_set_keypad_info(&e680_keypad_platform_data);
@@ -918,7 +918,7 @@ static void __init a1200_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(a1200_i2c_board_info));
- set_pxa_fb_info(&ezx_fb_info_2);
+ pxa_set_fb_info(NULL, &ezx_fb_info_2);
pxa_set_keypad_info(&a1200_keypad_platform_data);
@@ -1103,7 +1103,7 @@ static void __init a910_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(a910_i2c_board_info));
- set_pxa_fb_info(&ezx_fb_info_2);
+ pxa_set_fb_info(NULL, &ezx_fb_info_2);
pxa_set_keypad_info(&a910_keypad_platform_data);
@@ -1173,7 +1173,7 @@ static void __init e6_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(e6_i2c_board_info));
- set_pxa_fb_info(&ezx_fb_info_2);
+ pxa_set_fb_info(NULL, &ezx_fb_info_2);
pxa_set_keypad_info(&e6_keypad_platform_data);
@@ -1212,7 +1212,7 @@ static void __init e2_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(e2_i2c_board_info));
- set_pxa_fb_info(&ezx_fb_info_2);
+ pxa_set_fb_info(NULL, &ezx_fb_info_2);
pxa_set_keypad_info(&e2_keypad_platform_data);
diff --git a/arch/arm/mach-pxa/gumstix.c b/arch/arm/mach-pxa/gumstix.c
index 6fd319ea528..d65e4bde9b9 100644
--- a/arch/arm/mach-pxa/gumstix.c
+++ b/arch/arm/mach-pxa/gumstix.c
@@ -26,6 +26,7 @@
#include <linux/gpio.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/usb/gpio_vbus.h>
#include <asm/setup.h>
#include <asm/memory.h>
@@ -106,14 +107,22 @@ static void __init gumstix_mmc_init(void)
#endif
#ifdef CONFIG_USB_GADGET_PXA25X
-static struct pxa2xx_udc_mach_info gumstix_udc_info __initdata = {
+static struct gpio_vbus_mach_info gumstix_udc_info = {
.gpio_vbus = GPIO_GUMSTIX_USB_GPIOn,
.gpio_pullup = GPIO_GUMSTIX_USB_GPIOx,
};
+static struct platform_device gumstix_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &gumstix_udc_info,
+ },
+};
+
static void __init gumstix_udc_init(void)
{
- pxa_set_udc_info(&gumstix_udc_info);
+ platform_device_register(&gumstix_gpio_vbus);
}
#else
static void gumstix_udc_init(void)
diff --git a/arch/arm/mach-pxa/idp.c b/arch/arm/mach-pxa/idp.c
index dd40e4a9291..f7fb64f11a7 100644
--- a/arch/arm/mach-pxa/idp.c
+++ b/arch/arm/mach-pxa/idp.c
@@ -167,7 +167,7 @@ static void __init idp_init(void)
platform_device_register(&smc91x_device);
//platform_device_register(&mst_audio_device);
- set_pxa_fb_info(&sharp_lm8v31);
+ pxa_set_fb_info(NULL, &sharp_lm8v31);
pxa_set_mci_info(&idp_mci_platform_data);
}
diff --git a/arch/arm/mach-pxa/include/mach/palmz72.h b/arch/arm/mach-pxa/include/mach/palmz72.h
index 2bbcf70dd93..0d4700a7961 100644
--- a/arch/arm/mach-pxa/include/mach/palmz72.h
+++ b/arch/arm/mach-pxa/include/mach/palmz72.h
@@ -44,6 +44,11 @@
#define GPIO_NR_PALMZ72_BT_POWER 17
#define GPIO_NR_PALMZ72_BT_RESET 83
+/* Camera */
+#define GPIO_NR_PALMZ72_CAM_PWDN 56
+#define GPIO_NR_PALMZ72_CAM_RESET 57
+#define GPIO_NR_PALMZ72_CAM_POWER 91
+
/** Initial values **/
/* Battery */
diff --git a/arch/arm/mach-pxa/include/mach/pxafb.h b/arch/arm/mach-pxa/include/mach/pxafb.h
index 160ec83f51a..01a45ac4811 100644
--- a/arch/arm/mach-pxa/include/mach/pxafb.h
+++ b/arch/arm/mach-pxa/include/mach/pxafb.h
@@ -154,8 +154,8 @@ struct pxafb_mach_info {
void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
void (*smart_update)(struct fb_info *);
};
-void set_pxa_fb_info(struct pxafb_mach_info *hard_pxa_fb_info);
-void set_pxa_fb_parent(struct device *parent_dev);
+
+void pxa_set_fb_info(struct device *, struct pxafb_mach_info *);
unsigned long pxafb_get_hsync_time(struct device *dev);
extern int pxafb_smart_queue(struct fb_info *info, uint16_t *cmds, int);
diff --git a/arch/arm/mach-pxa/include/mach/z2.h b/arch/arm/mach-pxa/include/mach/z2.h
index 8835c16bc82..7b0f71ef316 100644
--- a/arch/arm/mach-pxa/include/mach/z2.h
+++ b/arch/arm/mach-pxa/include/mach/z2.h
@@ -25,8 +25,7 @@
#define GPIO98_ZIPITZ2_LID_BUTTON 98
/* Libertas GSPI8686 WiFi */
-#define GPIO14_ZIPITZ2_WIFI_RESET 14
-#define GPIO15_ZIPITZ2_WIFI_POWER 15
+#define GPIO14_ZIPITZ2_WIFI_POWER 14
#define GPIO24_ZIPITZ2_WIFI_CS 24
#define GPIO36_ZIPITZ2_WIFI_IRQ 36
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 2693e3c3776..6251e3f5c62 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -137,9 +137,9 @@ static void __init pxa_init_low_gpio_irq(set_wake_t fn)
GEDR0 = 0x3;
for (irq = IRQ_GPIO0; irq <= IRQ_GPIO1; irq++) {
- set_irq_chip(irq, &pxa_low_gpio_chip);
- set_irq_chip_data(irq, irq_base(0));
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &pxa_low_gpio_chip,
+ handle_edge_irq);
+ irq_set_chip_data(irq, irq_base(0));
set_irq_flags(irq, IRQF_VALID);
}
@@ -165,9 +165,9 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
__raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i));
irq = PXA_IRQ(i);
- set_irq_chip(irq, &pxa_internal_irq_chip);
- set_irq_chip_data(irq, base);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &pxa_internal_irq_chip,
+ handle_level_irq);
+ irq_set_chip_data(irq, base);
set_irq_flags(irq, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-pxa/littleton.c b/arch/arm/mach-pxa/littleton.c
index 87c1ed9ccd2..e5e326d2cdc 100644
--- a/arch/arm/mach-pxa/littleton.c
+++ b/arch/arm/mach-pxa/littleton.c
@@ -185,7 +185,7 @@ static struct pxafb_mach_info littleton_lcd_info = {
static void littleton_init_lcd(void)
{
- set_pxa_fb_info(&littleton_lcd_info);
+ pxa_set_fb_info(NULL, &littleton_lcd_info);
}
#else
static inline void littleton_init_lcd(void) {};
diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c
index c9a3e775c2d..f5de541725b 100644
--- a/arch/arm/mach-pxa/lpd270.c
+++ b/arch/arm/mach-pxa/lpd270.c
@@ -149,12 +149,12 @@ static void __init lpd270_init_irq(void)
/* setup extra LogicPD PXA270 irqs */
for (irq = LPD270_IRQ(2); irq <= LPD270_IRQ(4); irq++) {
- set_irq_chip(irq, &lpd270_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &lpd270_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
- set_irq_chained_handler(IRQ_GPIO(0), lpd270_irq_handler);
- set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
+ irq_set_chained_handler(IRQ_GPIO(0), lpd270_irq_handler);
+ irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
}
@@ -480,7 +480,7 @@ static void __init lpd270_init(void)
pxa_set_ac97_info(NULL);
if (lpd270_lcd_to_use != NULL)
- set_pxa_fb_info(lpd270_lcd_to_use);
+ pxa_set_fb_info(NULL, lpd270_lcd_to_use);
pxa_set_ohci_info(&lpd270_ohci_platform_data);
}
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index dca20de306b..3ede978c83d 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -165,13 +165,13 @@ static void __init lubbock_init_irq(void)
/* setup extra lubbock irqs */
for (irq = LUBBOCK_IRQ(0); irq <= LUBBOCK_LAST_IRQ; irq++) {
- set_irq_chip(irq, &lubbock_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &lubbock_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
- set_irq_chained_handler(IRQ_GPIO(0), lubbock_irq_handler);
- set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
+ irq_set_chained_handler(IRQ_GPIO(0), lubbock_irq_handler);
+ irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
}
#ifdef CONFIG_PM
@@ -521,7 +521,7 @@ static void __init lubbock_init(void)
clk_add_alias("SA1111_CLK", NULL, "GPIO11_CLK", NULL);
pxa_set_udc_info(&udc_info);
- set_pxa_fb_info(&sharp_lm8v31);
+ pxa_set_fb_info(NULL, &sharp_lm8v31);
pxa_set_mci_info(&lubbock_mci_platform_data);
pxa_set_ficp_info(&lubbock_ficp_platform_data);
pxa_set_ac97_info(NULL);
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 5535991c4a3..a72993dde2b 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -757,7 +757,7 @@ static void __init magician_init(void)
gpio_direction_output(GPIO104_MAGICIAN_LCD_POWER_1, 0);
gpio_direction_output(GPIO105_MAGICIAN_LCD_POWER_2, 0);
gpio_direction_output(GPIO106_MAGICIAN_LCD_POWER_3, 0);
- set_pxa_fb_info(lcd_select ? &samsung_info : &toppoly_info);
+ pxa_set_fb_info(NULL, lcd_select ? &samsung_info : &toppoly_info);
} else
pr_err("LCD detection: CPLD mapping failed\n");
}
diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c
index f9542220595..95163baca29 100644
--- a/arch/arm/mach-pxa/mainstone.c
+++ b/arch/arm/mach-pxa/mainstone.c
@@ -166,8 +166,8 @@ static void __init mainstone_init_irq(void)
/* setup extra Mainstone irqs */
for(irq = MAINSTONE_IRQ(0); irq <= MAINSTONE_IRQ(15); irq++) {
- set_irq_chip(irq, &mainstone_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &mainstone_irq_chip,
+ handle_level_irq);
if (irq == MAINSTONE_IRQ(10) || irq == MAINSTONE_IRQ(14))
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE | IRQF_NOAUTOEN);
else
@@ -179,8 +179,8 @@ static void __init mainstone_init_irq(void)
MST_INTMSKENA = 0;
MST_INTSETCLR = 0;
- set_irq_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
- set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
+ irq_set_chained_handler(IRQ_GPIO(0), mainstone_irq_handler);
+ irq_set_irq_type(IRQ_GPIO(0), IRQ_TYPE_EDGE_FALLING);
}
#ifdef CONFIG_PM
@@ -592,7 +592,7 @@ static void __init mainstone_init(void)
else
mainstone_pxafb_info.modes = &toshiba_ltm035a776c_mode;
- set_pxa_fb_info(&mainstone_pxafb_info);
+ pxa_set_fb_info(NULL, &mainstone_pxafb_info);
mainstone_backlight_register();
pxa_set_mci_info(&mainstone_mci_platform_data);
diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c
index 78d98a8607e..dd13bb63259 100644
--- a/arch/arm/mach-pxa/mioa701.c
+++ b/arch/arm/mach-pxa/mioa701.c
@@ -795,7 +795,7 @@ static void __init mioa701_machine_init(void)
pxa_set_stuart_info(NULL);
mio_gpio_request(ARRAY_AND_SIZE(global_gpios));
bootstrap_init();
- set_pxa_fb_info(&mioa701_pxafb_info);
+ pxa_set_fb_info(NULL, &mioa701_pxafb_info);
pxa_set_mci_info(&mioa701_mci_info);
pxa_set_keypad_info(&mioa701_keypad_info);
pxa_set_udc_info(&mioa701_udc_info);
diff --git a/arch/arm/mach-pxa/palm27x.c b/arch/arm/mach-pxa/palm27x.c
index 72adb3ae2b4..325c245c0a0 100644
--- a/arch/arm/mach-pxa/palm27x.c
+++ b/arch/arm/mach-pxa/palm27x.c
@@ -1,8 +1,7 @@
/*
* Common code for Palm LD, T5, TX, Z72
*
- * Copyright (C) 2010
- * Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -158,7 +157,7 @@ void __init palm27x_lcd_init(int power, struct pxafb_mode_info *mode)
palm27x_lcd_screen.pxafb_lcd_power = palm27x_lcd_ctl;
}
- set_pxa_fb_info(&palm27x_lcd_screen);
+ pxa_set_fb_info(NULL, &palm27x_lcd_screen);
}
#endif
diff --git a/arch/arm/mach-pxa/palmtc.c b/arch/arm/mach-pxa/palmtc.c
index a09a2374697..fb06bd04727 100644
--- a/arch/arm/mach-pxa/palmtc.c
+++ b/arch/arm/mach-pxa/palmtc.c
@@ -507,7 +507,7 @@ static struct pxafb_mach_info palmtc_lcd_screen = {
static void __init palmtc_lcd_init(void)
{
- set_pxa_fb_info(&palmtc_lcd_screen);
+ pxa_set_fb_info(NULL, &palmtc_lcd_screen);
}
#else
static inline void palmtc_lcd_init(void) {}
diff --git a/arch/arm/mach-pxa/palmte2.c b/arch/arm/mach-pxa/palmte2.c
index 3f25014a136..726f5b98dcd 100644
--- a/arch/arm/mach-pxa/palmte2.c
+++ b/arch/arm/mach-pxa/palmte2.c
@@ -136,30 +136,14 @@ static struct platform_device palmte2_pxa_keys = {
/******************************************************************************
* Backlight
******************************************************************************/
+static struct gpio palmte_bl_gpios[] = {
+ { GPIO_NR_PALMTE2_BL_POWER, GPIOF_INIT_LOW, "Backlight power" },
+ { GPIO_NR_PALMTE2_LCD_POWER, GPIOF_INIT_LOW, "LCD power" },
+};
+
static int palmte2_backlight_init(struct device *dev)
{
- int ret;
-
- ret = gpio_request(GPIO_NR_PALMTE2_BL_POWER, "BL POWER");
- if (ret)
- goto err;
- ret = gpio_direction_output(GPIO_NR_PALMTE2_BL_POWER, 0);
- if (ret)
- goto err2;
- ret = gpio_request(GPIO_NR_PALMTE2_LCD_POWER, "LCD POWER");
- if (ret)
- goto err2;
- ret = gpio_direction_output(GPIO_NR_PALMTE2_LCD_POWER, 0);
- if (ret)
- goto err3;
-
- return 0;
-err3:
- gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
-err2:
- gpio_free(GPIO_NR_PALMTE2_BL_POWER);
-err:
- return ret;
+ return gpio_request_array(ARRAY_AND_SIZE(palmte_bl_gpios));
}
static int palmte2_backlight_notify(struct device *dev, int brightness)
@@ -171,8 +155,7 @@ static int palmte2_backlight_notify(struct device *dev, int brightness)
static void palmte2_backlight_exit(struct device *dev)
{
- gpio_free(GPIO_NR_PALMTE2_BL_POWER);
- gpio_free(GPIO_NR_PALMTE2_LCD_POWER);
+ gpio_free_array(ARRAY_AND_SIZE(palmte_bl_gpios));
}
static struct platform_pwm_backlight_data palmte2_backlight_data = {
@@ -363,7 +346,7 @@ static void __init palmte2_init(void)
pxa_set_btuart_info(NULL);
pxa_set_stuart_info(NULL);
- set_pxa_fb_info(&palmte2_lcd_screen);
+ pxa_set_fb_info(NULL, &palmte2_lcd_screen);
pxa_set_mci_info(&palmte2_mci_platform_data);
palmte2_udc_init();
pxa_set_ac97_info(&palmte2_ac97_pdata);
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c
index 3010193b081..3b8a4f37dbb 100644
--- a/arch/arm/mach-pxa/palmz72.c
+++ b/arch/arm/mach-pxa/palmz72.c
@@ -30,6 +30,7 @@
#include <linux/wm97xx.h>
#include <linux/power_supply.h>
#include <linux/usb/gpio_vbus.h>
+#include <linux/i2c-gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@@ -47,6 +48,9 @@
#include <mach/palm27x.h>
#include <mach/pm.h>
+#include <mach/camera.h>
+
+#include <media/soc_camera.h>
#include "generic.h"
#include "devices.h"
@@ -103,6 +107,28 @@ static unsigned long palmz72_pin_config[] __initdata = {
GPIO22_GPIO, /* LCD border color */
GPIO96_GPIO, /* lcd power */
+ /* PXA Camera */
+ GPIO81_CIF_DD_0,
+ GPIO48_CIF_DD_5,
+ GPIO50_CIF_DD_3,
+ GPIO51_CIF_DD_2,
+ GPIO52_CIF_DD_4,
+ GPIO53_CIF_MCLK,
+ GPIO54_CIF_PCLK,
+ GPIO55_CIF_DD_1,
+ GPIO84_CIF_FV,
+ GPIO85_CIF_LV,
+ GPIO93_CIF_DD_6,
+ GPIO108_CIF_DD_7,
+
+ GPIO56_GPIO, /* OV9640 Powerdown */
+ GPIO57_GPIO, /* OV9640 Reset */
+ GPIO91_GPIO, /* OV9640 Power */
+
+ /* I2C */
+ GPIO117_GPIO, /* I2C_SCL */
+ GPIO118_GPIO, /* I2C_SDA */
+
/* Misc. */
GPIO0_GPIO | WAKEUP_ON_LEVEL_HIGH, /* power detect */
GPIO88_GPIO, /* green led */
@@ -254,6 +280,106 @@ device_initcall(palmz72_pm_init);
#endif
/******************************************************************************
+ * SoC Camera
+ ******************************************************************************/
+#if defined(CONFIG_SOC_CAMERA_OV9640) || \
+ defined(CONFIG_SOC_CAMERA_OV9640_MODULE)
+static struct pxacamera_platform_data palmz72_pxacamera_platform_data = {
+ .flags = PXA_CAMERA_MASTER | PXA_CAMERA_DATAWIDTH_8 |
+ PXA_CAMERA_PCLK_EN | PXA_CAMERA_MCLK_EN,
+ .mclk_10khz = 2600,
+};
+
+/* Board I2C devices. */
+static struct i2c_board_info palmz72_i2c_device[] = {
+ {
+ I2C_BOARD_INFO("ov9640", 0x30),
+ }
+};
+
+static int palmz72_camera_power(struct device *dev, int power)
+{
+ gpio_set_value(GPIO_NR_PALMZ72_CAM_PWDN, !power);
+ mdelay(50);
+ return 0;
+}
+
+static int palmz72_camera_reset(struct device *dev)
+{
+ gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 1);
+ mdelay(50);
+ gpio_set_value(GPIO_NR_PALMZ72_CAM_RESET, 0);
+ mdelay(50);
+ return 0;
+}
+
+static struct soc_camera_link palmz72_iclink = {
+ .bus_id = 0, /* Match id in pxa27x_device_camera in device.c */
+ .board_info = &palmz72_i2c_device[0],
+ .i2c_adapter_id = 0,
+ .module_name = "ov96xx",
+ .power = &palmz72_camera_power,
+ .reset = &palmz72_camera_reset,
+ .flags = SOCAM_DATAWIDTH_8,
+};
+
+static struct i2c_gpio_platform_data palmz72_i2c_bus_data = {
+ .sda_pin = 118,
+ .scl_pin = 117,
+ .udelay = 10,
+ .timeout = 100,
+};
+
+static struct platform_device palmz72_i2c_bus_device = {
+ .name = "i2c-gpio",
+ .id = 0, /* we use this as a replacement for i2c-pxa */
+ .dev = {
+ .platform_data = &palmz72_i2c_bus_data,
+ }
+};
+
+static struct platform_device palmz72_camera = {
+ .name = "soc-camera-pdrv",
+ .id = -1,
+ .dev = {
+ .platform_data = &palmz72_iclink,
+ },
+};
+
+/* Here we request the camera GPIOs and configure them. We power up the camera
+ * module, deassert the reset pin, but put it into powerdown (low to no power
+ * consumption) mode. This allows us to later bring the module up fast. */
+static struct gpio palmz72_camera_gpios[] = {
+ { GPIO_NR_PALMZ72_CAM_POWER, GPIOF_INIT_HIGH,"Camera DVDD" },
+ { GPIO_NR_PALMZ72_CAM_RESET, GPIOF_INIT_LOW, "Camera RESET" },
+ { GPIO_NR_PALMZ72_CAM_PWDN, GPIOF_INIT_LOW, "Camera PWDN" },
+};
+
+static inline void __init palmz72_cam_gpio_init(void)
+{
+ int ret;
+
+ ret = gpio_request_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
+ if (!ret)
+ gpio_free_array(ARRAY_AND_SIZE(palmz72_camera_gpios));
+ else
+ printk(KERN_ERR "Camera GPIO init failed!\n");
+
+ return;
+}
+
+static void __init palmz72_camera_init(void)
+{
+ palmz72_cam_gpio_init();
+ pxa_set_camera_info(&palmz72_pxacamera_platform_data);
+ platform_device_register(&palmz72_i2c_bus_device);
+ platform_device_register(&palmz72_camera);
+}
+#else
+static inline void palmz72_camera_init(void) {}
+#endif
+
+/******************************************************************************
* Machine init
******************************************************************************/
static void __init palmz72_init(void)
@@ -276,6 +402,7 @@ static void __init palmz72_init(void)
palm27x_pmic_init();
palmz72_kpc_init();
palmz72_leds_init();
+ palmz72_camera_init();
}
MACHINE_START(PALMZ72, "Palm Zire72")
diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c
index 9dbf3ccd415..6d5b7e06212 100644
--- a/arch/arm/mach-pxa/pcm990-baseboard.c
+++ b/arch/arm/mach-pxa/pcm990-baseboard.c
@@ -281,16 +281,16 @@ static void __init pcm990_init_irq(void)
/* setup extra PCM990 irqs */
for (irq = PCM027_IRQ(0); irq <= PCM027_IRQ(3); irq++) {
- set_irq_chip(irq, &pcm990_irq_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &pcm990_irq_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
PCM990_INTMSKENA = 0x00; /* disable all Interrupts */
PCM990_INTSETCLR = 0xFF;
- set_irq_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
- set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
+ irq_set_chained_handler(PCM990_CTRL_INT_IRQ, pcm990_irq_handler);
+ irq_set_irq_type(PCM990_CTRL_INT_IRQ, PCM990_CTRL_INT_IRQ_EDGE);
}
static int pcm990_mci_init(struct device *dev, irq_handler_t mci_detect_int,
@@ -515,7 +515,7 @@ void __init pcm990_baseboard_init(void)
pcm990_init_irq();
#ifndef CONFIG_PCM990_DISPLAY_NONE
- set_pxa_fb_info(&pcm990_fbinfo);
+ pxa_set_fb_info(NULL, &pcm990_fbinfo);
#endif
platform_device_register(&pcm990_backlight_device);
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 35353af345d..16d14fd79b4 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -445,8 +445,7 @@ static void __init poodle_init(void)
if (ret)
pr_warning("poodle: Unable to register LoCoMo device\n");
- set_pxa_fb_parent(&poodle_locomo_device.dev);
- set_pxa_fb_info(&poodle_fb_info);
+ pxa_set_fb_info(&poodle_locomo_device.dev, &poodle_fb_info);
pxa_set_udc_info(&udc_info);
pxa_set_mci_info(&poodle_mci_platform_data);
pxa_set_ficp_info(&poodle_ficp_platform_data);
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index f374247b846..8dd10739115 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -362,8 +362,8 @@ static void __init pxa_init_ext_wakeup_irq(set_wake_t fn)
int irq;
for (irq = IRQ_WAKEUP0; irq <= IRQ_WAKEUP1; irq++) {
- set_irq_chip(irq, &pxa_ext_wakeup_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &pxa_ext_wakeup_chip,
+ handle_edge_irq);
set_irq_flags(irq, IRQF_VALID);
}
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c
index 47094188e02..cd1861351f7 100644
--- a/arch/arm/mach-pxa/raumfeld.c
+++ b/arch/arm/mach-pxa/raumfeld.c
@@ -597,7 +597,7 @@ static void __init raumfeld_lcd_init(void)
{
int ret;
- set_pxa_fb_info(&raumfeld_sharp_lcd_info);
+ pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info);
/* Earlier devices had the backlight regulator controlled
* via PWM, later versions use another controller for that */
diff --git a/arch/arm/mach-pxa/saar.c b/arch/arm/mach-pxa/saar.c
index eb83c89428e..fee97a93512 100644
--- a/arch/arm/mach-pxa/saar.c
+++ b/arch/arm/mach-pxa/saar.c
@@ -473,7 +473,7 @@ static struct pxafb_mach_info saar_lcd_info = {
static void __init saar_init_lcd(void)
{
- set_pxa_fb_info(&saar_lcd_info);
+ pxa_set_fb_info(NULL, &saar_lcd_info);
}
#else
static inline void saar_init_lcd(void) {}
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 38e2c0912b9..01c576963e9 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -724,7 +724,7 @@ static struct pxafb_mach_info spitz_pxafb_info = {
static void __init spitz_lcd_init(void)
{
- set_pxa_fb_info(&spitz_pxafb_info);
+ pxa_set_fb_info(NULL, &spitz_pxafb_info);
}
#else
static inline void spitz_lcd_init(void) {}
diff --git a/arch/arm/mach-pxa/tavorevb.c b/arch/arm/mach-pxa/tavorevb.c
index 9cecf8366db..53d4a472b69 100644
--- a/arch/arm/mach-pxa/tavorevb.c
+++ b/arch/arm/mach-pxa/tavorevb.c
@@ -466,7 +466,7 @@ static void __init tavorevb_init_lcd(void)
{
platform_device_register(&tavorevb_backlight_devices[0]);
platform_device_register(&tavorevb_backlight_devices[1]);
- set_pxa_fb_info(&tavorevb_lcd_info);
+ pxa_set_fb_info(NULL, &tavorevb_lcd_info);
}
#else
static inline void tavorevb_init_lcd(void) {}
diff --git a/arch/arm/mach-pxa/time.c b/arch/arm/mach-pxa/time.c
index e7f64d9b4f2..428da3ff33a 100644
--- a/arch/arm/mach-pxa/time.c
+++ b/arch/arm/mach-pxa/time.c
@@ -100,7 +100,6 @@ pxa_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *dev)
static struct clock_event_device ckevt_pxa_osmr0 = {
.name = "osmr0",
.features = CLOCK_EVT_FEAT_ONESHOT,
- .shift = 32,
.rating = 200,
.set_next_event = pxa_osmr0_set_next_event,
.set_mode = pxa_osmr0_set_mode,
@@ -135,8 +134,8 @@ static void __init pxa_timer_init(void)
init_sched_clock(&cd, pxa_update_sched_clock, 32, clock_tick_rate);
- ckevt_pxa_osmr0.mult =
- div_sc(clock_tick_rate, NSEC_PER_SEC, ckevt_pxa_osmr0.shift);
+ clocksource_calc_mult_shift(&cksrc_pxa_oscr0, clock_tick_rate, 4);
+ clockevents_calc_mult_shift(&ckevt_pxa_osmr0, clock_tick_rate, 4);
ckevt_pxa_osmr0.max_delta_ns =
clockevent_delta2ns(0x7fffffff, &ckevt_pxa_osmr0);
ckevt_pxa_osmr0.min_delta_ns =
diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c
index 5ad3807af33..5fa145778e7 100644
--- a/arch/arm/mach-pxa/tosa.c
+++ b/arch/arm/mach-pxa/tosa.c
@@ -35,6 +35,7 @@
#include <linux/spi/pxa2xx_spi.h>
#include <linux/input/matrix_keypad.h>
#include <linux/i2c/pxa-i2c.h>
+#include <linux/usb/gpio_vbus.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -240,12 +241,20 @@ static struct scoop_pcmcia_config tosa_pcmcia_config = {
/*
* USB Device Controller
*/
-static struct pxa2xx_udc_mach_info udc_info __initdata = {
+static struct gpio_vbus_mach_info tosa_udc_info = {
.gpio_pullup = TOSA_GPIO_USB_PULLUP,
.gpio_vbus = TOSA_GPIO_USB_IN,
.gpio_vbus_inverted = 1,
};
+static struct platform_device tosa_gpio_vbus = {
+ .name = "gpio-vbus",
+ .id = -1,
+ .dev = {
+ .platform_data = &tosa_udc_info,
+ },
+};
+
/*
* MMC/SD Device
*/
@@ -891,6 +900,7 @@ static struct platform_device *devices[] __initdata = {
&tosa_bt_device,
&sharpsl_rom_device,
&wm9712_device,
+ &tosa_gpio_vbus,
};
static void tosa_poweroff(void)
@@ -937,7 +947,6 @@ static void __init tosa_init(void)
dummy = gpiochip_reserve(TOSA_TC6393XB_GPIO_BASE, 16);
pxa_set_mci_info(&tosa_mci_platform_data);
- pxa_set_udc_info(&udc_info);
pxa_set_ficp_info(&tosa_ficp_platform_data);
pxa_set_i2c_info(NULL);
pxa_set_ac97_info(NULL);
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 857bb2e6348..b9cfbebdfe9 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -516,9 +516,9 @@ static void __init trizeps4_init(void)
pxa_set_stuart_info(NULL);
if (0) /* dont know how to determine LCD */
- set_pxa_fb_info(&sharp_lcd);
+ pxa_set_fb_info(NULL, &sharp_lcd);
else
- set_pxa_fb_info(&toshiba_lcd);
+ pxa_set_fb_info(NULL, &toshiba_lcd);
pxa_set_mci_info(&trizeps4_mci_platform_data);
#ifndef STATUS_LEDS_ON_STUART_PINS
diff --git a/arch/arm/mach-pxa/viper.c b/arch/arm/mach-pxa/viper.c
index 12279214c87..b523f119e0f 100644
--- a/arch/arm/mach-pxa/viper.c
+++ b/arch/arm/mach-pxa/viper.c
@@ -310,14 +310,14 @@ static void __init viper_init_irq(void)
/* setup ISA IRQs */
for (level = 0; level < ARRAY_SIZE(viper_isa_irqs); level++) {
isa_irq = viper_bit_to_irq(level);
- set_irq_chip(isa_irq, &viper_irq_chip);
- set_irq_handler(isa_irq, handle_edge_irq);
+ irq_set_chip_and_handler(isa_irq, &viper_irq_chip,
+ handle_edge_irq);
set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
}
- set_irq_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO),
+ irq_set_chained_handler(gpio_to_irq(VIPER_CPLD_GPIO),
viper_irq_handler);
- set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(gpio_to_irq(VIPER_CPLD_GPIO), IRQ_TYPE_EDGE_BOTH);
}
/* Flat Panel */
@@ -932,7 +932,7 @@ static void __init viper_init(void)
/* Wake-up serial console */
viper_init_serial_gpio();
- set_pxa_fb_info(&fb_info);
+ pxa_set_fb_info(NULL, &fb_info);
/* v1 hardware cannot use the datacs line */
version = viper_hw_version();
diff --git a/arch/arm/mach-pxa/vpac270.c b/arch/arm/mach-pxa/vpac270.c
index e709fd45926..f71d377c864 100644
--- a/arch/arm/mach-pxa/vpac270.c
+++ b/arch/arm/mach-pxa/vpac270.c
@@ -572,7 +572,7 @@ static void __init vpac270_lcd_init(void)
}
vpac270_lcd_screen.pxafb_lcd_power = vpac270_lcd_power;
- set_pxa_fb_info(&vpac270_lcd_screen);
+ pxa_set_fb_info(NULL, &vpac270_lcd_screen);
return;
err2:
diff --git a/arch/arm/mach-pxa/z2.c b/arch/arm/mach-pxa/z2.c
index aaf883754ef..fbe9e02e2f9 100644
--- a/arch/arm/mach-pxa/z2.c
+++ b/arch/arm/mach-pxa/z2.c
@@ -91,13 +91,13 @@ static unsigned long z2_pin_config[] = {
GPIO47_STUART_TXD,
/* Keypad */
- GPIO100_KP_MKIN_0 | WAKEUP_ON_LEVEL_HIGH,
- GPIO101_KP_MKIN_1 | WAKEUP_ON_LEVEL_HIGH,
- GPIO102_KP_MKIN_2 | WAKEUP_ON_LEVEL_HIGH,
- GPIO34_KP_MKIN_3 | WAKEUP_ON_LEVEL_HIGH,
- GPIO38_KP_MKIN_4 | WAKEUP_ON_LEVEL_HIGH,
- GPIO16_KP_MKIN_5 | WAKEUP_ON_LEVEL_HIGH,
- GPIO17_KP_MKIN_6 | WAKEUP_ON_LEVEL_HIGH,
+ GPIO100_KP_MKIN_0,
+ GPIO101_KP_MKIN_1,
+ GPIO102_KP_MKIN_2,
+ GPIO34_KP_MKIN_3,
+ GPIO38_KP_MKIN_4,
+ GPIO16_KP_MKIN_5,
+ GPIO17_KP_MKIN_6,
GPIO103_KP_MKOUT_0,
GPIO104_KP_MKOUT_1,
GPIO105_KP_MKOUT_2,
@@ -138,8 +138,7 @@ static unsigned long z2_pin_config[] = {
GPIO1_GPIO, /* Power button */
GPIO37_GPIO, /* Headphone detect */
GPIO98_GPIO, /* Lid switch */
- GPIO14_GPIO, /* WiFi Reset */
- GPIO15_GPIO, /* WiFi Power */
+ GPIO14_GPIO, /* WiFi Power */
GPIO24_GPIO, /* WiFi CS */
GPIO36_GPIO, /* WiFi IRQ */
GPIO88_GPIO, /* LCD CS */
@@ -204,7 +203,7 @@ static struct platform_pwm_backlight_data z2_backlight_data[] = {
/* Keypad Backlight */
.pwm_id = 1,
.max_brightness = 1023,
- .dft_brightness = 512,
+ .dft_brightness = 0,
.pwm_period_ns = 1260320,
},
[1] = {
@@ -271,7 +270,7 @@ static struct pxafb_mach_info z2_lcd_screen = {
static void __init z2_lcd_init(void)
{
- set_pxa_fb_info(&z2_lcd_screen);
+ pxa_set_fb_info(NULL, &z2_lcd_screen);
}
#else
static inline void z2_lcd_init(void) {}
@@ -309,12 +308,12 @@ struct gpio_led z2_gpio_leds[] = {
.active_low = 1,
}, {
.name = "z2:green:charged",
- .default_trigger = "none",
+ .default_trigger = "mmc0",
.gpio = GPIO85_ZIPITZ2_LED_CHARGED,
.active_low = 1,
}, {
.name = "z2:amber:charging",
- .default_trigger = "none",
+ .default_trigger = "Z2-charging-or-full",
.gpio = GPIO83_ZIPITZ2_LED_CHARGING,
.active_low = 1,
},
@@ -427,8 +426,22 @@ static inline void z2_mkp_init(void) {}
******************************************************************************/
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
static struct gpio_keys_button z2_pxa_buttons[] = {
- {KEY_POWER, GPIO1_ZIPITZ2_POWER_BUTTON, 0, "Power Button" },
- {KEY_CLOSE, GPIO98_ZIPITZ2_LID_BUTTON, 0, "Lid Button" },
+ {
+ .code = KEY_POWER,
+ .gpio = GPIO1_ZIPITZ2_POWER_BUTTON,
+ .active_low = 0,
+ .desc = "Power Button",
+ .wakeup = 1,
+ .type = EV_KEY,
+ },
+ {
+ .code = SW_LID,
+ .gpio = GPIO98_ZIPITZ2_LID_BUTTON,
+ .active_low = 1,
+ .desc = "Lid Switch",
+ .wakeup = 0,
+ .type = EV_SW,
+ },
};
static struct gpio_keys_platform_data z2_pxa_keys_data = {
@@ -461,9 +474,9 @@ static struct z2_battery_info batt_chip_info = {
.batt_I2C_addr = 0x55,
.batt_I2C_reg = 2,
.charge_gpio = GPIO0_ZIPITZ2_AC_DETECT,
- .min_voltage = 2400000,
- .max_voltage = 3700000,
- .batt_div = 69,
+ .min_voltage = 3475000,
+ .max_voltage = 4190000,
+ .batt_div = 59,
.batt_mult = 1000000,
.batt_tech = POWER_SUPPLY_TECHNOLOGY_LION,
.batt_name = "Z2",
@@ -497,26 +510,16 @@ static int z2_lbs_spi_setup(struct spi_device *spi)
{
int ret = 0;
- ret = gpio_request(GPIO15_ZIPITZ2_WIFI_POWER, "WiFi Power");
+ ret = gpio_request(GPIO14_ZIPITZ2_WIFI_POWER, "WiFi Power");
if (ret)
goto err;
- ret = gpio_direction_output(GPIO15_ZIPITZ2_WIFI_POWER, 1);
+ ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_POWER, 1);
if (ret)
goto err2;
- ret = gpio_request(GPIO14_ZIPITZ2_WIFI_RESET, "WiFi Reset");
- if (ret)
- goto err2;
-
- ret = gpio_direction_output(GPIO14_ZIPITZ2_WIFI_RESET, 0);
- if (ret)
- goto err3;
-
- /* Reset the card */
+ /* Wait until card is powered on */
mdelay(180);
- gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 1);
- mdelay(20);
spi->bits_per_word = 16;
spi->mode = SPI_MODE_2,
@@ -525,22 +528,18 @@ static int z2_lbs_spi_setup(struct spi_device *spi)
return 0;
-err3:
- gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
err2:
- gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
+ gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
err:
return ret;
};
static int z2_lbs_spi_teardown(struct spi_device *spi)
{
- gpio_set_value(GPIO14_ZIPITZ2_WIFI_RESET, 0);
- gpio_set_value(GPIO15_ZIPITZ2_WIFI_POWER, 0);
- gpio_free(GPIO14_ZIPITZ2_WIFI_RESET);
- gpio_free(GPIO15_ZIPITZ2_WIFI_POWER);
- return 0;
+ gpio_set_value(GPIO14_ZIPITZ2_WIFI_POWER, 0);
+ gpio_free(GPIO14_ZIPITZ2_WIFI_POWER);
+ return 0;
};
static struct pxa2xx_spi_chip z2_lbs_chip_info = {
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index 730f51e57c1..00363c7ac18 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -136,22 +136,23 @@ static void __init zeus_init_irq(void)
/* Peripheral IRQs. It would be nice to move those inside driver
configuration, but it is not supported at the moment. */
- set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING);
- set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING);
- set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING);
- set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO), IRQ_TYPE_EDGE_FALLING);
- set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_AC97_GPIO), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_WAKEUP_GPIO), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_PTT_GPIO), IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_EXTGPIO_GPIO),
+ IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(gpio_to_irq(ZEUS_CAN_GPIO), IRQ_TYPE_EDGE_FALLING);
/* Setup ISA IRQs */
for (level = 0; level < ARRAY_SIZE(zeus_isa_irqs); level++) {
isa_irq = zeus_bit_to_irq(level);
- set_irq_chip(isa_irq, &zeus_irq_chip);
- set_irq_handler(isa_irq, handle_edge_irq);
+ irq_set_chip_and_handler(isa_irq, &zeus_irq_chip,
+ handle_edge_irq);
set_irq_flags(isa_irq, IRQF_VALID | IRQF_PROBE);
}
- set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING);
- set_irq_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler);
+ irq_set_irq_type(gpio_to_irq(ZEUS_ISA_GPIO), IRQ_TYPE_EDGE_RISING);
+ irq_set_chained_handler(gpio_to_irq(ZEUS_ISA_GPIO), zeus_irq_handler);
}
@@ -846,7 +847,7 @@ static void __init zeus_init(void)
if (zeus_setup_fb_gpios())
pr_err("Failed to setup fb gpios\n");
else
- set_pxa_fb_info(&zeus_fb_info);
+ pxa_set_fb_info(NULL, &zeus_fb_info);
pxa_set_mci_info(&zeus_mci_platform_data);
pxa_set_udc_info(&zeus_udc_info);
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index a4c784aab76..5821185f77a 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -208,7 +208,7 @@ static void __init zylonite_init_lcd(void)
platform_device_register(&zylonite_backlight_device);
if (lcd_id & 0x20) {
- set_pxa_fb_info(&zylonite_sharp_lcd_info);
+ pxa_set_fb_info(NULL, &zylonite_sharp_lcd_info);
return;
}
@@ -220,7 +220,7 @@ static void __init zylonite_init_lcd(void)
else
zylonite_toshiba_lcd_info.modes = &toshiba_ltm04c380k_mode;
- set_pxa_fb_info(&zylonite_toshiba_lcd_info);
+ pxa_set_fb_info(NULL, &zylonite_toshiba_lcd_info);
}
#else
static inline void zylonite_init_lcd(void) {}
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 2ecc1d94284..10e75faba4c 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -348,7 +348,7 @@ static void __init gic_init_irq(void)
#ifndef CONFIG_REALVIEW_EB_ARM11MP_REVB
/* board GIC, secondary */
- gic_init(1, 64, __io_address(REALVIEW_EB_GIC_DIST_BASE),
+ gic_init(1, 96, __io_address(REALVIEW_EB_GIC_DIST_BASE),
__io_address(REALVIEW_EB_GIC_CPU_BASE));
gic_cascade_irq(1, IRQ_EB11MP_EB_IRQ1);
#endif
diff --git a/arch/arm/mach-rpc/irq.c b/arch/arm/mach-rpc/irq.c
index d29cd9b737f..2e1b5309fba 100644
--- a/arch/arm/mach-rpc/irq.c
+++ b/arch/arm/mach-rpc/irq.c
@@ -133,25 +133,25 @@ void __init rpc_init_irq(void)
switch (irq) {
case 0 ... 7:
- set_irq_chip(irq, &iomd_a_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &iomd_a_chip,
+ handle_level_irq);
set_irq_flags(irq, flags);
break;
case 8 ... 15:
- set_irq_chip(irq, &iomd_b_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &iomd_b_chip,
+ handle_level_irq);
set_irq_flags(irq, flags);
break;
case 16 ... 21:
- set_irq_chip(irq, &iomd_dma_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &iomd_dma_chip,
+ handle_level_irq);
set_irq_flags(irq, flags);
break;
case 64 ... 71:
- set_irq_chip(irq, &iomd_fiq_chip);
+ irq_set_chip(irq, &iomd_fiq_chip);
set_irq_flags(irq, IRQF_VALID);
break;
}
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 606cb6b1cc4..bc53d2d16d1 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -147,15 +147,15 @@ static __init int bast_irq_init(void)
__raw_writeb(0x0, BAST_VA_PC104_IRQMASK);
- set_irq_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
+ irq_set_chained_handler(IRQ_ISA, bast_irq_pc104_demux);
/* register our IRQs */
for (i = 0; i < 4; i++) {
unsigned int irqno = bast_pc104_irqs[i];
- set_irq_chip(irqno, &bast_pc104_chip);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &bast_pc104_chip,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-s3c2412/irq.c b/arch/arm/mach-s3c2412/irq.c
index eddb52ba5b6..f3355d2ec63 100644
--- a/arch/arm/mach-s3c2412/irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -175,18 +175,18 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
unsigned int irqno;
for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
- set_irq_chip(irqno, &s3c2412_irq_eint0t4);
- set_irq_handler(irqno, handle_edge_irq);
+ irq_set_chip_and_handler(irqno, &s3c2412_irq_eint0t4,
+ handle_edge_irq);
set_irq_flags(irqno, IRQF_VALID);
}
/* add demux support for CF/SDI */
- set_irq_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
+ irq_set_chained_handler(IRQ_S3C2412_CFSDI, s3c2412_irq_demux_cfsdi);
for (irqno = IRQ_S3C2412_SDI; irqno <= IRQ_S3C2412_CF; irqno++) {
- set_irq_chip(irqno, &s3c2412_irq_cfsdi);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &s3c2412_irq_cfsdi,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
@@ -195,7 +195,7 @@ static int s3c2412_irq_add(struct sys_device *sysdev)
s3c2412_irq_rtc_chip = s3c_irq_chip;
s3c2412_irq_rtc_chip.irq_set_wake = s3c2412_irq_rtc_wake;
- set_irq_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
+ irq_set_chip(IRQ_RTC, &s3c2412_irq_rtc_chip);
return 0;
}
diff --git a/arch/arm/mach-s3c2416/irq.c b/arch/arm/mach-s3c2416/irq.c
index 680fe386aca..77b38f2381c 100644
--- a/arch/arm/mach-s3c2416/irq.c
+++ b/arch/arm/mach-s3c2416/irq.c
@@ -202,13 +202,11 @@ static int __init s3c2416_add_sub(unsigned int base,
{
unsigned int irqno;
- set_irq_chip(base, &s3c_irq_level_chip);
- set_irq_handler(base, handle_level_irq);
- set_irq_chained_handler(base, demux);
+ irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+ irq_set_chained_handler(base, demux);
for (irqno = start; irqno <= end; irqno++) {
- set_irq_chip(irqno, chip);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, chip, handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
diff --git a/arch/arm/mach-s3c2440/irq.c b/arch/arm/mach-s3c2440/irq.c
index acad4428bef..eb1cc0f0705 100644
--- a/arch/arm/mach-s3c2440/irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -100,13 +100,13 @@ static int s3c2440_irq_add(struct sys_device *sysdev)
/* add new chained handler for wdt, ac7 */
- set_irq_chip(IRQ_WDT, &s3c_irq_level_chip);
- set_irq_handler(IRQ_WDT, handle_level_irq);
- set_irq_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
+ irq_set_chip_and_handler(IRQ_WDT, &s3c_irq_level_chip,
+ handle_level_irq);
+ irq_set_chained_handler(IRQ_WDT, s3c_irq_demux_wdtac97);
for (irqno = IRQ_S3C2440_WDT; irqno <= IRQ_S3C2440_AC97; irqno++) {
- set_irq_chip(irqno, &s3c_irq_wdtac97);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_wdtac97,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
diff --git a/arch/arm/mach-s3c2440/s3c244x-irq.c b/arch/arm/mach-s3c2440/s3c244x-irq.c
index 83daf4ece76..de07c2feaa3 100644
--- a/arch/arm/mach-s3c2440/s3c244x-irq.c
+++ b/arch/arm/mach-s3c2440/s3c244x-irq.c
@@ -95,19 +95,19 @@ static int s3c244x_irq_add(struct sys_device *sysdev)
{
unsigned int irqno;
- set_irq_chip(IRQ_NFCON, &s3c_irq_level_chip);
- set_irq_handler(IRQ_NFCON, handle_level_irq);
+ irq_set_chip_and_handler(IRQ_NFCON, &s3c_irq_level_chip,
+ handle_level_irq);
set_irq_flags(IRQ_NFCON, IRQF_VALID);
/* add chained handler for camera */
- set_irq_chip(IRQ_CAM, &s3c_irq_level_chip);
- set_irq_handler(IRQ_CAM, handle_level_irq);
- set_irq_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
+ irq_set_chip_and_handler(IRQ_CAM, &s3c_irq_level_chip,
+ handle_level_irq);
+ irq_set_chained_handler(IRQ_CAM, s3c_irq_demux_cam);
for (irqno = IRQ_S3C2440_CAM_C; irqno <= IRQ_S3C2440_CAM_P; irqno++) {
- set_irq_chip(irqno, &s3c_irq_cam);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_cam,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
index c7820f9c135..83ecb1173fb 100644
--- a/arch/arm/mach-s3c2443/irq.c
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -230,13 +230,11 @@ static int __init s3c2443_add_sub(unsigned int base,
{
unsigned int irqno;
- set_irq_chip(base, &s3c_irq_level_chip);
- set_irq_handler(base, handle_level_irq);
- set_irq_chained_handler(base, demux);
+ irq_set_chip_and_handler(base, &s3c_irq_level_chip, handle_level_irq);
+ irq_set_chained_handler(base, demux);
for (irqno = start; irqno <= end; irqno++) {
- set_irq_chip(irqno, chip);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, chip, handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c
index 2ead8189da7..4d203be1f4c 100644
--- a/arch/arm/mach-s3c64xx/irq-eint.c
+++ b/arch/arm/mach-s3c64xx/irq-eint.c
@@ -197,16 +197,15 @@ static int __init s3c64xx_init_irq_eint(void)
int irq;
for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) {
- set_irq_chip(irq, &s3c_irq_eint);
- set_irq_chip_data(irq, (void *)eint_irq_to_bit(irq));
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &s3c_irq_eint, handle_level_irq);
+ irq_set_chip_data(irq, (void *)eint_irq_to_bit(irq));
set_irq_flags(irq, IRQF_VALID);
}
- set_irq_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
- set_irq_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
- set_irq_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
- set_irq_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
+ irq_set_chained_handler(IRQ_EINT0_3, s3c_irq_demux_eint0_3);
+ irq_set_chained_handler(IRQ_EINT4_11, s3c_irq_demux_eint4_11);
+ irq_set_chained_handler(IRQ_EINT12_19, s3c_irq_demux_eint12_19);
+ irq_set_chained_handler(IRQ_EINT20_27, s3c_irq_demux_eint20_27);
return 0;
}
diff --git a/arch/arm/mach-s5p64x0/cpu.c b/arch/arm/mach-s5p64x0/cpu.c
index b8d02eb4cf3..a5c00952ea3 100644
--- a/arch/arm/mach-s5p64x0/cpu.c
+++ b/arch/arm/mach-s5p64x0/cpu.c
@@ -119,7 +119,7 @@ void __init s5p6450_map_io(void)
s3c_adc_setname("s3c64xx-adc");
iotable_init(s5p64x0_iodesc, ARRAY_SIZE(s5p64x0_iodesc));
- iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6440_iodesc));
+ iotable_init(s5p6450_iodesc, ARRAY_SIZE(s5p6450_iodesc));
}
/*
diff --git a/arch/arm/mach-s5pv210/include/mach/irqs.h b/arch/arm/mach-s5pv210/include/mach/irqs.h
index 26710b35ef8..b9f9ec33384 100644
--- a/arch/arm/mach-s5pv210/include/mach/irqs.h
+++ b/arch/arm/mach-s5pv210/include/mach/irqs.h
@@ -99,9 +99,9 @@
#define IRQ_TC IRQ_PENDN
#define IRQ_KEYPAD S5P_IRQ_VIC2(25)
#define IRQ_CG S5P_IRQ_VIC2(26)
-#define IRQ_SEC S5P_IRQ_VIC2(27)
-#define IRQ_SECRX S5P_IRQ_VIC2(28)
-#define IRQ_SECTX S5P_IRQ_VIC2(29)
+#define IRQ_SSS_INT S5P_IRQ_VIC2(27)
+#define IRQ_SSS_HASH S5P_IRQ_VIC2(28)
+#define IRQ_PCM2 S5P_IRQ_VIC2(29)
#define IRQ_SDMIRQ S5P_IRQ_VIC2(30)
#define IRQ_SDMFIQ S5P_IRQ_VIC2(31)
diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c
index bc08ac42e7c..c6a9e86c2d5 100644
--- a/arch/arm/mach-s5pv210/mach-smdkv210.c
+++ b/arch/arm/mach-s5pv210/mach-smdkv210.c
@@ -44,7 +44,6 @@
#include <plat/keypad.h>
#include <plat/pm.h>
#include <plat/fb.h>
-#include <plat/gpio-cfg.h>
#include <plat/s5p-time.h>
/* Following are default values for UCON, ULCON and UFCON UART registers */
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 98d780608c7..7f3da4b11ec 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -96,7 +96,7 @@ static struct resource cerf_flash_resource = {
static void __init cerf_init_irq(void)
{
sa1100_init_irq();
- set_irq_type(CERF_ETH_IRQ, IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(CERF_ETH_IRQ, IRQ_TYPE_EDGE_RISING);
}
static struct map_desc cerf_io_desc[] __initdata = {
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 3d85dfad9c1..423ddb3d65e 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -323,28 +323,28 @@ void __init sa1100_init_irq(void)
ICCR = 1;
for (irq = 0; irq <= 10; irq++) {
- set_irq_chip(irq, &sa1100_low_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip,
+ handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
for (irq = 12; irq <= 31; irq++) {
- set_irq_chip(irq, &sa1100_normal_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &sa1100_normal_chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
for (irq = 32; irq <= 48; irq++) {
- set_irq_chip(irq, &sa1100_high_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip,
+ handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
/*
* Install handler for GPIO 11-27 edge detect interrupts
*/
- set_irq_chip(IRQ_GPIO11_27, &sa1100_normal_chip);
- set_irq_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
+ irq_set_chip(IRQ_GPIO11_27, &sa1100_normal_chip);
+ irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
sa1100_init_gpio();
}
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
index 4aad01f7366..b4fa53a1427 100644
--- a/arch/arm/mach-sa1100/neponset.c
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -145,8 +145,8 @@ static int __devinit neponset_probe(struct platform_device *dev)
/*
* Install handler for GPIO25.
*/
- set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING);
- set_irq_chained_handler(IRQ_GPIO25, neponset_irq_handler);
+ irq_set_irq_type(IRQ_GPIO25, IRQ_TYPE_EDGE_RISING);
+ irq_set_chained_handler(IRQ_GPIO25, neponset_irq_handler);
/*
* We would set IRQ_GPIO25 to be a wake-up IRQ, but
@@ -161,9 +161,9 @@ static int __devinit neponset_probe(struct platform_device *dev)
* Setup other Neponset IRQs. SA1111 will be done by the
* generic SA1111 code.
*/
- set_irq_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq);
+ irq_set_handler(IRQ_NEPONSET_SMC9196, handle_simple_irq);
set_irq_flags(IRQ_NEPONSET_SMC9196, IRQF_VALID | IRQF_PROBE);
- set_irq_handler(IRQ_NEPONSET_USAR, handle_simple_irq);
+ irq_set_handler(IRQ_NEPONSET_USAR, handle_simple_irq);
set_irq_flags(IRQ_NEPONSET_USAR, IRQF_VALID | IRQF_PROBE);
/*
diff --git a/arch/arm/mach-sa1100/pleb.c b/arch/arm/mach-sa1100/pleb.c
index 42b80400c10..65161f2bea2 100644
--- a/arch/arm/mach-sa1100/pleb.c
+++ b/arch/arm/mach-sa1100/pleb.c
@@ -142,7 +142,7 @@ static void __init pleb_map_io(void)
GPDR &= ~GPIO_ETH0_IRQ;
- set_irq_type(GPIO_ETH0_IRQ, IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(GPIO_ETH0_IRQ, IRQ_TYPE_EDGE_FALLING);
}
MACHINE_START(PLEB, "PLEB")
diff --git a/arch/arm/mach-shark/irq.c b/arch/arm/mach-shark/irq.c
index 831fc66dfa4..5dce13e429f 100644
--- a/arch/arm/mach-shark/irq.c
+++ b/arch/arm/mach-shark/irq.c
@@ -80,8 +80,7 @@ void __init shark_init_irq(void)
int irq;
for (irq = 0; irq < NR_IRQS; irq++) {
- set_irq_chip(irq, &fb_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &fb_chip, handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index a94f29da5d3..783b66fa95f 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -24,9 +24,9 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
@@ -312,7 +312,7 @@ static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0xe6850000,
- .end = 0xe68501ff,
+ .end = 0xe68500ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -345,7 +345,7 @@ static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0xe6860000,
- .end = 0xe68601ff,
+ .end = 0xe68600ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -1255,7 +1255,7 @@ static void __init ap4evb_init(void)
gpio_request(GPIO_FN_KEYIN4, NULL);
/* enable TouchScreen */
- set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ28, IRQ_TYPE_LEVEL_LOW);
tsc_device.irq = IRQ28;
i2c_register_board_info(1, &tsc_device, 1);
@@ -1311,7 +1311,7 @@ static void __init ap4evb_init(void)
lcdc_info.ch[0].lcd_size_cfg.height = 91;
/* enable TouchScreen */
- set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
tsc_device.irq = IRQ7;
i2c_register_board_info(0, &tsc_device, 1);
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index dee3e9231fb..c87a7b7c583 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -31,7 +31,7 @@
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
#include <linux/mmc/host.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/gpio.h>
#include <mach/sh7377.h>
#include <mach/common.h>
@@ -205,7 +205,7 @@ static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0xe6d50000,
- .end = 0xe6d501ff,
+ .end = 0xe6d50nff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -232,7 +232,7 @@ static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0xe6d60000,
- .end = 0xe6d601ff,
+ .end = 0xe6d600ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 49bc0748217..8184d4d4f23 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -32,10 +32,10 @@
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/leds.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
@@ -690,7 +690,7 @@ static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0xe6850000,
- .end = 0xe68501ff,
+ .end = 0xe68500ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -725,7 +725,7 @@ static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0xe6860000,
- .end = 0xe68601ff,
+ .end = 0xe68600ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -768,7 +768,7 @@ static struct resource sdhi2_resources[] = {
[0] = {
.name = "SDHI2",
.start = 0xe6870000,
- .end = 0xe68701ff,
+ .end = 0xe68700ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -1124,15 +1124,15 @@ static void __init mackerel_init(void)
/* enable Keypad */
gpio_request(GPIO_FN_IRQ9_42, NULL);
- set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_irq_type(IRQ9, IRQ_TYPE_LEVEL_HIGH);
/* enable Touchscreen */
gpio_request(GPIO_FN_IRQ7_40, NULL);
- set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ7, IRQ_TYPE_LEVEL_LOW);
/* enable Accelerometer */
gpio_request(GPIO_FN_IRQ21, NULL);
- set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_irq_type(IRQ21, IRQ_TYPE_LEVEL_HIGH);
/* enable SDHI0 */
gpio_request(GPIO_FN_SDHICD0, NULL);
diff --git a/arch/arm/mach-shmobile/intc-sh7367.c b/arch/arm/mach-shmobile/intc-sh7367.c
index 2fe9704d5ea..cc442d198cd 100644
--- a/arch/arm/mach-shmobile/intc-sh7367.c
+++ b/arch/arm/mach-shmobile/intc-sh7367.c
@@ -421,7 +421,7 @@ static struct intc_desc intcs_desc __initdata = {
static void intcs_demux(unsigned int irq, struct irq_desc *desc)
{
- void __iomem *reg = (void *)get_irq_data(irq);
+ void __iomem *reg = (void *)irq_get_handler_data(irq);
unsigned int evtcodeas = ioread32(reg);
generic_handle_irq(intcs_evt2irq(evtcodeas));
@@ -435,6 +435,6 @@ void __init sh7367_init_irq(void)
register_intc_controller(&intcs_desc);
/* demux using INTEVTSA */
- set_irq_data(evt2irq(0xf80), (void *)intevtsa);
- set_irq_chained_handler(evt2irq(0xf80), intcs_demux);
+ irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
+ irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
}
diff --git a/arch/arm/mach-shmobile/intc-sh7372.c b/arch/arm/mach-shmobile/intc-sh7372.c
index ca5f9d17b39..7a4960f9c1e 100644
--- a/arch/arm/mach-shmobile/intc-sh7372.c
+++ b/arch/arm/mach-shmobile/intc-sh7372.c
@@ -601,7 +601,7 @@ static struct intc_desc intcs_desc __initdata = {
static void intcs_demux(unsigned int irq, struct irq_desc *desc)
{
- void __iomem *reg = (void *)get_irq_data(irq);
+ void __iomem *reg = (void *)irq_get_handler_data(irq);
unsigned int evtcodeas = ioread32(reg);
generic_handle_irq(intcs_evt2irq(evtcodeas));
@@ -615,6 +615,6 @@ void __init sh7372_init_irq(void)
register_intc_controller(&intcs_desc);
/* demux using INTEVTSA */
- set_irq_data(evt2irq(0xf80), (void *)intevtsa);
- set_irq_chained_handler(evt2irq(0xf80), intcs_demux);
+ irq_set_handler_data(evt2irq(0xf80), (void *)intevtsa);
+ irq_set_chained_handler(evt2irq(0xf80), intcs_demux);
}
diff --git a/arch/arm/mach-shmobile/intc-sh7377.c b/arch/arm/mach-shmobile/intc-sh7377.c
index dd568382cc9..fe45154ce66 100644
--- a/arch/arm/mach-shmobile/intc-sh7377.c
+++ b/arch/arm/mach-shmobile/intc-sh7377.c
@@ -626,7 +626,7 @@ static struct intc_desc intcs_desc __initdata = {
static void intcs_demux(unsigned int irq, struct irq_desc *desc)
{
- void __iomem *reg = (void *)get_irq_data(irq);
+ void __iomem *reg = (void *)irq_get_handler_data(irq);
unsigned int evtcodeas = ioread32(reg);
generic_handle_irq(intcs_evt2irq(evtcodeas));
@@ -641,6 +641,6 @@ void __init sh7377_init_irq(void)
register_intc_controller(&intcs_desc);
/* demux using INTEVTSA */
- set_irq_data(evt2irq(INTCS_INTVECT), (void *)intevtsa);
- set_irq_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux);
+ irq_set_handler_data(evt2irq(INTCS_INTVECT), (void *)intevtsa);
+ irq_set_chained_handler(evt2irq(INTCS_INTVECT), intcs_demux);
}
diff --git a/arch/arm/mach-tcc8k/irq.c b/arch/arm/mach-tcc8k/irq.c
index aa9231f4fc6..209fa5c65d4 100644
--- a/arch/arm/mach-tcc8k/irq.c
+++ b/arch/arm/mach-tcc8k/irq.c
@@ -102,10 +102,10 @@ void __init tcc8k_init_irq(void)
for (irqno = 0; irqno < NR_IRQS; irqno++) {
if (irqno < 32)
- set_irq_chip(irqno, &tcc8000_irq_chip0);
+ irq_set_chip(irqno, &tcc8000_irq_chip0);
else
- set_irq_chip(irqno, &tcc8000_irq_chip1);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip(irqno, &tcc8000_irq_chip1);
+ irq_set_handler(irqno, handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
index 12090a2cf3e..76a3f654220 100644
--- a/arch/arm/mach-tegra/gpio.c
+++ b/arch/arm/mach-tegra/gpio.c
@@ -208,9 +208,9 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
- __set_irq_handler_unlocked(d->irq, handle_level_irq);
+ __irq_set_handler_locked(d->irq, handle_level_irq);
else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
- __set_irq_handler_unlocked(d->irq, handle_edge_irq);
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
return 0;
}
@@ -224,7 +224,7 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
desc->irq_data.chip->irq_ack(&desc->irq_data);
- bank = get_irq_data(irq);
+ bank = irq_get_handler_data(irq);
for (port = 0; port < 4; port++) {
int gpio = tegra_gpio_compose(bank->bank, port, 0);
@@ -275,13 +275,6 @@ void tegra_gpio_resume(void)
}
local_irq_restore(flags);
-
- for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
- struct irq_desc *desc = irq_to_desc(i);
- if (!desc || (desc->status & IRQ_WAKEUP))
- continue;
- enable_irq(i);
- }
}
void tegra_gpio_suspend(void)
@@ -289,18 +282,6 @@ void tegra_gpio_suspend(void)
unsigned long flags;
int b, p, i;
- for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
- struct irq_desc *desc = irq_to_desc(i);
- if (!desc)
- continue;
- if (desc->status & IRQ_WAKEUP) {
- int gpio = i - INT_GPIO_BASE;
- pr_debug("gpio %d.%d is wakeup\n", gpio/8, gpio&7);
- continue;
- }
- disable_irq(i);
- }
-
local_irq_save(flags);
for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
@@ -320,7 +301,7 @@ void tegra_gpio_suspend(void)
static int tegra_gpio_wake_enable(struct irq_data *d, unsigned int enable)
{
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
- return set_irq_wake(bank->irq, enable);
+ return irq_set_irq_wake(bank->irq, enable);
}
#endif
@@ -359,18 +340,18 @@ static int __init tegra_gpio_init(void)
for (i = INT_GPIO_BASE; i < (INT_GPIO_BASE + TEGRA_NR_GPIOS); i++) {
bank = &tegra_gpio_banks[GPIO_BANK(irq_to_gpio(i))];
- lockdep_set_class(&irq_desc[i].lock, &gpio_lock_class);
- set_irq_chip_data(i, bank);
- set_irq_chip(i, &tegra_gpio_irq_chip);
- set_irq_handler(i, handle_simple_irq);
+ irq_set_lockdep_class(i, &gpio_lock_class);
+ irq_set_chip_data(i, bank);
+ irq_set_chip_and_handler(i, &tegra_gpio_irq_chip,
+ handle_simple_irq);
set_irq_flags(i, IRQF_VALID);
}
for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
bank = &tegra_gpio_banks[i];
- set_irq_chained_handler(bank->irq, tegra_gpio_irq_handler);
- set_irq_data(bank->irq, bank);
+ irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
+ irq_set_handler_data(bank->irq, bank);
for (j = 0; j < 4; j++)
spin_lock_init(&bank->lvl_lock[j]);
diff --git a/arch/arm/mach-tegra/irq.c b/arch/arm/mach-tegra/irq.c
index dfbc219ea49..4330d8995b2 100644
--- a/arch/arm/mach-tegra/irq.c
+++ b/arch/arm/mach-tegra/irq.c
@@ -144,7 +144,7 @@ void __init tegra_init_irq(void)
gic_init(0, 29, IO_ADDRESS(TEGRA_ARM_INT_DIST_BASE),
IO_ADDRESS(TEGRA_ARM_PERIF_BASE + 0x100));
- gic = get_irq_chip(29);
+ gic = irq_get_chip(29);
tegra_gic_unmask_irq = gic->irq_unmask;
tegra_gic_mask_irq = gic->irq_mask;
tegra_gic_ack_irq = gic->irq_ack;
@@ -154,8 +154,7 @@ void __init tegra_init_irq(void)
for (i = 0; i < INT_MAIN_NR; i++) {
irq = INT_PRI_BASE + i;
- set_irq_chip(irq, &tegra_irq);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &tegra_irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
}
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig
index 203b986280f..58626013aa3 100644
--- a/arch/arm/mach-ux500/Kconfig
+++ b/arch/arm/mach-ux500/Kconfig
@@ -23,6 +23,7 @@ menu "Ux500 target platform"
config MACH_U8500
bool "U8500 Development platform"
depends on UX500_SOC_DB8500
+ select TPS6105X
help
Include support for the mop500 development platform.
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.c b/arch/arm/mach-ux500/board-mop500-regulators.c
index 875c91b2f8a..9ed0f90cfe2 100644
--- a/arch/arm/mach-ux500/board-mop500-regulators.c
+++ b/arch/arm/mach-ux500/board-mop500-regulators.c
@@ -13,6 +13,30 @@
#include <linux/regulator/ab8500.h>
#include "board-mop500-regulators.h"
+/*
+ * TPS61052 regulator
+ */
+static struct regulator_consumer_supply tps61052_vaudio_consumers[] = {
+ /*
+ * Boost converter supply to raise voltage on audio speaker, this
+ * is actually connected to three pins, VInVhfL (left amplifier)
+ * VInVhfR (right amplifier) and VIntDClassInt - all three must
+ * be connected to the same voltage.
+ */
+ REGULATOR_SUPPLY("vintdclassint", "ab8500-codec.0"),
+};
+
+struct regulator_init_data tps61052_regulator = {
+ .constraints = {
+ .name = "vaudio-hf",
+ .min_uV = 4500000,
+ .max_uV = 4500000,
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(tps61052_vaudio_consumers),
+ .consumer_supplies = tps61052_vaudio_consumers,
+};
+
static struct regulator_consumer_supply ab8500_vaux1_consumers[] = {
/* External displays, connector on board 2v5 power supply */
REGULATOR_SUPPLY("vaux12v5", "mcde.0"),
@@ -62,6 +86,182 @@ static struct regulator_consumer_supply ab8500_vana_consumers[] = {
REGULATOR_SUPPLY("vsmps2", "mcde.0"),
};
+/* ab8500 regulator register initialization */
+struct ab8500_regulator_reg_init
+ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS] = {
+ /*
+ * VanaRequestCtrl = HP/LP depending on VxRequest
+ * VextSupply1RequestCtrl = HP/LP depending on VxRequest
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL2, 0x00),
+ /*
+ * VextSupply2RequestCtrl = HP/LP depending on VxRequest
+ * VextSupply3RequestCtrl = HP/LP depending on VxRequest
+ * Vaux1RequestCtrl = HP/LP depending on VxRequest
+ * Vaux2RequestCtrl = HP/LP depending on VxRequest
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL3, 0x00),
+ /*
+ * Vaux3RequestCtrl = HP/LP depending on VxRequest
+ * SwHPReq = Control through SWValid disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUREQUESTCTRL4, 0x00),
+ /*
+ * VanaSysClkReq1HPValid = disabled
+ * Vaux1SysClkReq1HPValid = disabled
+ * Vaux2SysClkReq1HPValid = disabled
+ * Vaux3SysClkReq1HPValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID1, 0x00),
+ /*
+ * VextSupply1SysClkReq1HPValid = disabled
+ * VextSupply2SysClkReq1HPValid = disabled
+ * VextSupply3SysClkReq1HPValid = SysClkReq1 controlled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQ1HPVALID2, 0x40),
+ /*
+ * VanaHwHPReq1Valid = disabled
+ * Vaux1HwHPreq1Valid = disabled
+ * Vaux2HwHPReq1Valid = disabled
+ * Vaux3HwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID1, 0x00),
+ /*
+ * VextSupply1HwHPReq1Valid = disabled
+ * VextSupply2HwHPReq1Valid = disabled
+ * VextSupply3HwHPReq1Valid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ1VALID2, 0x00),
+ /*
+ * VanaHwHPReq2Valid = disabled
+ * Vaux1HwHPReq2Valid = disabled
+ * Vaux2HwHPReq2Valid = disabled
+ * Vaux3HwHPReq2Valid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID1, 0x00),
+ /*
+ * VextSupply1HwHPReq2Valid = disabled
+ * VextSupply2HwHPReq2Valid = disabled
+ * VextSupply3HwHPReq2Valid = HWReq2 controlled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUHWHPREQ2VALID2, 0x04),
+ /*
+ * VanaSwHPReqValid = disabled
+ * Vaux1SwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID1, 0x00),
+ /*
+ * Vaux2SwHPReqValid = disabled
+ * Vaux3SwHPReqValid = disabled
+ * VextSupply1SwHPReqValid = disabled
+ * VextSupply2SwHPReqValid = disabled
+ * VextSupply3SwHPReqValid = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSWHPREQVALID2, 0x00),
+ /*
+ * SysClkReq2Valid1 = SysClkReq2 controlled
+ * SysClkReq3Valid1 = disabled
+ * SysClkReq4Valid1 = SysClkReq4 controlled
+ * SysClkReq5Valid1 = disabled
+ * SysClkReq6Valid1 = SysClkReq6 controlled
+ * SysClkReq7Valid1 = disabled
+ * SysClkReq8Valid1 = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID1, 0x2a),
+ /*
+ * SysClkReq2Valid2 = disabled
+ * SysClkReq3Valid2 = disabled
+ * SysClkReq4Valid2 = disabled
+ * SysClkReq5Valid2 = disabled
+ * SysClkReq6Valid2 = SysClkReq6 controlled
+ * SysClkReq7Valid2 = disabled
+ * SysClkReq8Valid2 = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUSYSCLKREQVALID2, 0x20),
+ /*
+ * VTVoutEna = disabled
+ * Vintcore12Ena = disabled
+ * Vintcore12Sel = 1.25 V
+ * Vintcore12LP = inactive (HP)
+ * VTVoutLP = inactive (HP)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUMISC1, 0x10),
+ /*
+ * VaudioEna = disabled
+ * VdmicEna = disabled
+ * Vamic1Ena = disabled
+ * Vamic2Ena = disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUDIOSUPPLY, 0x00),
+ /*
+ * Vamic1_dzout = high-Z when Vamic1 is disabled
+ * Vamic2_dzout = high-Z when Vamic2 is disabled
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRL1VAMIC, 0x00),
+ /*
+ * VPll = Hw controlled
+ * VanaRegu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VPLLVANAREGU, 0x02),
+ /*
+ * VrefDDREna = disabled
+ * VrefDDRSleepMode = inactive (no pulldown)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VREFDDR, 0x00),
+ /*
+ * VextSupply1Regu = HW control
+ * VextSupply2Regu = HW control
+ * VextSupply3Regu = HW control
+ * ExtSupply2Bypass = ExtSupply12LPn ball is 0 when Ena is 0
+ * ExtSupply3Bypass = ExtSupply3LPn ball is 0 when Ena is 0
+ */
+ INIT_REGULATOR_REGISTER(AB8500_EXTSUPPLYREGU, 0x2a),
+ /*
+ * Vaux1Regu = force HP
+ * Vaux2Regu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX12REGU, 0x01),
+ /*
+ * Vaux3regu = force off
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3REGU, 0x00),
+ /*
+ * Vsmps1 = 1.15V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VSMPS1SEL1, 0x24),
+ /*
+ * Vaux1Sel = 2.5 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX1SEL, 0x08),
+ /*
+ * Vaux2Sel = 2.9 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VAUX2SEL, 0x0d),
+ /*
+ * Vaux3Sel = 2.91 V
+ */
+ INIT_REGULATOR_REGISTER(AB8500_VRF1VAUX3SEL, 0x07),
+ /*
+ * VextSupply12LP = disabled (no LP)
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRL2SPARE, 0x00),
+ /*
+ * Vaux1Disch = short discharge time
+ * Vaux2Disch = short discharge time
+ * Vaux3Disch = short discharge time
+ * Vintcore12Disch = short discharge time
+ * VTVoutDisch = short discharge time
+ * VaudioDisch = short discharge time
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH, 0x00),
+ /*
+ * VanaDisch = short discharge time
+ * VdmicPullDownEna = pulldown disabled when Vdmic is disabled
+ * VdmicDisch = short discharge time
+ */
+ INIT_REGULATOR_REGISTER(AB8500_REGUCTRLDISCH2, 0x00),
+};
+
/* AB8500 regulators */
struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
/* supplies to the display/camera */
@@ -72,6 +272,7 @@ struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS] = {
.max_uV = 2900000,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
REGULATOR_CHANGE_STATUS,
+ .boot_on = 1, /* must be on for display */
},
.num_consumer_supplies = ARRAY_SIZE(ab8500_vaux1_consumers),
.consumer_supplies = ab8500_vaux1_consumers,
diff --git a/arch/arm/mach-ux500/board-mop500-regulators.h b/arch/arm/mach-ux500/board-mop500-regulators.h
index 2675fae5253..94992158d96 100644
--- a/arch/arm/mach-ux500/board-mop500-regulators.h
+++ b/arch/arm/mach-ux500/board-mop500-regulators.h
@@ -14,6 +14,9 @@
#include <linux/regulator/machine.h>
#include <linux/regulator/ab8500.h>
+extern struct ab8500_regulator_reg_init
+ab8500_regulator_reg_init[AB8500_NUM_REGULATOR_REGISTERS];
extern struct regulator_init_data ab8500_regulators[AB8500_NUM_REGULATORS];
+extern struct regulator_init_data tps61052_regulator;
#endif
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 8790d984cac..dc8746d7826 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -20,7 +20,10 @@
#include <linux/amba/serial.h>
#include <linux/spi/spi.h>
#include <linux/mfd/ab8500.h>
+#include <linux/regulator/ab8500.h>
#include <linux/mfd/tc3589x.h>
+#include <linux/mfd/tps6105x.h>
+#include <linux/mfd/ab8500/gpio.h>
#include <linux/leds-lp5521.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
@@ -41,10 +44,35 @@
#include "board-mop500.h"
#include "board-mop500-regulators.h"
+static struct ab8500_gpio_platform_data ab8500_gpio_pdata = {
+ .gpio_base = MOP500_AB8500_GPIO(0),
+ .irq_base = MOP500_AB8500_VIR_GPIO_IRQ_BASE,
+ /* config_reg is the initial configuration of ab8500 pins.
+ * The pins can be configured as GPIO or alt functions based
+ * on value present in GpioSel1 to GpioSel6 and AlternatFunction
+ * register. This is the array of 7 configuration settings.
+ * One has to compile time decide these settings. Below is the
+ * explaination of these setting
+ * GpioSel1 = 0x00 => Pins GPIO1 to GPIO8 are not used as GPIO
+ * GpioSel2 = 0x1E => Pins GPIO10 to GPIO13 are configured as GPIO
+ * GpioSel3 = 0x80 => Pin GPIO24 is configured as GPIO
+ * GpioSel4 = 0x01 => Pin GPIo25 is configured as GPIO
+ * GpioSel5 = 0x7A => Pins GPIO34, GPIO36 to GPIO39 are conf as GPIO
+ * GpioSel6 = 0x00 => Pins GPIO41 & GPIo42 are not configured as GPIO
+ * AlternaFunction = 0x00 => If Pins GPIO10 to 13 are not configured
+ * as GPIO then this register selectes the alternate fucntions
+ */
+ .config_reg = {0x00, 0x1E, 0x80, 0x01,
+ 0x7A, 0x00, 0x00},
+};
+
static struct ab8500_platform_data ab8500_platdata = {
.irq_base = MOP500_AB8500_IRQ_BASE,
+ .regulator_reg_init = ab8500_regulator_reg_init,
+ .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init),
.regulator = ab8500_regulators,
.num_regulator = ARRAY_SIZE(ab8500_regulators),
+ .gpio = &ab8500_gpio_pdata,
};
static struct resource ab8500_resources[] = {
@@ -66,6 +94,15 @@ struct platform_device ab8500_device = {
};
/*
+ * TPS61052
+ */
+
+static struct tps6105x_platform_data mop500_tps61052_data = {
+ .mode = TPS6105X_MODE_VOLTAGE,
+ .regulator_data = &tps61052_regulator,
+};
+
+/*
* TC35892
*/
@@ -135,7 +172,7 @@ static struct lp5521_platform_data __initdata lp5521_sec_data = {
.clock_mode = LP5521_CLOCK_EXT,
};
-static struct i2c_board_info mop500_i2c0_devices[] = {
+static struct i2c_board_info __initdata mop500_i2c0_devices[] = {
{
I2C_BOARD_INFO("tc3589x", 0x42),
.irq = NOMADIK_GPIO_TO_IRQ(217),
@@ -143,6 +180,14 @@ static struct i2c_board_info mop500_i2c0_devices[] = {
},
};
+/* I2C0 devices only available prior to HREFv60 */
+static struct i2c_board_info __initdata mop500_i2c0_old_devices[] = {
+ {
+ I2C_BOARD_INFO("tps61052", 0x33),
+ .platform_data = &mop500_tps61052_data,
+ },
+};
+
static struct i2c_board_info __initdata mop500_i2c2_devices[] = {
{
/* lp5521 LED driver, 1st device */
@@ -405,6 +450,9 @@ static void __init mop500_init_machine(void)
i2c_register_board_info(0, mop500_i2c0_devices,
ARRAY_SIZE(mop500_i2c0_devices));
+ if (!machine_is_hrefv60())
+ i2c_register_board_info(0, mop500_i2c0_old_devices,
+ ARRAY_SIZE(mop500_i2c0_old_devices));
i2c_register_board_info(2, mop500_i2c2_devices,
ARRAY_SIZE(mop500_i2c2_devices));
}
diff --git a/arch/arm/mach-ux500/board-mop500.h b/arch/arm/mach-ux500/board-mop500.h
index 56722f4be71..03a31cc9b08 100644
--- a/arch/arm/mach-ux500/board-mop500.h
+++ b/arch/arm/mach-ux500/board-mop500.h
@@ -27,6 +27,10 @@
#define GPIO_BU21013_CS MOP500_EGPIO(13)
#define GPIO_SDMMC_EN MOP500_EGPIO(17)
#define GPIO_SDMMC_1V8_3V_SEL MOP500_EGPIO(18)
+#define MOP500_EGPIO_END MOP500_EGPIO(24)
+
+/* GPIOs on the AB8500 mixed-signals circuit */
+#define MOP500_AB8500_GPIO(x) (MOP500_EGPIO_END + (x))
struct i2c_board_info;
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
index 7cdeb2af0eb..97ef55f8493 100644
--- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
+++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
@@ -35,9 +35,20 @@
#define MOP500_STMPE1601_IRQBASE MOP500_EGPIO_IRQ_END
#define MOP500_STMPE1601_IRQ(x) (MOP500_STMPE1601_IRQBASE + (x))
-#define MOP500_NR_IRQS MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
+#define MOP500_STMPE1601_IRQ_END \
+ MOP500_STMPE1601_IRQ(STMPE_NR_INTERNAL_IRQS)
-#define MOP500_IRQ_END MOP500_NR_IRQS
+/* AB8500 virtual gpio IRQ */
+#define AB8500_VIR_GPIO_NR_IRQS 16
+
+#define MOP500_AB8500_VIR_GPIO_IRQ_BASE \
+ MOP500_STMPE1601_IRQ_END
+#define MOP500_AB8500_VIR_GPIO_IRQ_END \
+ (MOP500_AB8500_VIR_GPIO_IRQ_BASE + AB8500_VIR_GPIO_NR_IRQS)
+
+#define MOP500_NR_IRQS MOP500_AB8500_VIR_GPIO_IRQ_END
+
+#define MOP500_IRQ_END MOP500_NR_IRQS
#if MOP500_IRQ_END > IRQ_BOARD_END
#undef IRQ_BOARD_END
diff --git a/arch/arm/mach-ux500/modem-irq-db5500.c b/arch/arm/mach-ux500/modem-irq-db5500.c
index e1296a7447c..6b86416c94c 100644
--- a/arch/arm/mach-ux500/modem-irq-db5500.c
+++ b/arch/arm/mach-ux500/modem-irq-db5500.c
@@ -90,8 +90,7 @@ static irqreturn_t modem_cpu_irq_handler(int irq, void *data)
static void create_virtual_irq(int irq, struct irq_chip *modem_irq_chip)
{
- set_irq_chip(irq, modem_irq_chip);
- set_irq_handler(irq, handle_simple_irq);
+ irq_set_chip_and_handler(irq, modem_irq_chip, handle_simple_irq);
set_irq_flags(irq, IRQF_VALID);
pr_debug("modem_irq: Created virtual IRQ %d\n", irq);
diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c
index 5f4ddde4f02..245140c0df1 100644
--- a/arch/arm/mach-vt8500/irq.c
+++ b/arch/arm/mach-vt8500/irq.c
@@ -97,15 +97,15 @@ static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type)
return -EINVAL;
case IRQF_TRIGGER_HIGH:
dctr |= VT8500_TRIGGER_HIGH;
- irq_desc[orig_irq].handle_irq = handle_level_irq;
+ __irq_set_handler_locked(orig_irq, handle_level_irq);
break;
case IRQF_TRIGGER_FALLING:
dctr |= VT8500_TRIGGER_FALLING;
- irq_desc[orig_irq].handle_irq = handle_edge_irq;
+ __irq_set_handler_locked(orig_irq, handle_edge_irq);
break;
case IRQF_TRIGGER_RISING:
dctr |= VT8500_TRIGGER_RISING;
- irq_desc[orig_irq].handle_irq = handle_edge_irq;
+ __irq_set_handler_locked(orig_irq, handle_edge_irq);
break;
}
writeb(dctr, base + VT8500_IC_DCTR + irq);
@@ -136,8 +136,8 @@ void __init vt8500_init_irq(void)
/* Disable all interrupts and route them to IRQ */
writeb(0x00, ic_regbase + VT8500_IC_DCTR + i);
- set_irq_chip(i, &vt8500_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &vt8500_irq_chip,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
} else {
@@ -167,8 +167,8 @@ void __init wm8505_init_irq(void)
writeb(0x00, sic_regbase + VT8500_IC_DCTR
+ i - 64);
- set_irq_chip(i, &vt8500_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &vt8500_irq_chip,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
} else {
diff --git a/arch/arm/mach-w90x900/irq.c b/arch/arm/mach-w90x900/irq.c
index 9c350103dcd..7bf143c443f 100644
--- a/arch/arm/mach-w90x900/irq.c
+++ b/arch/arm/mach-w90x900/irq.c
@@ -207,8 +207,8 @@ void __init nuc900_init_irq(void)
__raw_writel(0xFFFFFFFE, REG_AIC_MDCR);
for (irqno = IRQ_WDT; irqno <= IRQ_ADC; irqno++) {
- set_irq_chip(irqno, &nuc900_irq_chip);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &nuc900_irq_chip,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
}
diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c
index c856fa39760..f0ba0726306 100644
--- a/arch/arm/plat-mxc/3ds_debugboard.c
+++ b/arch/arm/plat-mxc/3ds_debugboard.c
@@ -100,14 +100,9 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
expio_irq = MXC_BOARD_IRQ_START;
for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
- struct irq_desc *d;
if ((int_valid & 1) == 0)
continue;
- d = irq_desc + expio_irq;
- if (unlikely(!(d->handle_irq)))
- pr_err("\nEXPIO irq: %d unhandled\n", expio_irq);
- else
- d->handle_irq(expio_irq, d);
+ generic_handle_irq(expio_irq);
}
desc->irq_data.chip->irq_ack(&desc->irq_data);
@@ -186,12 +181,11 @@ int __init mxc_expio_init(u32 base, u32 p_irq)
__raw_writew(0x1F, brd_io + INTR_MASK_REG);
for (i = MXC_EXP_IO_BASE;
i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) {
- set_irq_chip(i, &expio_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
- set_irq_type(p_irq, IRQF_TRIGGER_LOW);
- set_irq_chained_handler(p_irq, mxc_expio_irq_handler);
+ irq_set_irq_type(p_irq, IRQF_TRIGGER_LOW);
+ irq_set_chained_handler(p_irq, mxc_expio_irq_handler);
/* Register Lan device on the debugboard */
smsc911x_resources[0].start = LAN9217_BASE_ADDR(base);
diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
index deb284bc7c4..09e2bd0fcdc 100644
--- a/arch/arm/plat-mxc/avic.c
+++ b/arch/arm/plat-mxc/avic.c
@@ -139,8 +139,8 @@ void __init mxc_init_irq(void __iomem *irqbase)
__raw_writel(0, avic_base + AVIC_INTTYPEH);
__raw_writel(0, avic_base + AVIC_INTTYPEL);
for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
- set_irq_chip(i, &mxc_avic_chip.base);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &mxc_avic_chip.base,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
index 6561c9df5f0..ccc789e21da 100644
--- a/arch/arm/plat-mxc/devices/platform-fec.c
+++ b/arch/arm/plat-mxc/devices/platform-fec.c
@@ -53,7 +53,7 @@ struct platform_device *__init imx_add_fec(
struct resource res[] = {
{
.start = data->iobase,
- .end = data->iobase + SZ_4K,
+ .end = data->iobase + SZ_4K - 1,
.flags = IORESOURCE_MEM,
}, {
.start = data->irq,
diff --git a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
index 10653cc8d1f..805336fdc25 100644
--- a/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
+++ b/arch/arm/plat-mxc/devices/platform-imxdi_rtc.c
@@ -27,7 +27,7 @@ struct platform_device *__init imx_add_imxdi_rtc(
struct resource res[] = {
{
.start = data->iobase,
- .end = data->iobase + SZ_16K,
+ .end = data->iobase + SZ_16K - 1,
.flags = IORESOURCE_MEM,
}, {
.start = data->irq,
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 57d59855f9e..7a107246fd9 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -175,7 +175,7 @@ static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{
u32 irq_stat;
- struct mxc_gpio_port *port = get_irq_data(irq);
+ struct mxc_gpio_port *port = irq_get_handler_data(irq);
irq_stat = __raw_readl(port->base + GPIO_ISR) &
__raw_readl(port->base + GPIO_IMR);
@@ -188,7 +188,7 @@ static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
{
int i;
u32 irq_msk, irq_stat;
- struct mxc_gpio_port *port = get_irq_data(irq);
+ struct mxc_gpio_port *port = irq_get_handler_data(irq);
/* walk through all interrupt status registers */
for (i = 0; i < gpio_table_size; i++) {
@@ -311,8 +311,8 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
__raw_writel(~0, port[i].base + GPIO_ISR);
for (j = port[i].virtual_irq_start;
j < port[i].virtual_irq_start + 32; j++) {
- set_irq_chip(j, &gpio_irq_chip);
- set_irq_handler(j, handle_level_irq);
+ irq_set_chip_and_handler(j, &gpio_irq_chip,
+ handle_level_irq);
set_irq_flags(j, IRQF_VALID);
}
@@ -331,21 +331,23 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) {
/* setup one handler for each entry */
- set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
- set_irq_data(port[i].irq, &port[i]);
+ irq_set_chained_handler(port[i].irq,
+ mx3_gpio_irq_handler);
+ irq_set_handler_data(port[i].irq, &port[i]);
if (port[i].irq_high) {
/* setup handler for GPIO 16 to 31 */
- set_irq_chained_handler(port[i].irq_high,
- mx3_gpio_irq_handler);
- set_irq_data(port[i].irq_high, &port[i]);
+ irq_set_chained_handler(port[i].irq_high,
+ mx3_gpio_irq_handler);
+ irq_set_handler_data(port[i].irq_high,
+ &port[i]);
}
}
}
if (cpu_is_mx2()) {
/* setup one handler for all GPIO interrupts */
- set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler);
- set_irq_data(port[0].irq, port);
+ irq_set_chained_handler(port[0].irq, mx2_gpio_irq_handler);
+ irq_set_handler_data(port[0].irq, port);
}
return 0;
diff --git a/arch/arm/plat-mxc/include/mach/audmux.h b/arch/arm/plat-mxc/include/mach/audmux.h
index 5cd6466964a..6fda788ed0e 100644
--- a/arch/arm/plat-mxc/include/mach/audmux.h
+++ b/arch/arm/plat-mxc/include/mach/audmux.h
@@ -15,6 +15,14 @@
#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
+#define MX51_AUDMUX_PORT1_SSI0 0
+#define MX51_AUDMUX_PORT2_SSI1 1
+#define MX51_AUDMUX_PORT3 2
+#define MX51_AUDMUX_PORT4 3
+#define MX51_AUDMUX_PORT5 4
+#define MX51_AUDMUX_PORT6 5
+#define MX51_AUDMUX_PORT7 6
+
/* Register definitions for the i.MX21/27 Digital Audio Multiplexer */
#define MXC_AUDMUX_V1_PCR_INMMASK(x) ((x) & 0xff)
#define MXC_AUDMUX_V1_PCR_INMEN (1 << 8)
@@ -28,7 +36,7 @@
#define MXC_AUDMUX_V1_PCR_TCLKDIR (1 << 30)
#define MXC_AUDMUX_V1_PCR_TFSDIR (1 << 31)
-/* Register definitions for the i.MX25/31/35 Digital Audio Multiplexer */
+/* Register definitions for the i.MX25/31/35/51 Digital Audio Multiplexer */
#define MXC_AUDMUX_V2_PTCR_TFSDIR (1 << 31)
#define MXC_AUDMUX_V2_PTCR_TFSEL(x) (((x) & 0xf) << 27)
#define MXC_AUDMUX_V2_PTCR_TCLKDIR (1 << 26)
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
index c4f116d214f..7a9b20abda0 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h
@@ -90,12 +90,12 @@
#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31)
#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17)
#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18)
-#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | 19)
-#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | 20)
-#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | 21)
-#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | 22)
-#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | 23)
-#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | 24)
+#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19)
+#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20)
+#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21)
+#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22)
+#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 23)
+#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24)
#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25)
#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26)
#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27)
diff --git a/arch/arm/plat-mxc/include/mach/mx50.h b/arch/arm/plat-mxc/include/mach/mx50.h
index aaec2a6e7b3..5f2da75a47f 100644
--- a/arch/arm/plat-mxc/include/mach/mx50.h
+++ b/arch/arm/plat-mxc/include/mach/mx50.h
@@ -282,4 +282,8 @@
#define MX50_INT_APBHDMA_CHAN6 116
#define MX50_INT_APBHDMA_CHAN7 117
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+extern int mx50_revision(void);
+#endif
+
#endif /* ifndef __MACH_MX50_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h
index 1eb339e6c85..dede19a766f 100644
--- a/arch/arm/plat-mxc/include/mach/mx51.h
+++ b/arch/arm/plat-mxc/include/mach/mx51.h
@@ -347,6 +347,7 @@
#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
extern int mx51_revision(void);
+extern void mx51_display_revision(void);
#endif
/* tape-out 1 defines */
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 7e072637eef..1aea818d9d3 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -51,6 +51,20 @@
#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
@@ -181,6 +195,15 @@ struct cpu_op {
u32 cpu_rate;
};
+int tzic_enable_wake(int is_idle);
+enum mxc_cpu_pwr_mode {
+ WAIT_CLOCKED, /* wfi only */
+ WAIT_UNCLOCKED, /* WAIT */
+ WAIT_UNCLOCKED_POWER_OFF, /* WAIT + SRPG */
+ STOP_POWER_ON, /* just STOP */
+ STOP_POWER_OFF, /* STOP + SRPG */
+};
+
extern struct cpu_op *(*get_cpu_op)(int *op);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index 95be51bfe9a..0417da9f710 100644
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -20,6 +20,8 @@
#include <mach/hardware.h>
#include <mach/common.h>
+extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
+
static inline void arch_idle(void)
{
#ifdef CONFIG_ARCH_MXC91231
@@ -54,7 +56,9 @@ static inline void arch_idle(void)
"orr %0, %0, #0x00000004\n"
"mcr p15, 0, %0, c1, c0, 0\n"
: "=r" (reg));
- } else
+ } else if (cpu_is_mx51())
+ mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+ else
cpu_do_idle();
}
diff --git a/arch/arm/plat-mxc/irq-common.c b/arch/arm/plat-mxc/irq-common.c
index 0c799ac2773..e1c6eff7258 100644
--- a/arch/arm/plat-mxc/irq-common.c
+++ b/arch/arm/plat-mxc/irq-common.c
@@ -29,7 +29,7 @@ int imx_irq_set_priority(unsigned char irq, unsigned char prio)
ret = -ENOSYS;
- base = get_irq_chip(irq);
+ base = irq_get_chip(irq);
if (base) {
chip = container_of(base, struct mxc_irq_chip, base);
if (chip->set_priority)
@@ -48,7 +48,7 @@ int mxc_set_irq_fiq(unsigned int irq, unsigned int type)
ret = -ENOSYS;
- base = get_irq_chip(irq);
+ base = irq_get_chip(irq);
if (base) {
chip = container_of(base, struct mxc_irq_chip, base);
if (chip->set_irq_fiq)
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 9f0c2610595..2237ff8b434 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -27,6 +27,7 @@
#include <linux/clk.h>
#include <mach/hardware.h>
+#include <asm/sched_clock.h>
#include <asm/mach/time.h>
#include <mach/common.h>
@@ -105,6 +106,11 @@ static void gpt_irq_acknowledge(void)
__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
}
+static cycle_t dummy_get_cycles(struct clocksource *cs)
+{
+ return 0;
+}
+
static cycle_t mx1_2_get_cycles(struct clocksource *cs)
{
return __raw_readl(timer_base + MX1_2_TCN);
@@ -118,18 +124,35 @@ static cycle_t v2_get_cycles(struct clocksource *cs)
static struct clocksource clocksource_mxc = {
.name = "mxc_timer1",
.rating = 200,
- .read = mx1_2_get_cycles,
+ .read = dummy_get_cycles,
.mask = CLOCKSOURCE_MASK(32),
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
+static DEFINE_CLOCK_DATA(cd);
+unsigned long long notrace sched_clock(void)
+{
+ cycle_t cyc = clocksource_mxc.read(&clocksource_mxc);
+
+ return cyc_to_sched_clock(&cd, cyc, (u32)~0);
+}
+
+static void notrace mxc_update_sched_clock(void)
+{
+ cycle_t cyc = clocksource_mxc.read(&clocksource_mxc);
+ update_sched_clock(&cd, cyc, (u32)~0);
+}
+
static int __init mxc_clocksource_init(struct clk *timer_clk)
{
unsigned int c = clk_get_rate(timer_clk);
if (timer_is_v2())
clocksource_mxc.read = v2_get_cycles;
+ else
+ clocksource_mxc.read = mx1_2_get_cycles;
+ init_sched_clock(&cd, mxc_update_sched_clock, 32, c);
clocksource_register_hz(&clocksource_mxc, c);
return 0;
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index bc3a6be8a27..57f9395f87c 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -167,8 +167,8 @@ void __init tzic_init_irq(void __iomem *irqbase)
/* all IRQ no FIQ Warning :: No selection */
for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
- set_irq_chip(i, &mxc_tzic_chip.base);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, &mxc_tzic_chip.base,
+ handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
diff --git a/arch/arm/plat-nomadik/gpio.c b/arch/arm/plat-nomadik/gpio.c
index 80643bc38e1..f49748eca1a 100644
--- a/arch/arm/plat-nomadik/gpio.c
+++ b/arch/arm/plat-nomadik/gpio.c
@@ -54,6 +54,7 @@ struct nmk_gpio_chip {
u32 rwimsc;
u32 fwimsc;
u32 slpm;
+ u32 enabled;
};
static struct nmk_gpio_chip *
@@ -318,7 +319,7 @@ static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep)
struct nmk_gpio_chip *nmk_chip;
int pin = PIN_NUM(cfgs[i]);
- nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(pin));
+ nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(pin));
if (!nmk_chip) {
ret = -EINVAL;
break;
@@ -397,7 +398,7 @@ int nmk_gpio_set_slpm(int gpio, enum nmk_gpio_slpm mode)
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
- nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
if (!nmk_chip)
return -EINVAL;
@@ -430,7 +431,7 @@ int nmk_gpio_set_pull(int gpio, enum nmk_gpio_pull pull)
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
- nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
if (!nmk_chip)
return -EINVAL;
@@ -456,7 +457,7 @@ int nmk_gpio_set_mode(int gpio, int gpio_mode)
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
- nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
if (!nmk_chip)
return -EINVAL;
@@ -473,7 +474,7 @@ int nmk_gpio_get_mode(int gpio)
struct nmk_gpio_chip *nmk_chip;
u32 afunc, bfunc, bit;
- nmk_chip = get_irq_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
+ nmk_chip = irq_get_chip_data(NOMADIK_GPIO_TO_IRQ(gpio));
if (!nmk_chip)
return -EINVAL;
@@ -541,13 +542,6 @@ static void __nmk_gpio_irq_modify(struct nmk_gpio_chip *nmk_chip,
static void __nmk_gpio_set_wake(struct nmk_gpio_chip *nmk_chip,
int gpio, bool on)
{
-#ifdef CONFIG_ARCH_U8500
- if (cpu_is_u8500v2()) {
- __nmk_gpio_set_slpm(nmk_chip, gpio - nmk_chip->chip.base,
- on ? NMK_GPIO_SLPM_WAKEUP_ENABLE
- : NMK_GPIO_SLPM_WAKEUP_DISABLE);
- }
-#endif
__nmk_gpio_irq_modify(nmk_chip, gpio, WAKE, on);
}
@@ -564,6 +558,11 @@ static int nmk_gpio_irq_maskunmask(struct irq_data *d, bool enable)
if (!nmk_chip)
return -EINVAL;
+ if (enable)
+ nmk_chip->enabled |= bitmask;
+ else
+ nmk_chip->enabled &= ~bitmask;
+
spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
spin_lock(&nmk_chip->lock);
@@ -590,8 +589,6 @@ static void nmk_gpio_irq_unmask(struct irq_data *d)
static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
{
- struct irq_desc *desc = irq_to_desc(d->irq);
- bool enabled = !(desc->status & IRQ_DISABLED);
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
u32 bitmask;
@@ -606,7 +603,7 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
spin_lock_irqsave(&nmk_gpio_slpm_lock, flags);
spin_lock(&nmk_chip->lock);
- if (!enabled)
+ if (!(nmk_chip->enabled & bitmask))
__nmk_gpio_set_wake(nmk_chip, gpio, on);
if (on)
@@ -622,9 +619,7 @@ static int nmk_gpio_irq_set_wake(struct irq_data *d, unsigned int on)
static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
- struct irq_desc *desc = irq_to_desc(d->irq);
- bool enabled = !(desc->status & IRQ_DISABLED);
- bool wake = desc->wake_depth;
+ bool enabled, wake = irqd_is_wakeup_set(d);
int gpio;
struct nmk_gpio_chip *nmk_chip;
unsigned long flags;
@@ -641,6 +636,8 @@ static int nmk_gpio_irq_set_type(struct irq_data *d, unsigned int type)
if (type & IRQ_TYPE_LEVEL_LOW)
return -EINVAL;
+ enabled = nmk_chip->enabled & bitmask;
+
spin_lock_irqsave(&nmk_chip->lock, flags);
if (enabled)
@@ -681,7 +678,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
u32 status)
{
struct nmk_gpio_chip *nmk_chip;
- struct irq_chip *host_chip = get_irq_chip(irq);
+ struct irq_chip *host_chip = irq_get_chip(irq);
unsigned int first_irq;
if (host_chip->irq_mask_ack)
@@ -692,7 +689,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
host_chip->irq_ack(&desc->irq_data);
}
- nmk_chip = get_irq_data(irq);
+ nmk_chip = irq_get_handler_data(irq);
first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
while (status) {
int bit = __ffs(status);
@@ -706,7 +703,7 @@ static void __nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc,
static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
{
- struct nmk_gpio_chip *nmk_chip = get_irq_data(irq);
+ struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
u32 status = readl(nmk_chip->addr + NMK_GPIO_IS);
__nmk_gpio_irq_handler(irq, desc, status);
@@ -715,7 +712,7 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
static void nmk_gpio_secondary_irq_handler(unsigned int irq,
struct irq_desc *desc)
{
- struct nmk_gpio_chip *nmk_chip = get_irq_data(irq);
+ struct nmk_gpio_chip *nmk_chip = irq_get_handler_data(irq);
u32 status = nmk_chip->get_secondary_status(nmk_chip->bank);
__nmk_gpio_irq_handler(irq, desc, status);
@@ -728,20 +725,20 @@ static int nmk_gpio_init_irq(struct nmk_gpio_chip *nmk_chip)
first_irq = NOMADIK_GPIO_TO_IRQ(nmk_chip->chip.base);
for (i = first_irq; i < first_irq + nmk_chip->chip.ngpio; i++) {
- set_irq_chip(i, &nmk_gpio_irq_chip);
- set_irq_handler(i, handle_edge_irq);
+ irq_set_chip_and_handler(i, &nmk_gpio_irq_chip,
+ handle_edge_irq);
set_irq_flags(i, IRQF_VALID);
- set_irq_chip_data(i, nmk_chip);
- set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
+ irq_set_chip_data(i, nmk_chip);
+ irq_set_irq_type(i, IRQ_TYPE_EDGE_FALLING);
}
- set_irq_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
- set_irq_data(nmk_chip->parent_irq, nmk_chip);
+ irq_set_chained_handler(nmk_chip->parent_irq, nmk_gpio_irq_handler);
+ irq_set_handler_data(nmk_chip->parent_irq, nmk_chip);
if (nmk_chip->secondary_parent_irq >= 0) {
- set_irq_chained_handler(nmk_chip->secondary_parent_irq,
+ irq_set_chained_handler(nmk_chip->secondary_parent_irq,
nmk_gpio_secondary_irq_handler);
- set_irq_data(nmk_chip->secondary_parent_irq, nmk_chip);
+ irq_set_handler_data(nmk_chip->secondary_parent_irq, nmk_chip);
}
return 0;
diff --git a/arch/arm/plat-omap/gpio.c b/arch/arm/plat-omap/gpio.c
index 971d1863694..d2adcdda23c 100644
--- a/arch/arm/plat-omap/gpio.c
+++ b/arch/arm/plat-omap/gpio.c
@@ -755,18 +755,12 @@ static int gpio_irq_type(struct irq_data *d, unsigned type)
bank = irq_data_get_irq_chip_data(d);
spin_lock_irqsave(&bank->lock, flags);
retval = _set_gpio_triggering(bank, get_gpio_index(gpio), type);
- if (retval == 0) {
- struct irq_desc *desc = irq_to_desc(d->irq);
-
- desc->status &= ~IRQ_TYPE_SENSE_MASK;
- desc->status |= type;
- }
spin_unlock_irqrestore(&bank->lock, flags);
if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
- __set_irq_handler_unlocked(d->irq, handle_level_irq);
+ __irq_set_handler_locked(d->irq, handle_level_irq);
else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
- __set_irq_handler_unlocked(d->irq, handle_edge_irq);
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
return retval;
}
@@ -1146,7 +1140,7 @@ static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
desc->irq_data.chip->irq_ack(&desc->irq_data);
- bank = get_irq_data(irq);
+ bank = irq_get_handler_data(irq);
#ifdef CONFIG_ARCH_OMAP1
if (bank->method == METHOD_MPUIO)
isr_reg = bank->base +
@@ -1270,8 +1264,7 @@ static void gpio_unmask_irq(struct irq_data *d)
unsigned int gpio = d->irq - IH_GPIO_BASE;
struct gpio_bank *bank = irq_data_get_irq_chip_data(d);
unsigned int irq_mask = 1 << get_gpio_index(gpio);
- struct irq_desc *desc = irq_to_desc(d->irq);
- u32 trigger = desc->status & IRQ_TYPE_SENSE_MASK;
+ u32 trigger = irqd_get_trigger_type(d);
if (trigger)
_set_gpio_triggering(bank, get_gpio_index(gpio), trigger);
@@ -1672,19 +1665,17 @@ static void __init omap_gpio_chip_init(struct gpio_bank *bank)
for (j = bank->virtual_irq_start;
j < bank->virtual_irq_start + bank_width; j++) {
- struct irq_desc *d = irq_to_desc(j);
-
- lockdep_set_class(&d->lock, &gpio_lock_class);
- set_irq_chip_data(j, bank);
+ irq_set_lockdep_class(j, &gpio_lock_class);
+ irq_set_chip_data(j, bank);
if (bank_is_mpuio(bank))
- set_irq_chip(j, &mpuio_irq_chip);
+ irq_set_chip(j, &mpuio_irq_chip);
else
- set_irq_chip(j, &gpio_irq_chip);
- set_irq_handler(j, handle_simple_irq);
+ irq_set_chip(j, &gpio_irq_chip);
+ irq_set_handler(j, handle_simple_irq);
set_irq_flags(j, IRQF_VALID);
}
- set_irq_chained_handler(bank->irq, gpio_irq_handler);
- set_irq_data(bank->irq, bank);
+ irq_set_chained_handler(bank->irq, gpio_irq_handler);
+ irq_set_handler_data(bank->irq, bank);
}
static int __devinit omap_gpio_probe(struct platform_device *pdev)
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c
index 078894bc3b9..a431a138f40 100644
--- a/arch/arm/plat-orion/gpio.c
+++ b/arch/arm/plat-orion/gpio.c
@@ -324,9 +324,8 @@ EXPORT_SYMBOL(orion_gpio_set_blink);
static void gpio_irq_ack(struct irq_data *d)
{
struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d);
- int type;
+ int type = irqd_get_trigger_type(d);
- type = irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK;
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
int pin = d->irq - ochip->secondary_irq_base;
@@ -337,11 +336,10 @@ static void gpio_irq_ack(struct irq_data *d)
static void gpio_irq_mask(struct irq_data *d)
{
struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d);
- int type;
+ int type = irqd_get_trigger_type(d);
void __iomem *reg;
int pin;
- type = irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK;
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
reg = GPIO_EDGE_MASK(ochip);
else
@@ -355,11 +353,10 @@ static void gpio_irq_mask(struct irq_data *d)
static void gpio_irq_unmask(struct irq_data *d)
{
struct orion_gpio_chip *ochip = irq_data_get_irq_chip_data(d);
- int type;
+ int type = irqd_get_trigger_type(d);
void __iomem *reg;
int pin;
- type = irq_desc[d->irq].status & IRQ_TYPE_SENSE_MASK;
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING))
reg = GPIO_EDGE_MASK(ochip);
else
@@ -389,9 +386,9 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type)
* Set edge/level type.
*/
if (type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) {
- set_irq_handler(d->irq, handle_edge_irq);
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
} else if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) {
- set_irq_handler(d->irq, handle_level_irq);
+ __irq_set_handler_locked(d->irq, handle_level_irq);
} else {
printk(KERN_ERR "failed to set irq=%d (type=%d)\n",
d->irq, type);
@@ -477,10 +474,10 @@ void __init orion_gpio_init(int gpio_base, int ngpio,
for (i = 0; i < ngpio; i++) {
unsigned int irq = secondary_irq_base + i;
- set_irq_chip(irq, &orion_gpio_irq_chip);
- set_irq_handler(irq, handle_level_irq);
- set_irq_chip_data(irq, ochip);
- irq_desc[irq].status |= IRQ_LEVEL;
+ irq_set_chip_and_handler(irq, &orion_gpio_irq_chip,
+ handle_level_irq);
+ irq_set_chip_data(irq, ochip);
+ irq_set_status_flags(irq, IRQ_LEVEL);
set_irq_flags(irq, IRQF_VALID);
}
}
@@ -488,7 +485,7 @@ void __init orion_gpio_init(int gpio_base, int ngpio,
void orion_gpio_irq_handler(int pinoff)
{
struct orion_gpio_chip *ochip;
- u32 cause;
+ u32 cause, type;
int i;
ochip = orion_gpio_chip_find(pinoff);
@@ -500,15 +497,14 @@ void orion_gpio_irq_handler(int pinoff)
for (i = 0; i < ochip->chip.ngpio; i++) {
int irq;
- struct irq_desc *desc;
irq = ochip->secondary_irq_base + i;
if (!(cause & (1 << i)))
continue;
- desc = irq_desc + irq;
- if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+ type = irqd_get_trigger_type(irq_get_irq_data(irq));
+ if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
/* Swap polarity (race with GPIO line) */
u32 polarity;
@@ -516,7 +512,6 @@ void orion_gpio_irq_handler(int pinoff)
polarity ^= 1 << i;
writel(polarity, GPIO_IN_POL(ochip));
}
-
- desc_handle_irq(irq, desc);
+ generic_handle_irq(irq);
}
}
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c
index 7d0c7eb59f0..d8d638e09f8 100644
--- a/arch/arm/plat-orion/irq.c
+++ b/arch/arm/plat-orion/irq.c
@@ -56,10 +56,10 @@ void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr)
for (i = 0; i < 32; i++) {
unsigned int irq = irq_start + i;
- set_irq_chip(irq, &orion_irq_chip);
- set_irq_chip_data(irq, maskaddr);
- set_irq_handler(irq, handle_level_irq);
- irq_desc[irq].status |= IRQ_LEVEL;
+ irq_set_chip_and_handler(irq, &orion_irq_chip,
+ handle_level_irq);
+ irq_set_chip_data(irq, maskaddr);
+ irq_set_status_flags(irq, IRQ_LEVEL);
set_irq_flags(irq, IRQF_VALID);
}
}
diff --git a/arch/arm/plat-pxa/gpio.c b/arch/arm/plat-pxa/gpio.c
index e7de6ae2a1e..dce088f4567 100644
--- a/arch/arm/plat-pxa/gpio.c
+++ b/arch/arm/plat-pxa/gpio.c
@@ -284,13 +284,13 @@ void __init pxa_init_gpio(int mux_irq, int start, int end, set_wake_t fn)
}
for (irq = gpio_to_irq(start); irq <= gpio_to_irq(end); irq++) {
- set_irq_chip(irq, &pxa_muxed_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &pxa_muxed_gpio_chip,
+ handle_edge_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
/* Install handler for GPIO>=2 edge detect interrupts */
- set_irq_chained_handler(mux_irq, pxa_gpio_demux_handler);
+ irq_set_chained_handler(mux_irq, pxa_gpio_demux_handler);
pxa_muxed_gpio_chip.irq_set_wake = fn;
}
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
index 4434cb56bd9..9aee7e1668b 100644
--- a/arch/arm/plat-s3c24xx/irq.c
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -592,8 +592,8 @@ void __init s3c24xx_init_irq(void)
case IRQ_UART1:
case IRQ_UART2:
case IRQ_ADCPARENT:
- set_irq_chip(irqno, &s3c_irq_level_chip);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_level_chip,
+ handle_level_irq);
break;
case IRQ_RESERVED6:
@@ -603,35 +603,35 @@ void __init s3c24xx_init_irq(void)
default:
//irqdbf("registering irq %d (s3c irq)\n", irqno);
- set_irq_chip(irqno, &s3c_irq_chip);
- set_irq_handler(irqno, handle_edge_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_chip,
+ handle_edge_irq);
set_irq_flags(irqno, IRQF_VALID);
}
}
/* setup the cascade irq handlers */
- set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
- set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
+ irq_set_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
+ irq_set_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
- set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
- set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
- set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
- set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
+ irq_set_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
+ irq_set_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
+ irq_set_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
+ irq_set_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
/* external interrupts */
for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
irqdbf("registering irq %d (ext int)\n", irqno);
- set_irq_chip(irqno, &s3c_irq_eint0t4);
- set_irq_handler(irqno, handle_edge_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_eint0t4,
+ handle_edge_irq);
set_irq_flags(irqno, IRQF_VALID);
}
for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
irqdbf("registering irq %d (extended s3c irq)\n", irqno);
- set_irq_chip(irqno, &s3c_irqext_chip);
- set_irq_handler(irqno, handle_edge_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irqext_chip,
+ handle_edge_irq);
set_irq_flags(irqno, IRQF_VALID);
}
@@ -641,29 +641,28 @@ void __init s3c24xx_init_irq(void)
for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
- set_irq_chip(irqno, &s3c_irq_uart0);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart0,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
- set_irq_chip(irqno, &s3c_irq_uart1);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart1,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
- set_irq_chip(irqno, &s3c_irq_uart2);
- set_irq_handler(irqno, handle_level_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_uart2,
+ handle_level_irq);
set_irq_flags(irqno, IRQF_VALID);
}
for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
irqdbf("registering irq %d (s3c adc irq)\n", irqno);
- set_irq_chip(irqno, &s3c_irq_adc);
- set_irq_handler(irqno, handle_edge_irq);
+ irq_set_chip_and_handler(irqno, &s3c_irq_adc, handle_edge_irq);
set_irq_flags(irqno, IRQF_VALID);
}
diff --git a/arch/arm/plat-s5p/cpu.c b/arch/arm/plat-s5p/cpu.c
index c3bfe9b13ac..5cf5e721e6c 100644
--- a/arch/arm/plat-s5p/cpu.c
+++ b/arch/arm/plat-s5p/cpu.c
@@ -39,7 +39,7 @@ static const char name_exynos4210[] = "EXYNOS4210";
static struct cpu_table cpu_ids[] __initdata = {
{
.idcode = 0x56440100,
- .idmask = 0xffffff00,
+ .idmask = 0xfffff000,
.map_io = s5p6440_map_io,
.init_clocks = s5p6440_init_clocks,
.init_uarts = s5p6440_init_uarts,
@@ -47,7 +47,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.name = name_s5p6440,
}, {
.idcode = 0x36442000,
- .idmask = 0xffffff00,
+ .idmask = 0xfffff000,
.map_io = s5p6442_map_io,
.init_clocks = s5p6442_init_clocks,
.init_uarts = s5p6442_init_uarts,
@@ -55,7 +55,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.name = name_s5p6442,
}, {
.idcode = 0x36450000,
- .idmask = 0xffffff00,
+ .idmask = 0xfffff000,
.map_io = s5p6450_map_io,
.init_clocks = s5p6450_init_clocks,
.init_uarts = s5p6450_init_uarts,
@@ -79,7 +79,7 @@ static struct cpu_table cpu_ids[] __initdata = {
.name = name_s5pv210,
}, {
.idcode = 0x43210000,
- .idmask = 0xfffff000,
+ .idmask = 0xfffe0000,
.map_io = exynos4_map_io,
.init_clocks = exynos4_init_clocks,
.init_uarts = exynos4_init_uarts,
diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c
index 225aa25405d..b5bb774985b 100644
--- a/arch/arm/plat-s5p/irq-eint.c
+++ b/arch/arm/plat-s5p/irq-eint.c
@@ -205,15 +205,14 @@ int __init s5p_init_irq_eint(void)
int irq;
for (irq = IRQ_EINT(0); irq <= IRQ_EINT(15); irq++)
- set_irq_chip(irq, &s5p_irq_vic_eint);
+ irq_set_chip(irq, &s5p_irq_vic_eint);
for (irq = IRQ_EINT(16); irq <= IRQ_EINT(31); irq++) {
- set_irq_chip(irq, &s5p_irq_eint);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &s5p_irq_eint, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
- set_irq_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31);
+ irq_set_chained_handler(IRQ_EINT16_31, s5p_irq_demux_eint16_31);
return 0;
}
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c
index cd87d3256e0..46dd078147d 100644
--- a/arch/arm/plat-s5p/irq-gpioint.c
+++ b/arch/arm/plat-s5p/irq-gpioint.c
@@ -43,13 +43,13 @@ LIST_HEAD(banks);
static int s5p_gpioint_get_offset(struct irq_data *data)
{
- struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
+ struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
return data->irq - chip->irq_base;
}
static void s5p_gpioint_ack(struct irq_data *data)
{
- struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
+ struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
int group, offset, pend_offset;
unsigned int value;
@@ -64,7 +64,7 @@ static void s5p_gpioint_ack(struct irq_data *data)
static void s5p_gpioint_mask(struct irq_data *data)
{
- struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
+ struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
int group, offset, mask_offset;
unsigned int value;
@@ -79,7 +79,7 @@ static void s5p_gpioint_mask(struct irq_data *data)
static void s5p_gpioint_unmask(struct irq_data *data)
{
- struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
+ struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
int group, offset, mask_offset;
unsigned int value;
@@ -100,7 +100,7 @@ static void s5p_gpioint_mask_ack(struct irq_data *data)
static int s5p_gpioint_set_type(struct irq_data *data, unsigned int type)
{
- struct s3c_gpio_chip *chip = irq_data_get_irq_data(data);
+ struct s3c_gpio_chip *chip = irq_data_get_irq_handler_data(data);
int group, offset, con_offset;
unsigned int value;
@@ -149,7 +149,7 @@ static struct irq_chip s5p_gpioint = {
static void s5p_gpioint_handler(unsigned int irq, struct irq_desc *desc)
{
- struct s5p_gpioint_bank *bank = get_irq_data(irq);
+ struct s5p_gpioint_bank *bank = irq_get_handler_data(irq);
int group, pend_offset, mask_offset;
unsigned int pend, mask;
@@ -200,8 +200,8 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
if (!bank->chips)
return -ENOMEM;
- set_irq_chained_handler(bank->irq, s5p_gpioint_handler);
- set_irq_data(bank->irq, bank);
+ irq_set_chained_handler(bank->irq, s5p_gpioint_handler);
+ irq_set_handler_data(bank->irq, bank);
bank->handler = s5p_gpioint_handler;
printk(KERN_INFO "Registered chained gpio int handler for interrupt %d.\n",
bank->irq);
@@ -219,9 +219,9 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip)
bank->chips[group - bank->start] = chip;
for (i = 0; i < chip->chip.ngpio; i++) {
irq = chip->irq_base + i;
- set_irq_chip(irq, &s5p_gpioint);
- set_irq_data(irq, chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip(irq, &s5p_gpioint);
+ irq_set_handler_data(irq, chip);
+ irq_set_handler(irq, handle_level_irq);
set_irq_flags(irq, IRQF_VALID);
}
return 0;
diff --git a/arch/arm/plat-samsung/init.c b/arch/arm/plat-samsung/init.c
index 6790edfaca6..79d10fca909 100644
--- a/arch/arm/plat-samsung/init.c
+++ b/arch/arm/plat-samsung/init.c
@@ -36,7 +36,7 @@ static struct cpu_table * __init s3c_lookup_cpu(unsigned long idcode,
unsigned int count)
{
for (; count != 0; count--, tab++) {
- if ((idcode & tab->idmask) == tab->idcode)
+ if ((idcode & tab->idmask) == (tab->idcode & tab->idmask))
return tab;
}
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c
index 4e770355ccb..4d4e571af55 100644
--- a/arch/arm/plat-samsung/irq-uart.c
+++ b/arch/arm/plat-samsung/irq-uart.c
@@ -107,7 +107,6 @@ static struct irq_chip s3c_irq_uart = {
static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
{
- struct irq_desc *desc = irq_to_desc(uirq->parent_irq);
void __iomem *reg_base = uirq->regs;
unsigned int irq;
int offs;
@@ -118,14 +117,13 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq)
for (offs = 0; offs < 3; offs++) {
irq = uirq->base_irq + offs;
- set_irq_chip(irq, &s3c_irq_uart);
- set_irq_chip_data(irq, uirq);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_and_handler(irq, &s3c_irq_uart, handle_level_irq);
+ irq_set_chip_data(irq, uirq);
set_irq_flags(irq, IRQF_VALID);
}
- desc->irq_data.handler_data = uirq;
- set_irq_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
+ irq_set_handler_data(uirq->parent_irq, uirq);
+ irq_set_chained_handler(uirq->parent_irq, s3c_irq_demux_uart);
}
/**
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c
index dd8692ae5c4..d6ad66ab929 100644
--- a/arch/arm/plat-samsung/irq-vic-timer.c
+++ b/arch/arm/plat-samsung/irq-vic-timer.c
@@ -77,14 +77,11 @@ static struct irq_chip s3c_irq_timer = {
void __init s3c_init_vic_timer_irq(unsigned int parent_irq,
unsigned int timer_irq)
{
- struct irq_desc *desc = irq_to_desc(parent_irq);
- set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
+ irq_set_chained_handler(parent_irq, s3c_irq_demux_vic_timer);
+ irq_set_handler_data(parent_irq, (void *)timer_irq);
- set_irq_chip(timer_irq, &s3c_irq_timer);
- set_irq_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0)));
- set_irq_handler(timer_irq, handle_level_irq);
+ irq_set_chip_and_handler(timer_irq, &s3c_irq_timer, handle_level_irq);
+ irq_set_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0)));
set_irq_flags(timer_irq, IRQF_VALID);
-
- desc->irq_data.handler_data = (void *)timer_irq;
}
diff --git a/arch/arm/plat-samsung/wakeup-mask.c b/arch/arm/plat-samsung/wakeup-mask.c
index 2e09b6ad84c..dc814037297 100644
--- a/arch/arm/plat-samsung/wakeup-mask.c
+++ b/arch/arm/plat-samsung/wakeup-mask.c
@@ -22,7 +22,7 @@
void samsung_sync_wakemask(void __iomem *reg,
struct samsung_wakeup_mask *mask, int nr_mask)
{
- struct irq_desc *desc;
+ struct irq_data *data;
u32 val;
val = __raw_readl(reg);
@@ -33,10 +33,10 @@ void samsung_sync_wakemask(void __iomem *reg,
continue;
}
- desc = irq_to_desc(mask->irq);
+ data = irq_get_irq_data(mask->irq);
- /* bit of a liberty to read this directly from irq_desc. */
- if (desc->wake_depth > 0)
+ /* bit of a liberty to read this directly from irq_data. */
+ if (irqd_is_wakeup_set(data))
val &= ~mask->bit;
else
val |= mask->bit;
diff --git a/arch/arm/plat-spear/shirq.c b/arch/arm/plat-spear/shirq.c
index 78189035e7f..961fb726124 100644
--- a/arch/arm/plat-spear/shirq.c
+++ b/arch/arm/plat-spear/shirq.c
@@ -68,7 +68,7 @@ static struct irq_chip shirq_chip = {
static void shirq_handler(unsigned irq, struct irq_desc *desc)
{
u32 i, val, mask;
- struct spear_shirq *shirq = get_irq_data(irq);
+ struct spear_shirq *shirq = irq_get_handler_data(irq);
desc->irq_data.chip->irq_ack(&desc->irq_data);
while ((val = readl(shirq->regs.base + shirq->regs.status_reg) &
@@ -105,14 +105,14 @@ int spear_shirq_register(struct spear_shirq *shirq)
if (!shirq->dev_count)
return -EINVAL;
- set_irq_chained_handler(shirq->irq, shirq_handler);
+ irq_set_chained_handler(shirq->irq, shirq_handler);
for (i = 0; i < shirq->dev_count; i++) {
- set_irq_chip(shirq->dev_config[i].virq, &shirq_chip);
- set_irq_handler(shirq->dev_config[i].virq, handle_simple_irq);
+ irq_set_chip_and_handler(shirq->dev_config[i].virq,
+ &shirq_chip, handle_simple_irq);
set_irq_flags(shirq->dev_config[i].virq, IRQF_VALID);
- set_irq_chip_data(shirq->dev_config[i].virq, shirq);
+ irq_set_chip_data(shirq->dev_config[i].virq, shirq);
}
- set_irq_data(shirq->irq, shirq);
+ irq_set_handler_data(shirq->irq, shirq);
return 0;
}
diff --git a/arch/arm/plat-stmp3xxx/irq.c b/arch/arm/plat-stmp3xxx/irq.c
index aaa168683d4..6fdf9acf82e 100644
--- a/arch/arm/plat-stmp3xxx/irq.c
+++ b/arch/arm/plat-stmp3xxx/irq.c
@@ -35,8 +35,7 @@ void __init stmp3xxx_init_irq(struct irq_chip *chip)
/* Disable all interrupts initially */
for (i = 0; i < NR_REAL_IRQS; i++) {
chip->irq_mask(irq_get_irq_data(i));
- set_irq_chip(i, chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip_and_handler(i, chip, handle_level_irq);
set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
}
diff --git a/arch/arm/plat-stmp3xxx/pinmux.c b/arch/arm/plat-stmp3xxx/pinmux.c
index 66d5bac3ace..3def03b3217 100644
--- a/arch/arm/plat-stmp3xxx/pinmux.c
+++ b/arch/arm/plat-stmp3xxx/pinmux.c
@@ -489,14 +489,13 @@ static void stmp3xxx_gpio_free(struct gpio_chip *chip, unsigned offset)
static void stmp3xxx_gpio_irq(u32 irq, struct irq_desc *desc)
{
- struct stmp3xxx_pinmux_bank *pm = get_irq_data(irq);
+ struct stmp3xxx_pinmux_bank *pm = irq_get_handler_data(irq);
int gpio_irq = pm->virq;
u32 stat = __raw_readl(pm->irqstat);
while (stat) {
if (stat & 1)
- irq_desc[gpio_irq].handle_irq(gpio_irq,
- &irq_desc[gpio_irq]);
+ generic_handle_irq(gpio_irq);
gpio_irq++;
stat >>= 1;
}
@@ -534,15 +533,15 @@ int __init stmp3xxx_pinmux_init(int virtual_irq_start)
for (virq = pm->virq; virq < pm->virq; virq++) {
gpio_irq_chip.irq_mask(irq_get_irq_data(virq));
- set_irq_chip(virq, &gpio_irq_chip);
- set_irq_handler(virq, handle_level_irq);
+ irq_set_chip_and_handler(virq, &gpio_irq_chip,
+ handle_level_irq);
set_irq_flags(virq, IRQF_VALID);
}
r = gpiochip_add(&pm->chip);
if (r < 0)
break;
- set_irq_chained_handler(pm->irq, stmp3xxx_gpio_irq);
- set_irq_data(pm->irq, pm);
+ irq_set_chained_handler(pm->irq, stmp3xxx_gpio_irq);
+ irq_set_handler_data(pm->irq, pm);
}
return r;
}
diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c
index 31d945d37e4..f0cc8e19b09 100644
--- a/arch/arm/plat-versatile/fpga-irq.c
+++ b/arch/arm/plat-versatile/fpga-irq.c
@@ -30,7 +30,7 @@ static void fpga_irq_unmask(struct irq_data *d)
static void fpga_irq_handle(unsigned int irq, struct irq_desc *desc)
{
- struct fpga_irq_data *f = get_irq_desc_data(desc);
+ struct fpga_irq_data *f = irq_desc_get_handler_data(desc);
u32 status = readl(f->base + IRQ_STATUS);
if (status == 0) {
@@ -55,17 +55,17 @@ void __init fpga_irq_init(int parent_irq, u32 valid, struct fpga_irq_data *f)
f->chip.irq_unmask = fpga_irq_unmask;
if (parent_irq != -1) {
- set_irq_data(parent_irq, f);
- set_irq_chained_handler(parent_irq, fpga_irq_handle);
+ irq_set_handler_data(parent_irq, f);
+ irq_set_chained_handler(parent_irq, fpga_irq_handle);
}
for (i = 0; i < 32; i++) {
if (valid & (1 << i)) {
unsigned int irq = f->irq_start + i;
- set_irq_chip_data(irq, f);
- set_irq_chip(irq, &f->chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip_data(irq, f);
+ irq_set_chip_and_handler(irq, &f->chip,
+ handle_level_irq);
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
}
}
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 49642b59f73..e9d689b7c83 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -10,7 +10,6 @@ config AVR32
select GENERIC_IRQ_PROBE
select HARDIRQS_SW_RESEND
select GENERIC_IRQ_SHOW
- select GENERIC_HARDIRQS_NO_DEPRECATED
help
AVR32 is a high-performance 32-bit RISC microprocessor core,
designed for cost-sensitive embedded applications, with particular
diff --git a/arch/avr32/mach-at32ap/pio.c b/arch/avr32/mach-at32ap/pio.c
index 37534103574..f308e1ddc62 100644
--- a/arch/avr32/mach-at32ap/pio.c
+++ b/arch/avr32/mach-at32ap/pio.c
@@ -282,7 +282,7 @@ static struct irq_chip gpio_irqchip = {
static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct pio_device *pio = get_irq_desc_chip_data(desc);
+ struct pio_device *pio = irq_desc_get_chip_data(desc);
unsigned gpio_irq;
gpio_irq = (unsigned) irq_get_handler_data(irq);
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 672c21632f2..8addb1220b4 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -34,7 +34,6 @@ config BLACKFIN
select GENERIC_ATOMIC64
select GENERIC_IRQ_PROBE
select IRQ_PER_CPU if SMP
- select GENERIC_HARDIRQS_NO_DEPRECATED
config GENERIC_CSUM
def_bool y
diff --git a/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
index 362f59dd522..ad0881ba30a 100644
--- a/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
+++ b/arch/blackfin/configs/BF527-AD7160-EVAL_defconfig
@@ -46,7 +46,6 @@ CONFIG_UNIX=y
# CONFIG_WIRELESS is not set
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
diff --git a/arch/blackfin/configs/BF538-EZKIT_defconfig b/arch/blackfin/configs/BF538-EZKIT_defconfig
index 6883803e6ca..580bf4296a1 100644
--- a/arch/blackfin/configs/BF538-EZKIT_defconfig
+++ b/arch/blackfin/configs/BF538-EZKIT_defconfig
@@ -70,7 +70,6 @@ CONFIG_MTD_ROM=m
CONFIG_MTD_PHYSMAP=m
CONFIG_MTD_NAND=m
CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
CONFIG_NETDEVICES=y
CONFIG_PHYLIB=y
CONFIG_SMSC_PHY=y
diff --git a/arch/blackfin/configs/BF561-ACVILON_defconfig b/arch/blackfin/configs/BF561-ACVILON_defconfig
index b7c8451f26a..77a27e31d6d 100644
--- a/arch/blackfin/configs/BF561-ACVILON_defconfig
+++ b/arch/blackfin/configs/BF561-ACVILON_defconfig
@@ -63,7 +63,6 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_BLK_DEV_RAM_SIZE=16384
-# CONFIG_MISC_DEVICES is not set
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
CONFIG_BLK_DEV_SD=y
diff --git a/arch/blackfin/configs/BlackStamp_defconfig b/arch/blackfin/configs/BlackStamp_defconfig
index 97ebe09a737..85014319672 100644
--- a/arch/blackfin/configs/BlackStamp_defconfig
+++ b/arch/blackfin/configs/BlackStamp_defconfig
@@ -58,6 +58,7 @@ CONFIG_MTD_M25P80=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT25=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
diff --git a/arch/blackfin/configs/CM-BF527_defconfig b/arch/blackfin/configs/CM-BF527_defconfig
index c2457543e58..dbf750cd2db 100644
--- a/arch/blackfin/configs/CM-BF527_defconfig
+++ b/arch/blackfin/configs/CM-BF527_defconfig
@@ -64,7 +64,6 @@ CONFIG_MTD_ROM=m
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_GPIO_ADDR=y
CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
# CONFIG_SCSI_LOWLEVEL is not set
diff --git a/arch/blackfin/configs/CM-BF533_defconfig b/arch/blackfin/configs/CM-BF533_defconfig
index baf1c1573e5..07ffbdae34e 100644
--- a/arch/blackfin/configs/CM-BF533_defconfig
+++ b/arch/blackfin/configs/CM-BF533_defconfig
@@ -44,7 +44,6 @@ CONFIG_MTD_CFI=y
CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_RAM=y
CONFIG_MTD_PHYSMAP=y
-# CONFIG_MISC_DEVICES is not set
CONFIG_NETDEVICES=y
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
diff --git a/arch/blackfin/configs/CM-BF548_defconfig b/arch/blackfin/configs/CM-BF548_defconfig
index df267588efe..31d954216c0 100644
--- a/arch/blackfin/configs/CM-BF548_defconfig
+++ b/arch/blackfin/configs/CM-BF548_defconfig
@@ -63,7 +63,6 @@ CONFIG_MTD_RAM=y
CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
CONFIG_SCSI=m
CONFIG_BLK_DEV_SD=m
# CONFIG_SCSI_LOWLEVEL is not set
diff --git a/arch/blackfin/configs/DNP5370_defconfig b/arch/blackfin/configs/DNP5370_defconfig
index f50313657f3..b192acfae38 100644
--- a/arch/blackfin/configs/DNP5370_defconfig
+++ b/arch/blackfin/configs/DNP5370_defconfig
@@ -55,7 +55,6 @@ CONFIG_MTD_NAND=y
CONFIG_MTD_NAND_PLATFORM=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
-# CONFIG_MISC_DEVICES is not set
CONFIG_NETDEVICES=y
CONFIG_DAVICOM_PHY=y
CONFIG_NET_ETHERNET=y
diff --git a/arch/blackfin/configs/H8606_defconfig b/arch/blackfin/configs/H8606_defconfig
index 7450127b645..06e9f497fae 100644
--- a/arch/blackfin/configs/H8606_defconfig
+++ b/arch/blackfin/configs/H8606_defconfig
@@ -45,6 +45,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_M25P80=y
# CONFIG_M25PXX_USE_FAST_READ is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT25=y
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
diff --git a/arch/blackfin/configs/SRV1_defconfig b/arch/blackfin/configs/SRV1_defconfig
index 853809510ee..12e66cd7cda 100644
--- a/arch/blackfin/configs/SRV1_defconfig
+++ b/arch/blackfin/configs/SRV1_defconfig
@@ -48,6 +48,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y
CONFIG_MTD_UCLINUX=y
CONFIG_MTD_NAND=m
CONFIG_BLK_DEV_RAM=y
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT25=m
CONFIG_NETDEVICES=y
# CONFIG_NETDEV_1000 is not set
diff --git a/arch/blackfin/include/asm/bitops.h b/arch/blackfin/include/asm/bitops.h
index 49762c6bb0d..8a0fed16058 100644
--- a/arch/blackfin/include/asm/bitops.h
+++ b/arch/blackfin/include/asm/bitops.h
@@ -25,7 +25,6 @@
#include <asm-generic/bitops/const_hweight.h>
#include <asm-generic/bitops/lock.h>
-#include <asm-generic/bitops/le.h>
#include <asm-generic/bitops/ext2-atomic.h>
#ifndef CONFIG_SMP
@@ -113,6 +112,9 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
#endif /* CONFIG_SMP */
+/* Needs to be after test_bit and friends */
+#include <asm-generic/bitops/le.h>
+
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index 8f079392aff..1696d34f51c 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -48,7 +48,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%3d: ", i);
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
- seq_printf(p, " %8s", get_irq_desc_chip(desc)->name);
+ seq_printf(p, " %8s", irq_desc_get_chip(desc)->name);
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
seq_printf(p, " %s", action->name);
diff --git a/arch/blackfin/kernel/module.c b/arch/blackfin/kernel/module.c
index a6dfa6b71e6..35e350cad9d 100644
--- a/arch/blackfin/kernel/module.c
+++ b/arch/blackfin/kernel/module.c
@@ -4,7 +4,7 @@
* Licensed under the GPL-2 or later
*/
-#define pr_fmt(fmt) "module %s: " fmt
+#define pr_fmt(fmt) "module %s: " fmt, mod->name
#include <linux/moduleloader.h>
#include <linux/elf.h>
@@ -57,8 +57,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
dest = l1_inst_sram_alloc(s->sh_size);
mod->arch.text_l1 = dest;
if (dest == NULL) {
- pr_err("L1 inst memory allocation failed\n",
- mod->name);
+ pr_err("L1 inst memory allocation failed\n");
return -1;
}
dma_memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -70,8 +69,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
dest = l1_data_sram_alloc(s->sh_size);
mod->arch.data_a_l1 = dest;
if (dest == NULL) {
- pr_err("L1 data memory allocation failed\n",
- mod->name);
+ pr_err("L1 data memory allocation failed\n");
return -1;
}
memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -83,8 +81,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
dest = l1_data_sram_zalloc(s->sh_size);
mod->arch.bss_a_l1 = dest;
if (dest == NULL) {
- pr_err("L1 data memory allocation failed\n",
- mod->name);
+ pr_err("L1 data memory allocation failed\n");
return -1;
}
@@ -93,8 +90,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
dest = l1_data_B_sram_alloc(s->sh_size);
mod->arch.data_b_l1 = dest;
if (dest == NULL) {
- pr_err("L1 data memory allocation failed\n",
- mod->name);
+ pr_err("L1 data memory allocation failed\n");
return -1;
}
memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -104,8 +100,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
dest = l1_data_B_sram_alloc(s->sh_size);
mod->arch.bss_b_l1 = dest;
if (dest == NULL) {
- pr_err("L1 data memory allocation failed\n",
- mod->name);
+ pr_err("L1 data memory allocation failed\n");
return -1;
}
memset(dest, 0, s->sh_size);
@@ -117,8 +112,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
dest = l2_sram_alloc(s->sh_size);
mod->arch.text_l2 = dest;
if (dest == NULL) {
- pr_err("L2 SRAM allocation failed\n",
- mod->name);
+ pr_err("L2 SRAM allocation failed\n");
return -1;
}
memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -130,8 +124,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
dest = l2_sram_alloc(s->sh_size);
mod->arch.data_l2 = dest;
if (dest == NULL) {
- pr_err("L2 SRAM allocation failed\n",
- mod->name);
+ pr_err("L2 SRAM allocation failed\n");
return -1;
}
memcpy(dest, (void *)s->sh_addr, s->sh_size);
@@ -143,8 +136,7 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
dest = l2_sram_zalloc(s->sh_size);
mod->arch.bss_l2 = dest;
if (dest == NULL) {
- pr_err("L2 SRAM allocation failed\n",
- mod->name);
+ pr_err("L2 SRAM allocation failed\n");
return -1;
}
@@ -160,9 +152,9 @@ module_frob_arch_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs,
int
apply_relocate(Elf_Shdr * sechdrs, const char *strtab,
- unsigned int symindex, unsigned int relsec, struct module *me)
+ unsigned int symindex, unsigned int relsec, struct module *mod)
{
- pr_err(".rel unsupported\n", me->name);
+ pr_err(".rel unsupported\n");
return -ENOEXEC;
}
@@ -186,7 +178,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
Elf32_Sym *sym;
unsigned long location, value, size;
- pr_debug("applying relocate section %u to %u\n", mod->name,
+ pr_debug("applying relocate section %u to %u\n",
relsec, sechdrs[relsec].sh_info);
for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
@@ -203,14 +195,14 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
#ifdef CONFIG_SMP
if (location >= COREB_L1_DATA_A_START) {
- pr_err("cannot relocate in L1: %u (SMP kernel)",
- mod->name, ELF32_R_TYPE(rel[i].r_info));
+ pr_err("cannot relocate in L1: %u (SMP kernel)\n",
+ ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
#endif
pr_debug("location is %lx, value is %lx type is %d\n",
- mod->name, location, value, ELF32_R_TYPE(rel[i].r_info));
+ location, value, ELF32_R_TYPE(rel[i].r_info));
switch (ELF32_R_TYPE(rel[i].r_info)) {
@@ -230,11 +222,11 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
case R_BFIN_PCREL12_JUMP_S:
case R_BFIN_PCREL10:
pr_err("unsupported relocation: %u (no -mlong-calls?)\n",
- mod->name, ELF32_R_TYPE(rel[i].r_info));
+ ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
default:
- pr_err("unknown relocation: %u\n", mod->name,
+ pr_err("unknown relocation: %u\n",
ELF32_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
@@ -251,8 +243,7 @@ apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
isram_memcpy((void *)location, &value, size);
break;
default:
- pr_err("invalid relocation for %#lx\n",
- mod->name, location);
+ pr_err("invalid relocation for %#lx\n", location);
return -ENOEXEC;
}
}
diff --git a/arch/blackfin/kernel/trace.c b/arch/blackfin/kernel/trace.c
index 05b550891ce..050db44fe91 100644
--- a/arch/blackfin/kernel/trace.c
+++ b/arch/blackfin/kernel/trace.c
@@ -912,10 +912,11 @@ void show_regs(struct pt_regs *fp)
/* if no interrupts are going off, don't print this out */
if (fp->ipend & ~0x3F) {
for (i = 0; i < (NR_IRQS - 1); i++) {
+ struct irq_desc *desc = irq_to_desc(i);
if (!in_atomic)
- raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
+ raw_spin_lock_irqsave(&desc->lock, flags);
- action = irq_desc[i].action;
+ action = desc->action;
if (!action)
goto unlock;
@@ -928,7 +929,7 @@ void show_regs(struct pt_regs *fp)
pr_cont("\n");
unlock:
if (!in_atomic)
- raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
}
}
diff --git a/arch/blackfin/mach-bf561/smp.c b/arch/blackfin/mach-bf561/smp.c
index 5d68bf613b0..7b07740cf68 100644
--- a/arch/blackfin/mach-bf561/smp.c
+++ b/arch/blackfin/mach-bf561/smp.c
@@ -154,13 +154,13 @@ void platform_clear_ipi(unsigned int cpu, int irq)
void __cpuinit bfin_local_timer_setup(void)
{
#if defined(CONFIG_TICKSOURCE_CORETMR)
- struct irq_chip *chip = get_irq_chip(IRQ_CORETMR);
- struct irq_desc *desc = irq_to_desc(IRQ_CORETMR);
+ struct irq_data *data = irq_get_irq_data(IRQ_CORETMR);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
bfin_coretmr_init();
bfin_coretmr_clockevent_init();
- chip->irq_unmask(&desc->irq_data);
+ chip->irq_unmask(data);
#else
/* Power down the core timer, just to play safe. */
bfin_write_TCNTL(0);
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c
index 6cd52395a99..43d9fb195c1 100644
--- a/arch/blackfin/mach-common/ints-priority.c
+++ b/arch/blackfin/mach-common/ints-priority.c
@@ -559,7 +559,7 @@ static inline void bfin_set_irq_handler(unsigned irq, irq_flow_handler_t handle)
#ifdef CONFIG_IPIPE
handle = handle_level_irq;
#endif
- __set_irq_handler_unlocked(irq, handle);
+ __irq_set_handler_locked(irq, handle);
}
static DECLARE_BITMAP(gpio_enabled, MAX_BLACKFIN_GPIOS);
@@ -578,10 +578,9 @@ static void bfin_gpio_ack_irq(struct irq_data *d)
static void bfin_gpio_mask_ack_irq(struct irq_data *d)
{
unsigned int irq = d->irq;
- struct irq_desc *desc = irq_to_desc(irq);
u32 gpionr = irq_to_gpio(irq);
- if (desc->handle_irq == handle_edge_irq)
+ if (!irqd_is_level_type(d))
set_gpio_data(gpionr, 0);
set_gpio_maska(gpionr, 0);
@@ -837,12 +836,11 @@ void init_pint_lut(void)
static void bfin_gpio_ack_irq(struct irq_data *d)
{
- struct irq_desc *desc = irq_to_desc(d->irq);
u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS];
u32 pintbit = PINT_BIT(pint_val);
u32 bank = PINT_2_BANK(pint_val);
- if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+ if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
if (pint[bank]->invert_set & pintbit)
pint[bank]->invert_clear = pintbit;
else
@@ -854,12 +852,11 @@ static void bfin_gpio_ack_irq(struct irq_data *d)
static void bfin_gpio_mask_ack_irq(struct irq_data *d)
{
- struct irq_desc *desc = irq_to_desc(d->irq);
u32 pint_val = irq2pint_lut[d->irq - SYS_IRQS];
u32 pintbit = PINT_BIT(pint_val);
u32 bank = PINT_2_BANK(pint_val);
- if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
+ if (irqd_get_trigger_type(d) == IRQ_TYPE_EDGE_BOTH) {
if (pint[bank]->invert_set & pintbit)
pint[bank]->invert_clear = pintbit;
else
@@ -1166,9 +1163,9 @@ int __init init_arch_irq(void)
for (irq = 0; irq <= SYS_IRQS; irq++) {
if (irq <= IRQ_CORETMR)
- set_irq_chip(irq, &bfin_core_irqchip);
+ irq_set_chip(irq, &bfin_core_irqchip);
else
- set_irq_chip(irq, &bfin_internal_irqchip);
+ irq_set_chip(irq, &bfin_internal_irqchip);
switch (irq) {
#if defined(CONFIG_BF53x)
@@ -1192,50 +1189,50 @@ int __init init_arch_irq(void)
#elif defined(CONFIG_BF538) || defined(CONFIG_BF539)
case IRQ_PORTF_INTA:
#endif
- set_irq_chained_handler(irq,
- bfin_demux_gpio_irq);
+ irq_set_chained_handler(irq, bfin_demux_gpio_irq);
break;
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
case IRQ_GENERIC_ERROR:
- set_irq_chained_handler(irq, bfin_demux_error_irq);
+ irq_set_chained_handler(irq, bfin_demux_error_irq);
break;
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
case IRQ_MAC_ERROR:
- set_irq_chained_handler(irq, bfin_demux_mac_status_irq);
+ irq_set_chained_handler(irq,
+ bfin_demux_mac_status_irq);
break;
#endif
#ifdef CONFIG_SMP
case IRQ_SUPPLE_0:
case IRQ_SUPPLE_1:
- set_irq_handler(irq, handle_percpu_irq);
+ irq_set_handler(irq, handle_percpu_irq);
break;
#endif
#ifdef CONFIG_TICKSOURCE_CORETMR
case IRQ_CORETMR:
# ifdef CONFIG_SMP
- set_irq_handler(irq, handle_percpu_irq);
+ irq_set_handler(irq, handle_percpu_irq);
break;
# else
- set_irq_handler(irq, handle_simple_irq);
+ irq_set_handler(irq, handle_simple_irq);
break;
# endif
#endif
#ifdef CONFIG_TICKSOURCE_GPTMR0
case IRQ_TIMER0:
- set_irq_handler(irq, handle_simple_irq);
+ irq_set_handler(irq, handle_simple_irq);
break;
#endif
#ifdef CONFIG_IPIPE
default:
- set_irq_handler(irq, handle_level_irq);
+ irq_set_handler(irq, handle_level_irq);
break;
#else /* !CONFIG_IPIPE */
default:
- set_irq_handler(irq, handle_simple_irq);
+ irq_set_handler(irq, handle_simple_irq);
break;
#endif /* !CONFIG_IPIPE */
}
@@ -1243,22 +1240,22 @@ int __init init_arch_irq(void)
#ifdef BF537_GENERIC_ERROR_INT_DEMUX
for (irq = IRQ_PPI_ERROR; irq <= IRQ_UART1_ERROR; irq++)
- set_irq_chip_and_handler(irq, &bfin_generic_error_irqchip,
+ irq_set_chip_and_handler(irq, &bfin_generic_error_irqchip,
handle_level_irq);
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
- set_irq_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
+ irq_set_chained_handler(IRQ_MAC_ERROR, bfin_demux_mac_status_irq);
#endif
#endif
#if defined(CONFIG_BFIN_MAC) || defined(CONFIG_BFIN_MAC_MODULE)
for (irq = IRQ_MAC_PHYINT; irq <= IRQ_MAC_STMDONE; irq++)
- set_irq_chip_and_handler(irq, &bfin_mac_status_irqchip,
+ irq_set_chip_and_handler(irq, &bfin_mac_status_irqchip,
handle_level_irq);
#endif
/* if configured as edge, then will be changed to do_edge_IRQ */
for (irq = GPIO_IRQ_BASE;
irq < (GPIO_IRQ_BASE + MAX_BLACKFIN_GPIOS); irq++)
- set_irq_chip_and_handler(irq, &bfin_gpio_irqchip,
+ irq_set_chip_and_handler(irq, &bfin_gpio_irqchip,
handle_level_irq);
bfin_write_IMASK(0);
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index 04a7fc5eaf4..a6d03069d0f 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -55,7 +55,6 @@ config CRIS
default y
select HAVE_IDE
select HAVE_GENERIC_HARDIRQS
- select GENERIC_HARDIRQS_NO_DEPRECATED
select GENERIC_IRQ_SHOW
config HZ
@@ -296,8 +295,7 @@ config ETRAX_RTC
choice
prompt "RTC chip"
depends on ETRAX_RTC
- default ETRAX_PCF8563 if ETRAX_ARCH_V32
- default ETRAX_DS1302 if ETRAX_ARCH_V10
+ default ETRAX_DS1302
config ETRAX_DS1302
depends on ETRAX_ARCH_V10
diff --git a/arch/cris/arch-v10/drivers/pcf8563.c b/arch/cris/arch-v10/drivers/pcf8563.c
index ea69faba9b6..1391b731ad1 100644
--- a/arch/cris/arch-v10/drivers/pcf8563.c
+++ b/arch/cris/arch-v10/drivers/pcf8563.c
@@ -345,7 +345,7 @@ static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned
int ret;
mutex_lock(&pcf8563_mutex);
- return pcf8563_ioctl(filp, cmd, arg);
+ ret = pcf8563_ioctl(filp, cmd, arg);
mutex_unlock(&pcf8563_mutex);
return ret;
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c
index b6be705c2a3..e78fe49a984 100644
--- a/arch/cris/arch-v10/kernel/signal.c
+++ b/arch/cris/arch-v10/kernel/signal.c
@@ -537,7 +537,7 @@ void do_signal(int canrestart, struct pt_regs *regs)
RESTART_CRIS_SYS(regs);
}
if (regs->r10 == -ERESTART_RESTARTBLOCK) {
- regs->r10 = __NR_restart_syscall;
+ regs->r9 = __NR_restart_syscall;
regs->irp -= 2;
}
}
diff --git a/arch/cris/arch-v32/drivers/Makefile b/arch/cris/arch-v32/drivers/Makefile
index e8c02437eda..39aa3c117a8 100644
--- a/arch/cris/arch-v32/drivers/Makefile
+++ b/arch/cris/arch-v32/drivers/Makefile
@@ -7,7 +7,6 @@ obj-$(CONFIG_ETRAX_AXISFLASHMAP) += axisflashmap.o
obj-$(CONFIG_ETRAXFS) += mach-fs/
obj-$(CONFIG_CRIS_MACH_ARTPEC3) += mach-a3/
obj-$(CONFIG_ETRAX_IOP_FW_LOAD) += iop_fw_load.o
-obj-$(CONFIG_ETRAX_PCF8563) += pcf8563.o
obj-$(CONFIG_ETRAX_I2C) += i2c.o
obj-$(CONFIG_ETRAX_SYNCHRONOUS_SERIAL) += sync_serial.o
obj-$(CONFIG_PCI) += pci/
diff --git a/arch/cris/arch-v32/drivers/pcf8563.c b/arch/cris/arch-v32/drivers/pcf8563.c
deleted file mode 100644
index b6e4fc0aad4..00000000000
--- a/arch/cris/arch-v32/drivers/pcf8563.c
+++ /dev/null
@@ -1,377 +0,0 @@
-/*
- * PCF8563 RTC
- *
- * From Phillips' datasheet:
- *
- * The PCF8563 is a CMOS real-time clock/calendar optimized for low power
- * consumption. A programmable clock output, interrupt output and voltage
- * low detector are also provided. All address and data are transferred
- * serially via two-line bidirectional I2C-bus. Maximum bus speed is
- * 400 kbits/s. The built-in word address register is incremented
- * automatically after each written or read byte.
- *
- * Copyright (c) 2002-2007, Axis Communications AB
- * All rights reserved.
- *
- * Author: Tobias Anderberg <tobiasa@axis.com>.
- *
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/fs.h>
-#include <linux/ioctl.h>
-#include <linux/delay.h>
-#include <linux/bcd.h>
-#include <linux/mutex.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/rtc.h>
-
-#include "i2c.h"
-
-#define PCF8563_MAJOR 121 /* Local major number. */
-#define DEVICE_NAME "rtc" /* Name which is registered in /proc/devices. */
-#define PCF8563_NAME "PCF8563"
-#define DRIVER_VERSION "$Revision: 1.17 $"
-
-/* Two simple wrapper macros, saves a few keystrokes. */
-#define rtc_read(x) i2c_readreg(RTC_I2C_READ, x)
-#define rtc_write(x,y) i2c_writereg(RTC_I2C_WRITE, x, y)
-
-static DEFINE_MUTEX(pcf8563_mutex);
-static DEFINE_MUTEX(rtc_lock); /* Protect state etc */
-
-static const unsigned char days_in_month[] =
- { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
-
-/* Cache VL bit value read at driver init since writing the RTC_SECOND
- * register clears the VL status.
- */
-static int voltage_low;
-
-static const struct file_operations pcf8563_fops = {
- .owner = THIS_MODULE,
- .unlocked_ioctl = pcf8563_unlocked_ioctl,
- .llseek = noop_llseek,
-};
-
-unsigned char
-pcf8563_readreg(int reg)
-{
- unsigned char res = rtc_read(reg);
-
- /* The PCF8563 does not return 0 for unimplemented bits. */
- switch (reg) {
- case RTC_SECONDS:
- case RTC_MINUTES:
- res &= 0x7F;
- break;
- case RTC_HOURS:
- case RTC_DAY_OF_MONTH:
- res &= 0x3F;
- break;
- case RTC_WEEKDAY:
- res &= 0x07;
- break;
- case RTC_MONTH:
- res &= 0x1F;
- break;
- case RTC_CONTROL1:
- res &= 0xA8;
- break;
- case RTC_CONTROL2:
- res &= 0x1F;
- break;
- case RTC_CLOCKOUT_FREQ:
- case RTC_TIMER_CONTROL:
- res &= 0x83;
- break;
- }
- return res;
-}
-
-void
-pcf8563_writereg(int reg, unsigned char val)
-{
- rtc_write(reg, val);
-}
-
-void
-get_rtc_time(struct rtc_time *tm)
-{
- tm->tm_sec = rtc_read(RTC_SECONDS);
- tm->tm_min = rtc_read(RTC_MINUTES);
- tm->tm_hour = rtc_read(RTC_HOURS);
- tm->tm_mday = rtc_read(RTC_DAY_OF_MONTH);
- tm->tm_wday = rtc_read(RTC_WEEKDAY);
- tm->tm_mon = rtc_read(RTC_MONTH);
- tm->tm_year = rtc_read(RTC_YEAR);
-
- if (tm->tm_sec & 0x80) {
- printk(KERN_ERR "%s: RTC Voltage Low - reliable date/time "
- "information is no longer guaranteed!\n", PCF8563_NAME);
- }
-
- tm->tm_year = bcd2bin(tm->tm_year) +
- ((tm->tm_mon & 0x80) ? 100 : 0);
- tm->tm_sec &= 0x7F;
- tm->tm_min &= 0x7F;
- tm->tm_hour &= 0x3F;
- tm->tm_mday &= 0x3F;
- tm->tm_wday &= 0x07; /* Not coded in BCD. */
- tm->tm_mon &= 0x1F;
-
- tm->tm_sec = bcd2bin(tm->tm_sec);
- tm->tm_min = bcd2bin(tm->tm_min);
- tm->tm_hour = bcd2bin(tm->tm_hour);
- tm->tm_mday = bcd2bin(tm->tm_mday);
- tm->tm_mon = bcd2bin(tm->tm_mon);
- tm->tm_mon--; /* Month is 1..12 in RTC but 0..11 in linux */
-}
-
-int __init
-pcf8563_init(void)
-{
- static int res;
- static int first = 1;
-
- if (!first)
- return res;
- first = 0;
-
- /* Initiate the i2c protocol. */
- res = i2c_init();
- if (res < 0) {
- printk(KERN_CRIT "pcf8563_init: Failed to init i2c.\n");
- return res;
- }
-
- /*
- * First of all we need to reset the chip. This is done by
- * clearing control1, control2 and clk freq and resetting
- * all alarms.
- */
- if (rtc_write(RTC_CONTROL1, 0x00) < 0)
- goto err;
-
- if (rtc_write(RTC_CONTROL2, 0x00) < 0)
- goto err;
-
- if (rtc_write(RTC_CLOCKOUT_FREQ, 0x00) < 0)
- goto err;
-
- if (rtc_write(RTC_TIMER_CONTROL, 0x03) < 0)
- goto err;
-
- /* Reset the alarms. */
- if (rtc_write(RTC_MINUTE_ALARM, 0x80) < 0)
- goto err;
-
- if (rtc_write(RTC_HOUR_ALARM, 0x80) < 0)
- goto err;
-
- if (rtc_write(RTC_DAY_ALARM, 0x80) < 0)
- goto err;
-
- if (rtc_write(RTC_WEEKDAY_ALARM, 0x80) < 0)
- goto err;
-
- /* Check for low voltage, and warn about it. */
- if (rtc_read(RTC_SECONDS) & 0x80) {
- voltage_low = 1;
- printk(KERN_WARNING "%s: RTC Voltage Low - reliable "
- "date/time information is no longer guaranteed!\n",
- PCF8563_NAME);
- }
-
- return res;
-
-err:
- printk(KERN_INFO "%s: Error initializing chip.\n", PCF8563_NAME);
- res = -1;
- return res;
-}
-
-void __exit
-pcf8563_exit(void)
-{
- unregister_chrdev(PCF8563_MAJOR, DEVICE_NAME);
-}
-
-/*
- * ioctl calls for this driver. Why return -ENOTTY upon error? Because
- * POSIX says so!
- */
-static int pcf8563_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- /* Some sanity checks. */
- if (_IOC_TYPE(cmd) != RTC_MAGIC)
- return -ENOTTY;
-
- if (_IOC_NR(cmd) > RTC_MAX_IOCTL)
- return -ENOTTY;
-
- switch (cmd) {
- case RTC_RD_TIME:
- {
- struct rtc_time tm;
-
- mutex_lock(&rtc_lock);
- memset(&tm, 0, sizeof tm);
- get_rtc_time(&tm);
-
- if (copy_to_user((struct rtc_time *) arg, &tm,
- sizeof tm)) {
- mutex_unlock(&rtc_lock);
- return -EFAULT;
- }
-
- mutex_unlock(&rtc_lock);
-
- return 0;
- }
- case RTC_SET_TIME:
- {
- int leap;
- int year;
- int century;
- struct rtc_time tm;
-
- memset(&tm, 0, sizeof tm);
- if (!capable(CAP_SYS_TIME))
- return -EPERM;
-
- if (copy_from_user(&tm, (struct rtc_time *) arg,
- sizeof tm))
- return -EFAULT;
-
- /* Convert from struct tm to struct rtc_time. */
- tm.tm_year += 1900;
- tm.tm_mon += 1;
-
- /*
- * Check if tm.tm_year is a leap year. A year is a leap
- * year if it is divisible by 4 but not 100, except
- * that years divisible by 400 _are_ leap years.
- */
- year = tm.tm_year;
- leap = (tm.tm_mon == 2) &&
- ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
-
- /* Perform some sanity checks. */
- if ((tm.tm_year < 1970) ||
- (tm.tm_mon > 12) ||
- (tm.tm_mday == 0) ||
- (tm.tm_mday > days_in_month[tm.tm_mon] + leap) ||
- (tm.tm_wday >= 7) ||
- (tm.tm_hour >= 24) ||
- (tm.tm_min >= 60) ||
- (tm.tm_sec >= 60))
- return -EINVAL;
-
- century = (tm.tm_year >= 2000) ? 0x80 : 0;
- tm.tm_year = tm.tm_year % 100;
-
- tm.tm_year = bin2bcd(tm.tm_year);
- tm.tm_mon = bin2bcd(tm.tm_mon);
- tm.tm_mday = bin2bcd(tm.tm_mday);
- tm.tm_hour = bin2bcd(tm.tm_hour);
- tm.tm_min = bin2bcd(tm.tm_min);
- tm.tm_sec = bin2bcd(tm.tm_sec);
- tm.tm_mon |= century;
-
- mutex_lock(&rtc_lock);
-
- rtc_write(RTC_YEAR, tm.tm_year);
- rtc_write(RTC_MONTH, tm.tm_mon);
- rtc_write(RTC_WEEKDAY, tm.tm_wday); /* Not coded in BCD. */
- rtc_write(RTC_DAY_OF_MONTH, tm.tm_mday);
- rtc_write(RTC_HOURS, tm.tm_hour);
- rtc_write(RTC_MINUTES, tm.tm_min);
- rtc_write(RTC_SECONDS, tm.tm_sec);
-
- mutex_unlock(&rtc_lock);
-
- return 0;
- }
- case RTC_VL_READ:
- if (voltage_low)
- printk(KERN_ERR "%s: RTC Voltage Low - "
- "reliable date/time information is no "
- "longer guaranteed!\n", PCF8563_NAME);
-
- if (copy_to_user((int *) arg, &voltage_low, sizeof(int)))
- return -EFAULT;
- return 0;
-
- case RTC_VL_CLR:
- {
- /* Clear the VL bit in the seconds register in case
- * the time has not been set already (which would
- * have cleared it). This does not really matter
- * because of the cached voltage_low value but do it
- * anyway for consistency. */
-
- int ret = rtc_read(RTC_SECONDS);
-
- rtc_write(RTC_SECONDS, (ret & 0x7F));
-
- /* Clear the cached value. */
- voltage_low = 0;
-
- return 0;
- }
- default:
- return -ENOTTY;
- }
-
- return 0;
-}
-
-static long pcf8563_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
-{
- int ret;
-
- mutex_lock(&pcf8563_mutex);
- return pcf8563_ioctl(filp, cmd, arg);
- mutex_unlock(&pcf8563_mutex);
-
- return ret;
-}
-
-static int __init pcf8563_register(void)
-{
- if (pcf8563_init() < 0) {
- printk(KERN_INFO "%s: Unable to initialize Real-Time Clock "
- "Driver, %s\n", PCF8563_NAME, DRIVER_VERSION);
- return -1;
- }
-
- if (register_chrdev(PCF8563_MAJOR, DEVICE_NAME, &pcf8563_fops) < 0) {
- printk(KERN_INFO "%s: Unable to get major numer %d for RTC "
- "device.\n", PCF8563_NAME, PCF8563_MAJOR);
- return -1;
- }
-
- printk(KERN_INFO "%s Real-Time Clock Driver, %s\n", PCF8563_NAME,
- DRIVER_VERSION);
-
- /* Check for low voltage, and warn about it. */
- if (voltage_low) {
- printk(KERN_WARNING "%s: RTC Voltage Low - reliable date/time "
- "information is no longer guaranteed!\n", PCF8563_NAME);
- }
-
- return 0;
-}
-
-module_init(pcf8563_register);
-module_exit(pcf8563_exit);
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index f6037b2da25..064f6219674 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -6,6 +6,7 @@ config FRV
select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
config ZONE_DMA
bool
@@ -361,7 +362,6 @@ menu "Power management options"
config ARCH_SUSPEND_POSSIBLE
def_bool y
- depends on !SMP
source kernel/power/Kconfig
endmenu
diff --git a/arch/frv/include/asm/system.h b/arch/frv/include/asm/system.h
index 0a6d8d9ca45..6c10fd2c626 100644
--- a/arch/frv/include/asm/system.h
+++ b/arch/frv/include/asm/system.h
@@ -45,21 +45,12 @@ do { \
#define wmb() asm volatile ("membar" : : :"memory")
#define read_barrier_depends() do { } while (0)
-#ifdef CONFIG_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#define smp_read_barrier_depends() read_barrier_depends()
-#define set_mb(var, value) \
- do { xchg(&var, (value)); } while (0)
-#else
#define smp_mb() barrier()
#define smp_rmb() barrier()
#define smp_wmb() barrier()
#define smp_read_barrier_depends() do {} while(0)
#define set_mb(var, value) \
do { var = (value); barrier(); } while (0)
-#endif
extern void die_if_kernel(const char *, ...) __attribute__((format(printf, 1, 2)));
extern void free_initmem(void);
diff --git a/arch/frv/include/asm/thread_info.h b/arch/frv/include/asm/thread_info.h
index 8582e9c7531..cefbe73dc11 100644
--- a/arch/frv/include/asm/thread_info.h
+++ b/arch/frv/include/asm/thread_info.h
@@ -21,6 +21,8 @@
#define THREAD_SIZE 8192
+#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
+
/*
* low level task data that entry.S needs immediate access to
* - this struct should fit entirely inside of one cache line
@@ -87,7 +89,7 @@ register struct thread_info *__current_thread_info asm("gr15");
#define alloc_thread_info_node(tsk, node) \
kzalloc_node(THREAD_SIZE, GFP_KERNEL, node)
#else
-#define alloc_thread_info_node(tsk) \
+#define alloc_thread_info_node(tsk, node) \
kmalloc_node(THREAD_SIZE, GFP_KERNEL, node)
#endif
diff --git a/arch/frv/kernel/irq-mb93091.c b/arch/frv/kernel/irq-mb93091.c
index 4dd9adaf115..9afc2ea400d 100644
--- a/arch/frv/kernel/irq-mb93091.c
+++ b/arch/frv/kernel/irq-mb93091.c
@@ -36,45 +36,45 @@
/*
* on-motherboard FPGA PIC operations
*/
-static void frv_fpga_mask(unsigned int irq)
+static void frv_fpga_mask(struct irq_data *d)
{
uint16_t imr = __get_IMR();
- imr |= 1 << (irq - IRQ_BASE_FPGA);
+ imr |= 1 << (d->irq - IRQ_BASE_FPGA);
__set_IMR(imr);
}
-static void frv_fpga_ack(unsigned int irq)
+static void frv_fpga_ack(struct irq_data *d)
{
- __clr_IFR(1 << (irq - IRQ_BASE_FPGA));
+ __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
}
-static void frv_fpga_mask_ack(unsigned int irq)
+static void frv_fpga_mask_ack(struct irq_data *d)
{
uint16_t imr = __get_IMR();
- imr |= 1 << (irq - IRQ_BASE_FPGA);
+ imr |= 1 << (d->irq - IRQ_BASE_FPGA);
__set_IMR(imr);
- __clr_IFR(1 << (irq - IRQ_BASE_FPGA));
+ __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
}
-static void frv_fpga_unmask(unsigned int irq)
+static void frv_fpga_unmask(struct irq_data *d)
{
uint16_t imr = __get_IMR();
- imr &= ~(1 << (irq - IRQ_BASE_FPGA));
+ imr &= ~(1 << (d->irq - IRQ_BASE_FPGA));
__set_IMR(imr);
}
static struct irq_chip frv_fpga_pic = {
.name = "mb93091",
- .ack = frv_fpga_ack,
- .mask = frv_fpga_mask,
- .mask_ack = frv_fpga_mask_ack,
- .unmask = frv_fpga_unmask,
+ .irq_ack = frv_fpga_ack,
+ .irq_mask = frv_fpga_mask,
+ .irq_mask_ack = frv_fpga_mask_ack,
+ .irq_unmask = frv_fpga_unmask,
};
/*
@@ -146,9 +146,9 @@ void __init fpga_init(void)
__clr_IFR(0x0000);
for (irq = IRQ_BASE_FPGA + 1; irq <= IRQ_BASE_FPGA + 14; irq++)
- set_irq_chip_and_handler(irq, &frv_fpga_pic, handle_level_irq);
+ irq_set_chip_and_handler(irq, &frv_fpga_pic, handle_level_irq);
- set_irq_chip_and_handler(IRQ_FPGA_NMI, &frv_fpga_pic, handle_edge_irq);
+ irq_set_chip_and_handler(IRQ_FPGA_NMI, &frv_fpga_pic, handle_edge_irq);
/* the FPGA drives the first four external IRQ inputs on the CPU PIC */
setup_irq(IRQ_CPU_EXTERNAL0, &fpga_irq[0]);
diff --git a/arch/frv/kernel/irq-mb93093.c b/arch/frv/kernel/irq-mb93093.c
index e4520903187..4d4ad09d3c9 100644
--- a/arch/frv/kernel/irq-mb93093.c
+++ b/arch/frv/kernel/irq-mb93093.c
@@ -35,45 +35,44 @@
/*
* off-CPU FPGA PIC operations
*/
-static void frv_fpga_mask(unsigned int irq)
+static void frv_fpga_mask(struct irq_data *d)
{
uint16_t imr = __get_IMR();
- imr |= 1 << (irq - IRQ_BASE_FPGA);
+ imr |= 1 << (d->irq - IRQ_BASE_FPGA);
__set_IMR(imr);
}
-static void frv_fpga_ack(unsigned int irq)
+static void frv_fpga_ack(struct irq_data *d)
{
- __clr_IFR(1 << (irq - IRQ_BASE_FPGA));
+ __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
}
-static void frv_fpga_mask_ack(unsigned int irq)
+static void frv_fpga_mask_ack(struct irq_data *d)
{
uint16_t imr = __get_IMR();
- imr |= 1 << (irq - IRQ_BASE_FPGA);
+ imr |= 1 << (d->irq - IRQ_BASE_FPGA);
__set_IMR(imr);
- __clr_IFR(1 << (irq - IRQ_BASE_FPGA));
+ __clr_IFR(1 << (d->irq - IRQ_BASE_FPGA));
}
-static void frv_fpga_unmask(unsigned int irq)
+static void frv_fpga_unmask(struct irq_data *d)
{
uint16_t imr = __get_IMR();
- imr &= ~(1 << (irq - IRQ_BASE_FPGA));
+ imr &= ~(1 << (d->irq - IRQ_BASE_FPGA));
__set_IMR(imr);
}
static struct irq_chip frv_fpga_pic = {
.name = "mb93093",
- .ack = frv_fpga_ack,
- .mask = frv_fpga_mask,
- .mask_ack = frv_fpga_mask_ack,
- .unmask = frv_fpga_unmask,
- .end = frv_fpga_end,
+ .irq_ack = frv_fpga_ack,
+ .irq_mask = frv_fpga_mask,
+ .irq_mask_ack = frv_fpga_mask_ack,
+ .irq_unmask = frv_fpga_unmask,
};
/*
@@ -94,7 +93,7 @@ static irqreturn_t fpga_interrupt(int irq, void *_mask)
irq = 31 - irq;
mask &= ~(1 << irq);
- generic_irq_handle(IRQ_BASE_FPGA + irq);
+ generic_handle_irq(IRQ_BASE_FPGA + irq);
}
return IRQ_HANDLED;
@@ -125,7 +124,7 @@ void __init fpga_init(void)
__clr_IFR(0x0000);
for (irq = IRQ_BASE_FPGA + 8; irq <= IRQ_BASE_FPGA + 10; irq++)
- set_irq_chip_and_handler(irq, &frv_fpga_pic, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &frv_fpga_pic, handle_edge_irq);
/* the FPGA drives external IRQ input #2 on the CPU PIC */
setup_irq(IRQ_CPU_EXTERNAL2, &fpga_irq[0]);
diff --git a/arch/frv/kernel/irq-mb93493.c b/arch/frv/kernel/irq-mb93493.c
index ba55ecdfb24..4d034c7840c 100644
--- a/arch/frv/kernel/irq-mb93493.c
+++ b/arch/frv/kernel/irq-mb93493.c
@@ -45,46 +45,46 @@
* daughter board PIC operations
* - there is no way to ACK interrupts in the MB93493 chip
*/
-static void frv_mb93493_mask(unsigned int irq)
+static void frv_mb93493_mask(struct irq_data *d)
{
uint32_t iqsr;
volatile void *piqsr;
- if (IRQ_ROUTING & (1 << (irq - IRQ_BASE_MB93493)))
+ if (IRQ_ROUTING & (1 << (d->irq - IRQ_BASE_MB93493)))
piqsr = __addr_MB93493_IQSR(1);
else
piqsr = __addr_MB93493_IQSR(0);
iqsr = readl(piqsr);
- iqsr &= ~(1 << (irq - IRQ_BASE_MB93493 + 16));
+ iqsr &= ~(1 << (d->irq - IRQ_BASE_MB93493 + 16));
writel(iqsr, piqsr);
}
-static void frv_mb93493_ack(unsigned int irq)
+static void frv_mb93493_ack(struct irq_data *d)
{
}
-static void frv_mb93493_unmask(unsigned int irq)
+static void frv_mb93493_unmask(struct irq_data *d)
{
uint32_t iqsr;
volatile void *piqsr;
- if (IRQ_ROUTING & (1 << (irq - IRQ_BASE_MB93493)))
+ if (IRQ_ROUTING & (1 << (d->irq - IRQ_BASE_MB93493)))
piqsr = __addr_MB93493_IQSR(1);
else
piqsr = __addr_MB93493_IQSR(0);
iqsr = readl(piqsr);
- iqsr |= 1 << (irq - IRQ_BASE_MB93493 + 16);
+ iqsr |= 1 << (d->irq - IRQ_BASE_MB93493 + 16);
writel(iqsr, piqsr);
}
static struct irq_chip frv_mb93493_pic = {
.name = "mb93093",
- .ack = frv_mb93493_ack,
- .mask = frv_mb93493_mask,
- .mask_ack = frv_mb93493_mask,
- .unmask = frv_mb93493_unmask,
+ .irq_ack = frv_mb93493_ack,
+ .irq_mask = frv_mb93493_mask,
+ .irq_mask_ack = frv_mb93493_mask,
+ .irq_unmask = frv_mb93493_unmask,
};
/*
@@ -139,7 +139,8 @@ void __init mb93493_init(void)
int irq;
for (irq = IRQ_BASE_MB93493 + 0; irq <= IRQ_BASE_MB93493 + 10; irq++)
- set_irq_chip_and_handler(irq, &frv_mb93493_pic, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &frv_mb93493_pic,
+ handle_edge_irq);
/* the MB93493 drives external IRQ inputs on the CPU PIC */
setup_irq(IRQ_CPU_MB93493_0, &mb93493_irq[0]);
diff --git a/arch/frv/kernel/irq.c b/arch/frv/kernel/irq.c
index 625136625a7..a5f624a9f55 100644
--- a/arch/frv/kernel/irq.c
+++ b/arch/frv/kernel/irq.c
@@ -47,89 +47,45 @@ extern void __init mb93493_init(void);
atomic_t irq_err_count;
-/*
- * Generic, controller-independent functions:
- */
-int show_interrupts(struct seq_file *p, void *v)
+int arch_show_interrupts(struct seq_file *p, int prec)
{
- int i = *(loff_t *) v, cpu;
- struct irqaction * action;
- unsigned long flags;
-
- if (i == 0) {
- char cpuname[12];
-
- seq_printf(p, " ");
- for_each_present_cpu(cpu) {
- sprintf(cpuname, "CPU%d", cpu);
- seq_printf(p, " %10s", cpuname);
- }
- seq_putc(p, '\n');
- }
-
- if (i < NR_IRQS) {
- raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
- action = irq_desc[i].action;
- if (action) {
- seq_printf(p, "%3d: ", i);
- for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
- seq_printf(p, " %10s", irq_desc[i].chip->name ? : "-");
- seq_printf(p, " %s", action->name);
- for (action = action->next;
- action;
- action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
- }
-
- raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS) {
- seq_printf(p, "Err: %10u\n", atomic_read(&irq_err_count));
- }
-
+ seq_printf(p, "%*s: ", prec, "ERR");
+ seq_printf(p, "%10u\n", atomic_read(&irq_err_count));
return 0;
}
/*
* on-CPU PIC operations
*/
-static void frv_cpupic_ack(unsigned int irqlevel)
+static void frv_cpupic_ack(struct irq_data *d)
{
- __clr_RC(irqlevel);
+ __clr_RC(d->irq);
__clr_IRL();
}
-static void frv_cpupic_mask(unsigned int irqlevel)
+static void frv_cpupic_mask(struct irq_data *d)
{
- __set_MASK(irqlevel);
+ __set_MASK(d->irq);
}
-static void frv_cpupic_mask_ack(unsigned int irqlevel)
+static void frv_cpupic_mask_ack(struct irq_data *d)
{
- __set_MASK(irqlevel);
- __clr_RC(irqlevel);
+ __set_MASK(d->irq);
+ __clr_RC(d->irq);
__clr_IRL();
}
-static void frv_cpupic_unmask(unsigned int irqlevel)
-{
- __clr_MASK(irqlevel);
-}
-
-static void frv_cpupic_end(unsigned int irqlevel)
+static void frv_cpupic_unmask(struct irq_data *d)
{
- __clr_MASK(irqlevel);
+ __clr_MASK(d->irq);
}
static struct irq_chip frv_cpu_pic = {
.name = "cpu",
- .ack = frv_cpupic_ack,
- .mask = frv_cpupic_mask,
- .mask_ack = frv_cpupic_mask_ack,
- .unmask = frv_cpupic_unmask,
- .end = frv_cpupic_end,
+ .irq_ack = frv_cpupic_ack,
+ .irq_mask = frv_cpupic_mask,
+ .irq_mask_ack = frv_cpupic_mask_ack,
+ .irq_unmask = frv_cpupic_unmask,
};
/*
@@ -161,10 +117,10 @@ void __init init_IRQ(void)
int level;
for (level = 1; level <= 14; level++)
- set_irq_chip_and_handler(level, &frv_cpu_pic,
+ irq_set_chip_and_handler(level, &frv_cpu_pic,
handle_level_irq);
- set_irq_handler(IRQ_CPU_TIMER0, handle_edge_irq);
+ irq_set_handler(IRQ_CPU_TIMER0, handle_edge_irq);
/* set the trigger levels for internal interrupt sources
* - timers all falling-edge
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 931a1ac99ff..e20322ffcaf 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -3,7 +3,6 @@ config H8300
default y
select HAVE_IDE
select HAVE_GENERIC_HARDIRQS
- select GENERIC_HARDIRQS_NO_DEPRECATED
select GENERIC_IRQ_SHOW
config SYMBOL_PREFIX
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index fcf3b437a2d..c4ea0925cdb 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -26,6 +26,7 @@ config IA64
select GENERIC_IRQ_PROBE
select GENERIC_PENDING_IRQ if SMP
select IRQ_PER_CPU
+ select GENERIC_IRQ_SHOW
default y
help
The Itanium Processor Family is Intel's 64-bit successor to
diff --git a/arch/ia64/hp/sim/hpsim_irq.c b/arch/ia64/hp/sim/hpsim_irq.c
index b272261d77c..4bd9a63260e 100644
--- a/arch/ia64/hp/sim/hpsim_irq.c
+++ b/arch/ia64/hp/sim/hpsim_irq.c
@@ -11,42 +11,41 @@
#include <linux/irq.h>
static unsigned int
-hpsim_irq_startup (unsigned int irq)
+hpsim_irq_startup(struct irq_data *data)
{
return 0;
}
static void
-hpsim_irq_noop (unsigned int irq)
+hpsim_irq_noop(struct irq_data *data)
{
}
static int
-hpsim_set_affinity_noop(unsigned int a, const struct cpumask *b)
+hpsim_set_affinity_noop(struct irq_data *d, const struct cpumask *b, bool f)
{
return 0;
}
static struct irq_chip irq_type_hp_sim = {
- .name = "hpsim",
- .startup = hpsim_irq_startup,
- .shutdown = hpsim_irq_noop,
- .enable = hpsim_irq_noop,
- .disable = hpsim_irq_noop,
- .ack = hpsim_irq_noop,
- .end = hpsim_irq_noop,
- .set_affinity = hpsim_set_affinity_noop,
+ .name = "hpsim",
+ .irq_startup = hpsim_irq_startup,
+ .irq_shutdown = hpsim_irq_noop,
+ .irq_enable = hpsim_irq_noop,
+ .irq_disable = hpsim_irq_noop,
+ .irq_ack = hpsim_irq_noop,
+ .irq_set_affinity = hpsim_set_affinity_noop,
};
void __init
hpsim_irq_init (void)
{
- struct irq_desc *idesc;
int i;
- for (i = 0; i < NR_IRQS; ++i) {
- idesc = irq_desc + i;
- if (idesc->chip == &no_irq_chip)
- idesc->chip = &irq_type_hp_sim;
+ for_each_active_irq(i) {
+ struct irq_chip *chip = irq_get_chip(i);
+
+ if (chip == &no_irq_chip)
+ irq_set_chip(i, &irq_type_hp_sim);
}
}
diff --git a/arch/ia64/include/asm/hw_irq.h b/arch/ia64/include/asm/hw_irq.h
index bf2e37493e0..a681d02cb32 100644
--- a/arch/ia64/include/asm/hw_irq.h
+++ b/arch/ia64/include/asm/hw_irq.h
@@ -151,9 +151,6 @@ static inline void ia64_native_resend_irq(unsigned int vector)
/*
* Default implementations for the irq-descriptor API:
*/
-
-extern struct irq_desc irq_desc[NR_IRQS];
-
#ifndef CONFIG_IA64_GENERIC
static inline ia64_vector __ia64_irq_to_vector(int irq)
{
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 22c38404f53..b0f9afebb14 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -257,7 +257,7 @@ set_rte (unsigned int gsi, unsigned int irq, unsigned int dest, int mask)
}
static void
-nop (unsigned int irq)
+nop (struct irq_data *data)
{
/* do nothing... */
}
@@ -287,8 +287,9 @@ kexec_disable_iosapic(void)
#endif
static void
-mask_irq (unsigned int irq)
+mask_irq (struct irq_data *data)
{
+ unsigned int irq = data->irq;
u32 low32;
int rte_index;
struct iosapic_rte_info *rte;
@@ -305,8 +306,9 @@ mask_irq (unsigned int irq)
}
static void
-unmask_irq (unsigned int irq)
+unmask_irq (struct irq_data *data)
{
+ unsigned int irq = data->irq;
u32 low32;
int rte_index;
struct iosapic_rte_info *rte;
@@ -323,9 +325,11 @@ unmask_irq (unsigned int irq)
static int
-iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
+iosapic_set_affinity(struct irq_data *data, const struct cpumask *mask,
+ bool force)
{
#ifdef CONFIG_SMP
+ unsigned int irq = data->irq;
u32 high32, low32;
int cpu, dest, rte_index;
int redir = (irq & IA64_IRQ_REDIRECTED) ? 1 : 0;
@@ -379,32 +383,33 @@ iosapic_set_affinity(unsigned int irq, const struct cpumask *mask)
*/
static unsigned int
-iosapic_startup_level_irq (unsigned int irq)
+iosapic_startup_level_irq (struct irq_data *data)
{
- unmask_irq(irq);
+ unmask_irq(data);
return 0;
}
static void
-iosapic_unmask_level_irq (unsigned int irq)
+iosapic_unmask_level_irq (struct irq_data *data)
{
+ unsigned int irq = data->irq;
ia64_vector vec = irq_to_vector(irq);
struct iosapic_rte_info *rte;
int do_unmask_irq = 0;
irq_complete_move(irq);
- if (unlikely(irq_desc[irq].status & IRQ_MOVE_PENDING)) {
+ if (unlikely(irqd_is_setaffinity_pending(data))) {
do_unmask_irq = 1;
- mask_irq(irq);
+ mask_irq(data);
} else
- unmask_irq(irq);
+ unmask_irq(data);
list_for_each_entry(rte, &iosapic_intr_info[irq].rtes, rte_list)
iosapic_eoi(rte->iosapic->addr, vec);
if (unlikely(do_unmask_irq)) {
- move_masked_irq(irq);
- unmask_irq(irq);
+ irq_move_masked_irq(data);
+ unmask_irq(data);
}
}
@@ -414,15 +419,15 @@ iosapic_unmask_level_irq (unsigned int irq)
#define iosapic_ack_level_irq nop
static struct irq_chip irq_type_iosapic_level = {
- .name = "IO-SAPIC-level",
- .startup = iosapic_startup_level_irq,
- .shutdown = iosapic_shutdown_level_irq,
- .enable = iosapic_enable_level_irq,
- .disable = iosapic_disable_level_irq,
- .ack = iosapic_ack_level_irq,
- .mask = mask_irq,
- .unmask = iosapic_unmask_level_irq,
- .set_affinity = iosapic_set_affinity
+ .name = "IO-SAPIC-level",
+ .irq_startup = iosapic_startup_level_irq,
+ .irq_shutdown = iosapic_shutdown_level_irq,
+ .irq_enable = iosapic_enable_level_irq,
+ .irq_disable = iosapic_disable_level_irq,
+ .irq_ack = iosapic_ack_level_irq,
+ .irq_mask = mask_irq,
+ .irq_unmask = iosapic_unmask_level_irq,
+ .irq_set_affinity = iosapic_set_affinity
};
/*
@@ -430,9 +435,9 @@ static struct irq_chip irq_type_iosapic_level = {
*/
static unsigned int
-iosapic_startup_edge_irq (unsigned int irq)
+iosapic_startup_edge_irq (struct irq_data *data)
{
- unmask_irq(irq);
+ unmask_irq(data);
/*
* IOSAPIC simply drops interrupts pended while the
* corresponding pin was masked, so we can't know if an
@@ -442,37 +447,25 @@ iosapic_startup_edge_irq (unsigned int irq)
}
static void
-iosapic_ack_edge_irq (unsigned int irq)
+iosapic_ack_edge_irq (struct irq_data *data)
{
- struct irq_desc *idesc = irq_desc + irq;
-
- irq_complete_move(irq);
- move_native_irq(irq);
- /*
- * Once we have recorded IRQ_PENDING already, we can mask the
- * interrupt for real. This prevents IRQ storms from unhandled
- * devices.
- */
- if ((idesc->status & (IRQ_PENDING|IRQ_DISABLED)) ==
- (IRQ_PENDING|IRQ_DISABLED))
- mask_irq(irq);
+ irq_complete_move(data->irq);
+ irq_move_irq(data);
}
#define iosapic_enable_edge_irq unmask_irq
#define iosapic_disable_edge_irq nop
-#define iosapic_end_edge_irq nop
static struct irq_chip irq_type_iosapic_edge = {
- .name = "IO-SAPIC-edge",
- .startup = iosapic_startup_edge_irq,
- .shutdown = iosapic_disable_edge_irq,
- .enable = iosapic_enable_edge_irq,
- .disable = iosapic_disable_edge_irq,
- .ack = iosapic_ack_edge_irq,
- .end = iosapic_end_edge_irq,
- .mask = mask_irq,
- .unmask = unmask_irq,
- .set_affinity = iosapic_set_affinity
+ .name = "IO-SAPIC-edge",
+ .irq_startup = iosapic_startup_edge_irq,
+ .irq_shutdown = iosapic_disable_edge_irq,
+ .irq_enable = iosapic_enable_edge_irq,
+ .irq_disable = iosapic_disable_edge_irq,
+ .irq_ack = iosapic_ack_edge_irq,
+ .irq_mask = mask_irq,
+ .irq_unmask = unmask_irq,
+ .irq_set_affinity = iosapic_set_affinity
};
static unsigned int
@@ -562,8 +555,7 @@ static int
register_intr (unsigned int gsi, int irq, unsigned char delivery,
unsigned long polarity, unsigned long trigger)
{
- struct irq_desc *idesc;
- struct irq_chip *irq_type;
+ struct irq_chip *chip, *irq_type;
int index;
struct iosapic_rte_info *rte;
@@ -610,19 +602,18 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
irq_type = iosapic_get_irq_chip(trigger);
- idesc = irq_desc + irq;
- if (irq_type != NULL && idesc->chip != irq_type) {
- if (idesc->chip != &no_irq_chip)
+ chip = irq_get_chip(irq);
+ if (irq_type != NULL && chip != irq_type) {
+ if (chip != &no_irq_chip)
printk(KERN_WARNING
"%s: changing vector %d from %s to %s\n",
__func__, irq_to_vector(irq),
- idesc->chip->name, irq_type->name);
- idesc->chip = irq_type;
+ chip->name, irq_type->name);
+ chip = irq_type;
}
- if (trigger == IOSAPIC_EDGE)
- __set_irq_handler_unlocked(irq, handle_edge_irq);
- else
- __set_irq_handler_unlocked(irq, handle_level_irq);
+ __irq_set_chip_handler_name_locked(irq, chip, trigger == IOSAPIC_EDGE ?
+ handle_edge_irq : handle_level_irq,
+ NULL);
return 0;
}
@@ -732,6 +723,7 @@ iosapic_register_intr (unsigned int gsi,
struct iosapic_rte_info *rte;
u32 low32;
unsigned char dmode;
+ struct irq_desc *desc;
/*
* If this GSI has already been registered (i.e., it's a
@@ -759,12 +751,13 @@ iosapic_register_intr (unsigned int gsi,
goto unlock_iosapic_lock;
}
- raw_spin_lock(&irq_desc[irq].lock);
+ desc = irq_to_desc(irq);
+ raw_spin_lock(&desc->lock);
dest = get_target_cpu(gsi, irq);
dmode = choose_dmode();
err = register_intr(gsi, irq, dmode, polarity, trigger);
if (err < 0) {
- raw_spin_unlock(&irq_desc[irq].lock);
+ raw_spin_unlock(&desc->lock);
irq = err;
goto unlock_iosapic_lock;
}
@@ -783,7 +776,7 @@ iosapic_register_intr (unsigned int gsi,
(polarity == IOSAPIC_POL_HIGH ? "high" : "low"),
cpu_logical_id(dest), dest, irq_to_vector(irq));
- raw_spin_unlock(&irq_desc[irq].lock);
+ raw_spin_unlock(&desc->lock);
unlock_iosapic_lock:
spin_unlock_irqrestore(&iosapic_lock, flags);
return irq;
@@ -794,7 +787,6 @@ iosapic_unregister_intr (unsigned int gsi)
{
unsigned long flags;
int irq, index;
- struct irq_desc *idesc;
u32 low32;
unsigned long trigger, polarity;
unsigned int dest;
@@ -824,7 +816,6 @@ iosapic_unregister_intr (unsigned int gsi)
if (--rte->refcnt > 0)
goto out;
- idesc = irq_desc + irq;
rte->refcnt = NO_REF_RTE;
/* Mask the interrupt */
@@ -848,7 +839,7 @@ iosapic_unregister_intr (unsigned int gsi)
if (iosapic_intr_info[irq].count == 0) {
#ifdef CONFIG_SMP
/* Clear affinity */
- cpumask_setall(idesc->affinity);
+ cpumask_setall(irq_get_irq_data(irq)->affinity);
#endif
/* Clear the interrupt information */
iosapic_intr_info[irq].dest = 0;
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index 94ee9d067cb..ad69606613e 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -53,47 +53,9 @@ atomic_t irq_err_count;
/*
* /proc/interrupts printing:
*/
-
-int show_interrupts(struct seq_file *p, void *v)
+int arch_show_interrupts(struct seq_file *p, int prec)
{
- int i = *(loff_t *) v, j;
- struct irqaction * action;
- unsigned long flags;
-
- if (i == 0) {
- char cpuname[16];
- seq_printf(p, " ");
- for_each_online_cpu(j) {
- snprintf(cpuname, 10, "CPU%d", j);
- seq_printf(p, "%10s ", cpuname);
- }
- seq_putc(p, '\n');
- }
-
- if (i < NR_IRQS) {
- raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
- action = irq_desc[i].action;
- if (!action)
- goto skip;
- seq_printf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(i));
-#else
- for_each_online_cpu(j) {
- seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
- }
-#endif
- seq_printf(p, " %14s", irq_desc[i].chip->name);
- seq_printf(p, " %s", action->name);
-
- for (action=action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
-skip:
- raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS)
- seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
+ seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
return 0;
}
@@ -103,7 +65,7 @@ static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
{
if (irq < NR_IRQS) {
- cpumask_copy(irq_desc[irq].affinity,
+ cpumask_copy(irq_get_irq_data(irq)->affinity,
cpumask_of(cpu_logical_id(hwid)));
irq_redir[irq] = (char) (redir & 0xff);
}
@@ -130,13 +92,14 @@ unsigned int vectors_in_migration[NR_IRQS];
*/
static void migrate_irqs(void)
{
- struct irq_desc *desc;
int irq, new_cpu;
for (irq=0; irq < NR_IRQS; irq++) {
- desc = irq_desc + irq;
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_data *data = irq_desc_get_irq_data(desc);
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
- if (desc->status == IRQ_DISABLED)
+ if (irqd_irq_disabled(data))
continue;
/*
@@ -145,10 +108,10 @@ static void migrate_irqs(void)
* tell CPU not to respond to these local intr sources.
* such as ITV,CPEI,MCA etc.
*/
- if (desc->status == IRQ_PER_CPU)
+ if (irqd_is_per_cpu(data))
continue;
- if (cpumask_any_and(irq_desc[irq].affinity, cpu_online_mask)
+ if (cpumask_any_and(data->affinity, cpu_online_mask)
>= nr_cpu_ids) {
/*
* Save it for phase 2 processing
@@ -160,16 +123,16 @@ static void migrate_irqs(void)
/*
* Al three are essential, currently WARN_ON.. maybe panic?
*/
- if (desc->chip && desc->chip->disable &&
- desc->chip->enable && desc->chip->set_affinity) {
- desc->chip->disable(irq);
- desc->chip->set_affinity(irq,
- cpumask_of(new_cpu));
- desc->chip->enable(irq);
+ if (chip && chip->irq_disable &&
+ chip->irq_enable && chip->irq_set_affinity) {
+ chip->irq_disable(data);
+ chip->irq_set_affinity(data,
+ cpumask_of(new_cpu), false);
+ chip->irq_enable(data);
} else {
- WARN_ON((!(desc->chip) || !(desc->chip->disable) ||
- !(desc->chip->enable) ||
- !(desc->chip->set_affinity)));
+ WARN_ON((!chip || !chip->irq_disable ||
+ !chip->irq_enable ||
+ !chip->irq_set_affinity));
}
}
}
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 38c07b86690..5b704740f16 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -343,7 +343,7 @@ static irqreturn_t smp_irq_move_cleanup_interrupt(int irq, void *dev_id)
if (irq < 0)
continue;
- desc = irq_desc + irq;
+ desc = irq_to_desc(irq);
cfg = irq_cfg + irq;
raw_spin_lock(&desc->lock);
if (!cfg->move_cleanup_count)
@@ -626,17 +626,15 @@ static struct irqaction tlb_irqaction = {
void
ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action)
{
- struct irq_desc *desc;
unsigned int irq;
irq = vec;
BUG_ON(bind_irq_vector(irq, vec, CPU_MASK_ALL));
- desc = irq_desc + irq;
- desc->status |= IRQ_PER_CPU;
- set_irq_chip(irq, &irq_type_ia64_lsapic);
+ irq_set_status_flags(irq, IRQ_PER_CPU);
+ irq_set_chip(irq, &irq_type_ia64_lsapic);
if (action)
setup_irq(irq, action);
- set_irq_handler(irq, handle_percpu_irq);
+ irq_set_handler(irq, handle_percpu_irq);
}
void __init
diff --git a/arch/ia64/kernel/irq_lsapic.c b/arch/ia64/kernel/irq_lsapic.c
index fc1549d4564..1b3a776e516 100644
--- a/arch/ia64/kernel/irq_lsapic.c
+++ b/arch/ia64/kernel/irq_lsapic.c
@@ -15,31 +15,30 @@
#include <linux/irq.h>
static unsigned int
-lsapic_noop_startup (unsigned int irq)
+lsapic_noop_startup (struct irq_data *data)
{
return 0;
}
static void
-lsapic_noop (unsigned int irq)
+lsapic_noop (struct irq_data *data)
{
/* nothing to do... */
}
-static int lsapic_retrigger(unsigned int irq)
+static int lsapic_retrigger(struct irq_data *data)
{
- ia64_resend_irq(irq);
+ ia64_resend_irq(data->irq);
return 1;
}
struct irq_chip irq_type_ia64_lsapic = {
- .name = "LSAPIC",
- .startup = lsapic_noop_startup,
- .shutdown = lsapic_noop,
- .enable = lsapic_noop,
- .disable = lsapic_noop,
- .ack = lsapic_noop,
- .end = lsapic_noop,
- .retrigger = lsapic_retrigger,
+ .name = "LSAPIC",
+ .irq_startup = lsapic_noop_startup,
+ .irq_shutdown = lsapic_noop,
+ .irq_enable = lsapic_noop,
+ .irq_disable = lsapic_noop,
+ .irq_ack = lsapic_noop,
+ .irq_retrigger = lsapic_retrigger,
};
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 80d50b83d41..84fb405eee8 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -2125,7 +2125,6 @@ ia64_mca_late_init(void)
cpe_poll_timer.function = ia64_mca_cpe_poll;
{
- struct irq_desc *desc;
unsigned int irq;
if (cpe_vector >= 0) {
@@ -2133,8 +2132,7 @@ ia64_mca_late_init(void)
irq = local_vector_to_irq(cpe_vector);
if (irq > 0) {
cpe_poll_enabled = 0;
- desc = irq_desc + irq;
- desc->status |= IRQ_PER_CPU;
+ irq_set_status_flags(irq, IRQ_PER_CPU);
setup_irq(irq, &mca_cpe_irqaction);
ia64_cpe_irq = irq;
ia64_mca_register_cpev(cpe_vector);
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 00b19a416ea..009df5434a7 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -12,12 +12,13 @@
static struct irq_chip ia64_msi_chip;
#ifdef CONFIG_SMP
-static int ia64_set_msi_irq_affinity(unsigned int irq,
- const cpumask_t *cpu_mask)
+static int ia64_set_msi_irq_affinity(struct irq_data *idata,
+ const cpumask_t *cpu_mask, bool force)
{
struct msi_msg msg;
u32 addr, data;
int cpu = first_cpu(*cpu_mask);
+ unsigned int irq = idata->irq;
if (!cpu_online(cpu))
return -1;
@@ -38,7 +39,7 @@ static int ia64_set_msi_irq_affinity(unsigned int irq,
msg.data = data;
write_msi_msg(irq, &msg);
- cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
+ cpumask_copy(idata->affinity, cpumask_of(cpu));
return 0;
}
@@ -55,7 +56,7 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
if (irq < 0)
return irq;
- set_irq_msi(irq, desc);
+ irq_set_msi_desc(irq, desc);
cpus_and(mask, irq_to_domain(irq), cpu_online_map);
dest_phys_id = cpu_physical_id(first_cpu(mask));
vector = irq_to_vector(irq);
@@ -74,7 +75,7 @@ int ia64_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
MSI_DATA_VECTOR(vector);
write_msi_msg(irq, &msg);
- set_irq_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &ia64_msi_chip, handle_edge_irq);
return 0;
}
@@ -84,16 +85,16 @@ void ia64_teardown_msi_irq(unsigned int irq)
destroy_irq(irq);
}
-static void ia64_ack_msi_irq(unsigned int irq)
+static void ia64_ack_msi_irq(struct irq_data *data)
{
- irq_complete_move(irq);
- move_native_irq(irq);
+ irq_complete_move(data->irq);
+ irq_move_irq(data);
ia64_eoi();
}
-static int ia64_msi_retrigger_irq(unsigned int irq)
+static int ia64_msi_retrigger_irq(struct irq_data *data)
{
- unsigned int vector = irq_to_vector(irq);
+ unsigned int vector = irq_to_vector(data->irq);
ia64_resend_irq(vector);
return 1;
@@ -103,14 +104,14 @@ static int ia64_msi_retrigger_irq(unsigned int irq)
* Generic ops used on most IA64 platforms.
*/
static struct irq_chip ia64_msi_chip = {
- .name = "PCI-MSI",
- .irq_mask = mask_msi_irq,
- .irq_unmask = unmask_msi_irq,
- .ack = ia64_ack_msi_irq,
+ .name = "PCI-MSI",
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
+ .irq_ack = ia64_ack_msi_irq,
#ifdef CONFIG_SMP
- .set_affinity = ia64_set_msi_irq_affinity,
+ .irq_set_affinity = ia64_set_msi_irq_affinity,
#endif
- .retrigger = ia64_msi_retrigger_irq,
+ .irq_retrigger = ia64_msi_retrigger_irq,
};
@@ -132,8 +133,10 @@ void arch_teardown_msi_irq(unsigned int irq)
#ifdef CONFIG_DMAR
#ifdef CONFIG_SMP
-static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
+static int dmar_msi_set_affinity(struct irq_data *data,
+ const struct cpumask *mask, bool force)
{
+ unsigned int irq = data->irq;
struct irq_cfg *cfg = irq_cfg + irq;
struct msi_msg msg;
int cpu = cpumask_first(mask);
@@ -152,7 +155,7 @@ static int dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
msg.address_lo |= MSI_ADDR_DEST_ID_CPU(cpu_physical_id(cpu));
dmar_msi_write(irq, &msg);
- cpumask_copy(irq_desc[irq].affinity, mask);
+ cpumask_copy(data->affinity, mask);
return 0;
}
@@ -162,11 +165,11 @@ static struct irq_chip dmar_msi_type = {
.name = "DMAR_MSI",
.irq_unmask = dmar_msi_unmask,
.irq_mask = dmar_msi_mask,
- .ack = ia64_ack_msi_irq,
+ .irq_ack = ia64_ack_msi_irq,
#ifdef CONFIG_SMP
- .set_affinity = dmar_msi_set_affinity,
+ .irq_set_affinity = dmar_msi_set_affinity,
#endif
- .retrigger = ia64_msi_retrigger_irq,
+ .irq_retrigger = ia64_msi_retrigger_irq,
};
static int
@@ -203,8 +206,8 @@ int arch_setup_dmar_msi(unsigned int irq)
if (ret < 0)
return ret;
dmar_msi_write(irq, &msg);
- set_irq_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
- "edge");
+ irq_set_chip_and_handler_name(irq, &dmar_msi_type, handle_edge_irq,
+ "edge");
return 0;
}
#endif /* CONFIG_DMAR */
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index d003b502a43..44f11ee411c 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -677,7 +677,7 @@ extern void fixup_irqs(void);
int migrate_platform_irqs(unsigned int cpu)
{
int new_cpei_cpu;
- struct irq_desc *desc = NULL;
+ struct irq_data *data = NULL;
const struct cpumask *mask;
int retval = 0;
@@ -693,20 +693,20 @@ int migrate_platform_irqs(unsigned int cpu)
new_cpei_cpu = any_online_cpu(cpu_online_map);
mask = cpumask_of(new_cpei_cpu);
set_cpei_target_cpu(new_cpei_cpu);
- desc = irq_desc + ia64_cpe_irq;
+ data = irq_get_irq_data(ia64_cpe_irq);
/*
* Switch for now, immediately, we need to do fake intr
* as other interrupts, but need to study CPEI behaviour with
* polling before making changes.
*/
- if (desc) {
- desc->chip->disable(ia64_cpe_irq);
- desc->chip->set_affinity(ia64_cpe_irq, mask);
- desc->chip->enable(ia64_cpe_irq);
+ if (data && data->chip) {
+ data->chip->irq_disable(data);
+ data->chip->irq_set_affinity(data, mask, false);
+ data->chip->irq_enable(data);
printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu);
}
}
- if (!desc) {
+ if (!data) {
printk ("Unable to retarget CPEI, offline cpu [%d] failed\n", cpu);
retval = -EBUSY;
}
diff --git a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
index 13c15d96809..7f399f9d99c 100644
--- a/arch/ia64/sn/kernel/irq.c
+++ b/arch/ia64/sn/kernel/irq.c
@@ -23,11 +23,9 @@
#include <asm/sn/sn_sal.h>
#include <asm/sn/sn_feature_sets.h>
-static void force_interrupt(int irq);
static void register_intr_pda(struct sn_irq_info *sn_irq_info);
static void unregister_intr_pda(struct sn_irq_info *sn_irq_info);
-int sn_force_interrupt_flag = 1;
extern int sn_ioif_inited;
struct list_head **sn_irq_lh;
static DEFINE_SPINLOCK(sn_irq_info_lock); /* non-IRQ lock */
@@ -78,62 +76,40 @@ u64 sn_intr_redirect(nasid_t local_nasid, int local_widget,
return ret_stuff.status;
}
-static unsigned int sn_startup_irq(unsigned int irq)
+static unsigned int sn_startup_irq(struct irq_data *data)
{
return 0;
}
-static void sn_shutdown_irq(unsigned int irq)
+static void sn_shutdown_irq(struct irq_data *data)
{
}
extern void ia64_mca_register_cpev(int);
-static void sn_disable_irq(unsigned int irq)
+static void sn_disable_irq(struct irq_data *data)
{
- if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
+ if (data->irq == local_vector_to_irq(IA64_CPE_VECTOR))
ia64_mca_register_cpev(0);
}
-static void sn_enable_irq(unsigned int irq)
+static void sn_enable_irq(struct irq_data *data)
{
- if (irq == local_vector_to_irq(IA64_CPE_VECTOR))
- ia64_mca_register_cpev(irq);
+ if (data->irq == local_vector_to_irq(IA64_CPE_VECTOR))
+ ia64_mca_register_cpev(data->irq);
}
-static void sn_ack_irq(unsigned int irq)
+static void sn_ack_irq(struct irq_data *data)
{
u64 event_occurred, mask;
+ unsigned int irq = data->irq & 0xff;
- irq = irq & 0xff;
event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED));
mask = event_occurred & SH_ALL_INT_MASK;
HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask);
__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
- move_native_irq(irq);
-}
-
-static void sn_end_irq(unsigned int irq)
-{
- int ivec;
- u64 event_occurred;
-
- ivec = irq & 0xff;
- if (ivec == SGI_UART_VECTOR) {
- event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR (SH_EVENT_OCCURRED));
- /* If the UART bit is set here, we may have received an
- * interrupt from the UART that the driver missed. To
- * make sure, we IPI ourselves to force us to look again.
- */
- if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) {
- platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR,
- IA64_IPI_DM_INT, 0);
- }
- }
- __clear_bit(ivec, (volatile void *)pda->sn_in_service_ivecs);
- if (sn_force_interrupt_flag)
- force_interrupt(irq);
+ irq_move_irq(data);
}
static void sn_irq_info_free(struct rcu_head *head);
@@ -228,9 +204,11 @@ finish_up:
return new_irq_info;
}
-static int sn_set_affinity_irq(unsigned int irq, const struct cpumask *mask)
+static int sn_set_affinity_irq(struct irq_data *data,
+ const struct cpumask *mask, bool force)
{
struct sn_irq_info *sn_irq_info, *sn_irq_info_safe;
+ unsigned int irq = data->irq;
nasid_t nasid;
int slice;
@@ -259,26 +237,25 @@ void sn_set_err_irq_affinity(unsigned int irq) { }
#endif
static void
-sn_mask_irq(unsigned int irq)
+sn_mask_irq(struct irq_data *data)
{
}
static void
-sn_unmask_irq(unsigned int irq)
+sn_unmask_irq(struct irq_data *data)
{
}
struct irq_chip irq_type_sn = {
- .name = "SN hub",
- .startup = sn_startup_irq,
- .shutdown = sn_shutdown_irq,
- .enable = sn_enable_irq,
- .disable = sn_disable_irq,
- .ack = sn_ack_irq,
- .end = sn_end_irq,
- .mask = sn_mask_irq,
- .unmask = sn_unmask_irq,
- .set_affinity = sn_set_affinity_irq
+ .name = "SN hub",
+ .irq_startup = sn_startup_irq,
+ .irq_shutdown = sn_shutdown_irq,
+ .irq_enable = sn_enable_irq,
+ .irq_disable = sn_disable_irq,
+ .irq_ack = sn_ack_irq,
+ .irq_mask = sn_mask_irq,
+ .irq_unmask = sn_unmask_irq,
+ .irq_set_affinity = sn_set_affinity_irq
};
ia64_vector sn_irq_to_vector(int irq)
@@ -296,15 +273,13 @@ unsigned int sn_local_vector_to_irq(u8 vector)
void sn_irq_init(void)
{
int i;
- struct irq_desc *base_desc = irq_desc;
ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR;
ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR;
for (i = 0; i < NR_IRQS; i++) {
- if (base_desc[i].chip == &no_irq_chip) {
- base_desc[i].chip = &irq_type_sn;
- }
+ if (irq_get_chip(i) == &no_irq_chip)
+ irq_set_chip(i, &irq_type_sn);
}
}
@@ -378,7 +353,6 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info)
int cpu = nasid_slice_to_cpuid(nasid, slice);
#ifdef CONFIG_SMP
int cpuphys;
- struct irq_desc *desc;
#endif
pci_dev_get(pci_dev);
@@ -395,12 +369,11 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info)
#ifdef CONFIG_SMP
cpuphys = cpu_physical_id(cpu);
set_irq_affinity_info(sn_irq_info->irq_irq, cpuphys, 0);
- desc = irq_to_desc(sn_irq_info->irq_irq);
/*
* Affinity was set by the PROM, prevent it from
* being reset by the request_irq() path.
*/
- desc->status |= IRQ_AFFINITY_SET;
+ irqd_mark_affinity_was_set(irq_get_irq_data(sn_irq_info->irq_irq));
#endif
}
@@ -439,25 +412,11 @@ sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info)
pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type];
/* Don't force an interrupt if the irq has been disabled */
- if (!(irq_desc[sn_irq_info->irq_irq].status & IRQ_DISABLED) &&
+ if (!irqd_irq_disabled(sn_irq_info->irq_irq) &&
pci_provider && pci_provider->force_interrupt)
(*pci_provider->force_interrupt)(sn_irq_info);
}
-static void force_interrupt(int irq)
-{
- struct sn_irq_info *sn_irq_info;
-
- if (!sn_ioif_inited)
- return;
-
- rcu_read_lock();
- list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list)
- sn_call_force_intr_provider(sn_irq_info);
-
- rcu_read_unlock();
-}
-
/*
* Check for lost interrupts. If the PIC int_status reg. says that
* an interrupt has been sent, but not handled, and the interrupt
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index a5e500f0285..2b98b9e088d 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -144,16 +144,16 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry)
*/
msg.data = 0x100 + irq;
- set_irq_msi(irq, entry);
+ irq_set_msi_desc(irq, entry);
write_msi_msg(irq, &msg);
- set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
+ irq_set_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq);
return 0;
}
#ifdef CONFIG_SMP
-static int sn_set_msi_irq_affinity(unsigned int irq,
- const struct cpumask *cpu_mask)
+static int sn_set_msi_irq_affinity(struct irq_data *data,
+ const struct cpumask *cpu_mask, bool force)
{
struct msi_msg msg;
int slice;
@@ -164,7 +164,7 @@ static int sn_set_msi_irq_affinity(unsigned int irq,
struct sn_irq_info *sn_irq_info;
struct sn_irq_info *new_irq_info;
struct sn_pcibus_provider *provider;
- unsigned int cpu;
+ unsigned int cpu, irq = data->irq;
cpu = cpumask_first(cpu_mask);
sn_irq_info = sn_msi_info[irq].sn_irq_info;
@@ -206,33 +206,33 @@ static int sn_set_msi_irq_affinity(unsigned int irq,
msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
write_msi_msg(irq, &msg);
- cpumask_copy(irq_desc[irq].affinity, cpu_mask);
+ cpumask_copy(data->affinity, cpu_mask);
return 0;
}
#endif /* CONFIG_SMP */
-static void sn_ack_msi_irq(unsigned int irq)
+static void sn_ack_msi_irq(struct irq_data *data)
{
- move_native_irq(irq);
+ irq_move_irq(data);
ia64_eoi();
}
-static int sn_msi_retrigger_irq(unsigned int irq)
+static int sn_msi_retrigger_irq(struct irq_data *data)
{
- unsigned int vector = irq;
+ unsigned int vector = data->irq;
ia64_resend_irq(vector);
return 1;
}
static struct irq_chip sn_msi_chip = {
- .name = "PCI-MSI",
- .irq_mask = mask_msi_irq,
- .irq_unmask = unmask_msi_irq,
- .ack = sn_ack_msi_irq,
+ .name = "PCI-MSI",
+ .irq_mask = mask_msi_irq,
+ .irq_unmask = unmask_msi_irq,
+ .irq_ack = sn_ack_msi_irq,
#ifdef CONFIG_SMP
- .set_affinity = sn_set_msi_irq_affinity,
+ .irq_set_affinity = sn_set_msi_irq_affinity,
#endif
- .retrigger = sn_msi_retrigger_irq,
+ .irq_retrigger = sn_msi_retrigger_irq,
};
diff --git a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
index c76d8dc3aea..7aab87f4806 100644
--- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
+++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
@@ -45,38 +45,6 @@ static int licenseID_open(struct inode *inode, struct file *file)
return single_open(file, licenseID_show, NULL);
}
-/*
- * Enable forced interrupt by default.
- * When set, the sn interrupt handler writes the force interrupt register on
- * the bridge chip. The hardware will then send an interrupt message if the
- * interrupt line is active. This mimics a level sensitive interrupt.
- */
-extern int sn_force_interrupt_flag;
-
-static int sn_force_interrupt_show(struct seq_file *s, void *p)
-{
- seq_printf(s, "Force interrupt is %s\n",
- sn_force_interrupt_flag ? "enabled" : "disabled");
- return 0;
-}
-
-static ssize_t sn_force_interrupt_write_proc(struct file *file,
- const char __user *buffer, size_t count, loff_t *data)
-{
- char val;
-
- if (copy_from_user(&val, buffer, 1))
- return -EFAULT;
-
- sn_force_interrupt_flag = (val == '0') ? 0 : 1;
- return count;
-}
-
-static int sn_force_interrupt_open(struct inode *inode, struct file *file)
-{
- return single_open(file, sn_force_interrupt_show, NULL);
-}
-
static int coherence_id_show(struct seq_file *s, void *p)
{
seq_printf(s, "%d\n", partition_coherence_id());
@@ -114,14 +82,6 @@ static const struct file_operations proc_license_id_fops = {
.release = single_release,
};
-static const struct file_operations proc_sn_force_intr_fops = {
- .open = sn_force_interrupt_open,
- .read = seq_read,
- .write = sn_force_interrupt_write_proc,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
static const struct file_operations proc_coherence_id_fops = {
.open = coherence_id_open,
.read = seq_read,
@@ -149,8 +109,6 @@ void register_sn_procfs(void)
proc_create("system_serial_number", 0444, sgi_proc_dir,
&proc_system_sn_fops);
proc_create("licenseID", 0444, sgi_proc_dir, &proc_license_id_fops);
- proc_create("sn_force_interrupt", 0644, sgi_proc_dir,
- &proc_sn_force_intr_fops);
proc_create("coherence_id", 0444, sgi_proc_dir,
&proc_coherence_id_fops);
proc_create("sn_topology", 0444, sgi_proc_dir, &proc_sn_topo_fops);
diff --git a/arch/ia64/xen/irq_xen.c b/arch/ia64/xen/irq_xen.c
index a3fb7cf9ae1..108bb858acf 100644
--- a/arch/ia64/xen/irq_xen.c
+++ b/arch/ia64/xen/irq_xen.c
@@ -138,7 +138,6 @@ static void
__xen_register_percpu_irq(unsigned int cpu, unsigned int vec,
struct irqaction *action, int save)
{
- struct irq_desc *desc;
int irq = 0;
if (xen_slab_ready) {
@@ -223,8 +222,7 @@ __xen_register_percpu_irq(unsigned int cpu, unsigned int vec,
* mark the interrupt for migrations and trigger it
* on cpu hotplug.
*/
- desc = irq_desc + irq;
- desc->status |= IRQ_PER_CPU;
+ irq_set_status_flags(irq, IRQ_PER_CPU);
}
}
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index b28d0908a40..736b808d229 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -8,7 +8,6 @@ config M32R
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
select HAVE_GENERIC_HARDIRQS
- select GENERIC_HARDIRQS_NO_DEPRECATED
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 6e056d3c5d0..75531da02a4 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -5,7 +5,6 @@ config M68K
select HAVE_AOUT if MMU
select GENERIC_ATOMIC64 if MMU
select HAVE_GENERIC_HARDIRQS if !MMU
- select GENERIC_HARDIRQS_NO_DEPRECATED if !MMU
config RWSEM_GENERIC_SPINLOCK
bool
diff --git a/arch/m68k/kernel/irq.c b/arch/m68k/kernel/irq.c
index c7dd48f37be..15dbc3e9d20 100644
--- a/arch/m68k/kernel/irq.c
+++ b/arch/m68k/kernel/irq.c
@@ -44,7 +44,7 @@ int show_interrupts(struct seq_file *p, void *v)
if (ap) {
seq_printf(p, "%3d: ", irq);
seq_printf(p, "%10u ", kstat_irqs(irq));
- seq_printf(p, "%14s ", get_irq_desc_chip(desc)->name);
+ seq_printf(p, "%14s ", irq_desc_get_chip(desc)->name);
seq_printf(p, "%s", ap->name);
for (ap = ap->next; ap; ap = ap->next)
diff --git a/arch/m68k/platform/5249/intc2.c b/arch/m68k/platform/5249/intc2.c
index 8f4b63e1736..f343bf7bf5b 100644
--- a/arch/m68k/platform/5249/intc2.c
+++ b/arch/m68k/platform/5249/intc2.c
@@ -51,8 +51,8 @@ static int __init mcf_intc2_init(void)
/* GPIO interrupt sources */
for (irq = MCFINTC2_GPIOIRQ0; (irq <= MCFINTC2_GPIOIRQ7); irq++) {
- set_irq_chip(irq, &intc2_irq_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip(irq, &intc2_irq_gpio_chip);
+ irq_set_handler(irq, handle_edge_irq);
}
return 0;
diff --git a/arch/m68k/platform/5272/intc.c b/arch/m68k/platform/5272/intc.c
index 969ff0a467c..43e6e96f087 100644
--- a/arch/m68k/platform/5272/intc.c
+++ b/arch/m68k/platform/5272/intc.c
@@ -145,7 +145,7 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type)
*/
static void intc_external_irq(unsigned int irq, struct irq_desc *desc)
{
- get_irq_desc_chip(desc)->irq_ack(&desc->irq_data);
+ irq_desc_get_chip(desc)->irq_ack(&desc->irq_data);
handle_simple_irq(irq, desc);
}
@@ -171,16 +171,16 @@ void __init init_IRQ(void)
writel(0x88888888, MCF_MBAR + MCFSIM_ICR4);
for (irq = 0; (irq < NR_IRQS); irq++) {
- set_irq_chip(irq, &intc_irq_chip);
+ irq_set_chip(irq, &intc_irq_chip);
edge = 0;
if ((irq >= MCFINT_VECBASE) && (irq <= MCFINT_VECMAX))
edge = intc_irqmap[irq - MCFINT_VECBASE].ack;
if (edge) {
- set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
- set_irq_handler(irq, intc_external_irq);
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_handler(irq, intc_external_irq);
} else {
- set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_handler(irq, handle_level_irq);
}
}
}
diff --git a/arch/m68k/platform/68328/ints.c b/arch/m68k/platform/68328/ints.c
index e5631831a20..a90288cf744 100644
--- a/arch/m68k/platform/68328/ints.c
+++ b/arch/m68k/platform/68328/ints.c
@@ -179,8 +179,8 @@ void __init init_IRQ(void)
IMR = ~0;
for (i = 0; (i < NR_IRQS); i++) {
- set_irq_chip(i, &intc_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip(i, &intc_irq_chip);
+ irq_set_handler(i, handle_level_irq);
}
}
diff --git a/arch/m68k/platform/68360/ints.c b/arch/m68k/platform/68360/ints.c
index 8de3feb568c..4af0f4e30f7 100644
--- a/arch/m68k/platform/68360/ints.c
+++ b/arch/m68k/platform/68360/ints.c
@@ -132,8 +132,8 @@ void init_IRQ(void)
pquicc->intr_cimr = 0x00000000;
for (i = 0; (i < NR_IRQS); i++) {
- set_irq_chip(i, &intc_irq_chip);
- set_irq_handler(i, handle_level_irq);
+ irq_set_chip(i, &intc_irq_chip);
+ irq_set_handler(i, handle_level_irq);
}
}
diff --git a/arch/m68k/platform/coldfire/intc-2.c b/arch/m68k/platform/coldfire/intc-2.c
index 2cbfbf035db..74b55cfbc3c 100644
--- a/arch/m68k/platform/coldfire/intc-2.c
+++ b/arch/m68k/platform/coldfire/intc-2.c
@@ -164,7 +164,7 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type)
}
if (tb)
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_handler(irq, handle_edge_irq);
irq -= EINT0;
pa = __raw_readw(MCFEPORT_EPPAR);
@@ -204,11 +204,11 @@ void __init init_IRQ(void)
for (irq = MCFINT_VECBASE; (irq < MCFINT_VECBASE + NR_VECS); irq++) {
if ((irq >= EINT1) && (irq <=EINT7))
- set_irq_chip(irq, &intc_irq_chip_edge_port);
+ irq_set_chip(irq, &intc_irq_chip_edge_port);
else
- set_irq_chip(irq, &intc_irq_chip);
- set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip(irq, &intc_irq_chip);
+ irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_handler(irq, handle_level_irq);
}
}
diff --git a/arch/m68k/platform/coldfire/intc-simr.c b/arch/m68k/platform/coldfire/intc-simr.c
index e642b24ab72..d6a4d9d53e4 100644
--- a/arch/m68k/platform/coldfire/intc-simr.c
+++ b/arch/m68k/platform/coldfire/intc-simr.c
@@ -141,7 +141,7 @@ static int intc_irq_set_type(struct irq_data *d, unsigned int type)
}
if (tb)
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_handler(irq, handle_edge_irq);
ebit = irq2ebit(irq) * 2;
pa = __raw_readw(MCFEPORT_EPPAR);
@@ -181,11 +181,11 @@ void __init init_IRQ(void)
eirq = MCFINT_VECBASE + 64 + (MCFINTC1_ICR0 ? 64 : 0);
for (irq = MCFINT_VECBASE; (irq < eirq); irq++) {
if ((irq >= EINT1) && (irq <= EINT7))
- set_irq_chip(irq, &intc_irq_chip_edge_port);
+ irq_set_chip(irq, &intc_irq_chip_edge_port);
else
- set_irq_chip(irq, &intc_irq_chip);
- set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip(irq, &intc_irq_chip);
+ irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_handler(irq, handle_level_irq);
}
}
diff --git a/arch/m68k/platform/coldfire/intc.c b/arch/m68k/platform/coldfire/intc.c
index d648081a63f..c28a6ed6cb2 100644
--- a/arch/m68k/platform/coldfire/intc.c
+++ b/arch/m68k/platform/coldfire/intc.c
@@ -143,9 +143,9 @@ void __init init_IRQ(void)
mcf_maskimr(0xffffffff);
for (irq = 0; (irq < NR_IRQS); irq++) {
- set_irq_chip(irq, &intc_irq_chip);
- set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip(irq, &intc_irq_chip);
+ irq_set_irq_type(irq, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_handler(irq, handle_level_irq);
}
}
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 5f0cf0e3265..851b3bf6e96 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -17,7 +17,7 @@ config MICROBLAZE
select OF_EARLY_FLATTREE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ select GENERIC_IRQ_SHOW
config SWAP
def_bool n
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index e4661285118..5ba7e162833 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -50,7 +50,7 @@ static void intc_enable_or_unmask(struct irq_data *d)
* ack function since the handle_level_irq function
* acks the irq before calling the interrupt handler
*/
- if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
+ if (irqd_is_level_type(d))
out_be32(INTC_BASE + IAR, mask);
}
@@ -157,11 +157,11 @@ void __init init_IRQ(void)
for (i = 0; i < nr_irq; ++i) {
if (intr_type & (0x00000001 << i)) {
- set_irq_chip_and_handler_name(i, &intc_dev,
+ irq_set_chip_and_handler_name(i, &intc_dev,
handle_edge_irq, intc_dev.name);
irq_clear_status_flags(i, IRQ_LEVEL);
} else {
- set_irq_chip_and_handler_name(i, &intc_dev,
+ irq_set_chip_and_handler_name(i, &intc_dev,
handle_level_irq, intc_dev.name);
irq_set_status_flags(i, IRQ_LEVEL);
}
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index 09882241372..ce7ac8435d5 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -47,48 +47,6 @@ next_irq:
trace_hardirqs_on();
}
-int show_interrupts(struct seq_file *p, void *v)
-{
- int i = *(loff_t *) v, j;
- struct irq_desc *desc;
- struct irqaction *action;
- unsigned long flags;
-
- if (i == 0) {
- seq_printf(p, " ");
- for_each_online_cpu(j)
- seq_printf(p, "CPU%-8d", j);
- seq_putc(p, '\n');
- }
-
- if (i < nr_irq) {
- desc = irq_to_desc(i);
- raw_spin_lock_irqsave(&desc->lock, flags);
- action = desc->action;
- if (!action)
- goto skip;
- seq_printf(p, "%3d: ", i);
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(i));
-#else
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
-#endif
- seq_printf(p, " %8s", desc->status &
- IRQ_LEVEL ? "level" : "edge");
- seq_printf(p, " %8s", desc->irq_data.chip->name);
- seq_printf(p, " %s", action->name);
-
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
-skip:
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- }
- return 0;
-}
-
/* MS: There is no any advance mapping mechanism. We are using simple 32bit
intc without any cascades or any connection that's why mapping is 1:1 */
unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
diff --git a/arch/microblaze/pci/pci-common.c b/arch/microblaze/pci/pci-common.c
index 1e01a125363..53599067d2f 100644
--- a/arch/microblaze/pci/pci-common.c
+++ b/arch/microblaze/pci/pci-common.c
@@ -237,7 +237,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
virq = irq_create_mapping(NULL, line);
if (virq != NO_IRQ)
- set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
} else {
pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.specifier[1],
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
index f91c43a7d5d..596ad00e7f0 100644
--- a/arch/mips/alchemy/devboards/bcsr.c
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -142,8 +142,8 @@ void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq)
bcsr_csc_base = csc_start;
for (irq = csc_start; irq <= csc_end; irq++)
- set_irq_chip_and_handler_name(irq, &bcsr_irq_type,
- handle_level_irq, "level");
+ irq_set_chip_and_handler_name(irq, &bcsr_irq_type,
+ handle_level_irq, "level");
- set_irq_chained_handler(hook_irq, bcsr_csc_handler);
+ irq_set_chained_handler(hook_irq, bcsr_csc_handler);
}
diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c
index 88761954755..4a8980027ec 100644
--- a/arch/mips/alchemy/devboards/db1200/setup.c
+++ b/arch/mips/alchemy/devboards/db1200/setup.c
@@ -63,20 +63,19 @@ void __init board_setup(void)
static int __init db1200_arch_init(void)
{
/* GPIO7 is low-level triggered CPLD cascade */
- set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
/* insert/eject pairs: one of both is always screaming. To avoid
* issues they must not be automatically enabled when initially
* requested.
*/
- irq_to_desc(DB1200_SD0_INSERT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_SD0_EJECT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_PC0_INSERT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_PC0_EJECT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_PC1_INSERT_INT)->status |= IRQ_NOAUTOEN;
- irq_to_desc(DB1200_PC1_EJECT_INT)->status |= IRQ_NOAUTOEN;
-
+ irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN);
return 0;
}
arch_initcall(db1200_arch_init);
diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c
index 9e45971343e..05f120ff90f 100644
--- a/arch/mips/alchemy/devboards/db1x00/board_setup.c
+++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c
@@ -215,35 +215,35 @@ void __init board_setup(void)
static int __init db1x00_init_irq(void)
{
#if defined(CONFIG_MIPS_MIRAGE)
- set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */
+ irq_set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */
#elif defined(CONFIG_MIPS_DB1550)
- set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
- set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */
- set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */
- set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
- set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+ irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */
+ irq_set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+ irq_set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+ irq_set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1500)
- set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
- set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
- set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
- set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
- set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+ irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+ irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+ irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+ irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1100)
- set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
- set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
- set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
- set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
- set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+ irq_set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+ irq_set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+ irq_set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+ irq_set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#elif defined(CONFIG_MIPS_DB1000)
- set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
- set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
- set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
- set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
- set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
+ irq_set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
+ irq_set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
+ irq_set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
+ irq_set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
#endif
return 0;
}
diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c
index f6540ec47a6..2d85c4b5be0 100644
--- a/arch/mips/alchemy/devboards/pb1000/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c
@@ -197,7 +197,7 @@ void __init board_setup(void)
static int __init pb1000_init_irq(void)
{
- set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW);
return 0;
}
arch_initcall(pb1000_init_irq);
diff --git a/arch/mips/alchemy/devboards/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c
index 90dda5f3ecc..d108fd573aa 100644
--- a/arch/mips/alchemy/devboards/pb1100/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c
@@ -117,10 +117,10 @@ void __init board_setup(void)
static int __init pb1100_init_irq(void)
{
- set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */
- set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
- set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
- set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
+ irq_set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */
+ irq_set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
+ irq_set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
+ irq_set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
return 0;
}
diff --git a/arch/mips/alchemy/devboards/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c
index 8b4466f2d44..6d06b07c238 100644
--- a/arch/mips/alchemy/devboards/pb1200/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1200/board_setup.c
@@ -142,7 +142,7 @@ static int __init pb1200_init_irq(void)
panic("Game over. Your score is 0.");
}
- set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT);
return 0;
diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c
index 9cd9dfa698e..83f46215eb0 100644
--- a/arch/mips/alchemy/devboards/pb1500/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c
@@ -134,14 +134,14 @@ void __init board_setup(void)
static int __init pb1500_init_irq(void)
{
- set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
- set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
- set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
- set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
+ irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
return 0;
}
diff --git a/arch/mips/alchemy/devboards/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c
index 9d7d6edafa8..b790213848b 100644
--- a/arch/mips/alchemy/devboards/pb1550/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c
@@ -73,9 +73,9 @@ void __init board_setup(void)
static int __init pb1550_init_irq(void)
{
- set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
/* enable both PCMCIA card irqs in the shared line */
alchemy_gpio2_enable_int(201);
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c
index 40b84b99119..cf436ab679a 100644
--- a/arch/mips/alchemy/mtx-1/board_setup.c
+++ b/arch/mips/alchemy/mtx-1/board_setup.c
@@ -123,11 +123,11 @@ mtx1_pci_idsel(unsigned int devsel, int assert)
static int __init mtx1_init_irq(void)
{
- set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
- set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
return 0;
}
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c
index 80c521e5290..febfb0fb089 100644
--- a/arch/mips/alchemy/xxs1500/board_setup.c
+++ b/arch/mips/alchemy/xxs1500/board_setup.c
@@ -85,19 +85,19 @@ void __init board_setup(void)
static int __init xxs1500_init_irq(void)
{
- set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
- set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW);
- set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */
- set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */
+ irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW);
return 0;
}
diff --git a/arch/mips/ar7/irq.c b/arch/mips/ar7/irq.c
index a6484b60642..03db3daadbd 100644
--- a/arch/mips/ar7/irq.c
+++ b/arch/mips/ar7/irq.c
@@ -119,11 +119,11 @@ static void __init ar7_irq_init(int base)
for (i = 0; i < 40; i++) {
writel(i, REG(CHNL_OFFSET(i)));
/* Primary IRQ's */
- set_irq_chip_and_handler(base + i, &ar7_irq_type,
+ irq_set_chip_and_handler(base + i, &ar7_irq_type,
handle_level_irq);
/* Secondary IRQ's */
if (i < 32)
- set_irq_chip_and_handler(base + i + 40,
+ irq_set_chip_and_handler(base + i + 40,
&ar7_sec_irq_type,
handle_level_irq);
}
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index 7c02bc948a3..ac610d5fe3b 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -124,11 +124,11 @@ static void __init ath79_misc_irq_init(void)
for (i = ATH79_MISC_IRQ_BASE;
i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
- set_irq_chip_and_handler(i, &ath79_misc_irq_chip,
+ irq_set_chip_and_handler(i, &ath79_misc_irq_chip,
handle_level_irq);
}
- set_irq_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
+ irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
}
asmlinkage void plat_irq_dispatch(void)
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index 1691531aa34..cea6021cb8d 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -230,11 +230,11 @@ void __init arch_init_irq(void)
mips_cpu_irq_init();
for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
- set_irq_chip_and_handler(i, &bcm63xx_internal_irq_chip,
+ irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip,
handle_level_irq);
for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
- set_irq_chip_and_handler(i, &bcm63xx_external_irq_chip,
+ irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip,
handle_edge_irq);
setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index ce7500cdf5b..ffd4ae660f7 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -3,10 +3,13 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004-2008, 2009, 2010 Cavium Networks
+ * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks
*/
-#include <linux/irq.h>
+
#include <linux/interrupt.h>
+#include <linux/bitops.h>
+#include <linux/percpu.h>
+#include <linux/irq.h>
#include <linux/smp.h>
#include <asm/octeon/octeon.h>
@@ -14,6 +17,47 @@
static DEFINE_RAW_SPINLOCK(octeon_irq_ciu0_lock);
static DEFINE_RAW_SPINLOCK(octeon_irq_ciu1_lock);
+static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu0_en_mirror);
+static DEFINE_PER_CPU(unsigned long, octeon_irq_ciu1_en_mirror);
+
+static __read_mostly u8 octeon_irq_ciu_to_irq[8][64];
+
+union octeon_ciu_chip_data {
+ void *p;
+ unsigned long l;
+ struct {
+ unsigned int line:6;
+ unsigned int bit:6;
+ } s;
+};
+
+struct octeon_core_chip_data {
+ struct mutex core_irq_mutex;
+ bool current_en;
+ bool desired_en;
+ u8 bit;
+};
+
+#define MIPS_CORE_IRQ_LINES 8
+
+static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
+
+static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit,
+ struct irq_chip *chip,
+ irq_flow_handler_t handler)
+{
+ union octeon_ciu_chip_data cd;
+
+ irq_set_chip_and_handler(irq, chip, handler);
+
+ cd.l = 0;
+ cd.s.line = line;
+ cd.s.bit = bit;
+
+ irq_set_chip_data(irq, cd.p);
+ octeon_irq_ciu_to_irq[line][bit] = irq;
+}
+
static int octeon_coreid_for_cpu(int cpu)
{
#ifdef CONFIG_SMP
@@ -23,9 +67,20 @@ static int octeon_coreid_for_cpu(int cpu)
#endif
}
-static void octeon_irq_core_ack(unsigned int irq)
+static int octeon_cpu_for_coreid(int coreid)
+{
+#ifdef CONFIG_SMP
+ return cpu_number_map(coreid);
+#else
+ return smp_processor_id();
+#endif
+}
+
+static void octeon_irq_core_ack(struct irq_data *data)
{
- unsigned int bit = irq - OCTEON_IRQ_SW0;
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ unsigned int bit = cd->bit;
+
/*
* We don't need to disable IRQs to make these atomic since
* they are already disabled earlier in the low level
@@ -37,131 +92,121 @@ static void octeon_irq_core_ack(unsigned int irq)
clear_c0_cause(0x100 << bit);
}
-static void octeon_irq_core_eoi(unsigned int irq)
+static void octeon_irq_core_eoi(struct irq_data *data)
{
- struct irq_desc *desc = irq_to_desc(irq);
- unsigned int bit = irq - OCTEON_IRQ_SW0;
- /*
- * If an IRQ is being processed while we are disabling it the
- * handler will attempt to unmask the interrupt after it has
- * been disabled.
- */
- if ((unlikely(desc->status & IRQ_DISABLED)))
- return;
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+
/*
* We don't need to disable IRQs to make these atomic since
* they are already disabled earlier in the low level
* interrupt code.
*/
- set_c0_status(0x100 << bit);
+ set_c0_status(0x100 << cd->bit);
}
-static void octeon_irq_core_enable(unsigned int irq)
+static void octeon_irq_core_set_enable_local(void *arg)
{
- unsigned long flags;
- unsigned int bit = irq - OCTEON_IRQ_SW0;
+ struct irq_data *data = arg;
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ unsigned int mask = 0x100 << cd->bit;
/*
- * We need to disable interrupts to make sure our updates are
- * atomic.
+ * Interrupts are already disabled, so these are atomic.
*/
- local_irq_save(flags);
- set_c0_status(0x100 << bit);
- local_irq_restore(flags);
+ if (cd->desired_en)
+ set_c0_status(mask);
+ else
+ clear_c0_status(mask);
+
}
-static void octeon_irq_core_disable_local(unsigned int irq)
+static void octeon_irq_core_disable(struct irq_data *data)
{
- unsigned long flags;
- unsigned int bit = irq - OCTEON_IRQ_SW0;
- /*
- * We need to disable interrupts to make sure our updates are
- * atomic.
- */
- local_irq_save(flags);
- clear_c0_status(0x100 << bit);
- local_irq_restore(flags);
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ cd->desired_en = false;
}
-static void octeon_irq_core_disable(unsigned int irq)
+static void octeon_irq_core_enable(struct irq_data *data)
{
-#ifdef CONFIG_SMP
- on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local,
- (void *) (long) irq, 1);
-#else
- octeon_irq_core_disable_local(irq);
-#endif
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ cd->desired_en = true;
}
-static struct irq_chip octeon_irq_chip_core = {
- .name = "Core",
- .enable = octeon_irq_core_enable,
- .disable = octeon_irq_core_disable,
- .ack = octeon_irq_core_ack,
- .eoi = octeon_irq_core_eoi,
-};
+static void octeon_irq_core_bus_lock(struct irq_data *data)
+{
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+ mutex_lock(&cd->core_irq_mutex);
+}
-static void octeon_irq_ciu0_ack(unsigned int irq)
+static void octeon_irq_core_bus_sync_unlock(struct irq_data *data)
{
- switch (irq) {
- case OCTEON_IRQ_GMX_DRP0:
- case OCTEON_IRQ_GMX_DRP1:
- case OCTEON_IRQ_IPD_DRP:
- case OCTEON_IRQ_KEY_ZERO:
- case OCTEON_IRQ_TIMER0:
- case OCTEON_IRQ_TIMER1:
- case OCTEON_IRQ_TIMER2:
- case OCTEON_IRQ_TIMER3:
- {
- int index = cvmx_get_core_num() * 2;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
- /*
- * CIU timer type interrupts must be acknoleged by
- * writing a '1' bit to their sum0 bit.
- */
- cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
- break;
- }
- default:
- break;
+ struct octeon_core_chip_data *cd = irq_data_get_irq_chip_data(data);
+
+ if (cd->desired_en != cd->current_en) {
+ on_each_cpu(octeon_irq_core_set_enable_local, data, 1);
+
+ cd->current_en = cd->desired_en;
}
- /*
- * In order to avoid any locking accessing the CIU, we
- * acknowledge CIU interrupts by disabling all of them. This
- * way we can use a per core register and avoid any out of
- * core locking requirements. This has the side affect that
- * CIU interrupts can't be processed recursively.
- *
- * We don't need to disable IRQs to make these atomic since
- * they are already disabled earlier in the low level
- * interrupt code.
- */
- clear_c0_status(0x100 << 2);
+ mutex_unlock(&cd->core_irq_mutex);
}
-static void octeon_irq_ciu0_eoi(unsigned int irq)
+static struct irq_chip octeon_irq_chip_core = {
+ .name = "Core",
+ .irq_enable = octeon_irq_core_enable,
+ .irq_disable = octeon_irq_core_disable,
+ .irq_ack = octeon_irq_core_ack,
+ .irq_eoi = octeon_irq_core_eoi,
+ .irq_bus_lock = octeon_irq_core_bus_lock,
+ .irq_bus_sync_unlock = octeon_irq_core_bus_sync_unlock,
+
+ .irq_cpu_online = octeon_irq_core_eoi,
+ .irq_cpu_offline = octeon_irq_core_ack,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
+
+static void __init octeon_irq_init_core(void)
{
- /*
- * Enable all CIU interrupts again. We don't need to disable
- * IRQs to make these atomic since they are already disabled
- * earlier in the low level interrupt code.
- */
- set_c0_status(0x100 << 2);
+ int i;
+ int irq;
+ struct octeon_core_chip_data *cd;
+
+ for (i = 0; i < MIPS_CORE_IRQ_LINES; i++) {
+ cd = &octeon_irq_core_chip_data[i];
+ cd->current_en = false;
+ cd->desired_en = false;
+ cd->bit = i;
+ mutex_init(&cd->core_irq_mutex);
+
+ irq = OCTEON_IRQ_SW0 + i;
+ switch (irq) {
+ case OCTEON_IRQ_TIMER:
+ case OCTEON_IRQ_SW0:
+ case OCTEON_IRQ_SW1:
+ case OCTEON_IRQ_5:
+ case OCTEON_IRQ_PERF:
+ irq_set_chip_data(irq, cd);
+ irq_set_chip_and_handler(irq, &octeon_irq_chip_core,
+ handle_percpu_irq);
+ break;
+ default:
+ break;
+ }
+ }
}
-static int next_coreid_for_irq(struct irq_desc *desc)
+static int next_cpu_for_irq(struct irq_data *data)
{
#ifdef CONFIG_SMP
- int coreid;
- int weight = cpumask_weight(desc->affinity);
+ int cpu;
+ int weight = cpumask_weight(data->affinity);
if (weight > 1) {
- int cpu = smp_processor_id();
+ cpu = smp_processor_id();
for (;;) {
- cpu = cpumask_next(cpu, desc->affinity);
+ cpu = cpumask_next(cpu, data->affinity);
if (cpu >= nr_cpu_ids) {
cpu = -1;
continue;
@@ -169,83 +214,175 @@ static int next_coreid_for_irq(struct irq_desc *desc)
break;
}
}
- coreid = octeon_coreid_for_cpu(cpu);
} else if (weight == 1) {
- coreid = octeon_coreid_for_cpu(cpumask_first(desc->affinity));
+ cpu = cpumask_first(data->affinity);
} else {
- coreid = cvmx_get_core_num();
+ cpu = smp_processor_id();
}
- return coreid;
+ return cpu;
#else
- return cvmx_get_core_num();
+ return smp_processor_id();
#endif
}
-static void octeon_irq_ciu0_enable(unsigned int irq)
+static void octeon_irq_ciu_enable(struct irq_data *data)
{
- struct irq_desc *desc = irq_to_desc(irq);
- int coreid = next_coreid_for_irq(desc);
+ int cpu = next_cpu_for_irq(data);
+ int coreid = octeon_coreid_for_cpu(cpu);
+ unsigned long *pen;
unsigned long flags;
- uint64_t en0;
- int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
- en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
- en0 |= 1ull << bit;
- cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
- cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
}
-static void octeon_irq_ciu0_enable_mbox(unsigned int irq)
+static void octeon_irq_ciu_enable_local(struct irq_data *data)
{
- int coreid = cvmx_get_core_num();
+ unsigned long *pen;
+ unsigned long flags;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
+}
+
+static void octeon_irq_ciu_disable_local(struct irq_data *data)
+{
+ unsigned long *pen;
unsigned long flags;
- uint64_t en0;
- int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
- en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
- en0 |= 1ull << bit;
- cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
- cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ pen = &__get_cpu_var(octeon_irq_ciu0_en_mirror);
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ pen = &__get_cpu_var(octeon_irq_ciu1_en_mirror);
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1), *pen);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
}
-static void octeon_irq_ciu0_disable(unsigned int irq)
+static void octeon_irq_ciu_disable_all(struct irq_data *data)
{
- int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
unsigned long flags;
- uint64_t en0;
+ unsigned long *pen;
int cpu;
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
- en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
- en0 &= ~(1ull << bit);
- cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
+ union octeon_ciu_chip_data cd;
+
+ wmb(); /* Make sure flag changes arrive before register updates. */
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ }
+}
+
+static void octeon_irq_ciu_enable_all(struct irq_data *data)
+{
+ unsigned long flags;
+ unsigned long *pen;
+ int cpu;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
}
- /*
- * We need to do a read after the last update to make sure all
- * of them are done.
- */
- cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
}
/*
* Enable the irq on the next core in the affinity set for chips that
* have the EN*_W1{S,C} registers.
*/
-static void octeon_irq_ciu0_enable_v2(unsigned int irq)
+static void octeon_irq_ciu_enable_v2(struct irq_data *data)
{
- int index;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
- struct irq_desc *desc = irq_to_desc(irq);
+ u64 mask;
+ int cpu = next_cpu_for_irq(data);
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
- if ((desc->status & IRQ_DISABLED) == 0) {
- index = next_coreid_for_irq(desc) * 2;
+ /*
+ * Called under the desc lock, so these should never get out
+ * of sync.
+ */
+ if (cd.s.line == 0) {
+ int index = octeon_coreid_for_cpu(cpu) * 2;
+ set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ } else {
+ int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
}
}
@@ -253,83 +390,155 @@ static void octeon_irq_ciu0_enable_v2(unsigned int irq)
* Enable the irq on the current CPU for chips that
* have the EN*_W1{S,C} registers.
*/
-static void octeon_irq_ciu0_enable_mbox_v2(unsigned int irq)
+static void octeon_irq_ciu_enable_local_v2(struct irq_data *data)
+{
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ int index = cvmx_get_core_num() * 2;
+ set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ } else {
+ int index = cvmx_get_core_num() * 2 + 1;
+ set_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ }
+}
+
+static void octeon_irq_ciu_disable_local_v2(struct irq_data *data)
{
- int index;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+ u64 mask;
+ union octeon_ciu_chip_data cd;
- index = cvmx_get_core_num() * 2;
- cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ int index = cvmx_get_core_num() * 2;
+ clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu0_en_mirror));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ } else {
+ int index = cvmx_get_core_num() * 2 + 1;
+ clear_bit(cd.s.bit, &__get_cpu_var(octeon_irq_ciu1_en_mirror));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ }
}
/*
- * Disable the irq on the current core for chips that have the EN*_W1{S,C}
- * registers.
+ * Write to the W1C bit in CVMX_CIU_INTX_SUM0 to clear the irq.
*/
-static void octeon_irq_ciu0_ack_v2(unsigned int irq)
-{
- int index = cvmx_get_core_num() * 2;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
-
- switch (irq) {
- case OCTEON_IRQ_GMX_DRP0:
- case OCTEON_IRQ_GMX_DRP1:
- case OCTEON_IRQ_IPD_DRP:
- case OCTEON_IRQ_KEY_ZERO:
- case OCTEON_IRQ_TIMER0:
- case OCTEON_IRQ_TIMER1:
- case OCTEON_IRQ_TIMER2:
- case OCTEON_IRQ_TIMER3:
- /*
- * CIU timer type interrupts must be acknoleged by
- * writing a '1' bit to their sum0 bit.
- */
+static void octeon_irq_ciu_ack(struct irq_data *data)
+{
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = data->chip_data;
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ int index = cvmx_get_core_num() * 2;
cvmx_write_csr(CVMX_CIU_INTX_SUM0(index), mask);
- break;
- default:
- break;
+ } else {
+ cvmx_write_csr(CVMX_CIU_INT_SUM1, mask);
}
-
- cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
}
/*
- * Enable the irq on the current core for chips that have the EN*_W1{S,C}
+ * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
* registers.
*/
-static void octeon_irq_ciu0_eoi_mbox_v2(unsigned int irq)
+static void octeon_irq_ciu_disable_all_v2(struct irq_data *data)
{
- struct irq_desc *desc = irq_to_desc(irq);
- int index = cvmx_get_core_num() * 2;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
+ int cpu;
+ u64 mask;
+ union octeon_ciu_chip_data cd;
- if (likely((desc->status & IRQ_DISABLED) == 0))
- cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ wmb(); /* Make sure flag changes arrive before register updates. */
+
+ cd.p = data->chip_data;
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ for_each_online_cpu(cpu) {
+ int index = octeon_coreid_for_cpu(cpu) * 2;
+ clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ }
+ } else {
+ for_each_online_cpu(cpu) {
+ int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ clear_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ }
+ }
}
/*
- * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
+ * Enable the irq on the all cores for chips that have the EN*_W1{S,C}
* registers.
*/
-static void octeon_irq_ciu0_disable_all_v2(unsigned int irq)
+static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
{
- u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
- int index;
int cpu;
- for_each_online_cpu(cpu) {
- index = octeon_coreid_for_cpu(cpu) * 2;
- cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ cd.p = data->chip_data;
+ mask = 1ull << (cd.s.bit);
+
+ if (cd.s.line == 0) {
+ for_each_online_cpu(cpu) {
+ int index = octeon_coreid_for_cpu(cpu) * 2;
+ set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu0_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ }
+ } else {
+ for_each_online_cpu(cpu) {
+ int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ set_bit(cd.s.bit, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ }
}
}
#ifdef CONFIG_SMP
-static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
+
+static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
+{
+ int cpu = smp_processor_id();
+ cpumask_t new_affinity;
+
+ if (!cpumask_test_cpu(cpu, data->affinity))
+ return;
+
+ if (cpumask_weight(data->affinity) > 1) {
+ /*
+ * It has multi CPU affinity, just remove this CPU
+ * from the affinity set.
+ */
+ cpumask_copy(&new_affinity, data->affinity);
+ cpumask_clear_cpu(cpu, &new_affinity);
+ } else {
+ /* Otherwise, put it on lowest numbered online CPU. */
+ cpumask_clear(&new_affinity);
+ cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
+ }
+ __irq_set_affinity_locked(data, &new_affinity);
+}
+
+static int octeon_irq_ciu_set_affinity(struct irq_data *data,
+ const struct cpumask *dest, bool force)
{
int cpu;
- struct irq_desc *desc = irq_to_desc(irq);
- int enable_one = (desc->status & IRQ_DISABLED) == 0;
+ bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
unsigned long flags;
- int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
+ union octeon_ciu_chip_data cd;
+
+ cd.p = data->chip_data;
/*
* For non-v2 CIU, we will allow only single CPU affinity.
@@ -339,26 +548,40 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
if (cpumask_weight(dest) != 1)
return -EINVAL;
- raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
- uint64_t en0 =
- cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
- if (cpumask_test_cpu(cpu, dest) && enable_one) {
- enable_one = 0;
- en0 |= 1ull << bit;
- } else {
- en0 &= ~(1ull << bit);
+ if (!enable_one)
+ return 0;
+
+ if (cd.s.line == 0) {
+ raw_spin_lock_irqsave(&octeon_irq_ciu0_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ set_bit(cd.s.bit, pen);
+ } else {
+ clear_bit(cd.s.bit, pen);
+ }
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), *pen);
}
- cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
+ } else {
+ raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = octeon_coreid_for_cpu(cpu);
+ unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ set_bit(cd.s.bit, pen);
+ } else {
+ clear_bit(cd.s.bit, pen);
+ }
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
+ }
+ raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
}
- /*
- * We need to do a read after the last update to make sure all
- * of them are done.
- */
- cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
- raw_spin_unlock_irqrestore(&octeon_irq_ciu0_lock, flags);
-
return 0;
}
@@ -366,22 +589,46 @@ static int octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *
* Set affinity for the irq for chips that have the EN*_W1{S,C}
* registers.
*/
-static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq,
- const struct cpumask *dest)
+static int octeon_irq_ciu_set_affinity_v2(struct irq_data *data,
+ const struct cpumask *dest,
+ bool force)
{
int cpu;
- int index;
- struct irq_desc *desc = irq_to_desc(irq);
- int enable_one = (desc->status & IRQ_DISABLED) == 0;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WORKQ0);
-
- for_each_online_cpu(cpu) {
- index = octeon_coreid_for_cpu(cpu) * 2;
- if (cpumask_test_cpu(cpu, dest) && enable_one) {
- enable_one = 0;
- cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
- } else {
- cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ bool enable_one = !irqd_irq_disabled(data) && !irqd_irq_masked(data);
+ u64 mask;
+ union octeon_ciu_chip_data cd;
+
+ if (!enable_one)
+ return 0;
+
+ cd.p = data->chip_data;
+ mask = 1ull << cd.s.bit;
+
+ if (cd.s.line == 0) {
+ for_each_online_cpu(cpu) {
+ unsigned long *pen = &per_cpu(octeon_irq_ciu0_en_mirror, cpu);
+ int index = octeon_coreid_for_cpu(cpu) * 2;
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1S(index), mask);
+ } else {
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0_W1C(index), mask);
+ }
+ }
+ } else {
+ for_each_online_cpu(cpu) {
+ unsigned long *pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ int index = octeon_coreid_for_cpu(cpu) * 2 + 1;
+ if (cpumask_test_cpu(cpu, dest) && enable_one) {
+ enable_one = false;
+ set_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ } else {
+ clear_bit(cd.s.bit, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ }
}
}
return 0;
@@ -389,80 +636,102 @@ static int octeon_irq_ciu0_set_affinity_v2(unsigned int irq,
#endif
/*
+ * The v1 CIU code already masks things, so supply a dummy version to
+ * the core chip code.
+ */
+static void octeon_irq_dummy_mask(struct irq_data *data)
+{
+}
+
+/*
* Newer octeon chips have support for lockless CIU operation.
*/
-static struct irq_chip octeon_irq_chip_ciu0_v2 = {
- .name = "CIU0",
- .enable = octeon_irq_ciu0_enable_v2,
- .disable = octeon_irq_ciu0_disable_all_v2,
- .eoi = octeon_irq_ciu0_enable_v2,
+static struct irq_chip octeon_irq_chip_ciu_v2 = {
+ .name = "CIU",
+ .irq_enable = octeon_irq_ciu_enable_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_v2,
#ifdef CONFIG_SMP
- .set_affinity = octeon_irq_ciu0_set_affinity_v2,
+ .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
#endif
};
-static struct irq_chip octeon_irq_chip_ciu0 = {
- .name = "CIU0",
- .enable = octeon_irq_ciu0_enable,
- .disable = octeon_irq_ciu0_disable,
- .eoi = octeon_irq_ciu0_eoi,
+static struct irq_chip octeon_irq_chip_ciu_edge_v2 = {
+ .name = "CIU-E",
+ .irq_enable = octeon_irq_ciu_enable_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_ack = octeon_irq_ciu_ack,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_v2,
#ifdef CONFIG_SMP
- .set_affinity = octeon_irq_ciu0_set_affinity,
+ .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
#endif
};
-/* The mbox versions don't do any affinity or round-robin. */
-static struct irq_chip octeon_irq_chip_ciu0_mbox_v2 = {
- .name = "CIU0-M",
- .enable = octeon_irq_ciu0_enable_mbox_v2,
- .disable = octeon_irq_ciu0_disable,
- .eoi = octeon_irq_ciu0_eoi_mbox_v2,
+static struct irq_chip octeon_irq_chip_ciu = {
+ .name = "CIU",
+ .irq_enable = octeon_irq_ciu_enable,
+ .irq_disable = octeon_irq_ciu_disable_all,
+ .irq_mask = octeon_irq_dummy_mask,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
};
-static struct irq_chip octeon_irq_chip_ciu0_mbox = {
- .name = "CIU0-M",
- .enable = octeon_irq_ciu0_enable_mbox,
- .disable = octeon_irq_ciu0_disable,
- .eoi = octeon_irq_ciu0_eoi,
+static struct irq_chip octeon_irq_chip_ciu_edge = {
+ .name = "CIU-E",
+ .irq_enable = octeon_irq_ciu_enable,
+ .irq_disable = octeon_irq_ciu_disable_all,
+ .irq_mask = octeon_irq_dummy_mask,
+ .irq_ack = octeon_irq_ciu_ack,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
};
-static void octeon_irq_ciu1_ack(unsigned int irq)
-{
- /*
- * In order to avoid any locking accessing the CIU, we
- * acknowledge CIU interrupts by disabling all of them. This
- * way we can use a per core register and avoid any out of
- * core locking requirements. This has the side affect that
- * CIU interrupts can't be processed recursively. We don't
- * need to disable IRQs to make these atomic since they are
- * already disabled earlier in the low level interrupt code.
- */
- clear_c0_status(0x100 << 3);
-}
+/* The mbox versions don't do any affinity or round-robin. */
+static struct irq_chip octeon_irq_chip_ciu_mbox_v2 = {
+ .name = "CIU-M",
+ .irq_enable = octeon_irq_ciu_enable_all_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_ack = octeon_irq_ciu_disable_local_v2,
+ .irq_eoi = octeon_irq_ciu_enable_local_v2,
+
+ .irq_cpu_online = octeon_irq_ciu_enable_local_v2,
+ .irq_cpu_offline = octeon_irq_ciu_disable_local_v2,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
-static void octeon_irq_ciu1_eoi(unsigned int irq)
-{
- /*
- * Enable all CIU interrupts again. We don't need to disable
- * IRQs to make these atomic since they are already disabled
- * earlier in the low level interrupt code.
- */
- set_c0_status(0x100 << 3);
-}
+static struct irq_chip octeon_irq_chip_ciu_mbox = {
+ .name = "CIU-M",
+ .irq_enable = octeon_irq_ciu_enable_all,
+ .irq_disable = octeon_irq_ciu_disable_all,
+
+ .irq_cpu_online = octeon_irq_ciu_enable_local,
+ .irq_cpu_offline = octeon_irq_ciu_disable_local,
+ .flags = IRQCHIP_ONOFFLINE_ENABLED,
+};
-static void octeon_irq_ciu1_enable(unsigned int irq)
+/*
+ * Watchdog interrupts are special. They are associated with a single
+ * core, so we hardwire the affinity to that core.
+ */
+static void octeon_irq_ciu_wd_enable(struct irq_data *data)
{
- struct irq_desc *desc = irq_to_desc(irq);
- int coreid = next_coreid_for_irq(desc);
unsigned long flags;
- uint64_t en1;
- int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
+ unsigned long *pen;
+ int coreid = data->irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
+ int cpu = octeon_cpu_for_coreid(coreid);
raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
- en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
- en1 |= 1ull << bit;
- cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
- cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+ pen = &per_cpu(octeon_irq_ciu1_en_mirror, cpu);
+ set_bit(coreid, pen);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), *pen);
raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
}
@@ -470,286 +739,281 @@ static void octeon_irq_ciu1_enable(unsigned int irq)
* Watchdog interrupts are special. They are associated with a single
* core, so we hardwire the affinity to that core.
*/
-static void octeon_irq_ciu1_wd_enable(unsigned int irq)
+static void octeon_irq_ciu1_wd_enable_v2(struct irq_data *data)
{
- unsigned long flags;
- uint64_t en1;
- int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
- int coreid = bit;
+ int coreid = data->irq - OCTEON_IRQ_WDOG0;
+ int cpu = octeon_cpu_for_coreid(coreid);
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
- en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
- en1 |= 1ull << bit;
- cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
- cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ set_bit(coreid, &per_cpu(octeon_irq_ciu1_en_mirror, cpu));
+ cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(coreid * 2 + 1), 1ull << coreid);
}
-static void octeon_irq_ciu1_disable(unsigned int irq)
+
+static struct irq_chip octeon_irq_chip_ciu_wd_v2 = {
+ .name = "CIU-W",
+ .irq_enable = octeon_irq_ciu1_wd_enable_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_local_v2,
+};
+
+static struct irq_chip octeon_irq_chip_ciu_wd = {
+ .name = "CIU-W",
+ .irq_enable = octeon_irq_ciu_wd_enable,
+ .irq_disable = octeon_irq_ciu_disable_all,
+ .irq_mask = octeon_irq_dummy_mask,
+};
+
+static void octeon_irq_ip2_v1(void)
{
- int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
- unsigned long flags;
- uint64_t en1;
- int cpu;
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
- en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
- en1 &= ~(1ull << bit);
- cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
+ const unsigned long core_id = cvmx_get_core_num();
+ u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
+
+ ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
+ clear_c0_status(STATUSF_IP2);
+ if (likely(ciu_sum)) {
+ int bit = fls64(ciu_sum) - 1;
+ int irq = octeon_irq_ciu_to_irq[0][bit];
+ if (likely(irq))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+ } else {
+ spurious_interrupt();
}
- /*
- * We need to do a read after the last update to make sure all
- * of them are done.
- */
- cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
+ set_c0_status(STATUSF_IP2);
}
-/*
- * Enable the irq on the current core for chips that have the EN*_W1{S,C}
- * registers.
- */
-static void octeon_irq_ciu1_enable_v2(unsigned int irq)
+static void octeon_irq_ip2_v2(void)
{
- int index;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
- struct irq_desc *desc = irq_to_desc(irq);
-
- if ((desc->status & IRQ_DISABLED) == 0) {
- index = next_coreid_for_irq(desc) * 2 + 1;
- cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ const unsigned long core_id = cvmx_get_core_num();
+ u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INTX_SUM0(core_id * 2));
+
+ ciu_sum &= __get_cpu_var(octeon_irq_ciu0_en_mirror);
+ if (likely(ciu_sum)) {
+ int bit = fls64(ciu_sum) - 1;
+ int irq = octeon_irq_ciu_to_irq[0][bit];
+ if (likely(irq))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+ } else {
+ spurious_interrupt();
}
}
-
-/*
- * Watchdog interrupts are special. They are associated with a single
- * core, so we hardwire the affinity to that core.
- */
-static void octeon_irq_ciu1_wd_enable_v2(unsigned int irq)
+static void octeon_irq_ip3_v1(void)
{
- int index;
- int coreid = irq - OCTEON_IRQ_WDOG0;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
- struct irq_desc *desc = irq_to_desc(irq);
-
- if ((desc->status & IRQ_DISABLED) == 0) {
- index = coreid * 2 + 1;
- cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
+ u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
+
+ ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
+ clear_c0_status(STATUSF_IP3);
+ if (likely(ciu_sum)) {
+ int bit = fls64(ciu_sum) - 1;
+ int irq = octeon_irq_ciu_to_irq[1][bit];
+ if (likely(irq))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+ } else {
+ spurious_interrupt();
}
+ set_c0_status(STATUSF_IP3);
}
-/*
- * Disable the irq on the current core for chips that have the EN*_W1{S,C}
- * registers.
- */
-static void octeon_irq_ciu1_ack_v2(unsigned int irq)
+static void octeon_irq_ip3_v2(void)
{
- int index = cvmx_get_core_num() * 2 + 1;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
-
- cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
+ u64 ciu_sum = cvmx_read_csr(CVMX_CIU_INT_SUM1);
+
+ ciu_sum &= __get_cpu_var(octeon_irq_ciu1_en_mirror);
+ if (likely(ciu_sum)) {
+ int bit = fls64(ciu_sum) - 1;
+ int irq = octeon_irq_ciu_to_irq[1][bit];
+ if (likely(irq))
+ do_IRQ(irq);
+ else
+ spurious_interrupt();
+ } else {
+ spurious_interrupt();
+ }
}
-/*
- * Disable the irq on the all cores for chips that have the EN*_W1{S,C}
- * registers.
- */
-static void octeon_irq_ciu1_disable_all_v2(unsigned int irq)
+static void octeon_irq_ip4_mask(void)
{
- u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
- int index;
- int cpu;
- for_each_online_cpu(cpu) {
- index = octeon_coreid_for_cpu(cpu) * 2 + 1;
- cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
- }
+ clear_c0_status(STATUSF_IP4);
+ spurious_interrupt();
}
-#ifdef CONFIG_SMP
-static int octeon_irq_ciu1_set_affinity(unsigned int irq,
- const struct cpumask *dest)
-{
- int cpu;
- struct irq_desc *desc = irq_to_desc(irq);
- int enable_one = (desc->status & IRQ_DISABLED) == 0;
- unsigned long flags;
- int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
+static void (*octeon_irq_ip2)(void);
+static void (*octeon_irq_ip3)(void);
+static void (*octeon_irq_ip4)(void);
- /*
- * For non-v2 CIU, we will allow only single CPU affinity.
- * This removes the need to do locking in the .ack/.eoi
- * functions.
- */
- if (cpumask_weight(dest) != 1)
- return -EINVAL;
+void __cpuinitdata (*octeon_irq_setup_secondary)(void);
- raw_spin_lock_irqsave(&octeon_irq_ciu1_lock, flags);
- for_each_online_cpu(cpu) {
- int coreid = octeon_coreid_for_cpu(cpu);
- uint64_t en1 =
- cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
- if (cpumask_test_cpu(cpu, dest) && enable_one) {
- enable_one = 0;
- en1 |= 1ull << bit;
- } else {
- en1 &= ~(1ull << bit);
- }
- cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
- }
+static void __cpuinit octeon_irq_percpu_enable(void)
+{
+ irq_cpu_online();
+}
+
+static void __cpuinit octeon_irq_init_ciu_percpu(void)
+{
+ int coreid = cvmx_get_core_num();
/*
- * We need to do a read after the last update to make sure all
- * of them are done.
+ * Disable All CIU Interrupts. The ones we need will be
+ * enabled later. Read the SUM register so we know the write
+ * completed.
*/
- cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
- raw_spin_unlock_irqrestore(&octeon_irq_ciu1_lock, flags);
-
- return 0;
+ cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
+ cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
}
-/*
- * Set affinity for the irq for chips that have the EN*_W1{S,C}
- * registers.
- */
-static int octeon_irq_ciu1_set_affinity_v2(unsigned int irq,
- const struct cpumask *dest)
+static void __cpuinit octeon_irq_setup_secondary_ciu(void)
{
- int cpu;
- int index;
- struct irq_desc *desc = irq_to_desc(irq);
- int enable_one = (desc->status & IRQ_DISABLED) == 0;
- u64 mask = 1ull << (irq - OCTEON_IRQ_WDOG0);
- for_each_online_cpu(cpu) {
- index = octeon_coreid_for_cpu(cpu) * 2 + 1;
- if (cpumask_test_cpu(cpu, dest) && enable_one) {
- enable_one = 0;
- cvmx_write_csr(CVMX_CIU_INTX_EN1_W1S(index), mask);
- } else {
- cvmx_write_csr(CVMX_CIU_INTX_EN1_W1C(index), mask);
- }
- }
- return 0;
-}
-#endif
-/*
- * Newer octeon chips have support for lockless CIU operation.
- */
-static struct irq_chip octeon_irq_chip_ciu1_v2 = {
- .name = "CIU1",
- .enable = octeon_irq_ciu1_enable_v2,
- .disable = octeon_irq_ciu1_disable_all_v2,
- .eoi = octeon_irq_ciu1_enable_v2,
-#ifdef CONFIG_SMP
- .set_affinity = octeon_irq_ciu1_set_affinity_v2,
-#endif
-};
+ __get_cpu_var(octeon_irq_ciu0_en_mirror) = 0;
+ __get_cpu_var(octeon_irq_ciu1_en_mirror) = 0;
-static struct irq_chip octeon_irq_chip_ciu1 = {
- .name = "CIU1",
- .enable = octeon_irq_ciu1_enable,
- .disable = octeon_irq_ciu1_disable,
- .eoi = octeon_irq_ciu1_eoi,
-#ifdef CONFIG_SMP
- .set_affinity = octeon_irq_ciu1_set_affinity,
-#endif
-};
+ octeon_irq_init_ciu_percpu();
+ octeon_irq_percpu_enable();
-static struct irq_chip octeon_irq_chip_ciu1_wd_v2 = {
- .name = "CIU1-W",
- .enable = octeon_irq_ciu1_wd_enable_v2,
- .disable = octeon_irq_ciu1_disable_all_v2,
- .eoi = octeon_irq_ciu1_wd_enable_v2,
-};
+ /* Enable the CIU lines */
+ set_c0_status(STATUSF_IP3 | STATUSF_IP2);
+ clear_c0_status(STATUSF_IP4);
+}
-static struct irq_chip octeon_irq_chip_ciu1_wd = {
- .name = "CIU1-W",
- .enable = octeon_irq_ciu1_wd_enable,
- .disable = octeon_irq_ciu1_disable,
- .eoi = octeon_irq_ciu1_eoi,
-};
+static void __init octeon_irq_init_ciu(void)
+{
+ unsigned int i;
+ struct irq_chip *chip;
+ struct irq_chip *chip_edge;
+ struct irq_chip *chip_mbox;
+ struct irq_chip *chip_wd;
+
+ octeon_irq_init_ciu_percpu();
+ octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
-static void (*octeon_ciu0_ack)(unsigned int);
-static void (*octeon_ciu1_ack)(unsigned int);
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ octeon_irq_ip2 = octeon_irq_ip2_v2;
+ octeon_irq_ip3 = octeon_irq_ip3_v2;
+ chip = &octeon_irq_chip_ciu_v2;
+ chip_edge = &octeon_irq_chip_ciu_edge_v2;
+ chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
+ chip_wd = &octeon_irq_chip_ciu_wd_v2;
+ } else {
+ octeon_irq_ip2 = octeon_irq_ip2_v1;
+ octeon_irq_ip3 = octeon_irq_ip3_v1;
+ chip = &octeon_irq_chip_ciu;
+ chip_edge = &octeon_irq_chip_ciu_edge;
+ chip_mbox = &octeon_irq_chip_ciu_mbox;
+ chip_wd = &octeon_irq_chip_ciu_wd;
+ }
+ octeon_irq_ip4 = octeon_irq_ip4_mask;
+
+ /* Mips internal */
+ octeon_irq_init_core();
+
+ /* CIU_0 */
+ for (i = 0; i < 16; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
+ for (i = 0; i < 16; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq);
+
+ for (i = 0; i < 4; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
+ for (i = 0; i < 4; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq);
+
+ for (i = 0; i < 2; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq);
+
+ for (i = 0; i < 4; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
+
+ /* CIU_1 */
+ for (i = 0; i < 16; i++)
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq);
+
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq);
+ octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq);
+
+ /* Enable the CIU lines */
+ set_c0_status(STATUSF_IP3 | STATUSF_IP2);
+ clear_c0_status(STATUSF_IP4);
+}
void __init arch_init_irq(void)
{
- unsigned int irq;
- struct irq_chip *chip0;
- struct irq_chip *chip0_mbox;
- struct irq_chip *chip1;
- struct irq_chip *chip1_wd;
-
#ifdef CONFIG_SMP
/* Set the default affinity to the boot cpu. */
cpumask_clear(irq_default_affinity);
cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
#endif
-
- if (NR_IRQS < OCTEON_IRQ_LAST)
- pr_err("octeon_irq_init: NR_IRQS is set too low\n");
-
- if (OCTEON_IS_MODEL(OCTEON_CN58XX_PASS2_X) ||
- OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
- OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X)) {
- octeon_ciu0_ack = octeon_irq_ciu0_ack_v2;
- octeon_ciu1_ack = octeon_irq_ciu1_ack_v2;
- chip0 = &octeon_irq_chip_ciu0_v2;
- chip0_mbox = &octeon_irq_chip_ciu0_mbox_v2;
- chip1 = &octeon_irq_chip_ciu1_v2;
- chip1_wd = &octeon_irq_chip_ciu1_wd_v2;
- } else {
- octeon_ciu0_ack = octeon_irq_ciu0_ack;
- octeon_ciu1_ack = octeon_irq_ciu1_ack;
- chip0 = &octeon_irq_chip_ciu0;
- chip0_mbox = &octeon_irq_chip_ciu0_mbox;
- chip1 = &octeon_irq_chip_ciu1;
- chip1_wd = &octeon_irq_chip_ciu1_wd;
- }
-
- /* 0 - 15 reserved for i8259 master and slave controller. */
-
- /* 17 - 23 Mips internal */
- for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) {
- set_irq_chip_and_handler(irq, &octeon_irq_chip_core,
- handle_percpu_irq);
- }
-
- /* 24 - 87 CIU_INT_SUM0 */
- for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
- switch (irq) {
- case OCTEON_IRQ_MBOX0:
- case OCTEON_IRQ_MBOX1:
- set_irq_chip_and_handler(irq, chip0_mbox, handle_percpu_irq);
- break;
- default:
- set_irq_chip_and_handler(irq, chip0, handle_fasteoi_irq);
- break;
- }
- }
-
- /* 88 - 151 CIU_INT_SUM1 */
- for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_WDOG15; irq++)
- set_irq_chip_and_handler(irq, chip1_wd, handle_fasteoi_irq);
-
- for (irq = OCTEON_IRQ_UART2; irq <= OCTEON_IRQ_RESERVED151; irq++)
- set_irq_chip_and_handler(irq, chip1, handle_fasteoi_irq);
-
- set_c0_status(0x300 << 2);
+ octeon_irq_init_ciu();
}
asmlinkage void plat_irq_dispatch(void)
{
- const unsigned long core_id = cvmx_get_core_num();
- const uint64_t ciu_sum0_address = CVMX_CIU_INTX_SUM0(core_id * 2);
- const uint64_t ciu_en0_address = CVMX_CIU_INTX_EN0(core_id * 2);
- const uint64_t ciu_sum1_address = CVMX_CIU_INT_SUM1;
- const uint64_t ciu_en1_address = CVMX_CIU_INTX_EN1(core_id * 2 + 1);
unsigned long cop0_cause;
unsigned long cop0_status;
- uint64_t ciu_en;
- uint64_t ciu_sum;
- unsigned int irq;
while (1) {
cop0_cause = read_c0_cause();
@@ -757,33 +1021,16 @@ asmlinkage void plat_irq_dispatch(void)
cop0_cause &= cop0_status;
cop0_cause &= ST0_IM;
- if (unlikely(cop0_cause & STATUSF_IP2)) {
- ciu_sum = cvmx_read_csr(ciu_sum0_address);
- ciu_en = cvmx_read_csr(ciu_en0_address);
- ciu_sum &= ciu_en;
- if (likely(ciu_sum)) {
- irq = fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1;
- octeon_ciu0_ack(irq);
- do_IRQ(irq);
- } else {
- spurious_interrupt();
- }
- } else if (unlikely(cop0_cause & STATUSF_IP3)) {
- ciu_sum = cvmx_read_csr(ciu_sum1_address);
- ciu_en = cvmx_read_csr(ciu_en1_address);
- ciu_sum &= ciu_en;
- if (likely(ciu_sum)) {
- irq = fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1;
- octeon_ciu1_ack(irq);
- do_IRQ(irq);
- } else {
- spurious_interrupt();
- }
- } else if (likely(cop0_cause)) {
+ if (unlikely(cop0_cause & STATUSF_IP2))
+ octeon_irq_ip2();
+ else if (unlikely(cop0_cause & STATUSF_IP3))
+ octeon_irq_ip3();
+ else if (unlikely(cop0_cause & STATUSF_IP4))
+ octeon_irq_ip4();
+ else if (likely(cop0_cause))
do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE);
- } else {
+ else
break;
- }
}
}
@@ -791,83 +1038,7 @@ asmlinkage void plat_irq_dispatch(void)
void fixup_irqs(void)
{
- int irq;
- struct irq_desc *desc;
- cpumask_t new_affinity;
- unsigned long flags;
- int do_set_affinity;
- int cpu;
-
- cpu = smp_processor_id();
-
- for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++)
- octeon_irq_core_disable_local(irq);
-
- for (irq = OCTEON_IRQ_WORKQ0; irq < OCTEON_IRQ_LAST; irq++) {
- desc = irq_to_desc(irq);
- switch (irq) {
- case OCTEON_IRQ_MBOX0:
- case OCTEON_IRQ_MBOX1:
- /* The eoi function will disable them on this CPU. */
- desc->chip->eoi(irq);
- break;
- case OCTEON_IRQ_WDOG0:
- case OCTEON_IRQ_WDOG1:
- case OCTEON_IRQ_WDOG2:
- case OCTEON_IRQ_WDOG3:
- case OCTEON_IRQ_WDOG4:
- case OCTEON_IRQ_WDOG5:
- case OCTEON_IRQ_WDOG6:
- case OCTEON_IRQ_WDOG7:
- case OCTEON_IRQ_WDOG8:
- case OCTEON_IRQ_WDOG9:
- case OCTEON_IRQ_WDOG10:
- case OCTEON_IRQ_WDOG11:
- case OCTEON_IRQ_WDOG12:
- case OCTEON_IRQ_WDOG13:
- case OCTEON_IRQ_WDOG14:
- case OCTEON_IRQ_WDOG15:
- /*
- * These have special per CPU semantics and
- * are handled in the watchdog driver.
- */
- break;
- default:
- raw_spin_lock_irqsave(&desc->lock, flags);
- /*
- * If this irq has an action, it is in use and
- * must be migrated if it has affinity to this
- * cpu.
- */
- if (desc->action && cpumask_test_cpu(cpu, desc->affinity)) {
- if (cpumask_weight(desc->affinity) > 1) {
- /*
- * It has multi CPU affinity,
- * just remove this CPU from
- * the affinity set.
- */
- cpumask_copy(&new_affinity, desc->affinity);
- cpumask_clear_cpu(cpu, &new_affinity);
- } else {
- /*
- * Otherwise, put it on lowest
- * numbered online CPU.
- */
- cpumask_clear(&new_affinity);
- cpumask_set_cpu(cpumask_first(cpu_online_mask), &new_affinity);
- }
- do_set_affinity = 1;
- } else {
- do_set_affinity = 0;
- }
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
- if (do_set_affinity)
- irq_set_affinity(irq, &new_affinity);
-
- break;
- }
- }
+ irq_cpu_offline();
}
#endif /* CONFIG_HOTPLUG_CPU */
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index b0c3686c96d..8b139bf4a1b 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -420,7 +420,6 @@ void octeon_user_io_init(void)
void __init prom_init(void)
{
struct cvmx_sysinfo *sysinfo;
- const int coreid = cvmx_get_core_num();
int i;
int argc;
#ifdef CONFIG_CAVIUM_RESERVE32
@@ -537,17 +536,6 @@ void __init prom_init(void)
octeon_uart = octeon_get_boot_uart();
- /*
- * Disable All CIU Interrupts. The ones we need will be
- * enabled later. Read the SUM register so we know the write
- * completed.
- */
- cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0);
- cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
- cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
- cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
- cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
-
#ifdef CONFIG_SMP
octeon_write_lcd("LinuxSMP");
#else
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index 391cefe556b..ba78b21cc8d 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -171,41 +171,19 @@ static void octeon_boot_secondary(int cpu, struct task_struct *idle)
* After we've done initial boot, this function is called to allow the
* board code to clean up state, if needed
*/
-static void octeon_init_secondary(void)
+static void __cpuinit octeon_init_secondary(void)
{
- const int coreid = cvmx_get_core_num();
- union cvmx_ciu_intx_sum0 interrupt_enable;
unsigned int sr;
-#ifdef CONFIG_HOTPLUG_CPU
- struct linux_app_boot_info *labi;
-
- labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
-
- if (labi->labi_signature != LABI_SIGNATURE)
- panic("The bootloader version on this board is incorrect.");
-#endif
-
sr = set_c0_status(ST0_BEV);
write_c0_ebase((u32)ebase);
write_c0_status(sr);
octeon_check_cpu_bist();
octeon_init_cvmcount();
- /*
- pr_info("SMP: CPU%d (CoreId %lu) started\n", cpu, coreid);
- */
- /* Enable Mailbox interrupts to this core. These are the only
- interrupts allowed on line 3 */
- cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), 0xffffffff);
- interrupt_enable.u64 = 0;
- interrupt_enable.s.mbox = 0x3;
- cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), interrupt_enable.u64);
- cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
- cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
- cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
- /* Enable core interrupt processing for 2,3 and 7 */
- set_c0_status(0x8c01);
+
+ octeon_irq_setup_secondary();
+ raw_local_irq_enable();
}
/**
@@ -214,6 +192,15 @@ static void octeon_init_secondary(void)
*/
void octeon_prepare_cpus(unsigned int max_cpus)
{
+#ifdef CONFIG_HOTPLUG_CPU
+ struct linux_app_boot_info *labi;
+
+ labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER);
+
+ if (labi->labi_signature != LABI_SIGNATURE)
+ panic("The bootloader version on this board is incorrect.");
+#endif
+
cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff);
if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_DISABLED,
"mailbox0", mailbox_interrupt)) {
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c
index 8d9a5fc607e..824e08c7379 100644
--- a/arch/mips/dec/ioasic-irq.c
+++ b/arch/mips/dec/ioasic-irq.c
@@ -68,10 +68,10 @@ void __init init_ioasic_irqs(int base)
fast_iob();
for (i = base; i < base + IO_INR_DMA; i++)
- set_irq_chip_and_handler(i, &ioasic_irq_type,
+ irq_set_chip_and_handler(i, &ioasic_irq_type,
handle_level_irq);
for (; i < base + IO_IRQ_LINES; i++)
- set_irq_chip(i, &ioasic_dma_irq_type);
+ irq_set_chip(i, &ioasic_dma_irq_type);
ioasic_irq_base = base;
}
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
index ef31d98c4fb..37199f742c4 100644
--- a/arch/mips/dec/kn02-irq.c
+++ b/arch/mips/dec/kn02-irq.c
@@ -73,7 +73,7 @@ void __init init_kn02_irqs(int base)
iob();
for (i = base; i < base + KN02_IRQ_LINES; i++)
- set_irq_chip_and_handler(i, &kn02_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &kn02_irq_type, handle_level_irq);
kn02_irq_base = base;
}
diff --git a/arch/mips/emma/markeins/irq.c b/arch/mips/emma/markeins/irq.c
index 9b1207ae225..3dbd7a5a6ad 100644
--- a/arch/mips/emma/markeins/irq.c
+++ b/arch/mips/emma/markeins/irq.c
@@ -69,7 +69,7 @@ void emma2rh_irq_init(void)
u32 i;
for (i = 0; i < NUM_EMMA2RH_IRQ; i++)
- set_irq_chip_and_handler_name(EMMA2RH_IRQ_BASE + i,
+ irq_set_chip_and_handler_name(EMMA2RH_IRQ_BASE + i,
&emma2rh_irq_controller,
handle_level_irq, "level");
}
@@ -105,7 +105,7 @@ void emma2rh_sw_irq_init(void)
u32 i;
for (i = 0; i < NUM_EMMA2RH_IRQ_SW; i++)
- set_irq_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i,
+ irq_set_chip_and_handler_name(EMMA2RH_SW_IRQ_BASE + i,
&emma2rh_sw_irq_controller,
handle_level_irq, "level");
}
@@ -162,7 +162,7 @@ void emma2rh_gpio_irq_init(void)
u32 i;
for (i = 0; i < NUM_EMMA2RH_IRQ_GPIO; i++)
- set_irq_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i,
+ irq_set_chip_and_handler_name(EMMA2RH_GPIO_IRQ_BASE + i,
&emma2rh_gpio_irq_controller,
handle_edge_irq, "edge");
}
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
index 6ddab8aef64..5b05f186e39 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/irq.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -11,172 +11,91 @@
#define NR_IRQS OCTEON_IRQ_LAST
#define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0
-/* 0 - 7 represent the i8259 master */
-#define OCTEON_IRQ_I8259M0 0
-#define OCTEON_IRQ_I8259M1 1
-#define OCTEON_IRQ_I8259M2 2
-#define OCTEON_IRQ_I8259M3 3
-#define OCTEON_IRQ_I8259M4 4
-#define OCTEON_IRQ_I8259M5 5
-#define OCTEON_IRQ_I8259M6 6
-#define OCTEON_IRQ_I8259M7 7
-/* 8 - 15 represent the i8259 slave */
-#define OCTEON_IRQ_I8259S0 8
-#define OCTEON_IRQ_I8259S1 9
-#define OCTEON_IRQ_I8259S2 10
-#define OCTEON_IRQ_I8259S3 11
-#define OCTEON_IRQ_I8259S4 12
-#define OCTEON_IRQ_I8259S5 13
-#define OCTEON_IRQ_I8259S6 14
-#define OCTEON_IRQ_I8259S7 15
-/* 16 - 23 represent the 8 MIPS standard interrupt sources */
-#define OCTEON_IRQ_SW0 16
-#define OCTEON_IRQ_SW1 17
-#define OCTEON_IRQ_CIU0 18
-#define OCTEON_IRQ_CIU1 19
-#define OCTEON_IRQ_CIU4 20
-#define OCTEON_IRQ_5 21
-#define OCTEON_IRQ_PERF 22
-#define OCTEON_IRQ_TIMER 23
-/* 24 - 87 represent the sources in CIU_INTX_EN0 */
-#define OCTEON_IRQ_WORKQ0 24
-#define OCTEON_IRQ_WORKQ1 25
-#define OCTEON_IRQ_WORKQ2 26
-#define OCTEON_IRQ_WORKQ3 27
-#define OCTEON_IRQ_WORKQ4 28
-#define OCTEON_IRQ_WORKQ5 29
-#define OCTEON_IRQ_WORKQ6 30
-#define OCTEON_IRQ_WORKQ7 31
-#define OCTEON_IRQ_WORKQ8 32
-#define OCTEON_IRQ_WORKQ9 33
-#define OCTEON_IRQ_WORKQ10 34
-#define OCTEON_IRQ_WORKQ11 35
-#define OCTEON_IRQ_WORKQ12 36
-#define OCTEON_IRQ_WORKQ13 37
-#define OCTEON_IRQ_WORKQ14 38
-#define OCTEON_IRQ_WORKQ15 39
-#define OCTEON_IRQ_GPIO0 40
-#define OCTEON_IRQ_GPIO1 41
-#define OCTEON_IRQ_GPIO2 42
-#define OCTEON_IRQ_GPIO3 43
-#define OCTEON_IRQ_GPIO4 44
-#define OCTEON_IRQ_GPIO5 45
-#define OCTEON_IRQ_GPIO6 46
-#define OCTEON_IRQ_GPIO7 47
-#define OCTEON_IRQ_GPIO8 48
-#define OCTEON_IRQ_GPIO9 49
-#define OCTEON_IRQ_GPIO10 50
-#define OCTEON_IRQ_GPIO11 51
-#define OCTEON_IRQ_GPIO12 52
-#define OCTEON_IRQ_GPIO13 53
-#define OCTEON_IRQ_GPIO14 54
-#define OCTEON_IRQ_GPIO15 55
-#define OCTEON_IRQ_MBOX0 56
-#define OCTEON_IRQ_MBOX1 57
-#define OCTEON_IRQ_UART0 58
-#define OCTEON_IRQ_UART1 59
-#define OCTEON_IRQ_PCI_INT0 60
-#define OCTEON_IRQ_PCI_INT1 61
-#define OCTEON_IRQ_PCI_INT2 62
-#define OCTEON_IRQ_PCI_INT3 63
-#define OCTEON_IRQ_PCI_MSI0 64
-#define OCTEON_IRQ_PCI_MSI1 65
-#define OCTEON_IRQ_PCI_MSI2 66
-#define OCTEON_IRQ_PCI_MSI3 67
-#define OCTEON_IRQ_RESERVED68 68 /* Summary of CIU_INT_SUM1 */
-#define OCTEON_IRQ_TWSI 69
-#define OCTEON_IRQ_RML 70
-#define OCTEON_IRQ_TRACE 71
-#define OCTEON_IRQ_GMX_DRP0 72
-#define OCTEON_IRQ_GMX_DRP1 73
-#define OCTEON_IRQ_IPD_DRP 74
-#define OCTEON_IRQ_KEY_ZERO 75
-#define OCTEON_IRQ_TIMER0 76
-#define OCTEON_IRQ_TIMER1 77
-#define OCTEON_IRQ_TIMER2 78
-#define OCTEON_IRQ_TIMER3 79
-#define OCTEON_IRQ_USB0 80
-#define OCTEON_IRQ_PCM 81
-#define OCTEON_IRQ_MPI 82
-#define OCTEON_IRQ_TWSI2 83
-#define OCTEON_IRQ_POWIQ 84
-#define OCTEON_IRQ_IPDPPTHR 85
-#define OCTEON_IRQ_MII0 86
-#define OCTEON_IRQ_BOOTDMA 87
-/* 88 - 151 represent the sources in CIU_INTX_EN1 */
-#define OCTEON_IRQ_WDOG0 88
-#define OCTEON_IRQ_WDOG1 89
-#define OCTEON_IRQ_WDOG2 90
-#define OCTEON_IRQ_WDOG3 91
-#define OCTEON_IRQ_WDOG4 92
-#define OCTEON_IRQ_WDOG5 93
-#define OCTEON_IRQ_WDOG6 94
-#define OCTEON_IRQ_WDOG7 95
-#define OCTEON_IRQ_WDOG8 96
-#define OCTEON_IRQ_WDOG9 97
-#define OCTEON_IRQ_WDOG10 98
-#define OCTEON_IRQ_WDOG11 99
-#define OCTEON_IRQ_WDOG12 100
-#define OCTEON_IRQ_WDOG13 101
-#define OCTEON_IRQ_WDOG14 102
-#define OCTEON_IRQ_WDOG15 103
-#define OCTEON_IRQ_UART2 104
-#define OCTEON_IRQ_USB1 105
-#define OCTEON_IRQ_MII1 106
-#define OCTEON_IRQ_RESERVED107 107
-#define OCTEON_IRQ_RESERVED108 108
-#define OCTEON_IRQ_RESERVED109 109
-#define OCTEON_IRQ_RESERVED110 110
-#define OCTEON_IRQ_RESERVED111 111
-#define OCTEON_IRQ_RESERVED112 112
-#define OCTEON_IRQ_RESERVED113 113
-#define OCTEON_IRQ_RESERVED114 114
-#define OCTEON_IRQ_RESERVED115 115
-#define OCTEON_IRQ_RESERVED116 116
-#define OCTEON_IRQ_RESERVED117 117
-#define OCTEON_IRQ_RESERVED118 118
-#define OCTEON_IRQ_RESERVED119 119
-#define OCTEON_IRQ_RESERVED120 120
-#define OCTEON_IRQ_RESERVED121 121
-#define OCTEON_IRQ_RESERVED122 122
-#define OCTEON_IRQ_RESERVED123 123
-#define OCTEON_IRQ_RESERVED124 124
-#define OCTEON_IRQ_RESERVED125 125
-#define OCTEON_IRQ_RESERVED126 126
-#define OCTEON_IRQ_RESERVED127 127
-#define OCTEON_IRQ_RESERVED128 128
-#define OCTEON_IRQ_RESERVED129 129
-#define OCTEON_IRQ_RESERVED130 130
-#define OCTEON_IRQ_RESERVED131 131
-#define OCTEON_IRQ_RESERVED132 132
-#define OCTEON_IRQ_RESERVED133 133
-#define OCTEON_IRQ_RESERVED134 134
-#define OCTEON_IRQ_RESERVED135 135
-#define OCTEON_IRQ_RESERVED136 136
-#define OCTEON_IRQ_RESERVED137 137
-#define OCTEON_IRQ_RESERVED138 138
-#define OCTEON_IRQ_RESERVED139 139
-#define OCTEON_IRQ_RESERVED140 140
-#define OCTEON_IRQ_RESERVED141 141
-#define OCTEON_IRQ_RESERVED142 142
-#define OCTEON_IRQ_RESERVED143 143
-#define OCTEON_IRQ_RESERVED144 144
-#define OCTEON_IRQ_RESERVED145 145
-#define OCTEON_IRQ_RESERVED146 146
-#define OCTEON_IRQ_RESERVED147 147
-#define OCTEON_IRQ_RESERVED148 148
-#define OCTEON_IRQ_RESERVED149 149
-#define OCTEON_IRQ_RESERVED150 150
-#define OCTEON_IRQ_RESERVED151 151
+enum octeon_irq {
+/* 1 - 8 represent the 8 MIPS standard interrupt sources */
+ OCTEON_IRQ_SW0 = 1,
+ OCTEON_IRQ_SW1,
+/* CIU0, CUI2, CIU4 are 3, 4, 5 */
+ OCTEON_IRQ_5 = 6,
+ OCTEON_IRQ_PERF,
+ OCTEON_IRQ_TIMER,
+/* sources in CIU_INTX_EN0 */
+ OCTEON_IRQ_WORKQ0,
+ OCTEON_IRQ_GPIO0 = OCTEON_IRQ_WORKQ0 + 16,
+ OCTEON_IRQ_WDOG0 = OCTEON_IRQ_GPIO0 + 16,
+ OCTEON_IRQ_WDOG15 = OCTEON_IRQ_WDOG0 + 15,
+ OCTEON_IRQ_MBOX0 = OCTEON_IRQ_WDOG0 + 16,
+ OCTEON_IRQ_MBOX1,
+ OCTEON_IRQ_UART0,
+ OCTEON_IRQ_UART1,
+ OCTEON_IRQ_UART2,
+ OCTEON_IRQ_PCI_INT0,
+ OCTEON_IRQ_PCI_INT1,
+ OCTEON_IRQ_PCI_INT2,
+ OCTEON_IRQ_PCI_INT3,
+ OCTEON_IRQ_PCI_MSI0,
+ OCTEON_IRQ_PCI_MSI1,
+ OCTEON_IRQ_PCI_MSI2,
+ OCTEON_IRQ_PCI_MSI3,
+
+ OCTEON_IRQ_TWSI,
+ OCTEON_IRQ_TWSI2,
+ OCTEON_IRQ_RML,
+ OCTEON_IRQ_TRACE0,
+ OCTEON_IRQ_GMX_DRP0 = OCTEON_IRQ_TRACE0 + 4,
+ OCTEON_IRQ_IPD_DRP = OCTEON_IRQ_GMX_DRP0 + 5,
+ OCTEON_IRQ_KEY_ZERO,
+ OCTEON_IRQ_TIMER0,
+ OCTEON_IRQ_TIMER1,
+ OCTEON_IRQ_TIMER2,
+ OCTEON_IRQ_TIMER3,
+ OCTEON_IRQ_USB0,
+ OCTEON_IRQ_USB1,
+ OCTEON_IRQ_PCM,
+ OCTEON_IRQ_MPI,
+ OCTEON_IRQ_POWIQ,
+ OCTEON_IRQ_IPDPPTHR,
+ OCTEON_IRQ_MII0,
+ OCTEON_IRQ_MII1,
+ OCTEON_IRQ_BOOTDMA,
+
+ OCTEON_IRQ_NAND,
+ OCTEON_IRQ_MIO, /* Summary of MIO_BOOT_ERR */
+ OCTEON_IRQ_IOB, /* Summary of IOB_INT_SUM */
+ OCTEON_IRQ_FPA, /* Summary of FPA_INT_SUM */
+ OCTEON_IRQ_POW, /* Summary of POW_ECC_ERR */
+ OCTEON_IRQ_L2C, /* Summary of L2C_INT_STAT */
+ OCTEON_IRQ_IPD, /* Summary of IPD_INT_SUM */
+ OCTEON_IRQ_PIP, /* Summary of PIP_INT_REG */
+ OCTEON_IRQ_PKO, /* Summary of PKO_REG_ERROR */
+ OCTEON_IRQ_ZIP, /* Summary of ZIP_ERROR */
+ OCTEON_IRQ_TIM, /* Summary of TIM_REG_ERROR */
+ OCTEON_IRQ_RAD, /* Summary of RAD_REG_ERROR */
+ OCTEON_IRQ_KEY, /* Summary of KEY_INT_SUM */
+ OCTEON_IRQ_DFA, /* Summary of DFA */
+ OCTEON_IRQ_USBCTL, /* Summary of USBN0_INT_SUM */
+ OCTEON_IRQ_SLI, /* Summary of SLI_INT_SUM */
+ OCTEON_IRQ_DPI, /* Summary of DPI_INT_SUM */
+ OCTEON_IRQ_AGX0, /* Summary of GMX0*+PCS0_INT*_REG */
+ OCTEON_IRQ_AGL = OCTEON_IRQ_AGX0 + 5,
+ OCTEON_IRQ_PTP,
+ OCTEON_IRQ_PEM0,
+ OCTEON_IRQ_PEM1,
+ OCTEON_IRQ_SRIO0,
+ OCTEON_IRQ_SRIO1,
+ OCTEON_IRQ_LMC0,
+ OCTEON_IRQ_DFM = OCTEON_IRQ_LMC0 + 4, /* Summary of DFM */
+ OCTEON_IRQ_RST,
+};
#ifdef CONFIG_PCI_MSI
-/* 152 - 215 represent the MSI interrupts 0-63 */
-#define OCTEON_IRQ_MSI_BIT0 152
-#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255)
+/* 152 - 407 represent the MSI interrupts 0-255 */
+#define OCTEON_IRQ_MSI_BIT0 (OCTEON_IRQ_RST + 1)
-#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1)
+#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255)
+#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1)
#else
-#define OCTEON_IRQ_LAST 152
+#define OCTEON_IRQ_LAST (OCTEON_IRQ_RST + 1)
#endif
#endif
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index 6b34afd0d4e..f72f768cd3a 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -257,4 +257,6 @@ extern struct cvmx_bootinfo *octeon_bootinfo;
extern uint64_t octeon_bootloader_entry_addr;
+extern void (*octeon_irq_setup_secondary)(void);
+
#endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index dae22c1d2c8..fa2e37ea2be 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -1005,7 +1005,7 @@
#define __NR_name_to_handle_at (__NR_Linux + 303)
#define __NR_open_by_handle_at (__NR_Linux + 304)
#define __NR_clock_adjtime (__NR_Linux + 305)
-#define __NR_clock_adjtime (__NR_Linux + 306)
+#define __NR_syncfs (__NR_Linux + 306)
/*
* Offset of the last N32 flavoured syscall
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index 40f7c6b1e26..260df475094 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -56,7 +56,7 @@ void __init init_r4030_ints(void)
int i;
for (i = JAZZ_IRQ_START; i <= JAZZ_IRQ_END; i++)
- set_irq_chip_and_handler(i, &r4030_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &r4030_irq_type, handle_level_irq);
r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, 0);
r4030_read_reg16(JAZZ_IO_IRQ_SOURCE); /* clear pending IRQs */
diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c
index bd2fc29b95e..73031f7fc82 100644
--- a/arch/mips/jz4740/gpio.c
+++ b/arch/mips/jz4740/gpio.c
@@ -306,7 +306,7 @@ static void jz_gpio_irq_demux_handler(unsigned int irq, struct irq_desc *desc)
uint32_t flag;
unsigned int gpio_irq;
unsigned int gpio_bank;
- struct jz_gpio_chip *chip = get_irq_desc_data(desc);
+ struct jz_gpio_chip *chip = irq_desc_get_handler_data(desc);
gpio_bank = JZ4740_IRQ_GPIO0 - irq;
@@ -416,7 +416,7 @@ static int jz_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
chip->wakeup &= ~IRQ_TO_BIT(data->irq);
spin_unlock(&chip->lock);
- set_irq_wake(chip->irq, on);
+ irq_set_irq_wake(chip->irq, on);
return 0;
}
@@ -510,14 +510,14 @@ static int jz4740_gpio_chip_init(struct jz_gpio_chip *chip, unsigned int id)
gpiochip_add(&chip->gpio_chip);
chip->irq = JZ4740_IRQ_INTC_GPIO(id);
- set_irq_data(chip->irq, chip);
- set_irq_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
+ irq_set_handler_data(chip->irq, chip);
+ irq_set_chained_handler(chip->irq, jz_gpio_irq_demux_handler);
for (irq = chip->irq_base; irq < chip->irq_base + chip->gpio_chip.ngpio; ++irq) {
irq_set_lockdep_class(irq, &gpio_lock_class);
- set_irq_chip_data(irq, chip);
- set_irq_chip_and_handler(irq, &jz_gpio_irq_chip,
- handle_level_irq);
+ irq_set_chip_data(irq, chip);
+ irq_set_chip_and_handler(irq, &jz_gpio_irq_chip,
+ handle_level_irq);
}
return 0;
diff --git a/arch/mips/jz4740/irq.c b/arch/mips/jz4740/irq.c
index dcc5593a938..d82c0c430e0 100644
--- a/arch/mips/jz4740/irq.c
+++ b/arch/mips/jz4740/irq.c
@@ -104,8 +104,8 @@ void __init arch_init_irq(void)
writel(0xffffffff, jz_intc_base + JZ_REG_INTC_SET_MASK);
for (i = JZ4740_IRQ_BASE; i < JZ4740_IRQ_BASE + 32; i++) {
- set_irq_chip_data(i, (void *)IRQ_BIT(i));
- set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
+ irq_set_chip_data(i, (void *)IRQ_BIT(i));
+ irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq);
}
setup_irq(2, &jz4740_cascade_action);
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
index e221662bb80..c018696765d 100644
--- a/arch/mips/kernel/i8259.c
+++ b/arch/mips/kernel/i8259.c
@@ -110,7 +110,7 @@ int i8259A_irq_pending(unsigned int irq)
void make_8259A_irq(unsigned int irq)
{
disable_irq_nosync(irq);
- set_irq_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
+ irq_set_chip_and_handler(irq, &i8259A_chip, handle_level_irq);
enable_irq(irq);
}
@@ -336,8 +336,8 @@ void __init init_i8259_irqs(void)
init_8259A(0);
for (i = I8259A_IRQ_BASE; i < I8259A_IRQ_BASE + 16; i++) {
- set_irq_chip_and_handler(i, &i8259A_chip, handle_level_irq);
- set_irq_probe(i);
+ irq_set_chip_and_handler(i, &i8259A_chip, handle_level_irq);
+ irq_set_probe(i);
}
setup_irq(I8259A_IRQ_BASE + PIC_CASCADE_IR, &irq2);
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index 43cd9628251..0c527f65219 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -229,7 +229,7 @@ static void __init gic_basic_init(int numintrs, int numvpes,
vpe_local_setup(numvpes);
for (i = _irqbase; i < (_irqbase + numintrs); i++)
- set_irq_chip(i, &gic_irq_controller);
+ irq_set_chip(i, &gic_irq_controller);
}
void __init gic_init(unsigned long gic_base_addr,
diff --git a/arch/mips/kernel/irq-gt641xx.c b/arch/mips/kernel/irq-gt641xx.c
index 7fd176fa367..883fc6cead3 100644
--- a/arch/mips/kernel/irq-gt641xx.c
+++ b/arch/mips/kernel/irq-gt641xx.c
@@ -126,6 +126,6 @@ void __init gt641xx_irq_init(void)
* bit31: logical or of bits[25:1].
*/
for (i = 1; i < 30; i++)
- set_irq_chip_and_handler(GT641XX_IRQ_BASE + i,
- &gt641xx_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(GT641XX_IRQ_BASE + i,
+ &gt641xx_irq_chip, handle_level_irq);
}
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c
index fc800cd9947..0c6afeed89d 100644
--- a/arch/mips/kernel/irq-msc01.c
+++ b/arch/mips/kernel/irq-msc01.c
@@ -137,16 +137,20 @@ void __init init_msc_irqs(unsigned long icubase, unsigned int irqbase, msc_irqma
switch (imp->im_type) {
case MSC01_IRQ_EDGE:
- set_irq_chip_and_handler_name(irqbase + n,
- &msc_edgeirq_type, handle_edge_irq, "edge");
+ irq_set_chip_and_handler_name(irqbase + n,
+ &msc_edgeirq_type,
+ handle_edge_irq,
+ "edge");
if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT);
else
MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl);
break;
case MSC01_IRQ_LEVEL:
- set_irq_chip_and_handler_name(irqbase+n,
- &msc_levelirq_type, handle_level_irq, "level");
+ irq_set_chip_and_handler_name(irqbase + n,
+ &msc_levelirq_type,
+ handle_level_irq,
+ "level");
if (cpu_has_veic)
MSCIC_WRITE(MSC01_IC_SUP+n*8, 0);
else
diff --git a/arch/mips/kernel/irq-rm7000.c b/arch/mips/kernel/irq-rm7000.c
index fd24fd98b04..a8a8977d588 100644
--- a/arch/mips/kernel/irq-rm7000.c
+++ b/arch/mips/kernel/irq-rm7000.c
@@ -45,6 +45,6 @@ void __init rm7k_cpu_irq_init(void)
clear_c0_intcontrol(0x00000f00); /* Mask all */
for (i = base; i < base + 4; i++)
- set_irq_chip_and_handler(i, &rm7k_irq_controller,
+ irq_set_chip_and_handler(i, &rm7k_irq_controller,
handle_percpu_irq);
}
diff --git a/arch/mips/kernel/irq-rm9000.c b/arch/mips/kernel/irq-rm9000.c
index ca463ec9bad..38874a4b925 100644
--- a/arch/mips/kernel/irq-rm9000.c
+++ b/arch/mips/kernel/irq-rm9000.c
@@ -98,10 +98,10 @@ void __init rm9k_cpu_irq_init(void)
clear_c0_intcontrol(0x0000f000); /* Mask all */
for (i = base; i < base + 4; i++)
- set_irq_chip_and_handler(i, &rm9k_irq_controller,
+ irq_set_chip_and_handler(i, &rm9k_irq_controller,
handle_level_irq);
rm9000_perfcount_irq = base + 1;
- set_irq_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq,
+ irq_set_chip_and_handler(rm9000_perfcount_irq, &rm9k_perfcounter_irq,
handle_percpu_irq);
}
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 1b68ebe1b45..9b734d74ae8 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -102,7 +102,7 @@ void __init init_IRQ(void)
#endif
for (i = 0; i < NR_IRQS; i++)
- set_irq_noprobe(i);
+ irq_set_noprobe(i);
arch_init_irq();
diff --git a/arch/mips/kernel/irq_cpu.c b/arch/mips/kernel/irq_cpu.c
index fd945c56bc3..6e71b284f6c 100644
--- a/arch/mips/kernel/irq_cpu.c
+++ b/arch/mips/kernel/irq_cpu.c
@@ -109,10 +109,10 @@ void __init mips_cpu_irq_init(void)
*/
if (cpu_has_mipsmt)
for (i = irq_base; i < irq_base + 2; i++)
- set_irq_chip_and_handler(i, &mips_mt_cpu_irq_controller,
+ irq_set_chip_and_handler(i, &mips_mt_cpu_irq_controller,
handle_percpu_irq);
for (i = irq_base + 2; i < irq_base + 8; i++)
- set_irq_chip_and_handler(i, &mips_cpu_irq_controller,
+ irq_set_chip_and_handler(i, &mips_cpu_irq_controller,
handle_percpu_irq);
}
diff --git a/arch/mips/kernel/irq_txx9.c b/arch/mips/kernel/irq_txx9.c
index 526e1581549..b0c55b50218 100644
--- a/arch/mips/kernel/irq_txx9.c
+++ b/arch/mips/kernel/irq_txx9.c
@@ -154,8 +154,8 @@ void __init txx9_irq_init(unsigned long baseaddr)
for (i = 0; i < TXx9_MAX_IR; i++) {
txx9irq[i].level = 4; /* middle level */
txx9irq[i].mode = TXx9_IRCR_LOW;
- set_irq_chip_and_handler(TXX9_IRQ_BASE + i,
- &txx9_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &txx9_irq_chip,
+ handle_level_irq);
}
/* mask all IRC interrupts */
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index f7e2c7807d7..5a88cc4ccd5 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -1146,7 +1146,7 @@ static void setup_cross_vpe_interrupts(unsigned int nvpe)
setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ));
- set_irq_handler(cpu_ipi_irq, handle_percpu_irq);
+ irq_set_handler(cpu_ipi_irq, handle_percpu_irq);
}
/*
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c
index 670e3e70d19..de4c165515d 100644
--- a/arch/mips/lasat/interrupt.c
+++ b/arch/mips/lasat/interrupt.c
@@ -128,7 +128,7 @@ void __init arch_init_irq(void)
mips_cpu_irq_init();
for (i = LASAT_IRQ_BASE; i <= LASAT_IRQ_END; i++)
- set_irq_chip_and_handler(i, &lasat_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &lasat_irq_type, handle_level_irq);
setup_irq(LASAT_CASCADE_IRQ, &cascade);
}
diff --git a/arch/mips/loongson/common/bonito-irq.c b/arch/mips/loongson/common/bonito-irq.c
index 1549361696a..f27d7ccca92 100644
--- a/arch/mips/loongson/common/bonito-irq.c
+++ b/arch/mips/loongson/common/bonito-irq.c
@@ -44,7 +44,8 @@ void bonito_irq_init(void)
u32 i;
for (i = LOONGSON_IRQ_BASE; i < LOONGSON_IRQ_BASE + 32; i++)
- set_irq_chip_and_handler(i, &bonito_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &bonito_irq_type,
+ handle_level_irq);
#ifdef CONFIG_CPU_LOONGSON2E
setup_irq(LOONGSON_IRQ_BASE + 10, &dma_timeout_irqaction);
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index b79b24afe3a..9027061f0ea 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -472,7 +472,7 @@ static void __init fill_ipi_map(void)
void __init arch_init_ipiirq(int irq, struct irqaction *action)
{
setup_irq(irq, action);
- set_irq_handler(irq, handle_percpu_irq);
+ irq_set_handler(irq, handle_percpu_irq);
}
void __init arch_init_irq(void)
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c
index 3c6f190aa61..1620b83cd13 100644
--- a/arch/mips/mti-malta/malta-time.c
+++ b/arch/mips/mti-malta/malta-time.c
@@ -119,7 +119,7 @@ static void __init plat_perf_setup(void)
set_vi_handler(cp0_perfcount_irq, mips_perf_dispatch);
mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;
#ifdef CONFIG_SMP
- set_irq_handler(mips_cpu_perf_irq, handle_percpu_irq);
+ irq_set_handler(mips_cpu_perf_irq, handle_percpu_irq);
#endif
}
}
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index d8080499872..5d530f89d87 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -172,7 +172,7 @@ msi_irq_allocated:
pci_write_config_word(dev, desc->msi_attrib.pos + PCI_MSI_FLAGS,
control);
- set_irq_msi(irq, desc);
+ irq_set_msi_desc(irq, desc);
write_msi_msg(irq, &msg);
return 0;
}
@@ -259,11 +259,11 @@ static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
static u64 msi_rcv_reg[4];
static u64 mis_ena_reg[4];
-static void octeon_irq_msi_enable_pcie(unsigned int irq)
+static void octeon_irq_msi_enable_pcie(struct irq_data *data)
{
u64 en;
unsigned long flags;
- int msi_number = irq - OCTEON_IRQ_MSI_BIT0;
+ int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0;
int irq_index = msi_number >> 6;
int irq_bit = msi_number & 0x3f;
@@ -275,11 +275,11 @@ static void octeon_irq_msi_enable_pcie(unsigned int irq)
raw_spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
}
-static void octeon_irq_msi_disable_pcie(unsigned int irq)
+static void octeon_irq_msi_disable_pcie(struct irq_data *data)
{
u64 en;
unsigned long flags;
- int msi_number = irq - OCTEON_IRQ_MSI_BIT0;
+ int msi_number = data->irq - OCTEON_IRQ_MSI_BIT0;
int irq_index = msi_number >> 6;
int irq_bit = msi_number & 0x3f;
@@ -293,11 +293,11 @@ static void octeon_irq_msi_disable_pcie(unsigned int irq)
static struct irq_chip octeon_irq_chip_msi_pcie = {
.name = "MSI",
- .enable = octeon_irq_msi_enable_pcie,
- .disable = octeon_irq_msi_disable_pcie,
+ .irq_enable = octeon_irq_msi_enable_pcie,
+ .irq_disable = octeon_irq_msi_disable_pcie,
};
-static void octeon_irq_msi_enable_pci(unsigned int irq)
+static void octeon_irq_msi_enable_pci(struct irq_data *data)
{
/*
* Octeon PCI doesn't have the ability to mask/unmask MSI
@@ -308,15 +308,15 @@ static void octeon_irq_msi_enable_pci(unsigned int irq)
*/
}
-static void octeon_irq_msi_disable_pci(unsigned int irq)
+static void octeon_irq_msi_disable_pci(struct irq_data *data)
{
/* See comment in enable */
}
static struct irq_chip octeon_irq_chip_msi_pci = {
.name = "MSI",
- .enable = octeon_irq_msi_enable_pci,
- .disable = octeon_irq_msi_disable_pci,
+ .irq_enable = octeon_irq_msi_enable_pci,
+ .irq_disable = octeon_irq_msi_disable_pci,
};
/*
@@ -388,7 +388,7 @@ int __init octeon_msi_initialize(void)
}
for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_LAST; irq++)
- set_irq_chip_and_handler(irq, msi, handle_simple_irq);
+ irq_set_chip_and_handler(irq, msi, handle_simple_irq);
if (octeon_has_feature(OCTEON_FEATURE_PCIE)) {
if (request_irq(OCTEON_IRQ_PCI_MSI0, octeon_msi_interrupt0,
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
index 352f29d9226..c4fa2d775d8 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_cic.c
@@ -182,7 +182,7 @@ void __init msp_cic_irq_init(void)
/* initialize all the IRQ descriptors */
for (i = MSP_CIC_INTBASE ; i < MSP_CIC_INTBASE + 32 ; i++) {
- set_irq_chip_and_handler(i, &msp_cic_irq_controller,
+ irq_set_chip_and_handler(i, &msp_cic_irq_controller,
handle_level_irq);
#ifdef CONFIG_MIPS_MT_SMTC
/* Mask of CIC interrupt */
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
index 8f51e4adc43..5bbcc47da6b 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_irq_slp.c
@@ -77,7 +77,7 @@ void __init msp_slp_irq_init(void)
/* initialize all the IRQ descriptors */
for (i = MSP_SLP_INTBASE; i < MSP_PER_INTBASE + 32; i++)
- set_irq_chip_and_handler(i, &msp_slp_irq_controller,
+ irq_set_chip_and_handler(i, &msp_slp_irq_controller,
handle_level_irq);
}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smp.c b/arch/mips/pmc-sierra/msp71xx/msp_smp.c
index 43a9e26e1c6..bec17901ff0 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_smp.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_smp.c
@@ -64,7 +64,7 @@ static struct irqaction irq_call = {
void __init arch_init_ipiirq(int irq, struct irqaction *action)
{
setup_irq(irq, action);
- set_irq_handler(irq, handle_percpu_irq);
+ irq_set_handler(irq, handle_percpu_irq);
}
void __init msp_vsmp_int_init(void)
diff --git a/arch/mips/pnx833x/common/interrupts.c b/arch/mips/pnx833x/common/interrupts.c
index b226bcb0a2f..adc171c8846 100644
--- a/arch/mips/pnx833x/common/interrupts.c
+++ b/arch/mips/pnx833x/common/interrupts.c
@@ -259,11 +259,13 @@ void __init arch_init_irq(void)
/* Set IRQ information in irq_desc */
for (irq = PNX833X_PIC_IRQ_BASE; irq < (PNX833X_PIC_IRQ_BASE + PNX833X_PIC_NUM_IRQ); irq++) {
pnx833x_hard_disable_pic_irq(irq);
- set_irq_chip_and_handler(irq, &pnx833x_pic_irq_type, handle_simple_irq);
+ irq_set_chip_and_handler(irq, &pnx833x_pic_irq_type,
+ handle_simple_irq);
}
for (irq = PNX833X_GPIO_IRQ_BASE; irq < (PNX833X_GPIO_IRQ_BASE + PNX833X_GPIO_NUM_IRQ); irq++)
- set_irq_chip_and_handler(irq, &pnx833x_gpio_irq_type, handle_simple_irq);
+ irq_set_chip_and_handler(irq, &pnx833x_gpio_irq_type,
+ handle_simple_irq);
/* Set PIC priority limiter register to 0 */
PNX833X_PIC_INT_PRIORITY = 0;
diff --git a/arch/mips/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c
index dbdc35c3531..6b93c81779c 100644
--- a/arch/mips/pnx8550/common/int.c
+++ b/arch/mips/pnx8550/common/int.c
@@ -183,7 +183,7 @@ void __init arch_init_irq(void)
int configPR;
for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++)
- set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq);
/* init of GIC/IPC interrupts */
/* should be done before cp0 since cp0 init enables the GIC int */
@@ -206,7 +206,7 @@ void __init arch_init_irq(void)
/* mask/priority is still 0 so we will not get any
* interrupts until it is unmasked */
- set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq);
}
/* Priority level 0 */
@@ -215,20 +215,20 @@ void __init arch_init_irq(void)
/* Set int vector table address */
PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0;
- set_irq_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type,
+ irq_set_chip_and_handler(MIPS_CPU_GIC_IRQ, &level_irq_type,
handle_level_irq);
setup_irq(MIPS_CPU_GIC_IRQ, &gic_action);
/* init of Timer interrupts */
for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++)
- set_irq_chip_and_handler(i, &level_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &level_irq_type, handle_level_irq);
/* Stop Timer 1-3 */
configPR = read_c0_config7();
configPR |= 0x00000038;
write_c0_config7(configPR);
- set_irq_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type,
+ irq_set_chip_and_handler(MIPS_CPU_TIMER_IRQ, &level_irq_type,
handle_level_irq);
setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action);
}
diff --git a/arch/mips/powertv/asic/irq_asic.c b/arch/mips/powertv/asic/irq_asic.c
index 6f1c8ef6a71..7fb97fb0931 100644
--- a/arch/mips/powertv/asic/irq_asic.c
+++ b/arch/mips/powertv/asic/irq_asic.c
@@ -112,5 +112,5 @@ void __init asic_irq_init(void)
* Initialize interrupt handlers.
*/
for (i = 0; i < NR_IRQS; i++)
- set_irq_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(i, &asic_irq_chip, handle_level_irq);
}
diff --git a/arch/mips/rb532/irq.c b/arch/mips/rb532/irq.c
index b32a768da89..7c6db74e3fa 100644
--- a/arch/mips/rb532/irq.c
+++ b/arch/mips/rb532/irq.c
@@ -207,8 +207,8 @@ void __init arch_init_irq(void)
pr_info("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS);
for (i = 0; i < RC32434_NR_IRQS; i++)
- set_irq_chip_and_handler(i, &rc32434_irq_type,
- handle_level_irq);
+ irq_set_chip_and_handler(i, &rc32434_irq_type,
+ handle_level_irq);
}
/* Main Interrupt dispatcher */
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index e6e64750e90..476423a0129 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -312,7 +312,7 @@ void __init arch_init_irq(void)
else
handler = &ip22_local3_irq_type;
- set_irq_chip_and_handler(i, handler, handle_level_irq);
+ irq_set_chip_and_handler(i, handler, handle_level_irq);
}
/* vector handler. this register the IRQ as non-sharable */
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index f2d09d7700d..11488719dd9 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -337,7 +337,7 @@ static struct irq_chip bridge_irq_type = {
void __devinit register_bridge_irq(unsigned int irq)
{
- set_irq_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(irq, &bridge_irq_type, handle_level_irq);
}
int __devinit request_bridge_irq(struct bridge_controller *bc)
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index c01f558a2a0..a152538d3c9 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -153,7 +153,7 @@ static void __init hub_rt_clock_event_global_init(void)
panic("Allocation of irq number for timer failed");
} while (xchg(&rt_timer_irq, irq));
- set_irq_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
+ irq_set_chip_and_handler(irq, &rt_irq_type, handle_percpu_irq);
setup_irq(irq, &hub_rt_irqaction);
}
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index e0a3ce4a8d4..c65ea76d56c 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -451,43 +451,51 @@ void __init arch_init_irq(void)
for (irq = CRIME_IRQ_BASE; irq <= IP32_IRQ_MAX; irq++) {
switch (irq) {
case MACE_VID_IN1_IRQ ... MACE_PCI_BRIDGE_IRQ:
- set_irq_chip_and_handler_name(irq,&ip32_mace_interrupt,
- handle_level_irq, "level");
+ irq_set_chip_and_handler_name(irq,
+ &ip32_mace_interrupt,
+ handle_level_irq,
+ "level");
break;
case MACEPCI_SCSI0_IRQ ... MACEPCI_SHARED2_IRQ:
- set_irq_chip_and_handler_name(irq,
- &ip32_macepci_interrupt, handle_level_irq,
- "level");
+ irq_set_chip_and_handler_name(irq,
+ &ip32_macepci_interrupt,
+ handle_level_irq,
+ "level");
break;
case CRIME_CPUERR_IRQ:
case CRIME_MEMERR_IRQ:
- set_irq_chip_and_handler_name(irq,
- &crime_level_interrupt, handle_level_irq,
- "level");
+ irq_set_chip_and_handler_name(irq,
+ &crime_level_interrupt,
+ handle_level_irq,
+ "level");
break;
case CRIME_GBE0_IRQ ... CRIME_GBE3_IRQ:
case CRIME_RE_EMPTY_E_IRQ ... CRIME_RE_IDLE_E_IRQ:
case CRIME_SOFT0_IRQ ... CRIME_SOFT2_IRQ:
case CRIME_VICE_IRQ:
- set_irq_chip_and_handler_name(irq,
- &crime_edge_interrupt, handle_edge_irq, "edge");
+ irq_set_chip_and_handler_name(irq,
+ &crime_edge_interrupt,
+ handle_edge_irq,
+ "edge");
break;
case MACEISA_PARALLEL_IRQ:
case MACEISA_SERIAL1_TDMAPR_IRQ:
case MACEISA_SERIAL2_TDMAPR_IRQ:
- set_irq_chip_and_handler_name(irq,
- &ip32_maceisa_edge_interrupt, handle_edge_irq,
- "edge");
+ irq_set_chip_and_handler_name(irq,
+ &ip32_maceisa_edge_interrupt,
+ handle_edge_irq,
+ "edge");
break;
default:
- set_irq_chip_and_handler_name(irq,
- &ip32_maceisa_level_interrupt, handle_level_irq,
- "level");
+ irq_set_chip_and_handler_name(irq,
+ &ip32_maceisa_level_interrupt,
+ handle_level_irq,
+ "level");
break;
}
}
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c
index 89e8188a466..09740d60e18 100644
--- a/arch/mips/sibyte/bcm1480/irq.c
+++ b/arch/mips/sibyte/bcm1480/irq.c
@@ -216,7 +216,8 @@ void __init init_bcm1480_irqs(void)
int i;
for (i = 0; i < BCM1480_NR_IRQS; i++) {
- set_irq_chip_and_handler(i, &bcm1480_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &bcm1480_irq_type,
+ handle_level_irq);
bcm1480_irq_owner[i] = 0;
}
}
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c
index fd269ea8d8a..be4460a5f6a 100644
--- a/arch/mips/sibyte/sb1250/irq.c
+++ b/arch/mips/sibyte/sb1250/irq.c
@@ -190,7 +190,8 @@ void __init init_sb1250_irqs(void)
int i;
for (i = 0; i < SB1250_NR_IRQS; i++) {
- set_irq_chip_and_handler(i, &sb1250_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &sb1250_irq_type,
+ handle_level_irq);
sb1250_irq_owner[i] = 0;
}
}
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c
index 72b94155778..c48194c3073 100644
--- a/arch/mips/sni/a20r.c
+++ b/arch/mips/sni/a20r.c
@@ -209,7 +209,7 @@ void __init sni_a20r_irq_init(void)
int i;
for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++)
- set_irq_chip_and_handler(i, &a20r_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &a20r_irq_type, handle_level_irq);
sni_hwint = a20r_hwint;
change_c0_status(ST0_IM, IE_IRQ0);
setup_irq(SNI_A20R_IRQ_BASE + 3, &sni_isa_irq);
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c
index cfcc68abc5b..ed3b3d31735 100644
--- a/arch/mips/sni/pcimt.c
+++ b/arch/mips/sni/pcimt.c
@@ -296,7 +296,7 @@ void __init sni_pcimt_irq_init(void)
mips_cpu_irq_init();
/* Actually we've got more interrupts to handle ... */
for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++)
- set_irq_chip_and_handler(i, &pcimt_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &pcimt_irq_type, handle_level_irq);
sni_hwint = sni_pcimt_hwint;
change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3);
}
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c
index 0846e99a6ef..b5246373d16 100644
--- a/arch/mips/sni/pcit.c
+++ b/arch/mips/sni/pcit.c
@@ -238,7 +238,7 @@ void __init sni_pcit_irq_init(void)
mips_cpu_irq_init();
for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
- set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
*(volatile u32 *)SNI_PCIT_INT_REG = 0;
sni_hwint = sni_pcit_hwint;
change_c0_status(ST0_IM, IE_IRQ1);
@@ -251,7 +251,7 @@ void __init sni_pcit_cplus_irq_init(void)
mips_cpu_irq_init();
for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++)
- set_irq_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &pcit_irq_type, handle_level_irq);
*(volatile u32 *)SNI_PCIT_INT_REG = 0x40000000;
sni_hwint = sni_pcit_hwint_cplus;
change_c0_status(ST0_IM, IE_IRQ0);
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c
index f05d8e59330..a7e5a6d917b 100644
--- a/arch/mips/sni/rm200.c
+++ b/arch/mips/sni/rm200.c
@@ -413,7 +413,7 @@ void __init sni_rm200_i8259_irqs(void)
sni_rm200_init_8259A();
for (i = RM200_I8259A_IRQ_BASE; i < RM200_I8259A_IRQ_BASE + 16; i++)
- set_irq_chip_and_handler(i, &sni_rm200_i8259A_chip,
+ irq_set_chip_and_handler(i, &sni_rm200_i8259A_chip,
handle_level_irq);
setup_irq(RM200_I8259A_IRQ_BASE + PIC_CASCADE_IR, &sni_rm200_irq2);
@@ -477,7 +477,7 @@ void __init sni_rm200_irq_init(void)
mips_cpu_irq_init();
/* Actually we've got more interrupts to handle ... */
for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++)
- set_irq_chip_and_handler(i, &rm200_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &rm200_irq_type, handle_level_irq);
sni_hwint = sni_rm200_hwint;
change_c0_status(ST0_IM, IE_IRQ0);
setup_irq(SNI_RM200_INT_START + 0, &sni_rm200_i8259A_irq);
diff --git a/arch/mips/txx9/generic/irq_tx4927.c b/arch/mips/txx9/generic/irq_tx4927.c
index e1828e8bcae..7e3ac5782da 100644
--- a/arch/mips/txx9/generic/irq_tx4927.c
+++ b/arch/mips/txx9/generic/irq_tx4927.c
@@ -35,7 +35,7 @@ void __init tx4927_irq_init(void)
mips_cpu_irq_init();
txx9_irq_init(TX4927_IRC_REG & 0xfffffffffULL);
- set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT,
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4927_IRC_INT,
handle_simple_irq);
/* raise priority for errors, timers, SIO */
txx9_irq_set_pri(TX4927_IR_ECCERR, 7);
diff --git a/arch/mips/txx9/generic/irq_tx4938.c b/arch/mips/txx9/generic/irq_tx4938.c
index a6e6e805097..aace8565332 100644
--- a/arch/mips/txx9/generic/irq_tx4938.c
+++ b/arch/mips/txx9/generic/irq_tx4938.c
@@ -23,7 +23,7 @@ void __init tx4938_irq_init(void)
mips_cpu_irq_init();
txx9_irq_init(TX4938_IRC_REG & 0xfffffffffULL);
- set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT,
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4938_IRC_INT,
handle_simple_irq);
/* raise priority for errors, timers, SIO */
txx9_irq_set_pri(TX4938_IR_ECCERR, 7);
diff --git a/arch/mips/txx9/generic/irq_tx4939.c b/arch/mips/txx9/generic/irq_tx4939.c
index 93b6edbedd6..6b067dbd2ae 100644
--- a/arch/mips/txx9/generic/irq_tx4939.c
+++ b/arch/mips/txx9/generic/irq_tx4939.c
@@ -176,8 +176,8 @@ void __init tx4939_irq_init(void)
for (i = 1; i < TX4939_NUM_IR; i++) {
tx4939irq[i].level = 4; /* middle level */
tx4939irq[i].mode = TXx9_IRCR_LOW;
- set_irq_chip_and_handler(TXX9_IRQ_BASE + i,
- &tx4939_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(TXX9_IRQ_BASE + i, &tx4939_irq_chip,
+ handle_level_irq);
}
/* mask all IRC interrupts */
@@ -193,7 +193,7 @@ void __init tx4939_irq_init(void)
__raw_writel(TXx9_IRCER_ICE, &tx4939_ircptr->den.r);
__raw_writel(irc_elevel, &tx4939_ircptr->msk.r);
- set_irq_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT,
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + TX4939_IRC_INT,
handle_simple_irq);
/* raise priority for errors, timers, sio */
diff --git a/arch/mips/txx9/jmr3927/irq.c b/arch/mips/txx9/jmr3927/irq.c
index 92a5c1b400f..c22c859a2c4 100644
--- a/arch/mips/txx9/jmr3927/irq.c
+++ b/arch/mips/txx9/jmr3927/irq.c
@@ -120,8 +120,9 @@ void __init jmr3927_irq_setup(void)
tx3927_irq_init();
for (i = JMR3927_IRQ_IOC; i < JMR3927_IRQ_IOC + JMR3927_NR_IRQ_IOC; i++)
- set_irq_chip_and_handler(i, &jmr3927_irq_ioc, handle_level_irq);
+ irq_set_chip_and_handler(i, &jmr3927_irq_ioc,
+ handle_level_irq);
/* setup IOC interrupt 1 (PCI, MODEM) */
- set_irq_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq);
+ irq_set_chained_handler(JMR3927_IRQ_IOCINT, handle_simple_irq);
}
diff --git a/arch/mips/txx9/rbtx4927/irq.c b/arch/mips/txx9/rbtx4927/irq.c
index 7c0a048b307..6c22c496090 100644
--- a/arch/mips/txx9/rbtx4927/irq.c
+++ b/arch/mips/txx9/rbtx4927/irq.c
@@ -164,9 +164,9 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void)
for (i = RBTX4927_IRQ_IOC;
i < RBTX4927_IRQ_IOC + RBTX4927_NR_IRQ_IOC; i++)
- set_irq_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type,
+ irq_set_chip_and_handler(i, &toshiba_rbtx4927_irq_ioc_type,
handle_level_irq);
- set_irq_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
+ irq_set_chained_handler(RBTX4927_IRQ_IOCINT, handle_simple_irq);
}
static int rbtx4927_irq_dispatch(int pending)
@@ -194,5 +194,5 @@ void __init rbtx4927_irq_setup(void)
tx4927_irq_init();
toshiba_rbtx4927_irq_ioc_init();
/* Onboard 10M Ether: High Active */
- set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(RBTX4927_RTL_8019_IRQ, IRQF_TRIGGER_HIGH);
}
diff --git a/arch/mips/txx9/rbtx4938/irq.c b/arch/mips/txx9/rbtx4938/irq.c
index 2ec4fe1b167..58cd7a9272c 100644
--- a/arch/mips/txx9/rbtx4938/irq.c
+++ b/arch/mips/txx9/rbtx4938/irq.c
@@ -132,10 +132,10 @@ static void __init toshiba_rbtx4938_irq_ioc_init(void)
for (i = RBTX4938_IRQ_IOC;
i < RBTX4938_IRQ_IOC + RBTX4938_NR_IRQ_IOC; i++)
- set_irq_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
+ irq_set_chip_and_handler(i, &toshiba_rbtx4938_irq_ioc_type,
handle_level_irq);
- set_irq_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq);
+ irq_set_chained_handler(RBTX4938_IRQ_IOCINT, handle_simple_irq);
}
void __init rbtx4938_irq_setup(void)
@@ -153,5 +153,5 @@ void __init rbtx4938_irq_setup(void)
tx4938_irq_init();
toshiba_rbtx4938_irq_ioc_init();
/* Onboard 10M Ether: High Active */
- set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
+ irq_set_irq_type(RBTX4938_IRQ_ETHER, IRQF_TRIGGER_HIGH);
}
diff --git a/arch/mips/txx9/rbtx4939/irq.c b/arch/mips/txx9/rbtx4939/irq.c
index 70074632fb9..69a80616f0c 100644
--- a/arch/mips/txx9/rbtx4939/irq.c
+++ b/arch/mips/txx9/rbtx4939/irq.c
@@ -88,8 +88,8 @@ void __init rbtx4939_irq_setup(void)
tx4939_irq_init();
for (i = RBTX4939_IRQ_IOC;
i < RBTX4939_IRQ_IOC + RBTX4939_NR_IRQ_IOC; i++)
- set_irq_chip_and_handler(i, &rbtx4939_ioc_irq_chip,
+ irq_set_chip_and_handler(i, &rbtx4939_ioc_irq_chip,
handle_level_irq);
- set_irq_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq);
+ irq_set_chained_handler(RBTX4939_IRQ_IOCINT, handle_simple_irq);
}
diff --git a/arch/mips/vr41xx/common/icu.c b/arch/mips/vr41xx/common/icu.c
index f53156bb9aa..a39ef3207d7 100644
--- a/arch/mips/vr41xx/common/icu.c
+++ b/arch/mips/vr41xx/common/icu.c
@@ -710,11 +710,11 @@ static int __init vr41xx_icu_init(void)
icu2_write(MGIUINTHREG, 0xffff);
for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++)
- set_irq_chip_and_handler(i, &sysint1_irq_type,
+ irq_set_chip_and_handler(i, &sysint1_irq_type,
handle_level_irq);
for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++)
- set_irq_chip_and_handler(i, &sysint2_irq_type,
+ irq_set_chip_and_handler(i, &sysint2_irq_type,
handle_level_irq);
cascade_irq(INT0_IRQ, icu_get_irq);
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c
index 9ff7f397c0e..70a3b85f375 100644
--- a/arch/mips/vr41xx/common/irq.c
+++ b/arch/mips/vr41xx/common/irq.c
@@ -87,7 +87,7 @@ static void irq_dispatch(unsigned int irq)
atomic_inc(&irq_err_count);
else
irq_dispatch(irq);
- if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
+ if (!irqd_irq_disabled(idata) && chip->irq_unmask)
chip->irq_unmask(idata);
} else
do_IRQ(irq);
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index d8ab97a73db..feaf09cc863 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -2,7 +2,7 @@ config MN10300
def_bool y
select HAVE_OPROFILE
select HAVE_GENERIC_HARDIRQS
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ select GENERIC_IRQ_SHOW
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_KGDB
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c
index 5f7fc3eb45e..86af0d7d077 100644
--- a/arch/mn10300/kernel/irq.c
+++ b/arch/mn10300/kernel/irq.c
@@ -263,7 +263,7 @@ void set_intr_level(int irq, u16 level)
*/
void mn10300_set_lateack_irq_type(int irq)
{
- set_irq_chip_and_handler(irq, &mn10300_cpu_pic_level,
+ irq_set_chip_and_handler(irq, &mn10300_cpu_pic_level,
handle_level_irq);
}
@@ -275,12 +275,12 @@ void __init init_IRQ(void)
int irq;
for (irq = 0; irq < NR_IRQS; irq++)
- if (get_irq_chip(irq) == &no_irq_chip)
+ if (irq_get_chip(irq) == &no_irq_chip)
/* due to the PIC latching interrupt requests, even
* when the IRQ is disabled, IRQ_PENDING is superfluous
* and we can use handle_level_irq() for edge-triggered
* interrupts */
- set_irq_chip_and_handler(irq, &mn10300_cpu_pic_edge,
+ irq_set_chip_and_handler(irq, &mn10300_cpu_pic_edge,
handle_level_irq);
unit_init_IRQ();
@@ -335,91 +335,42 @@ asmlinkage void do_IRQ(void)
/*
* Display interrupt management information through /proc/interrupts
*/
-int show_interrupts(struct seq_file *p, void *v)
+int arch_show_interrupts(struct seq_file *p, int prec)
{
- int i = *(loff_t *) v, j, cpu;
- struct irqaction *action;
- unsigned long flags;
-
- switch (i) {
- /* display column title bar naming CPUs */
- case 0:
- seq_printf(p, " ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%d ", j);
- seq_putc(p, '\n');
- break;
-
- /* display information rows, one per active CPU */
- case 1 ... NR_IRQS - 1:
- raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
-
- action = irq_desc[i].action;
- if (action) {
- seq_printf(p, "%3d: ", i);
- for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
-
- if (i < NR_CPU_IRQS)
- seq_printf(p, " %14s.%u",
- irq_desc[i].irq_data.chip->name,
- (GxICR(i) & GxICR_LEVEL) >>
- GxICR_LEVEL_SHIFT);
- else
- seq_printf(p, " %14s",
- irq_desc[i].irq_data.chip->name);
-
- seq_printf(p, " %s", action->name);
-
- for (action = action->next;
- action;
- action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
- }
-
- raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- break;
-
- /* polish off with NMI and error counters */
- case NR_IRQS:
#ifdef CONFIG_MN10300_WD_TIMER
- seq_printf(p, "NMI: ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "%10u ", nmi_count(j));
- seq_putc(p, '\n');
-#endif
+ int j;
- seq_printf(p, "ERR: %10u\n", atomic_read(&irq_err_count));
- break;
- }
+ seq_printf(p, "%*s: ", prec, "NMI");
+ for (j = 0; j < NR_CPUS; j++)
+ if (cpu_online(j))
+ seq_printf(p, "%10u ", nmi_count(j));
+ seq_putc(p, '\n');
+#endif
+ seq_printf(p, "%*s: ", prec, "ERR");
+ seq_printf(p, "%10u\n", atomic_read(&irq_err_count));
return 0;
}
#ifdef CONFIG_HOTPLUG_CPU
void migrate_irqs(void)
{
- irq_desc_t *desc;
int irq;
unsigned int self, new;
unsigned long flags;
self = smp_processor_id();
for (irq = 0; irq < NR_IRQS; irq++) {
- desc = irq_desc + irq;
+ struct irq_data *data = irq_get_irq_data(irq);
- if (desc->status == IRQ_PER_CPU)
+ if (irqd_is_per_cpu(data))
continue;
- if (cpu_isset(self, irq_desc[irq].affinity) &&
+ if (cpu_isset(self, data->affinity) &&
!cpus_intersects(irq_affinity[irq], cpu_online_map)) {
int cpu_id;
cpu_id = first_cpu(cpu_online_map);
- cpu_set(cpu_id, irq_desc[irq].affinity);
+ cpu_set(cpu_id, data->affinity);
}
/* We need to operate irq_affinity_online atomically. */
arch_local_cli_save(flags);
@@ -430,7 +381,7 @@ void migrate_irqs(void)
GxICR(irq) = x & GxICR_LEVEL;
tmp = GxICR(irq);
- new = any_online_cpu(irq_desc[irq].affinity);
+ new = any_online_cpu(data->affinity);
irq_affinity_online[irq] = new;
CROSS_GxICR(irq, new) =
diff --git a/arch/mn10300/kernel/mn10300-serial.c b/arch/mn10300/kernel/mn10300-serial.c
index efca426a2ed..94901c56baf 100644
--- a/arch/mn10300/kernel/mn10300-serial.c
+++ b/arch/mn10300/kernel/mn10300-serial.c
@@ -933,7 +933,7 @@ static int mn10300_serial_startup(struct uart_port *_port)
NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));
set_intr_level(port->tx_irq,
NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL));
- set_irq_chip(port->tm_irq, &mn10300_serial_pic);
+ irq_set_chip(port->tm_irq, &mn10300_serial_pic);
if (request_irq(port->rx_irq, mn10300_serial_interrupt,
IRQF_DISABLED, port->rx_name, port) < 0)
diff --git a/arch/mn10300/kernel/smp.c b/arch/mn10300/kernel/smp.c
index 51c02f97dce..226c826a219 100644
--- a/arch/mn10300/kernel/smp.c
+++ b/arch/mn10300/kernel/smp.c
@@ -156,15 +156,15 @@ static void init_ipi(void)
u16 tmp16;
/* set up the reschedule IPI */
- set_irq_chip_and_handler(RESCHEDULE_IPI,
- &mn10300_ipi_type, handle_percpu_irq);
+ irq_set_chip_and_handler(RESCHEDULE_IPI, &mn10300_ipi_type,
+ handle_percpu_irq);
setup_irq(RESCHEDULE_IPI, &reschedule_ipi);
set_intr_level(RESCHEDULE_IPI, RESCHEDULE_GxICR_LV);
mn10300_ipi_enable(RESCHEDULE_IPI);
/* set up the call function IPI */
- set_irq_chip_and_handler(CALL_FUNC_SINGLE_IPI,
- &mn10300_ipi_type, handle_percpu_irq);
+ irq_set_chip_and_handler(CALL_FUNC_SINGLE_IPI, &mn10300_ipi_type,
+ handle_percpu_irq);
setup_irq(CALL_FUNC_SINGLE_IPI, &call_function_ipi);
set_intr_level(CALL_FUNC_SINGLE_IPI, CALL_FUNCTION_GxICR_LV);
mn10300_ipi_enable(CALL_FUNC_SINGLE_IPI);
@@ -172,8 +172,8 @@ static void init_ipi(void)
/* set up the local timer IPI */
#if !defined(CONFIG_GENERIC_CLOCKEVENTS) || \
defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
- set_irq_chip_and_handler(LOCAL_TIMER_IPI,
- &mn10300_ipi_type, handle_percpu_irq);
+ irq_set_chip_and_handler(LOCAL_TIMER_IPI, &mn10300_ipi_type,
+ handle_percpu_irq);
setup_irq(LOCAL_TIMER_IPI, &local_timer_ipi);
set_intr_level(LOCAL_TIMER_IPI, LOCAL_TIMER_GxICR_LV);
mn10300_ipi_enable(LOCAL_TIMER_IPI);
diff --git a/arch/mn10300/unit-asb2364/irq-fpga.c b/arch/mn10300/unit-asb2364/irq-fpga.c
index ee84e62b16e..e16c216f31d 100644
--- a/arch/mn10300/unit-asb2364/irq-fpga.c
+++ b/arch/mn10300/unit-asb2364/irq-fpga.c
@@ -100,7 +100,8 @@ void __init irq_fpga_init(void)
SyncExBus();
for (irq = NR_CPU_IRQS; irq < NR_IRQS; irq++)
- set_irq_chip_and_handler(irq, &asb2364_fpga_pic, handle_level_irq);
+ irq_set_chip_and_handler(irq, &asb2364_fpga_pic,
+ handle_level_irq);
/* the FPGA drives the XIRQ1 input on the CPU PIC */
setup_irq(XIRQ1, &fpga_irq[0]);
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 9b1f427cdc3..69ff049c857 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -15,7 +15,6 @@ config PARISC
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select IRQ_PER_CPU
- select GENERIC_HARDIRQS_NO_DEPRECATED
help
The PA-RISC microprocessor is designed by Hewlett-Packard and used
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index cb450e1e79b..c0b1affc06a 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -113,13 +113,8 @@ int cpu_check_affinity(struct irq_data *d, const struct cpumask *dest)
int cpu_dest;
/* timer and ipi have to always be received on all CPUs */
- if (CHECK_IRQ_PER_CPU(irq_to_desc(d->irq)->status)) {
- /* Bad linux design decision. The mask has already
- * been set; we must reset it. Will fix - tglx
- */
- cpumask_setall(d->affinity);
+ if (irqd_is_per_cpu(d))
return -EINVAL;
- }
/* whatever mask they set, we just allow one CPU */
cpu_dest = first_cpu(*dest);
@@ -174,10 +169,11 @@ int show_interrupts(struct seq_file *p, void *v)
}
if (i < NR_IRQS) {
+ struct irq_desc *desc = irq_to_desc(i);
struct irqaction *action;
- raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
- action = irq_desc[i].action;
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ action = desc->action;
if (!action)
goto skip;
seq_printf(p, "%3d: ", i);
@@ -188,7 +184,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_irqs(i));
#endif
- seq_printf(p, " %14s", irq_desc[i].irq_data.chip->name);
+ seq_printf(p, " %14s", irq_desc_get_chip(desc)->name);
#ifndef PARISC_IRQ_CR16_COUNTS
seq_printf(p, " %s", action->name);
@@ -220,7 +216,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
skip:
- raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
}
return 0;
@@ -238,15 +234,15 @@ int show_interrupts(struct seq_file *p, void *v)
int cpu_claim_irq(unsigned int irq, struct irq_chip *type, void *data)
{
- if (irq_desc[irq].action)
+ if (irq_has_action(irq))
return -EBUSY;
- if (get_irq_chip(irq) != &cpu_interrupt_type)
+ if (irq_get_chip(irq) != &cpu_interrupt_type)
return -EBUSY;
/* for iosapic interrupts */
if (type) {
- set_irq_chip_and_handler(irq, type, handle_percpu_irq);
- set_irq_chip_data(irq, data);
+ irq_set_chip_and_handler(irq, type, handle_percpu_irq);
+ irq_set_chip_data(irq, data);
__cpu_unmask_irq(irq);
}
return 0;
@@ -357,7 +353,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
#ifdef CONFIG_SMP
desc = irq_to_desc(irq);
cpumask_copy(&dest, desc->irq_data.affinity);
- if (CHECK_IRQ_PER_CPU(desc->status) &&
+ if (irqd_is_per_cpu(&desc->irq_data) &&
!cpu_isset(smp_processor_id(), dest)) {
int cpu = first_cpu(dest);
@@ -398,14 +394,14 @@ static void claim_cpu_irqs(void)
{
int i;
for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) {
- set_irq_chip_and_handler(i, &cpu_interrupt_type,
+ irq_set_chip_and_handler(i, &cpu_interrupt_type,
handle_percpu_irq);
}
- set_irq_handler(TIMER_IRQ, handle_percpu_irq);
+ irq_set_handler(TIMER_IRQ, handle_percpu_irq);
setup_irq(TIMER_IRQ, &timer_action);
#ifdef CONFIG_SMP
- set_irq_handler(IPI_IRQ, handle_percpu_irq);
+ irq_set_handler(IPI_IRQ, handle_percpu_irq);
setup_irq(IPI_IRQ, &ipi_action);
#endif
}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 3584e4d4a4a..b6ff882f695 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -138,7 +138,8 @@ config PPC
select HAVE_GENERIC_HARDIRQS
select HAVE_SPARSE_IRQ
select IRQ_PER_CPU
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ select GENERIC_IRQ_SHOW
+ select GENERIC_IRQ_SHOW_LEVEL
config EARLY_PRINTK
bool
diff --git a/arch/powerpc/configs/44x/warp_defconfig b/arch/powerpc/configs/44x/warp_defconfig
index 6cf9d661480..abf74dc1f79 100644
--- a/arch/powerpc/configs/44x/warp_defconfig
+++ b/arch/powerpc/configs/44x/warp_defconfig
@@ -47,6 +47,7 @@ CONFIG_MTD_NAND_NDFC=y
CONFIG_MTD_UBI=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_RAM=y
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT24=y
CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig
index 6828eda02bd..0c7de9620ea 100644
--- a/arch/powerpc/configs/52xx/motionpro_defconfig
+++ b/arch/powerpc/configs/52xx/motionpro_defconfig
@@ -43,6 +43,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
diff --git a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
index 4b2441244ea..d41857a5152 100644
--- a/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
+++ b/arch/powerpc/configs/86xx/gef_ppc9a_defconfig
@@ -85,6 +85,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
CONFIG_DS1682=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECS=y
diff --git a/arch/powerpc/configs/86xx/gef_sbc310_defconfig b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
index a360ba44b92..38303ec11bc 100644
--- a/arch/powerpc/configs/86xx/gef_sbc310_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc310_defconfig
@@ -85,6 +85,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
CONFIG_DS1682=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECS=y
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
index be2829dd129..98533973d20 100644
--- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
@@ -138,6 +138,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
CONFIG_DS1682=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
diff --git a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
index 0c9c7ed7ec7..b614508d6fd 100644
--- a/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
+++ b/arch/powerpc/configs/86xx/mpc8641_hpcn_defconfig
@@ -63,6 +63,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
diff --git a/arch/powerpc/configs/e55xx_smp_defconfig b/arch/powerpc/configs/e55xx_smp_defconfig
index 06f95492afc..9fa1613e5e2 100644
--- a/arch/powerpc/configs/e55xx_smp_defconfig
+++ b/arch/powerpc/configs/e55xx_smp_defconfig
@@ -32,6 +32,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=y
CONFIG_INPUT_FF_MEMLESS=m
# CONFIG_INPUT_MOUSEDEV is not set
diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
index f39d0cf876d..8a874b99986 100644
--- a/arch/powerpc/configs/linkstation_defconfig
+++ b/arch/powerpc/configs/linkstation_defconfig
@@ -78,6 +78,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=2
CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=m
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_SG=y
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig
index 62db8a3df16..c02bbb2fddf 100644
--- a/arch/powerpc/configs/mpc512x_defconfig
+++ b/arch/powerpc/configs/mpc512x_defconfig
@@ -61,6 +61,7 @@ CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_COUNT=1
CONFIG_BLK_DEV_RAM_SIZE=8192
CONFIG_BLK_DEV_XIP=y
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT24=y
CONFIG_SCSI=y
# CONFIG_SCSI_PROC_FS is not set
diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig
index 7376e27b8ed..e63f537b854 100644
--- a/arch/powerpc/configs/mpc5200_defconfig
+++ b/arch/powerpc/configs/mpc5200_defconfig
@@ -52,6 +52,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=32768
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT24=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
diff --git a/arch/powerpc/configs/mpc85xx_defconfig b/arch/powerpc/configs/mpc85xx_defconfig
index 99a19d1e9bf..c06a86c3309 100644
--- a/arch/powerpc/configs/mpc85xx_defconfig
+++ b/arch/powerpc/configs/mpc85xx_defconfig
@@ -82,6 +82,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
diff --git a/arch/powerpc/configs/mpc85xx_smp_defconfig b/arch/powerpc/configs/mpc85xx_smp_defconfig
index c636f23f8c9..942ced90557 100644
--- a/arch/powerpc/configs/mpc85xx_smp_defconfig
+++ b/arch/powerpc/configs/mpc85xx_smp_defconfig
@@ -84,6 +84,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
diff --git a/arch/powerpc/configs/mpc86xx_defconfig b/arch/powerpc/configs/mpc86xx_defconfig
index 55b54318fef..038a308cbfc 100644
--- a/arch/powerpc/configs/mpc86xx_defconfig
+++ b/arch/powerpc/configs/mpc86xx_defconfig
@@ -66,6 +66,7 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_NBD=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=131072
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=y
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig
index edd2d54c819..f4deb0b78cf 100644
--- a/arch/powerpc/configs/pasemi_defconfig
+++ b/arch/powerpc/configs/pasemi_defconfig
@@ -59,6 +59,7 @@ CONFIG_PROC_DEVICETREE=y
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_RAM_SIZE=16384
+CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_LEGACY=y
CONFIG_IDE=y
CONFIG_BLK_DEV_IDECD=y
diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig
index 9d64a6822d8..0a10fb009ef 100644
--- a/arch/powerpc/configs/ppc6xx_defconfig
+++ b/arch/powerpc/configs/ppc6xx_defconfig
@@ -398,6 +398,7 @@ CONFIG_BLK_DEV_RAM_SIZE=16384
CONFIG_CDROM_PKTCDVD=m
CONFIG_VIRTIO_BLK=m
CONFIG_BLK_DEV_HD=y
+CONFIG_MISC_DEVICES=y
CONFIG_ENCLOSURE_SERVICES=m
CONFIG_SENSORS_TSL2550=m
CONFIG_EEPROM_AT24=m
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 9c3f22c6cde..249ddd0a27c 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -189,6 +189,7 @@ CONFIG_TIGON3=y
CONFIG_BNX2=m
CONFIG_CHELSIO_T1=m
CONFIG_CHELSIO_T3=m
+CONFIG_CHELSIO_T4=m
CONFIG_EHEA=y
CONFIG_IXGBE=m
CONFIG_IXGB=m
@@ -255,6 +256,8 @@ CONFIG_INFINIBAND_USER_MAD=m
CONFIG_INFINIBAND_USER_ACCESS=m
CONFIG_INFINIBAND_MTHCA=m
CONFIG_INFINIBAND_EHCA=m
+CONFIG_INFINIBAND_CXGB3=m
+CONFIG_INFINIBAND_CXGB4=m
CONFIG_MLX4_INFINIBAND=m
CONFIG_INFINIBAND_IPOIB=m
CONFIG_INFINIBAND_IPOIB_CM=y
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 6d2416a8570..dd70fac57ec 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -42,6 +42,7 @@ extern void __dma_free_coherent(size_t size, void *vaddr);
extern void __dma_sync(void *vaddr, size_t size, int direction);
extern void __dma_sync_page(struct page *page, unsigned long offset,
size_t size, int direction);
+extern unsigned long __dma_get_coherent_pfn(unsigned long cpu_addr);
#else /* ! CONFIG_NOT_COHERENT_CACHE */
/*
@@ -198,6 +199,11 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
+extern int dma_mmap_coherent(struct device *, struct vm_area_struct *,
+ void *, dma_addr_t, size_t);
+#define ARCH_HAS_DMA_MMAP_COHERENT
+
+
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index fe56a23e1ff..e4f01915fbb 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -35,9 +35,9 @@ struct smp_ops_t {
int (*probe)(void);
void (*kick_cpu)(int nr);
void (*setup_cpu)(int nr);
+ void (*bringup_done)(void);
void (*take_timebase)(void);
void (*give_timebase)(void);
- int (*cpu_enable)(unsigned int nr);
int (*cpu_disable)(void);
void (*cpu_die)(unsigned int nr);
int (*cpu_bootable)(unsigned int nr);
@@ -267,7 +267,6 @@ struct machdep_calls {
extern void e500_idle(void);
extern void power4_idle(void);
-extern void power4_cpu_offline_powersave(void);
extern void ppc6xx_idle(void);
extern void book3e_idle(void);
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index acac35d5b38..ae7b3efec8e 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -27,7 +27,7 @@
#define STE_VSID_SHIFT 12
/* Location of cpu0's segment table */
-#define STAB0_PAGE 0x6
+#define STAB0_PAGE 0x8
#define STAB0_OFFSET (STAB0_PAGE << 12)
#define STAB0_PHYS_ADDR (STAB0_OFFSET + PHYSICAL_START)
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index da4b2000854..2cd664ef0a5 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -100,7 +100,7 @@ extern phys_addr_t kernstart_addr;
#endif
#ifdef CONFIG_FLATMEM
-#define ARCH_PFN_OFFSET (MEMORY_START >> PAGE_SHIFT)
+#define ARCH_PFN_OFFSET ((unsigned long)(MEMORY_START >> PAGE_SHIFT))
#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && (pfn) < max_mapnr)
#endif
diff --git a/arch/powerpc/include/asm/qe_ic.h b/arch/powerpc/include/asm/qe_ic.h
index 9e2cb201916..f706164b0bd 100644
--- a/arch/powerpc/include/asm/qe_ic.h
+++ b/arch/powerpc/include/asm/qe_ic.h
@@ -81,7 +81,7 @@ int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
static inline void qe_ic_cascade_low_ipic(unsigned int irq,
struct irq_desc *desc)
{
- struct qe_ic *qe_ic = get_irq_desc_data(desc);
+ struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
if (cascade_irq != NO_IRQ)
@@ -91,7 +91,7 @@ static inline void qe_ic_cascade_low_ipic(unsigned int irq,
static inline void qe_ic_cascade_high_ipic(unsigned int irq,
struct irq_desc *desc)
{
- struct qe_ic *qe_ic = get_irq_desc_data(desc);
+ struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq != NO_IRQ)
@@ -101,9 +101,9 @@ static inline void qe_ic_cascade_high_ipic(unsigned int irq,
static inline void qe_ic_cascade_low_mpic(unsigned int irq,
struct irq_desc *desc)
{
- struct qe_ic *qe_ic = get_irq_desc_data(desc);
+ struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
@@ -114,9 +114,9 @@ static inline void qe_ic_cascade_low_mpic(unsigned int irq,
static inline void qe_ic_cascade_high_mpic(unsigned int irq,
struct irq_desc *desc)
{
- struct qe_ic *qe_ic = get_irq_desc_data(desc);
+ struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
if (cascade_irq != NO_IRQ)
generic_handle_irq(cascade_irq);
@@ -127,9 +127,9 @@ static inline void qe_ic_cascade_high_mpic(unsigned int irq,
static inline void qe_ic_cascade_muxed_mpic(unsigned int irq,
struct irq_desc *desc)
{
- struct qe_ic *qe_ic = get_irq_desc_data(desc);
+ struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq;
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
cascade_irq = qe_ic_get_high_irq(qe_ic);
if (cascade_irq == NO_IRQ)
diff --git a/arch/powerpc/include/asm/reg_booke.h b/arch/powerpc/include/asm/reg_booke.h
index 86ad8128963..3b1a9b70736 100644
--- a/arch/powerpc/include/asm/reg_booke.h
+++ b/arch/powerpc/include/asm/reg_booke.h
@@ -110,7 +110,7 @@
#define SPRN_MAS2 0x272 /* MMU Assist Register 2 */
#define SPRN_MAS3 0x273 /* MMU Assist Register 3 */
#define SPRN_MAS4 0x274 /* MMU Assist Register 4 */
-#define SPRN_MAS5 0x275 /* MMU Assist Register 5 */
+#define SPRN_MAS5 0x153 /* MMU Assist Register 5 */
#define SPRN_MAS6 0x276 /* MMU Assist Register 6 */
#define SPRN_PID1 0x279 /* Process ID Register 1 */
#define SPRN_PID2 0x27A /* Process ID Register 2 */
diff --git a/arch/powerpc/include/asm/smp.h b/arch/powerpc/include/asm/smp.h
index 66e237bbe15..a902a0d3ae0 100644
--- a/arch/powerpc/include/asm/smp.h
+++ b/arch/powerpc/include/asm/smp.h
@@ -36,15 +36,16 @@ extern void cpu_die(void);
extern void smp_send_debugger_break(int cpu);
extern void smp_message_recv(int);
+extern void start_secondary_resume(void);
DECLARE_PER_CPU(unsigned int, cpu_pvr);
#ifdef CONFIG_HOTPLUG_CPU
-extern void fixup_irqs(const struct cpumask *map);
+extern void migrate_irqs(void);
int generic_cpu_disable(void);
-int generic_cpu_enable(unsigned int cpu);
void generic_cpu_die(unsigned int cpu);
void generic_mach_cpu_die(void);
+void generic_set_cpu_dead(unsigned int cpu);
#endif
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/include/asm/systbl.h b/arch/powerpc/include/asm/systbl.h
index aa0f1ebb4aa..60f64b132bd 100644
--- a/arch/powerpc/include/asm/systbl.h
+++ b/arch/powerpc/include/asm/systbl.h
@@ -348,3 +348,7 @@ COMPAT_SYS_SPU(sendmsg)
COMPAT_SYS_SPU(recvmsg)
COMPAT_SYS_SPU(recvmmsg)
SYSCALL_SPU(accept4)
+SYSCALL_SPU(name_to_handle_at)
+COMPAT_SYS_SPU(open_by_handle_at)
+COMPAT_SYS_SPU(clock_adjtime)
+SYSCALL_SPU(syncfs)
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index 6151937657f..3c215648ce6 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -367,10 +367,14 @@
#define __NR_recvmsg 342
#define __NR_recvmmsg 343
#define __NR_accept4 344
+#define __NR_name_to_handle_at 345
+#define __NR_open_by_handle_at 346
+#define __NR_clock_adjtime 347
+#define __NR_syncfs 348
#ifdef __KERNEL__
-#define __NR_syscalls 345
+#define __NR_syscalls 349
#define __NR__exit __NR_exit
#define NR_syscalls __NR_syscalls
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index cf02cad62d9..d238c082c3c 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -179,3 +179,21 @@ static int __init dma_init(void)
return 0;
}
fs_initcall(dma_init);
+
+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size)
+{
+ unsigned long pfn;
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr);
+#else
+ pfn = page_to_pfn(virt_to_page(cpu_addr));
+#endif
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+EXPORT_SYMBOL_GPL(dma_mmap_coherent);
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 8a817995b4c..c532cb2c927 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -977,20 +977,6 @@ _GLOBAL(do_stab_bolted)
rfid
b . /* prevent speculative execution */
-/*
- * Space for CPU0's segment table.
- *
- * On iSeries, the hypervisor must fill in at least one entry before
- * we get control (with relocate on). The address is given to the hv
- * as a page number (see xLparMap below), so this must be at a
- * fixed address (the linker can't compute (u64)&initial_stab >>
- * PAGE_SHIFT).
- */
- . = STAB0_OFFSET /* 0x6000 */
- .globl initial_stab
-initial_stab:
- .space 4096
-
#ifdef CONFIG_PPC_PSERIES
/*
* Data area reserved for FWNMI option.
@@ -1027,3 +1013,17 @@ xLparMap:
#ifdef CONFIG_PPC_PSERIES
. = 0x8000
#endif /* CONFIG_PPC_PSERIES */
+
+/*
+ * Space for CPU0's segment table.
+ *
+ * On iSeries, the hypervisor must fill in at least one entry before
+ * we get control (with relocate on). The address is given to the hv
+ * as a page number (see xLparMap above), so this must be at a
+ * fixed address (the linker can't compute (u64)&initial_stab >>
+ * PAGE_SHIFT).
+ */
+ . = STAB0_OFFSET /* 0x8000 */
+ .globl initial_stab
+initial_stab:
+ .space 4096
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index 98c4b29a56f..c5c24beb838 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -890,6 +890,15 @@ __secondary_start:
mtspr SPRN_SRR1,r4
SYNC
RFI
+
+_GLOBAL(start_secondary_resume)
+ /* Reset stack */
+ rlwinm r1,r1,0,0,(31-THREAD_SHIFT) /* current_thread_info() */
+ addi r1,r1,THREAD_SIZE-STACK_FRAME_OVERHEAD
+ li r3,0
+ std r3,0(r1) /* Zero the stack frame pointer */
+ bl start_secondary
+ b .
#endif /* CONFIG_SMP */
#ifdef CONFIG_KVM_BOOK3S_HANDLER
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 782f23df7c8..271140b38b6 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -536,6 +536,13 @@ _GLOBAL(pmac_secondary_start)
add r13,r13,r4 /* for this processor. */
mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/
+ /* Mark interrupts soft and hard disabled (they might be enabled
+ * in the PACA when doing hotplug)
+ */
+ li r0,0
+ stb r0,PACASOFTIRQEN(r13)
+ stb r0,PACAHARDIRQEN(r13)
+
/* Create a temp kernel stack for use before relocation is on. */
ld r1,PACAEMERGSP(r13)
subi r1,r1,STACK_FRAME_OVERHEAD
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index 5328709eeed..ba319547860 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -53,24 +53,3 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
isync
b 1b
-_GLOBAL(power4_cpu_offline_powersave)
- /* Go to NAP now */
- mfmsr r7
- rldicl r0,r7,48,1
- rotldi r0,r0,16
- mtmsrd r0,1 /* hard-disable interrupts */
- li r0,1
- li r6,0
- stb r0,PACAHARDIRQEN(r13) /* we'll hard-enable shortly */
- stb r6,PACASOFTIRQEN(r13) /* soft-disable irqs */
-BEGIN_FTR_SECTION
- DSSALL
- sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
- ori r7,r7,MSR_EE
- oris r7,r7,MSR_POW@h
- sync
- isync
- mtmsrd r7
- isync
- blr
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 0a5570338b9..f621b7d2d86 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -195,7 +195,7 @@ notrace void arch_local_irq_restore(unsigned long en)
EXPORT_SYMBOL(arch_local_irq_restore);
#endif /* CONFIG_PPC64 */
-static int show_other_interrupts(struct seq_file *p, int prec)
+int arch_show_interrupts(struct seq_file *p, int prec)
{
int j;
@@ -231,65 +231,6 @@ static int show_other_interrupts(struct seq_file *p, int prec)
return 0;
}
-int show_interrupts(struct seq_file *p, void *v)
-{
- unsigned long flags, any_count = 0;
- int i = *(loff_t *) v, j, prec;
- struct irqaction *action;
- struct irq_desc *desc;
- struct irq_chip *chip;
-
- if (i > nr_irqs)
- return 0;
-
- for (prec = 3, j = 1000; prec < 10 && j <= nr_irqs; ++prec)
- j *= 10;
-
- if (i == nr_irqs)
- return show_other_interrupts(p, prec);
-
- /* print header */
- if (i == 0) {
- seq_printf(p, "%*s", prec + 8, "");
- for_each_online_cpu(j)
- seq_printf(p, "CPU%-8d", j);
- seq_putc(p, '\n');
- }
-
- desc = irq_to_desc(i);
- if (!desc)
- return 0;
-
- raw_spin_lock_irqsave(&desc->lock, flags);
- for_each_online_cpu(j)
- any_count |= kstat_irqs_cpu(i, j);
- action = desc->action;
- if (!action && !any_count)
- goto out;
-
- seq_printf(p, "%*d: ", prec, i);
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-
- chip = get_irq_desc_chip(desc);
- if (chip)
- seq_printf(p, " %-16s", chip->name);
- else
- seq_printf(p, " %-16s", "None");
- seq_printf(p, " %-8s", (desc->status & IRQ_LEVEL) ? "Level" : "Edge");
-
- if (action) {
- seq_printf(p, " %s", action->name);
- while ((action = action->next) != NULL)
- seq_printf(p, ", %s", action->name);
- }
-
- seq_putc(p, '\n');
-out:
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return 0;
-}
-
/*
* /proc/stat helpers
*/
@@ -305,34 +246,37 @@ u64 arch_irq_stat_cpu(unsigned int cpu)
}
#ifdef CONFIG_HOTPLUG_CPU
-void fixup_irqs(const struct cpumask *map)
+void migrate_irqs(void)
{
struct irq_desc *desc;
unsigned int irq;
static int warned;
cpumask_var_t mask;
+ const struct cpumask *map = cpu_online_mask;
alloc_cpumask_var(&mask, GFP_KERNEL);
for_each_irq(irq) {
+ struct irq_data *data;
struct irq_chip *chip;
desc = irq_to_desc(irq);
if (!desc)
continue;
- if (desc->status & IRQ_PER_CPU)
+ data = irq_desc_get_irq_data(desc);
+ if (irqd_is_per_cpu(data))
continue;
- chip = get_irq_desc_chip(desc);
+ chip = irq_data_get_irq_chip(data);
- cpumask_and(mask, desc->irq_data.affinity, map);
+ cpumask_and(mask, data->affinity, map);
if (cpumask_any(mask) >= nr_cpu_ids) {
printk("Breaking affinity for irq %i\n", irq);
cpumask_copy(mask, map);
}
if (chip->irq_set_affinity)
- chip->irq_set_affinity(&desc->irq_data, mask, true);
+ chip->irq_set_affinity(data, mask, true);
else if (desc->action && !(warned++))
printk("Cannot set affinity for irq %i\n", irq);
}
@@ -618,7 +562,7 @@ struct irq_host *irq_alloc_host(struct device_node *of_node,
smp_wmb();
/* Clear norequest flags */
- irq_to_desc(i)->status &= ~IRQ_NOREQUEST;
+ irq_clear_status_flags(i, IRQ_NOREQUEST);
/* Legacy flags are left to default at this point,
* one can then use irq_create_mapping() to
@@ -827,8 +771,8 @@ unsigned int irq_create_of_mapping(struct device_node *controller,
/* Set type if specified and different than the current one */
if (type != IRQ_TYPE_NONE &&
- type != (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
- set_irq_type(virq, type);
+ type != (irqd_get_trigger_type(irq_get_irq_data(virq))))
+ irq_set_irq_type(virq, type);
return virq;
}
EXPORT_SYMBOL_GPL(irq_create_of_mapping);
@@ -851,7 +795,7 @@ void irq_dispose_mapping(unsigned int virq)
return;
/* remove chip and handler */
- set_irq_chip_and_handler(virq, NULL, NULL);
+ irq_set_chip_and_handler(virq, NULL, NULL);
/* Make sure it's completed */
synchronize_irq(virq);
@@ -1156,7 +1100,7 @@ static int virq_debug_show(struct seq_file *m, void *private)
seq_printf(m, "%5d ", i);
seq_printf(m, "0x%05lx ", virq_to_hw(i));
- chip = get_irq_desc_chip(desc);
+ chip = irq_desc_get_chip(desc);
if (chip && chip->name)
p = chip->name;
else
diff --git a/arch/powerpc/kernel/machine_kexec.c b/arch/powerpc/kernel/machine_kexec.c
index bd1e1ff17b2..7ee50f0547c 100644
--- a/arch/powerpc/kernel/machine_kexec.c
+++ b/arch/powerpc/kernel/machine_kexec.c
@@ -31,17 +31,17 @@ void machine_kexec_mask_interrupts(void) {
if (!desc)
continue;
- chip = get_irq_desc_chip(desc);
+ chip = irq_desc_get_chip(desc);
if (!chip)
continue;
- if (chip->irq_eoi && desc->status & IRQ_INPROGRESS)
+ if (chip->irq_eoi && irqd_irq_inprogress(&desc->irq_data))
chip->irq_eoi(&desc->irq_data);
if (chip->irq_mask)
chip->irq_mask(&desc->irq_data);
- if (chip->irq_disable && !(desc->status & IRQ_DISABLED))
+ if (chip->irq_disable && !irqd_irq_disabled(&desc->irq_data))
chip->irq_disable(&desc->irq_data);
}
}
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index 3cd85faa8ac..893af2a9cd0 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -261,7 +261,7 @@ int pci_read_irq_line(struct pci_dev *pci_dev)
virq = irq_create_mapping(NULL, line);
if (virq != NO_IRQ)
- set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
} else {
pr_debug(" Got one, spec %d cells (0x%08x 0x%08x...) on %s\n",
oirq.size, oirq.specifier[0], oirq.specifier[1],
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 98136050917..cbdbb14be4b 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -57,6 +57,25 @@
#define DBG(fmt...)
#endif
+
+/* Store all idle threads, this can be reused instead of creating
+* a new thread. Also avoids complicated thread destroy functionality
+* for idle threads.
+*/
+#ifdef CONFIG_HOTPLUG_CPU
+/*
+ * Needed only for CONFIG_HOTPLUG_CPU because __cpuinitdata is
+ * removed after init for !CONFIG_HOTPLUG_CPU.
+ */
+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))
+#else
+static struct task_struct *idle_thread_array[NR_CPUS] __cpuinitdata ;
+#define get_idle_for_cpu(x) (idle_thread_array[(x)])
+#define set_idle_for_cpu(x, p) (idle_thread_array[(x)] = (p))
+#endif
+
struct thread_info *secondary_ti;
DEFINE_PER_CPU(cpumask_var_t, cpu_sibling_map);
@@ -238,23 +257,6 @@ static void __devinit smp_store_cpu_info(int id)
per_cpu(cpu_pvr, id) = mfspr(SPRN_PVR);
}
-static void __init smp_create_idle(unsigned int cpu)
-{
- struct task_struct *p;
-
- /* create a process for the processor */
- p = fork_idle(cpu);
- if (IS_ERR(p))
- panic("failed fork for CPU %u: %li", cpu, PTR_ERR(p));
-#ifdef CONFIG_PPC64
- paca[cpu].__current = p;
- paca[cpu].kstack = (unsigned long) task_thread_info(p)
- + THREAD_SIZE - STACK_FRAME_OVERHEAD;
-#endif
- current_set[cpu] = task_thread_info(p);
- task_thread_info(p)->cpu = cpu;
-}
-
void __init smp_prepare_cpus(unsigned int max_cpus)
{
unsigned int cpu;
@@ -288,10 +290,6 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
max_cpus = NR_CPUS;
else
max_cpus = 1;
-
- for_each_possible_cpu(cpu)
- if (cpu != boot_cpuid)
- smp_create_idle(cpu);
}
void __devinit smp_prepare_boot_cpu(void)
@@ -305,7 +303,7 @@ void __devinit smp_prepare_boot_cpu(void)
#ifdef CONFIG_HOTPLUG_CPU
/* State of each CPU during hotplug phases */
-DEFINE_PER_CPU(int, cpu_state) = { 0 };
+static DEFINE_PER_CPU(int, cpu_state) = { 0 };
int generic_cpu_disable(void)
{
@@ -317,30 +315,8 @@ int generic_cpu_disable(void)
set_cpu_online(cpu, false);
#ifdef CONFIG_PPC64
vdso_data->processorCount--;
- fixup_irqs(cpu_online_mask);
-#endif
- return 0;
-}
-
-int generic_cpu_enable(unsigned int cpu)
-{
- /* Do the normal bootup if we haven't
- * already bootstrapped. */
- if (system_state != SYSTEM_RUNNING)
- return -ENOSYS;
-
- /* get the target out of it's holding state */
- per_cpu(cpu_state, cpu) = CPU_UP_PREPARE;
- smp_wmb();
-
- while (!cpu_online(cpu))
- cpu_relax();
-
-#ifdef CONFIG_PPC64
- fixup_irqs(cpu_online_mask);
- /* counter the irq disable in fixup_irqs */
- local_irq_enable();
#endif
+ migrate_irqs();
return 0;
}
@@ -362,37 +338,89 @@ void generic_mach_cpu_die(void)
unsigned int cpu;
local_irq_disable();
+ idle_task_exit();
cpu = smp_processor_id();
printk(KERN_DEBUG "CPU%d offline\n", cpu);
__get_cpu_var(cpu_state) = CPU_DEAD;
smp_wmb();
while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE)
cpu_relax();
- set_cpu_online(cpu, true);
- local_irq_enable();
+}
+
+void generic_set_cpu_dead(unsigned int cpu)
+{
+ per_cpu(cpu_state, cpu) = CPU_DEAD;
}
#endif
-static int __devinit cpu_enable(unsigned int cpu)
+struct create_idle {
+ struct work_struct work;
+ struct task_struct *idle;
+ struct completion done;
+ int cpu;
+};
+
+static void __cpuinit do_fork_idle(struct work_struct *work)
{
- if (smp_ops && smp_ops->cpu_enable)
- return smp_ops->cpu_enable(cpu);
+ struct create_idle *c_idle =
+ container_of(work, struct create_idle, work);
+
+ c_idle->idle = fork_idle(c_idle->cpu);
+ complete(&c_idle->done);
+}
+
+static int __cpuinit create_idle(unsigned int cpu)
+{
+ struct thread_info *ti;
+ struct create_idle c_idle = {
+ .cpu = cpu,
+ .done = COMPLETION_INITIALIZER_ONSTACK(c_idle.done),
+ };
+ INIT_WORK_ONSTACK(&c_idle.work, do_fork_idle);
+
+ c_idle.idle = get_idle_for_cpu(cpu);
+
+ /* We can't use kernel_thread since we must avoid to
+ * reschedule the child. We use a workqueue because
+ * we want to fork from a kernel thread, not whatever
+ * userspace process happens to be trying to online us.
+ */
+ if (!c_idle.idle) {
+ schedule_work(&c_idle.work);
+ wait_for_completion(&c_idle.done);
+ } else
+ init_idle(c_idle.idle, cpu);
+ if (IS_ERR(c_idle.idle)) {
+ pr_err("Failed fork for CPU %u: %li", cpu, PTR_ERR(c_idle.idle));
+ return PTR_ERR(c_idle.idle);
+ }
+ ti = task_thread_info(c_idle.idle);
+
+#ifdef CONFIG_PPC64
+ paca[cpu].__current = c_idle.idle;
+ paca[cpu].kstack = (unsigned long)ti + THREAD_SIZE - STACK_FRAME_OVERHEAD;
+#endif
+ ti->cpu = cpu;
+ current_set[cpu] = ti;
- return -ENOSYS;
+ return 0;
}
int __cpuinit __cpu_up(unsigned int cpu)
{
- int c;
+ int rc, c;
secondary_ti = current_set[cpu];
- if (!cpu_enable(cpu))
- return 0;
if (smp_ops == NULL ||
(smp_ops->cpu_bootable && !smp_ops->cpu_bootable(cpu)))
return -EINVAL;
+ /* Make sure we have an idle thread */
+ rc = create_idle(cpu);
+ if (rc)
+ return rc;
+
/* Make sure callin-map entry is 0 (can be leftover a CPU
* hotplug
*/
@@ -502,7 +530,7 @@ static struct device_node *cpu_to_l2cache(int cpu)
}
/* Activate a secondary processor. */
-int __devinit start_secondary(void *unused)
+void __devinit start_secondary(void *unused)
{
unsigned int cpu = smp_processor_id();
struct device_node *l2_cache;
@@ -523,6 +551,10 @@ int __devinit start_secondary(void *unused)
secondary_cpu_time_init();
+#ifdef CONFIG_PPC64
+ if (system_state == SYSTEM_RUNNING)
+ vdso_data->processorCount++;
+#endif
ipi_call_lock();
notify_cpu_starting(cpu);
set_cpu_online(cpu, true);
@@ -558,7 +590,8 @@ int __devinit start_secondary(void *unused)
local_irq_enable();
cpu_idle();
- return 0;
+
+ BUG();
}
int setup_profiling_timer(unsigned int multiplier)
@@ -585,7 +618,11 @@ void __init smp_cpus_done(unsigned int max_cpus)
free_cpumask_var(old_mask);
+ if (smp_ops && smp_ops->bringup_done)
+ smp_ops->bringup_done();
+
dump_numa_cpu_topology();
+
}
int arch_sd_sibling_asym_packing(void)
@@ -660,5 +697,9 @@ void cpu_die(void)
{
if (ppc_md.cpu_die)
ppc_md.cpu_die();
+
+ /* If we return, we re-enter start_secondary */
+ start_secondary_resume();
}
+
#endif
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 09d31dbf43f..375480c56eb 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -356,7 +356,7 @@ void account_system_vtime(struct task_struct *tsk)
}
get_paca()->user_time_scaled += user_scaled;
- if (in_irq() || idle_task(smp_processor_id()) != tsk) {
+ if (in_interrupt() || idle_task(smp_processor_id()) != tsk) {
account_system_time(tsk, 0, delta, sys_scaled);
if (stolen)
account_steal_time(stolen);
@@ -577,14 +577,21 @@ void timer_interrupt(struct pt_regs * regs)
struct clock_event_device *evt = &decrementer->event;
u64 now;
+ /* Ensure a positive value is written to the decrementer, or else
+ * some CPUs will continue to take decrementer exceptions.
+ */
+ set_dec(DECREMENTER_MAX);
+
+ /* Some implementations of hotplug will get timer interrupts while
+ * offline, just ignore these
+ */
+ if (!cpu_online(smp_processor_id()))
+ return;
+
trace_timer_interrupt_entry(regs);
__get_cpu_var(irq_stat).timer_irqs++;
- /* Ensure a positive value is written to the decrementer, or else
- * some CPUs will continuue to take decrementer exceptions */
- set_dec(DECREMENTER_MAX);
-
#if defined(CONFIG_PPC32) && defined(CONFIG_PMAC)
if (atomic_read(&ppc_n_lost_interrupts) != 0)
do_IRQ(regs);
diff --git a/arch/powerpc/mm/dma-noncoherent.c b/arch/powerpc/mm/dma-noncoherent.c
index 757c0bed9a9..b42f76c4948 100644
--- a/arch/powerpc/mm/dma-noncoherent.c
+++ b/arch/powerpc/mm/dma-noncoherent.c
@@ -399,3 +399,23 @@ void __dma_sync_page(struct page *page, unsigned long offset,
#endif
}
EXPORT_SYMBOL(__dma_sync_page);
+
+/*
+ * Return the PFN for a given cpu virtual address returned by
+ * __dma_alloc_coherent. This is used by dma_mmap_coherent()
+ */
+unsigned long __dma_get_coherent_pfn(unsigned long cpu_addr)
+{
+ /* This should always be populated, so we don't test every
+ * level. If that fails, we'll have a nice crash which
+ * will be as good as a BUG_ON()
+ */
+ pgd_t *pgd = pgd_offset_k(cpu_addr);
+ pud_t *pud = pud_offset(pgd, cpu_addr);
+ pmd_t *pmd = pmd_offset(pud, cpu_addr);
+ pte_t *ptep = pte_offset_kernel(pmd, cpu_addr);
+
+ if (pte_none(*ptep) || !pte_present(*ptep))
+ return 0;
+ return pte_pfn(*ptep);
+}
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index fde0ea50c97..cfc4b200998 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -132,8 +132,8 @@ static int
cpld_pic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &cpld_pic, handle_level_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &cpld_pic, handle_level_irq);
return 0;
}
@@ -198,7 +198,7 @@ mpc5121_ads_cpld_pic_init(void)
goto end;
}
- set_irq_chained_handler(cascade_irq, cpld_pic_cascade);
+ irq_set_chained_handler(cascade_irq, cpld_pic_cascade);
end:
of_node_put(np);
}
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 2bd1e6cf1f5..57a6a349e93 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -82,7 +82,7 @@ static struct irq_chip media5200_irq_chip = {
void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
int sub_virq, val;
u32 status, enable;
@@ -107,7 +107,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
/* Processing done; can reenable the cascade now */
raw_spin_lock(&desc->lock);
chip->irq_ack(&desc->irq_data);
- if (!(desc->status & IRQ_DISABLED))
+ if (!irqd_irq_disabled(&desc->irq_data))
chip->irq_unmask(&desc->irq_data);
raw_spin_unlock(&desc->lock);
}
@@ -115,15 +115,10 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
static int media5200_irq_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- struct irq_desc *desc = irq_to_desc(virq);
-
pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
- set_irq_chip_data(virq, &media5200_irq);
- set_irq_chip_and_handler(virq, &media5200_irq_chip, handle_level_irq);
- set_irq_type(virq, IRQ_TYPE_LEVEL_LOW);
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= IRQ_TYPE_LEVEL_LOW | IRQ_LEVEL;
-
+ irq_set_chip_data(virq, &media5200_irq);
+ irq_set_chip_and_handler(virq, &media5200_irq_chip, handle_level_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
return 0;
}
@@ -187,8 +182,8 @@ static void __init media5200_init_irq(void)
media5200_irq.irqhost->host_data = &media5200_irq;
- set_irq_data(cascade_virq, &media5200_irq);
- set_irq_chained_handler(cascade_virq, media5200_irq_cascade);
+ irq_set_handler_data(cascade_virq, &media5200_irq);
+ irq_set_chained_handler(cascade_virq, media5200_irq_cascade);
return;
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index 6da44f0f293..6c39b9cc2fa 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -192,7 +192,7 @@ static struct irq_chip mpc52xx_gpt_irq_chip = {
void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
{
- struct mpc52xx_gpt_priv *gpt = get_irq_data(virq);
+ struct mpc52xx_gpt_priv *gpt = irq_get_handler_data(virq);
int sub_virq;
u32 status;
@@ -209,8 +209,8 @@ static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
struct mpc52xx_gpt_priv *gpt = h->host_data;
dev_dbg(gpt->dev, "%s: h=%p, virq=%i\n", __func__, h, virq);
- set_irq_chip_data(virq, gpt);
- set_irq_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq);
+ irq_set_chip_data(virq, gpt);
+ irq_set_chip_and_handler(virq, &mpc52xx_gpt_irq_chip, handle_edge_irq);
return 0;
}
@@ -259,8 +259,8 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
}
gpt->irqhost->host_data = gpt;
- set_irq_data(cascade_virq, gpt);
- set_irq_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
+ irq_set_handler_data(cascade_virq, gpt);
+ irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
/* If the GPT is currently disabled, then change it to be in Input
* Capture mode. If the mode is non-zero, then the pin could be
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 9f3ed582d08..3ddea96273c 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -214,7 +214,7 @@ static int mpc52xx_extirq_set_type(struct irq_data *d, unsigned int flow_type)
ctrl_reg |= (type << (22 - (l2irq * 2)));
out_be32(&intr->ctrl, ctrl_reg);
- __set_irq_handler_unlocked(d->irq, handler);
+ __irq_set_handler_locked(d->irq, handler);
return 0;
}
@@ -414,7 +414,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
else
hndlr = handle_level_irq;
- set_irq_chip_and_handler(virq, &mpc52xx_extirq_irqchip, hndlr);
+ irq_set_chip_and_handler(virq, &mpc52xx_extirq_irqchip, hndlr);
pr_debug("%s: External IRQ%i virq=%x, hw=%x. type=%x\n",
__func__, l2irq, virq, (int)irq, type);
return 0;
@@ -431,7 +431,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
return -EINVAL;
}
- set_irq_chip_and_handler(virq, irqchip, handle_level_irq);
+ irq_set_chip_and_handler(virq, irqchip, handle_level_irq);
pr_debug("%s: virq=%x, l1=%i, l2=%i\n", __func__, virq, l1irq, l2irq);
return 0;
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 926dfdaaf57..4a4eb6ffa12 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -81,7 +81,7 @@ static struct irq_chip pq2ads_pci_ic = {
static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
{
- struct pq2ads_pci_pic *priv = get_irq_desc_data(desc);
+ struct pq2ads_pci_pic *priv = irq_desc_get_handler_data(desc);
u32 stat, mask, pend;
int bit;
@@ -106,17 +106,17 @@ static void pq2ads_pci_irq_demux(unsigned int irq, struct irq_desc *desc)
static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_data(virq, h->host_data);
- set_irq_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_data(virq, h->host_data);
+ irq_set_chip_and_handler(virq, &pq2ads_pci_ic, handle_level_irq);
return 0;
}
static void pci_host_unmap(struct irq_host *h, unsigned int virq)
{
/* remove chip and handler */
- set_irq_chip_data(virq, NULL);
- set_irq_chip(virq, NULL);
+ irq_set_chip_data(virq, NULL);
+ irq_set_chip(virq, NULL);
}
static struct irq_host_ops pci_pic_host_ops = {
@@ -175,8 +175,8 @@ int __init pq2ads_pci_init_irq(void)
priv->host = host;
host->host_data = priv;
- set_irq_data(irq, priv);
- set_irq_chained_handler(irq, pq2ads_pci_irq_demux);
+ irq_set_handler_data(irq, priv);
+ irq_set_chained_handler(irq, pq2ads_pci_irq_demux);
of_node_put(np);
return 0;
diff --git a/arch/powerpc/platforms/85xx/ksi8560.c b/arch/powerpc/platforms/85xx/ksi8560.c
index 64447e48f3d..c46f9359be1 100644
--- a/arch/powerpc/platforms/85xx/ksi8560.c
+++ b/arch/powerpc/platforms/85xx/ksi8560.c
@@ -56,7 +56,7 @@ static void machine_restart(char *cmd)
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
@@ -106,7 +106,7 @@ static void __init ksi8560_pic_init(void)
cpm2_pic_init(np);
of_node_put(np);
- set_irq_chained_handler(irq, cpm2_cascade);
+ irq_set_chained_handler(irq, cpm2_cascade);
#endif
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index 1352d1107bf..3b2c9bb6619 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -50,7 +50,7 @@ static int mpc85xx_exclude_device(struct pci_controller *hose,
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
@@ -101,7 +101,7 @@ static void __init mpc85xx_ads_pic_init(void)
cpm2_pic_init(np);
of_node_put(np);
- set_irq_chained_handler(irq, cpm2_cascade);
+ irq_set_chained_handler(irq, cpm2_cascade);
#endif
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index 458d91fba91..6299a2a51ae 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -255,7 +255,7 @@ static int mpc85xx_cds_8259_attach(void)
}
/* Success. Connect our low-level cascade handler. */
- set_irq_handler(cascade_irq, mpc85xx_8259_cascade_handler);
+ irq_set_handler(cascade_irq, mpc85xx_8259_cascade_handler);
return 0;
}
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
index 793ead7993a..c7b97f70312 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
@@ -47,7 +47,7 @@
#ifdef CONFIG_PPC_I8259
static void mpc85xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ) {
@@ -122,7 +122,7 @@ void __init mpc85xx_ds_pic_init(void)
i8259_init(cascade_node, 0);
of_node_put(cascade_node);
- set_irq_chained_handler(cascade_irq, mpc85xx_8259_cascade);
+ irq_set_chained_handler(cascade_irq, mpc85xx_8259_cascade);
#endif /* CONFIG_PPC_I8259 */
}
diff --git a/arch/powerpc/platforms/85xx/sbc8560.c b/arch/powerpc/platforms/85xx/sbc8560.c
index d7e28ec3e07..d2dfd465fbf 100644
--- a/arch/powerpc/platforms/85xx/sbc8560.c
+++ b/arch/powerpc/platforms/85xx/sbc8560.c
@@ -41,7 +41,7 @@
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
@@ -92,7 +92,7 @@ static void __init sbc8560_pic_init(void)
cpm2_pic_init(np);
of_node_put(np);
- set_irq_chained_handler(irq, cpm2_cascade);
+ irq_set_chained_handler(irq, cpm2_cascade);
#endif
}
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 79d85aca476..db864623b4a 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -93,7 +93,7 @@ static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq)
void socrates_fpga_pic_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq;
/*
@@ -245,9 +245,9 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hwirq)
{
/* All interrupts are LEVEL sensitive */
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &socrates_fpga_pic_chip,
- handle_fasteoi_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &socrates_fpga_pic_chip,
+ handle_fasteoi_irq);
return 0;
}
@@ -308,8 +308,8 @@ void socrates_fpga_pic_init(struct device_node *pic)
pr_warning("FPGA PIC: can't get irq%d.\n", i);
continue;
}
- set_irq_chained_handler(socrates_fpga_irqs[i],
- socrates_fpga_pic_cascade);
+ irq_set_chained_handler(socrates_fpga_irqs[i],
+ socrates_fpga_pic_cascade);
}
socrates_fpga_pic_iobase = of_iomap(pic, 0);
diff --git a/arch/powerpc/platforms/85xx/stx_gp3.c b/arch/powerpc/platforms/85xx/stx_gp3.c
index 2b62b064eac..5387e9f06bd 100644
--- a/arch/powerpc/platforms/85xx/stx_gp3.c
+++ b/arch/powerpc/platforms/85xx/stx_gp3.c
@@ -46,7 +46,7 @@
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
@@ -102,7 +102,7 @@ static void __init stx_gp3_pic_init(void)
cpm2_pic_init(np);
of_node_put(np);
- set_irq_chained_handler(irq, cpm2_cascade);
+ irq_set_chained_handler(irq, cpm2_cascade);
#endif
}
diff --git a/arch/powerpc/platforms/85xx/tqm85xx.c b/arch/powerpc/platforms/85xx/tqm85xx.c
index 2265b68e327..325de772725 100644
--- a/arch/powerpc/platforms/85xx/tqm85xx.c
+++ b/arch/powerpc/platforms/85xx/tqm85xx.c
@@ -44,7 +44,7 @@
static void cpm2_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
int cascade_irq;
while ((cascade_irq = cpm2_get_irq()) >= 0)
@@ -100,7 +100,7 @@ static void __init tqm85xx_pic_init(void)
cpm2_pic_init(np);
of_node_put(np);
- set_irq_chained_handler(irq, cpm2_cascade);
+ irq_set_chained_handler(irq, cpm2_cascade);
#endif
}
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 0adfe3b740c..0beec7d5566 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -95,7 +95,7 @@ static int gef_pic_cascade_irq;
void gef_pic_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq;
/*
@@ -163,8 +163,8 @@ static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hwirq)
{
/* All interrupts are LEVEL sensitive */
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &gef_pic_chip, handle_level_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &gef_pic_chip, handle_level_irq);
return 0;
}
@@ -225,7 +225,7 @@ void __init gef_pic_init(struct device_node *np)
return;
/* Chain with parent controller */
- set_irq_chained_handler(gef_pic_cascade_irq, gef_pic_cascade);
+ irq_set_chained_handler(gef_pic_cascade_irq, gef_pic_cascade);
}
/*
diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c
index cbe33639b47..8ef8960abda 100644
--- a/arch/powerpc/platforms/86xx/pic.c
+++ b/arch/powerpc/platforms/86xx/pic.c
@@ -19,7 +19,7 @@
#ifdef CONFIG_PPC_I8259
static void mpc86xx_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ)
@@ -77,6 +77,6 @@ void __init mpc86xx_init_irq(void)
i8259_init(cascade_node, 0);
of_node_put(cascade_node);
- set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade);
+ irq_set_chained_handler(cascade_irq, mpc86xx_8259_cascade);
#endif
}
diff --git a/arch/powerpc/platforms/8xx/m8xx_setup.c b/arch/powerpc/platforms/8xx/m8xx_setup.c
index fabb108e874..9ecce995dd4 100644
--- a/arch/powerpc/platforms/8xx/m8xx_setup.c
+++ b/arch/powerpc/platforms/8xx/m8xx_setup.c
@@ -226,11 +226,11 @@ static void cpm_cascade(unsigned int irq, struct irq_desc *desc)
generic_handle_irq(cascade_irq);
- chip = get_irq_desc_chip(cdesc);
+ chip = irq_desc_get_chip(cdesc);
chip->irq_eoi(&cdesc->irq_data);
}
- chip = get_irq_desc_chip(desc);
+ chip = irq_desc_get_chip(desc);
chip->irq_eoi(&desc->irq_data);
}
@@ -251,5 +251,5 @@ void __init mpc8xx_pics_init(void)
irq = cpm_pic_init();
if (irq != NO_IRQ)
- set_irq_chained_handler(irq, cpm_cascade);
+ irq_set_chained_handler(irq, cpm_cascade);
}
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 48cd7d2e1b7..81239ebed83 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -9,6 +9,7 @@ config PPC_CELL_COMMON
select PPC_INDIRECT_IO
select PPC_NATIVE
select PPC_RTAS
+ select IRQ_EDGE_EOI_HANDLER
config PPC_CELL_NATIVE
bool
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index c48b66a67e4..bb5ebf8fa80 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -93,8 +93,8 @@ static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
- struct axon_msic *msic = get_irq_data(irq);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct axon_msic *msic = irq_get_handler_data(irq);
u32 write_offset, msi;
int idx;
int retry = 0;
@@ -287,7 +287,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
}
dev_dbg(&dev->dev, "axon_msi: allocated virq 0x%x\n", virq);
- set_irq_msi(virq, entry);
+ irq_set_msi_desc(virq, entry);
msg.data = virq;
write_msi_msg(virq, &msg);
}
@@ -305,7 +305,7 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev)
if (entry->irq == NO_IRQ)
continue;
- set_irq_msi(entry->irq, NULL);
+ irq_set_msi_desc(entry->irq, NULL);
irq_dispose_mapping(entry->irq);
}
}
@@ -320,7 +320,7 @@ static struct irq_chip msic_irq_chip = {
static int msic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- set_irq_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq);
+ irq_set_chip_and_handler(virq, &msic_irq_chip, handle_simple_irq);
return 0;
}
@@ -400,8 +400,8 @@ static int axon_msi_probe(struct platform_device *device)
msic->irq_host->host_data = msic;
- set_irq_data(virq, msic);
- set_irq_chained_handler(virq, axon_msi_cascade);
+ irq_set_handler_data(virq, msic);
+ irq_set_chained_handler(virq, axon_msi_cascade);
pr_devel("axon_msi: irq 0x%x setup for axon_msi\n", virq);
/* Enable the MSIC hardware */
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 0b8f7d7135c..4cb9e147c30 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -136,15 +136,14 @@ static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- struct irq_desc *desc = irq_to_desc(virq);
int64_t err;
err = beat_construct_and_connect_irq_plug(virq, hw);
if (err < 0)
return -EIO;
- desc->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &beatic_pic, handle_fasteoi_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &beatic_pic, handle_fasteoi_irq);
return 0;
}
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 624d26e72f1..44cfd1bef89 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -101,9 +101,9 @@ static void iic_ioexc_eoi(struct irq_data *d)
static void iic_ioexc_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
struct cbe_iic_regs __iomem *node_iic =
- (void __iomem *)get_irq_desc_data(desc);
+ (void __iomem *)irq_desc_get_handler_data(desc);
unsigned int base = (irq & 0xffffff00) | IIC_IRQ_TYPE_IOEXC;
unsigned long bits, ack;
int cascade;
@@ -235,67 +235,19 @@ static int iic_host_match(struct irq_host *h, struct device_node *node)
"IBM,CBEA-Internal-Interrupt-Controller");
}
-extern int noirqdebug;
-
-static void handle_iic_irq(unsigned int irq, struct irq_desc *desc)
-{
- struct irq_chip *chip = get_irq_desc_chip(desc);
-
- raw_spin_lock(&desc->lock);
-
- desc->status &= ~(IRQ_REPLAY | IRQ_WAITING);
-
- /*
- * If we're currently running this IRQ, or its disabled,
- * we shouldn't process the IRQ. Mark it pending, handle
- * the necessary masking and go out
- */
- if (unlikely((desc->status & (IRQ_INPROGRESS | IRQ_DISABLED)) ||
- !desc->action)) {
- desc->status |= IRQ_PENDING;
- goto out_eoi;
- }
-
- kstat_incr_irqs_this_cpu(irq, desc);
-
- /* Mark the IRQ currently in progress.*/
- desc->status |= IRQ_INPROGRESS;
-
- do {
- struct irqaction *action = desc->action;
- irqreturn_t action_ret;
-
- if (unlikely(!action))
- goto out_eoi;
-
- desc->status &= ~IRQ_PENDING;
- raw_spin_unlock(&desc->lock);
- action_ret = handle_IRQ_event(irq, action);
- if (!noirqdebug)
- note_interrupt(irq, desc, action_ret);
- raw_spin_lock(&desc->lock);
-
- } while ((desc->status & (IRQ_PENDING | IRQ_DISABLED)) == IRQ_PENDING);
-
- desc->status &= ~IRQ_INPROGRESS;
-out_eoi:
- chip->irq_eoi(&desc->irq_data);
- raw_spin_unlock(&desc->lock);
-}
-
static int iic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
switch (hw & IIC_IRQ_TYPE_MASK) {
case IIC_IRQ_TYPE_IPI:
- set_irq_chip_and_handler(virq, &iic_chip, handle_percpu_irq);
+ irq_set_chip_and_handler(virq, &iic_chip, handle_percpu_irq);
break;
case IIC_IRQ_TYPE_IOEXC:
- set_irq_chip_and_handler(virq, &iic_ioexc_chip,
- handle_iic_irq);
+ irq_set_chip_and_handler(virq, &iic_ioexc_chip,
+ handle_edge_eoi_irq);
break;
default:
- set_irq_chip_and_handler(virq, &iic_chip, handle_iic_irq);
+ irq_set_chip_and_handler(virq, &iic_chip, handle_edge_eoi_irq);
}
return 0;
}
@@ -412,8 +364,8 @@ static int __init setup_iic(void)
* irq_data is a generic pointer that gets passed back
* to us later, so the forced cast is fine.
*/
- set_irq_data(cascade, (void __force *)node_iic);
- set_irq_chained_handler(cascade , iic_ioexc_cascade);
+ irq_set_handler_data(cascade, (void __force *)node_iic);
+ irq_set_chained_handler(cascade, iic_ioexc_cascade);
out_be64(&node_iic->iic_ir,
(1 << 12) /* priority */ |
(node << 4) /* dest node */ |
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 6a28d027d95..fd57bfe00ed 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -187,8 +187,8 @@ machine_subsys_initcall(cell, cell_publish_devices);
static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
- struct mpic *mpic = get_irq_desc_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct mpic *mpic = irq_desc_get_handler_data(desc);
unsigned int virq;
virq = mpic_get_one_irq(mpic);
@@ -223,8 +223,8 @@ static void __init mpic_init_IRQ(void)
printk(KERN_INFO "%s : hooking up to IRQ %d\n",
dn->full_name, virq);
- set_irq_data(virq, mpic);
- set_irq_chained_handler(virq, cell_mpic_cascade);
+ irq_set_handler_data(virq, mpic);
+ irq_set_chained_handler(virq, cell_mpic_cascade);
}
}
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index b38cdfc1deb..c5cf50e6b45 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -102,7 +102,7 @@ static void spider_ack_irq(struct irq_data *d)
/* Reset edge detection logic if necessary
*/
- if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
+ if (irqd_is_level_type(d))
return;
/* Only interrupts 47 to 50 can be set to edge */
@@ -119,7 +119,6 @@ static int spider_set_irq_type(struct irq_data *d, unsigned int type)
struct spider_pic *pic = spider_virq_to_pic(d->irq);
unsigned int hw = irq_map[d->irq].hwirq;
void __iomem *cfg = spider_get_irq_config(pic, hw);
- struct irq_desc *desc = irq_to_desc(d->irq);
u32 old_mask;
u32 ic;
@@ -147,12 +146,6 @@ static int spider_set_irq_type(struct irq_data *d, unsigned int type)
return -EINVAL;
}
- /* Update irq_desc */
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= type & IRQ_TYPE_SENSE_MASK;
- if (type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
- desc->status |= IRQ_LEVEL;
-
/* Configure the source. One gross hack that was there before and
* that I've kept around is the priority to the BE which I set to
* be the same as the interrupt source number. I don't know wether
@@ -178,10 +171,10 @@ static struct irq_chip spider_pic = {
static int spider_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- set_irq_chip_and_handler(virq, &spider_pic, handle_level_irq);
+ irq_set_chip_and_handler(virq, &spider_pic, handle_level_irq);
/* Set default irq type */
- set_irq_type(virq, IRQ_TYPE_NONE);
+ irq_set_irq_type(virq, IRQ_TYPE_NONE);
return 0;
}
@@ -207,8 +200,8 @@ static struct irq_host_ops spider_host_ops = {
static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
- struct spider_pic *pic = get_irq_desc_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct spider_pic *pic = irq_desc_get_handler_data(desc);
unsigned int cs, virq;
cs = in_be32(pic->regs + TIR_CS) >> 24;
@@ -328,8 +321,8 @@ static void __init spider_init_one(struct device_node *of_node, int chip,
virq = spider_find_cascade_and_node(pic);
if (virq == NO_IRQ)
return;
- set_irq_data(virq, pic);
- set_irq_chained_handler(virq, spider_irq_cascade);
+ irq_set_handler_data(virq, pic);
+ irq_set_chained_handler(virq, spider_irq_cascade);
printk(KERN_INFO "spider_pic: node %d, addr: 0x%lx %s\n",
pic->node_id, addr, of_node->full_name);
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 4c1288451a2..12278649841 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -365,7 +365,7 @@ void __init chrp_setup_arch(void)
static void chrp_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ)
@@ -517,7 +517,7 @@ static void __init chrp_find_8259(void)
if (cascade_irq == NO_IRQ)
printk(KERN_ERR "i8259: failed to map cascade irq\n");
else
- set_irq_chained_handler(cascade_irq,
+ irq_set_chained_handler(cascade_irq,
chrp_8259_cascade);
}
}
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index 0aca0e28a8e..12aa62b6f22 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -101,16 +101,16 @@ static struct irq_host *flipper_irq_host;
static int flipper_pic_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hwirq)
{
- set_irq_chip_data(virq, h->host_data);
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &flipper_pic, handle_level_irq);
+ irq_set_chip_data(virq, h->host_data);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &flipper_pic, handle_level_irq);
return 0;
}
static void flipper_pic_unmap(struct irq_host *h, unsigned int irq)
{
- set_irq_chip_data(irq, NULL);
- set_irq_chip(irq, NULL);
+ irq_set_chip_data(irq, NULL);
+ irq_set_chip(irq, NULL);
}
static int flipper_pic_match(struct irq_host *h, struct device_node *np)
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index 35e448bd847..2bdddfc9d52 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -94,16 +94,16 @@ static struct irq_host *hlwd_irq_host;
static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hwirq)
{
- set_irq_chip_data(virq, h->host_data);
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &hlwd_pic, handle_level_irq);
+ irq_set_chip_data(virq, h->host_data);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &hlwd_pic, handle_level_irq);
return 0;
}
static void hlwd_pic_unmap(struct irq_host *h, unsigned int irq)
{
- set_irq_chip_data(irq, NULL);
- set_irq_chip(irq, NULL);
+ irq_set_chip_data(irq, NULL);
+ irq_set_chip(irq, NULL);
}
static struct irq_host_ops hlwd_irq_host_ops = {
@@ -129,8 +129,8 @@ static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
- struct irq_host *irq_host = get_irq_data(cascade_virq);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct irq_host *irq_host = irq_get_handler_data(cascade_virq);
unsigned int virq;
raw_spin_lock(&desc->lock);
@@ -145,7 +145,7 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
raw_spin_lock(&desc->lock);
chip->irq_ack(&desc->irq_data); /* IRQ_LEVEL */
- if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
+ if (!irqd_irq_disabled(&desc->irq_data) && chip->irq_unmask)
chip->irq_unmask(&desc->irq_data);
raw_spin_unlock(&desc->lock);
}
@@ -218,8 +218,8 @@ void hlwd_pic_probe(void)
host = hlwd_pic_init(np);
BUG_ON(!host);
cascade_virq = irq_of_parse_and_map(np, 0);
- set_irq_data(cascade_virq, host);
- set_irq_chained_handler(cascade_virq,
+ irq_set_handler_data(cascade_virq, host);
+ irq_set_chained_handler(cascade_virq,
hlwd_pic_irq_cascade);
hlwd_irq_host = host;
break;
diff --git a/arch/powerpc/platforms/embedded6xx/holly.c b/arch/powerpc/platforms/embedded6xx/holly.c
index b21fde589ca..487bda0d18d 100644
--- a/arch/powerpc/platforms/embedded6xx/holly.c
+++ b/arch/powerpc/platforms/embedded6xx/holly.c
@@ -198,8 +198,8 @@ static void __init holly_init_IRQ(void)
cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
pr_debug("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__, (u32) cascade_pci_irq);
tsi108_pci_int_init(cascade_node);
- set_irq_data(cascade_pci_irq, mpic);
- set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+ irq_set_handler_data(cascade_pci_irq, mpic);
+ irq_set_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
#endif
/* Configure MPIC outputs to CPU0 */
tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index 7a2ba39d781..1cb907c9435 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -153,8 +153,8 @@ static void __init mpc7448_hpc2_init_IRQ(void)
DBG("%s: tsi108 cascade_pci_irq = 0x%x\n", __func__,
(u32) cascade_pci_irq);
tsi108_pci_int_init(cascade_node);
- set_irq_data(cascade_pci_irq, mpic);
- set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
+ irq_set_handler_data(cascade_pci_irq, mpic);
+ irq_set_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
#endif
/* Configure MPIC outputs to CPU0 */
tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 4fb96f0b2df..52a6889832c 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -220,7 +220,7 @@ void __init iSeries_activate_IRQs()
if (!desc)
continue;
- chip = get_irq_desc_chip(desc);
+ chip = irq_desc_get_chip(desc);
if (chip && chip->irq_startup) {
raw_spin_lock_irqsave(&desc->lock, flags);
chip->irq_startup(&desc->irq_data);
@@ -346,7 +346,7 @@ unsigned int iSeries_get_irq(void)
static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- set_irq_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
+ irq_set_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
return 0;
}
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 04296ffff8b..dd2e48b2850 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -498,7 +498,7 @@ void __devinit maple_pci_irq_fixup(struct pci_dev *dev)
printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
dev->irq = irq_create_mapping(NULL, 1);
if (dev->irq != NO_IRQ)
- set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
}
/* Hide AMD8111 IDE interrupt when in legacy mode so
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index a6067b38d2c..7c858e6f843 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -239,7 +239,7 @@ static __init void pas_init_IRQ(void)
if (nmiprop) {
nmi_virq = irq_create_mapping(NULL, *nmiprop);
mpic_irq_set_priority(nmi_virq, 15);
- set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(nmi_virq, IRQ_TYPE_EDGE_RISING);
mpic_unmask_irq(irq_get_irq_data(nmi_virq));
}
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 3bc075c788e..ab689894270 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -988,7 +988,7 @@ void __devinit pmac_pci_irq_fixup(struct pci_dev *dev)
dev->vendor == PCI_VENDOR_ID_DEC &&
dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
dev->irq = irq_create_mapping(NULL, 60);
- set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
}
#endif /* CONFIG_PPC32 */
}
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index c55812bb6a5..023f24086a0 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -157,7 +157,7 @@ static unsigned int pmac_startup_irq(struct irq_data *d)
int i = src >> 5;
raw_spin_lock_irqsave(&pmac_pic_lock, flags);
- if ((irq_to_desc(d->irq)->status & IRQ_LEVEL) == 0)
+ if (!irqd_is_level_type(d))
out_le32(&pmac_irq_hw[i]->ack, bit);
__set_bit(src, ppc_cached_irq_mask);
__pmac_set_irq_mask(src, 0);
@@ -289,7 +289,6 @@ static int pmac_pic_host_match(struct irq_host *h, struct device_node *node)
static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t hw)
{
- struct irq_desc *desc = irq_to_desc(virq);
int level;
if (hw >= max_irqs)
@@ -300,9 +299,9 @@ static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
*/
level = !!(level_mask[hw >> 5] & (1UL << (hw & 0x1f)));
if (level)
- desc->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &pmac_pic, level ?
- handle_level_irq : handle_edge_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &pmac_pic,
+ level ? handle_level_irq : handle_edge_irq);
return 0;
}
@@ -472,8 +471,8 @@ int of_irq_map_oldworld(struct device_node *device, int index,
static void pmac_u3_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
- struct mpic *mpic = get_irq_desc_data(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct mpic *mpic = irq_desc_get_handler_data(desc);
unsigned int cascade_irq = mpic_get_one_irq(mpic);
if (cascade_irq != NO_IRQ)
@@ -591,8 +590,8 @@ static int __init pmac_pic_probe_mpic(void)
of_node_put(slave);
return 0;
}
- set_irq_data(cascade, mpic2);
- set_irq_chained_handler(cascade, pmac_u3_cascade);
+ irq_set_handler_data(cascade, mpic2);
+ irq_set_chained_handler(cascade, pmac_u3_cascade);
of_node_put(slave);
return 0;
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index f0bc08f6c1f..20468f49aec 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -33,7 +33,6 @@ extern void pmac_setup_pci_dma(void);
extern void pmac_check_ht_link(void);
extern void pmac_setup_smp(void);
-extern void pmac32_cpu_die(void);
extern void low_cpu_die(void) __attribute__((noreturn));
extern int pmac_nvram_init(void);
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index d5aceb7fb12..aa45281bd29 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -650,51 +650,6 @@ static int pmac_pci_probe_mode(struct pci_bus *bus)
return PCI_PROBE_NORMAL;
return PCI_PROBE_DEVTREE;
}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/* access per cpu vars from generic smp.c */
-DECLARE_PER_CPU(int, cpu_state);
-
-static void pmac64_cpu_die(void)
-{
- /*
- * turn off as much as possible, we'll be
- * kicked out as this will only be invoked
- * on core99 platforms for now ...
- */
-
- printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
- __get_cpu_var(cpu_state) = CPU_DEAD;
- smp_wmb();
-
- /*
- * during the path that leads here preemption is disabled,
- * reenable it now so that when coming up preempt count is
- * zero correctly
- */
- preempt_enable();
-
- /*
- * hard-disable interrupts for the non-NAP case, the NAP code
- * needs to re-enable interrupts (but soft-disables them)
- */
- hard_irq_disable();
-
- while (1) {
- /* let's not take timer interrupts too often ... */
- set_dec(0x7fffffff);
-
- /* should always be true at this point */
- if (cpu_has_feature(CPU_FTR_CAN_NAP))
- power4_cpu_offline_powersave();
- else {
- HMT_low();
- HMT_very_low();
- }
- }
-}
-#endif /* CONFIG_HOTPLUG_CPU */
-
#endif /* CONFIG_PPC64 */
define_machine(powermac) {
@@ -726,15 +681,4 @@ define_machine(powermac) {
.pcibios_after_init = pmac_pcibios_after_init,
.phys_mem_access_prot = pci_phys_mem_access_prot,
#endif
-#ifdef CONFIG_HOTPLUG_CPU
-#ifdef CONFIG_PPC64
- .cpu_die = pmac64_cpu_die,
-#endif
-#ifdef CONFIG_PPC32
- .cpu_die = pmac32_cpu_die,
-#endif
-#endif
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
- .cpu_die = generic_mach_cpu_die,
-#endif
};
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index c95215f4f8b..a830c5e8065 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -840,92 +840,149 @@ static void __devinit smp_core99_setup_cpu(int cpu_nr)
/* Setup openpic */
mpic_setup_this_cpu();
+}
- if (cpu_nr == 0) {
-#ifdef CONFIG_PPC64
- extern void g5_phy_disable_cpu1(void);
+#ifdef CONFIG_HOTPLUG_CPU
+static int smp_core99_cpu_notify(struct notifier_block *self,
+ unsigned long action, void *hcpu)
+{
+ int rc;
- /* Close i2c bus if it was used for tb sync */
+ switch(action) {
+ case CPU_UP_PREPARE:
+ case CPU_UP_PREPARE_FROZEN:
+ /* Open i2c bus if it was used for tb sync */
if (pmac_tb_clock_chip_host) {
- pmac_i2c_close(pmac_tb_clock_chip_host);
- pmac_tb_clock_chip_host = NULL;
+ rc = pmac_i2c_open(pmac_tb_clock_chip_host, 1);
+ if (rc) {
+ pr_err("Failed to open i2c bus for time sync\n");
+ return notifier_from_errno(rc);
+ }
}
+ break;
+ case CPU_ONLINE:
+ case CPU_UP_CANCELED:
+ /* Close i2c bus if it was used for tb sync */
+ if (pmac_tb_clock_chip_host)
+ pmac_i2c_close(pmac_tb_clock_chip_host);
+ break;
+ default:
+ break;
+ }
+ return NOTIFY_OK;
+}
- /* If we didn't start the second CPU, we must take
- * it off the bus
- */
- if (of_machine_is_compatible("MacRISC4") &&
- num_online_cpus() < 2)
- g5_phy_disable_cpu1();
-#endif /* CONFIG_PPC64 */
+static struct notifier_block __cpuinitdata smp_core99_cpu_nb = {
+ .notifier_call = smp_core99_cpu_notify,
+};
+#endif /* CONFIG_HOTPLUG_CPU */
+
+static void __init smp_core99_bringup_done(void)
+{
+#ifdef CONFIG_PPC64
+ extern void g5_phy_disable_cpu1(void);
+
+ /* Close i2c bus if it was used for tb sync */
+ if (pmac_tb_clock_chip_host)
+ pmac_i2c_close(pmac_tb_clock_chip_host);
- if (ppc_md.progress)
- ppc_md.progress("core99_setup_cpu 0 done", 0x349);
+ /* If we didn't start the second CPU, we must take
+ * it off the bus.
+ */
+ if (of_machine_is_compatible("MacRISC4") &&
+ num_online_cpus() < 2) {
+ set_cpu_present(1, false);
+ g5_phy_disable_cpu1();
}
-}
+#endif /* CONFIG_PPC64 */
+#ifdef CONFIG_HOTPLUG_CPU
+ register_cpu_notifier(&smp_core99_cpu_nb);
+#endif
+ if (ppc_md.progress)
+ ppc_md.progress("smp_core99_bringup_done", 0x349);
+}
-#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC32)
+#ifdef CONFIG_HOTPLUG_CPU
-int smp_core99_cpu_disable(void)
+static int smp_core99_cpu_disable(void)
{
- set_cpu_online(smp_processor_id(), false);
+ int rc = generic_cpu_disable();
+ if (rc)
+ return rc;
- /* XXX reset cpu affinity here */
mpic_cpu_set_priority(0xf);
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
- mb();
- udelay(20);
- asm volatile("mtdec %0" : : "r" (0x7fffffff));
+
return 0;
}
-static int cpu_dead[NR_CPUS];
+#ifdef CONFIG_PPC32
-void pmac32_cpu_die(void)
+static void pmac_cpu_die(void)
{
+ int cpu = smp_processor_id();
+
local_irq_disable();
- cpu_dead[smp_processor_id()] = 1;
+ idle_task_exit();
+ pr_debug("CPU%d offline\n", cpu);
+ generic_set_cpu_dead(cpu);
+ smp_wmb();
mb();
low_cpu_die();
}
-void smp_core99_cpu_die(unsigned int cpu)
+#else /* CONFIG_PPC32 */
+
+static void pmac_cpu_die(void)
{
- int timeout;
+ int cpu = smp_processor_id();
- timeout = 1000;
- while (!cpu_dead[cpu]) {
- if (--timeout == 0) {
- printk("CPU %u refused to die!\n", cpu);
- break;
- }
- msleep(1);
+ local_irq_disable();
+ idle_task_exit();
+
+ /*
+ * turn off as much as possible, we'll be
+ * kicked out as this will only be invoked
+ * on core99 platforms for now ...
+ */
+
+ printk(KERN_INFO "CPU#%d offline\n", cpu);
+ generic_set_cpu_dead(cpu);
+ smp_wmb();
+
+ /*
+ * Re-enable interrupts. The NAP code needs to enable them
+ * anyways, do it now so we deal with the case where one already
+ * happened while soft-disabled.
+ * We shouldn't get any external interrupts, only decrementer, and the
+ * decrementer handler is safe for use on offline CPUs
+ */
+ local_irq_enable();
+
+ while (1) {
+ /* let's not take timer interrupts too often ... */
+ set_dec(0x7fffffff);
+
+ /* Enter NAP mode */
+ power4_idle();
}
- cpu_dead[cpu] = 0;
}
-#endif /* CONFIG_HOTPLUG_CPU && CONFIG_PP32 */
+#endif /* else CONFIG_PPC32 */
+#endif /* CONFIG_HOTPLUG_CPU */
/* Core99 Macs (dual G4s and G5s) */
struct smp_ops_t core99_smp_ops = {
.message_pass = smp_mpic_message_pass,
.probe = smp_core99_probe,
+ .bringup_done = smp_core99_bringup_done,
.kick_cpu = smp_core99_kick_cpu,
.setup_cpu = smp_core99_setup_cpu,
.give_timebase = smp_core99_give_timebase,
.take_timebase = smp_core99_take_timebase,
#if defined(CONFIG_HOTPLUG_CPU)
-# if defined(CONFIG_PPC32)
.cpu_disable = smp_core99_cpu_disable,
- .cpu_die = smp_core99_cpu_die,
-# endif
-# if defined(CONFIG_PPC64)
- .cpu_disable = generic_cpu_disable,
.cpu_die = generic_cpu_die,
- /* intentionally do *NOT* assign cpu_enable,
- * the generic code will use kick_cpu then! */
-# endif
#endif
};
@@ -957,5 +1014,10 @@ void __init pmac_setup_smp(void)
smp_ops = &psurge_smp_ops;
}
#endif /* CONFIG_PPC32 */
+
+#ifdef CONFIG_HOTPLUG_CPU
+ ppc_md.cpu_die = pmac_cpu_die;
+#endif
}
+
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 3988c86682a..f2f6413b81d 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -194,7 +194,7 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
outlet, cpu, *virq);
- result = set_irq_chip_data(*virq, pd);
+ result = irq_set_chip_data(*virq, pd);
if (result) {
pr_debug("%s:%d: set_irq_chip_data failed\n",
@@ -221,12 +221,12 @@ fail_create:
static int ps3_virq_destroy(unsigned int virq)
{
- const struct ps3_private *pd = get_irq_chip_data(virq);
+ const struct ps3_private *pd = irq_get_chip_data(virq);
pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__,
__LINE__, pd->ppe_id, pd->thread_id, virq);
- set_irq_chip_data(virq, NULL);
+ irq_set_chip_data(virq, NULL);
irq_dispose_mapping(virq);
pr_debug("%s:%d <-\n", __func__, __LINE__);
@@ -256,7 +256,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
goto fail_setup;
}
- pd = get_irq_chip_data(*virq);
+ pd = irq_get_chip_data(*virq);
/* Binds outlet to cpu + virq. */
@@ -291,7 +291,7 @@ EXPORT_SYMBOL_GPL(ps3_irq_plug_setup);
int ps3_irq_plug_destroy(unsigned int virq)
{
int result;
- const struct ps3_private *pd = get_irq_chip_data(virq);
+ const struct ps3_private *pd = irq_get_chip_data(virq);
pr_debug("%s:%d: ppe_id %llu, thread_id %llu, virq %u\n", __func__,
__LINE__, pd->ppe_id, pd->thread_id, virq);
@@ -661,7 +661,7 @@ static void dump_bmp(struct ps3_private* pd) {};
static void ps3_host_unmap(struct irq_host *h, unsigned int virq)
{
- set_irq_chip_data(virq, NULL);
+ irq_set_chip_data(virq, NULL);
}
static int ps3_host_map(struct irq_host *h, unsigned int virq,
@@ -670,7 +670,7 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
pr_debug("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
virq);
- set_irq_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
+ irq_set_chip_and_handler(virq, &ps3_irq_chip, handle_fasteoi_irq);
return 0;
}
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index 18ac801f8e9..38d24e7e7bb 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -137,7 +137,7 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev)
if (entry->irq == NO_IRQ)
continue;
- set_irq_msi(entry->irq, NULL);
+ irq_set_msi_desc(entry->irq, NULL);
irq_dispose_mapping(entry->irq);
}
@@ -437,7 +437,7 @@ static int rtas_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
}
dev_dbg(&pdev->dev, "rtas_msi: allocated virq %d\n", virq);
- set_irq_msi(virq, entry);
+ irq_set_msi_desc(virq, entry);
/* Read config space back so we can restore after reset */
read_msi_msg(virq, &msg);
diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c
index 419707b0724..00cc3a09488 100644
--- a/arch/powerpc/platforms/pseries/nvram.c
+++ b/arch/powerpc/platforms/pseries/nvram.c
@@ -480,8 +480,32 @@ static void oops_to_nvram(struct kmsg_dumper *dumper,
const char *new_msgs, unsigned long new_len)
{
static unsigned int oops_count = 0;
+ static bool panicking = false;
size_t text_len;
+ switch (reason) {
+ case KMSG_DUMP_RESTART:
+ case KMSG_DUMP_HALT:
+ case KMSG_DUMP_POWEROFF:
+ /* These are almost always orderly shutdowns. */
+ return;
+ case KMSG_DUMP_OOPS:
+ case KMSG_DUMP_KEXEC:
+ break;
+ case KMSG_DUMP_PANIC:
+ panicking = true;
+ break;
+ case KMSG_DUMP_EMERG:
+ if (panicking)
+ /* Panic report already captured. */
+ return;
+ break;
+ default:
+ pr_err("%s: ignoring unrecognized KMSG_DUMP_* reason %d\n",
+ __FUNCTION__, (int) reason);
+ return;
+ }
+
if (clobbering_unread_rtas_event())
return;
diff --git a/arch/powerpc/platforms/pseries/offline_states.h b/arch/powerpc/platforms/pseries/offline_states.h
index 75a6f480d93..08672d9136a 100644
--- a/arch/powerpc/platforms/pseries/offline_states.h
+++ b/arch/powerpc/platforms/pseries/offline_states.h
@@ -34,6 +34,4 @@ static inline void set_default_offline_state(int cpu)
#endif
extern enum cpu_state_vals get_preferred_offline_state(int cpu);
-extern int start_secondary(void);
-extern void start_secondary_resume(void);
#endif
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 2a0089a2c82..c319d04aa79 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -114,7 +114,7 @@ static void __init fwnmi_init(void)
static void pseries_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq != NO_IRQ)
@@ -169,7 +169,7 @@ static void __init pseries_setup_i8259_cascade(void)
printk(KERN_DEBUG "pic: PCI 8259 intack at 0x%016lx\n", intack);
i8259_init(found, intack);
of_node_put(found);
- set_irq_chained_handler(cascade, pseries_8259_cascade);
+ irq_set_chained_handler(cascade, pseries_8259_cascade);
}
static void __init pseries_mpic_init_IRQ(void)
diff --git a/arch/powerpc/platforms/pseries/smp.c b/arch/powerpc/platforms/pseries/smp.c
index 0317cce877c..d6479f9738f 100644
--- a/arch/powerpc/platforms/pseries/smp.c
+++ b/arch/powerpc/platforms/pseries/smp.c
@@ -64,8 +64,8 @@ int smp_query_cpu_stopped(unsigned int pcpu)
int qcss_tok = rtas_token("query-cpu-stopped-state");
if (qcss_tok == RTAS_UNKNOWN_SERVICE) {
- printk(KERN_INFO "Firmware doesn't support "
- "query-cpu-stopped-state\n");
+ printk_once(KERN_INFO
+ "Firmware doesn't support query-cpu-stopped-state\n");
return QCSS_HARDWARE_ERROR;
}
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 01fea46c033..ec8fe22047b 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -204,33 +204,33 @@ static int get_irq_server(unsigned int virq, const struct cpumask *cpumask,
static void xics_unmask_irq(struct irq_data *d)
{
- unsigned int irq;
+ unsigned int hwirq;
int call_status;
int server;
pr_devel("xics: unmask virq %d\n", d->irq);
- irq = (unsigned int)irq_map[d->irq].hwirq;
- pr_devel(" -> map to hwirq 0x%x\n", irq);
- if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+ hwirq = (unsigned int)irq_map[d->irq].hwirq;
+ pr_devel(" -> map to hwirq 0x%x\n", hwirq);
+ if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
return;
server = get_irq_server(d->irq, d->affinity, 0);
- call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
+ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq, server,
DEFAULT_PRIORITY);
if (call_status != 0) {
printk(KERN_ERR
"%s: ibm_set_xive irq %u server %x returned %d\n",
- __func__, irq, server, call_status);
+ __func__, hwirq, server, call_status);
return;
}
/* Now unmask the interrupt (often a no-op) */
- call_status = rtas_call(ibm_int_on, 1, 1, NULL, irq);
+ call_status = rtas_call(ibm_int_on, 1, 1, NULL, hwirq);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_int_on irq=%u returned %d\n",
- __func__, irq, call_status);
+ __func__, hwirq, call_status);
return;
}
}
@@ -250,46 +250,46 @@ static unsigned int xics_startup(struct irq_data *d)
return 0;
}
-static void xics_mask_real_irq(struct irq_data *d)
+static void xics_mask_real_irq(unsigned int hwirq)
{
int call_status;
- if (d->irq == XICS_IPI)
+ if (hwirq == XICS_IPI)
return;
- call_status = rtas_call(ibm_int_off, 1, 1, NULL, d->irq);
+ call_status = rtas_call(ibm_int_off, 1, 1, NULL, hwirq);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_int_off irq=%u returned %d\n",
- __func__, d->irq, call_status);
+ __func__, hwirq, call_status);
return;
}
/* Have to set XIVE to 0xff to be able to remove a slot */
- call_status = rtas_call(ibm_set_xive, 3, 1, NULL, d->irq,
+ call_status = rtas_call(ibm_set_xive, 3, 1, NULL, hwirq,
default_server, 0xff);
if (call_status != 0) {
printk(KERN_ERR "%s: ibm_set_xive(0xff) irq=%u returned %d\n",
- __func__, d->irq, call_status);
+ __func__, hwirq, call_status);
return;
}
}
static void xics_mask_irq(struct irq_data *d)
{
- unsigned int irq;
+ unsigned int hwirq;
pr_devel("xics: mask virq %d\n", d->irq);
- irq = (unsigned int)irq_map[d->irq].hwirq;
- if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+ hwirq = (unsigned int)irq_map[d->irq].hwirq;
+ if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
return;
- xics_mask_real_irq(d);
+ xics_mask_real_irq(hwirq);
}
static void xics_mask_unknown_vec(unsigned int vec)
{
printk(KERN_ERR "Interrupt %u (real) is invalid, disabling it.\n", vec);
- xics_mask_real_irq(irq_get_irq_data(vec));
+ xics_mask_real_irq(vec);
}
static inline unsigned int xics_xirr_vector(unsigned int xirr)
@@ -373,37 +373,37 @@ static unsigned char pop_cppr(void)
static void xics_eoi_direct(struct irq_data *d)
{
- unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
+ unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq;
iosync();
- direct_xirr_info_set((pop_cppr() << 24) | irq);
+ direct_xirr_info_set((pop_cppr() << 24) | hwirq);
}
static void xics_eoi_lpar(struct irq_data *d)
{
- unsigned int irq = (unsigned int)irq_map[d->irq].hwirq;
+ unsigned int hwirq = (unsigned int)irq_map[d->irq].hwirq;
iosync();
- lpar_xirr_info_set((pop_cppr() << 24) | irq);
+ lpar_xirr_info_set((pop_cppr() << 24) | hwirq);
}
static int
xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
{
- unsigned int irq;
+ unsigned int hwirq;
int status;
int xics_status[2];
int irq_server;
- irq = (unsigned int)irq_map[d->irq].hwirq;
- if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+ hwirq = (unsigned int)irq_map[d->irq].hwirq;
+ if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
return -1;
- status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
+ status = rtas_call(ibm_get_xive, 1, 3, xics_status, hwirq);
if (status) {
printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
- __func__, irq, status);
+ __func__, hwirq, status);
return -1;
}
@@ -418,11 +418,11 @@ xics_set_affinity(struct irq_data *d, const struct cpumask *cpumask, bool force)
}
status = rtas_call(ibm_set_xive, 3, 1, NULL,
- irq, irq_server, xics_status[1]);
+ hwirq, irq_server, xics_status[1]);
if (status) {
printk(KERN_ERR "%s: ibm,set-xive irq=%u returns %d\n",
- __func__, irq, status);
+ __func__, hwirq, status);
return -1;
}
@@ -470,8 +470,8 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
/* Insert the interrupt mapping into the radix tree for fast lookup */
irq_radix_revmap_insert(xics_host, virq, hw);
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, xics_irq_chip, handle_fasteoi_irq);
return 0;
}
@@ -600,7 +600,7 @@ static void xics_request_ipi(void)
* IPIs are marked IRQF_DISABLED as they must run with irqs
* disabled
*/
- set_irq_handler(ipi, handle_percpu_irq);
+ irq_set_handler(ipi, handle_percpu_irq);
if (firmware_has_feature(FW_FEATURE_LPAR))
rc = request_irq(ipi, xics_ipi_action_lpar,
IRQF_DISABLED|IRQF_PERCPU, "IPI", NULL);
@@ -874,7 +874,7 @@ void xics_kexec_teardown_cpu(int secondary)
void xics_migrate_irqs_away(void)
{
int cpu = smp_processor_id(), hw_cpu = hard_smp_processor_id();
- unsigned int irq, virq;
+ int virq;
/* If we used to be the default server, move to the new "boot_cpuid" */
if (hw_cpu == default_server)
@@ -892,6 +892,7 @@ void xics_migrate_irqs_away(void)
for_each_irq(virq) {
struct irq_desc *desc;
struct irq_chip *chip;
+ unsigned int hwirq;
int xics_status[2];
int status;
unsigned long flags;
@@ -901,9 +902,9 @@ void xics_migrate_irqs_away(void)
continue;
if (irq_map[virq].host != xics_host)
continue;
- irq = (unsigned int)irq_map[virq].hwirq;
+ hwirq = (unsigned int)irq_map[virq].hwirq;
/* We need to get IPIs still. */
- if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+ if (hwirq == XICS_IPI || hwirq == XICS_IRQ_SPURIOUS)
continue;
desc = irq_to_desc(virq);
@@ -912,16 +913,16 @@ void xics_migrate_irqs_away(void)
if (desc == NULL || desc->action == NULL)
continue;
- chip = get_irq_desc_chip(desc);
+ chip = irq_desc_get_chip(desc);
if (chip == NULL || chip->irq_set_affinity == NULL)
continue;
raw_spin_lock_irqsave(&desc->lock, flags);
- status = rtas_call(ibm_get_xive, 1, 3, xics_status, irq);
+ status = rtas_call(ibm_get_xive, 1, 3, xics_status, hwirq);
if (status) {
printk(KERN_ERR "%s: ibm,get-xive irq=%u returns %d\n",
- __func__, irq, status);
+ __func__, hwirq, status);
goto unlock;
}
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 0476bcc7c3e..8b5aba26332 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -103,8 +103,8 @@ static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
{
pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq);
return 0;
}
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index 47303255671..5495c1be472 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -115,32 +115,25 @@ static void cpm2_ack(struct irq_data *d)
static void cpm2_end_irq(struct irq_data *d)
{
- struct irq_desc *desc;
int bit, word;
unsigned int irq_nr = virq_to_hw(d->irq);
- desc = irq_to_desc(irq_nr);
- if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS))
- && desc->action) {
-
- bit = irq_to_siubit[irq_nr];
- word = irq_to_siureg[irq_nr];
+ bit = irq_to_siubit[irq_nr];
+ word = irq_to_siureg[irq_nr];
- ppc_cached_irq_mask[word] |= 1 << bit;
- out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
+ ppc_cached_irq_mask[word] |= 1 << bit;
+ out_be32(&cpm2_intctl->ic_simrh + word, ppc_cached_irq_mask[word]);
- /*
- * Work around large numbers of spurious IRQs on PowerPC 82xx
- * systems.
- */
- mb();
- }
+ /*
+ * Work around large numbers of spurious IRQs on PowerPC 82xx
+ * systems.
+ */
+ mb();
}
static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
unsigned int src = virq_to_hw(d->irq);
- struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vold, vnew, edibit;
/* Port C interrupts are either IRQ_TYPE_EDGE_FALLING or
@@ -162,13 +155,11 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
goto err_sense;
}
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
- if (flow_type & IRQ_TYPE_LEVEL_LOW) {
- desc->status |= IRQ_LEVEL;
- desc->handle_irq = handle_level_irq;
- } else
- desc->handle_irq = handle_edge_irq;
+ irqd_set_trigger_type(d, flow_type);
+ if (flow_type & IRQ_TYPE_LEVEL_LOW)
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ else
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
/* internal IRQ senses are LEVEL_LOW
* EXT IRQ and Port C IRQ senses are programmable
@@ -179,7 +170,8 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
if (src >= CPM2_IRQ_PORTC15 && src <= CPM2_IRQ_PORTC0)
edibit = (31 - (CPM2_IRQ_PORTC0 - src));
else
- return (flow_type & IRQ_TYPE_LEVEL_LOW) ? 0 : -EINVAL;
+ return (flow_type & IRQ_TYPE_LEVEL_LOW) ?
+ IRQ_SET_MASK_OK_NOCOPY : -EINVAL;
vold = in_be32(&cpm2_intctl->ic_siexr);
@@ -190,7 +182,7 @@ static int cpm2_set_irq_type(struct irq_data *d, unsigned int flow_type)
if (vold != vnew)
out_be32(&cpm2_intctl->ic_siexr, vnew);
- return 0;
+ return IRQ_SET_MASK_OK_NOCOPY;
err_sense:
pr_err("CPM2 PIC: sense type 0x%x not supported\n", flow_type);
@@ -204,6 +196,7 @@ static struct irq_chip cpm2_pic = {
.irq_ack = cpm2_ack,
.irq_eoi = cpm2_end_irq,
.irq_set_type = cpm2_set_irq_type,
+ .flags = IRQCHIP_EOI_IF_HANDLED,
};
unsigned int cpm2_get_irq(void)
@@ -226,8 +219,8 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
{
pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &cpm2_pic, handle_level_irq);
return 0;
}
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 58e09b2833f..d5679dc1e20 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -64,10 +64,10 @@ static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
struct fsl_msi *msi_data = h->host_data;
struct irq_chip *chip = &fsl_msi_chip;
- irq_to_desc(virq)->status |= IRQ_TYPE_EDGE_FALLING;
+ irq_set_status_flags(virq, IRQ_TYPE_EDGE_FALLING);
- set_irq_chip_data(virq, msi_data);
- set_irq_chip_and_handler(virq, chip, handle_edge_irq);
+ irq_set_chip_data(virq, msi_data);
+ irq_set_chip_and_handler(virq, chip, handle_edge_irq);
return 0;
}
@@ -110,8 +110,8 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
list_for_each_entry(entry, &pdev->msi_list, list) {
if (entry->irq == NO_IRQ)
continue;
- msi_data = get_irq_data(entry->irq);
- set_irq_msi(entry->irq, NULL);
+ msi_data = irq_get_handler_data(entry->irq);
+ irq_set_msi_desc(entry->irq, NULL);
msi_bitmap_free_hwirqs(&msi_data->bitmap,
virq_to_hw(entry->irq), 1);
irq_dispose_mapping(entry->irq);
@@ -168,8 +168,8 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
rc = -ENOSPC;
goto out_free;
}
- set_irq_data(virq, msi_data);
- set_irq_msi(virq, entry);
+ irq_set_handler_data(virq, msi_data);
+ irq_set_msi_desc(virq, entry);
fsl_compose_msi_msg(pdev, hwirq, &msg, msi_data);
write_msi_msg(virq, &msg);
@@ -183,7 +183,8 @@ out_free:
static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct irq_data *idata = irq_desc_get_irq_data(desc);
unsigned int cascade_irq;
struct fsl_msi *msi_data;
int msir_index = -1;
@@ -192,20 +193,20 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
u32 have_shift = 0;
struct fsl_msi_cascade_data *cascade_data;
- cascade_data = (struct fsl_msi_cascade_data *)get_irq_data(irq);
+ cascade_data = (struct fsl_msi_cascade_data *)irq_get_handler_data(irq);
msi_data = cascade_data->msi_data;
raw_spin_lock(&desc->lock);
if ((msi_data->feature & FSL_PIC_IP_MASK) == FSL_PIC_IP_IPIC) {
if (chip->irq_mask_ack)
- chip->irq_mask_ack(&desc->irq_data);
+ chip->irq_mask_ack(idata);
else {
- chip->irq_mask(&desc->irq_data);
- chip->irq_ack(&desc->irq_data);
+ chip->irq_mask(idata);
+ chip->irq_ack(idata);
}
}
- if (unlikely(desc->status & IRQ_INPROGRESS))
+ if (unlikely(irqd_irq_inprogress(idata)))
goto unlock;
msir_index = cascade_data->index;
@@ -213,7 +214,7 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
if (msir_index >= NR_MSI_REG)
cascade_irq = NO_IRQ;
- desc->status |= IRQ_INPROGRESS;
+ irqd_set_chained_irq_inprogress(idata);
switch (msi_data->feature & FSL_PIC_IP_MASK) {
case FSL_PIC_IP_MPIC:
msir_value = fsl_msi_read(msi_data->msi_regs,
@@ -235,15 +236,15 @@ static void fsl_msi_cascade(unsigned int irq, struct irq_desc *desc)
have_shift += intr_index + 1;
msir_value = msir_value >> (intr_index + 1);
}
- desc->status &= ~IRQ_INPROGRESS;
+ irqd_clr_chained_irq_inprogress(idata);
switch (msi_data->feature & FSL_PIC_IP_MASK) {
case FSL_PIC_IP_MPIC:
- chip->irq_eoi(&desc->irq_data);
+ chip->irq_eoi(idata);
break;
case FSL_PIC_IP_IPIC:
- if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
- chip->irq_unmask(&desc->irq_data);
+ if (!irqd_irq_disabled(idata) && chip->irq_unmask)
+ chip->irq_unmask(idata);
break;
}
unlock:
@@ -261,7 +262,7 @@ static int fsl_of_msi_remove(struct platform_device *ofdev)
for (i = 0; i < NR_MSI_REG; i++) {
virq = msi->msi_virqs[i];
if (virq != NO_IRQ) {
- cascade_data = get_irq_data(virq);
+ cascade_data = irq_get_handler_data(virq);
kfree(cascade_data);
irq_dispose_mapping(virq);
}
@@ -297,8 +298,8 @@ 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->msi_data = msi;
- set_irq_data(virt_msir, cascade_data);
- set_irq_chained_handler(virt_msir, fsl_msi_cascade);
+ irq_set_handler_data(virt_msir, cascade_data);
+ irq_set_chained_handler(virt_msir, fsl_msi_cascade);
return 0;
}
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index aeda4c8d0a0..142770cb84b 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -175,13 +175,13 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
/* We block the internal cascade */
if (hw == 2)
- irq_to_desc(virq)->status |= IRQ_NOREQUEST;
+ irq_set_status_flags(virq, IRQ_NOREQUEST);
/* We use the level handler only for now, we might want to
* be more cautious here but that works for now
*/
- irq_to_desc(virq)->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &i8259_pic, handle_level_irq);
+ irq_set_status_flags(virq, IRQ_LEVEL);
+ irq_set_chip_and_handler(virq, &i8259_pic, handle_level_irq);
return 0;
}
@@ -191,7 +191,7 @@ static void i8259_host_unmap(struct irq_host *h, unsigned int virq)
i8259_mask_irq(irq_get_irq_data(virq));
/* remove chip and handler */
- set_irq_chip_and_handler(virq, NULL, NULL);
+ irq_set_chip_and_handler(virq, NULL, NULL);
/* Make sure it's completed */
synchronize_irq(virq);
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 497047dc986..fa438be962b 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -605,7 +605,6 @@ static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
struct ipic *ipic = ipic_from_irq(d->irq);
unsigned int src = ipic_irq_to_hw(d->irq);
- struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vold, vnew, edibit;
if (flow_type == IRQ_TYPE_NONE)
@@ -623,17 +622,16 @@ static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
printk(KERN_ERR "ipic: edge sense not supported on internal "
"interrupts\n");
return -EINVAL;
+
}
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
+ irqd_set_trigger_type(d, flow_type);
if (flow_type & IRQ_TYPE_LEVEL_LOW) {
- desc->status |= IRQ_LEVEL;
- desc->handle_irq = handle_level_irq;
- desc->irq_data.chip = &ipic_level_irq_chip;
+ __irq_set_handler_locked(d->irq, handle_level_irq);
+ d->chip = &ipic_level_irq_chip;
} else {
- desc->handle_irq = handle_edge_irq;
- desc->irq_data.chip = &ipic_edge_irq_chip;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
+ d->chip = &ipic_edge_irq_chip;
}
/* only EXT IRQ senses are programmable on ipic
@@ -655,7 +653,7 @@ static int ipic_set_irq_type(struct irq_data *d, unsigned int flow_type)
}
if (vold != vnew)
ipic_write(ipic->regs, IPIC_SECNR, vnew);
- return 0;
+ return IRQ_SET_MASK_OK_NOCOPY;
}
/* level interrupts and edge interrupts have different ack operations */
@@ -687,11 +685,11 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
{
struct ipic *ipic = h->host_data;
- set_irq_chip_data(virq, ipic);
- set_irq_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
+ irq_set_chip_data(virq, ipic);
+ irq_set_chip_and_handler(virq, &ipic_level_irq_chip, handle_level_irq);
/* Set default irq type */
- set_irq_type(virq, IRQ_TYPE_NONE);
+ irq_set_irq_type(virq, IRQ_TYPE_NONE);
return 0;
}
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 1a75a7fb4a9..a88800ff4d0 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -72,13 +72,6 @@ static void mpc8xx_end_irq(struct irq_data *d)
static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
- struct irq_desc *desc = irq_to_desc(d->irq);
-
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
- if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
- desc->status |= IRQ_LEVEL;
-
if (flow_type & IRQ_TYPE_EDGE_FALLING) {
irq_hw_number_t hw = (unsigned int)irq_map[d->irq].hwirq;
unsigned int siel = in_be32(&siu_reg->sc_siel);
@@ -87,7 +80,7 @@ static int mpc8xx_set_irq_type(struct irq_data *d, unsigned int flow_type)
if ((hw & 1) == 0) {
siel |= (0x80000000 >> hw);
out_be32(&siu_reg->sc_siel, siel);
- desc->handle_irq = handle_edge_irq;
+ __irq_set_handler_locked(d->irq, handle_edge_irq);
}
}
return 0;
@@ -124,7 +117,7 @@ static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw);
/* Set default irq handle */
- set_irq_chip_and_handler(virq, &mpc8xx_pic, handle_level_irq);
+ irq_set_chip_and_handler(virq, &mpc8xx_pic, handle_level_irq);
return 0;
}
diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c
index 232e701245d..0892a2841c2 100644
--- a/arch/powerpc/sysdev/mpc8xxx_gpio.c
+++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c
@@ -145,7 +145,7 @@ static int mpc8xxx_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
static void mpc8xxx_gpio_irq_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_desc_data(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;
@@ -278,9 +278,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
if (mpc8xxx_gc->of_dev_id_data)
mpc8xxx_irq_chip.irq_set_type = mpc8xxx_gc->of_dev_id_data;
- set_irq_chip_data(virq, h->host_data);
- set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq);
- set_irq_type(virq, IRQ_TYPE_NONE);
+ 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;
}
@@ -369,8 +369,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
out_be32(mm_gc->regs + GPIO_IMR, 0);
- set_irq_data(hwirq, mpc8xxx_gc);
- set_irq_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
+ irq_set_handler_data(hwirq, mpc8xxx_gc);
+ irq_set_chained_handler(hwirq, mpc8xxx_gpio_irq_cascade);
skip_irq:
return;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 0f7c6718d26..f91c065bed5 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -361,7 +361,7 @@ static inline void mpic_ht_end_irq(struct mpic *mpic, unsigned int source)
}
static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
- unsigned int irqflags)
+ bool level)
{
struct mpic_irq_fixup *fixup = &mpic->fixups[source];
unsigned long flags;
@@ -370,14 +370,14 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
if (fixup->base == NULL)
return;
- DBG("startup_ht_interrupt(0x%x, 0x%x) index: %d\n",
- source, irqflags, fixup->index);
+ DBG("startup_ht_interrupt(0x%x) index: %d\n",
+ source, fixup->index);
raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
/* Enable and configure */
writeb(0x10 + 2 * fixup->index, fixup->base + 2);
tmp = readl(fixup->base + 4);
tmp &= ~(0x23U);
- if (irqflags & IRQ_LEVEL)
+ if (level)
tmp |= 0x22;
writel(tmp, fixup->base + 4);
raw_spin_unlock_irqrestore(&mpic->fixup_lock, flags);
@@ -389,8 +389,7 @@ static void mpic_startup_ht_interrupt(struct mpic *mpic, unsigned int source,
#endif
}
-static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
- unsigned int irqflags)
+static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source)
{
struct mpic_irq_fixup *fixup = &mpic->fixups[source];
unsigned long flags;
@@ -399,7 +398,7 @@ static void mpic_shutdown_ht_interrupt(struct mpic *mpic, unsigned int source,
if (fixup->base == NULL)
return;
- DBG("shutdown_ht_interrupt(0x%x, 0x%x)\n", source, irqflags);
+ DBG("shutdown_ht_interrupt(0x%x)\n", source);
/* Disable */
raw_spin_lock_irqsave(&mpic->fixup_lock, flags);
@@ -616,7 +615,7 @@ static struct mpic *mpic_find(unsigned int irq)
if (irq < NUM_ISA_INTERRUPTS)
return NULL;
- return get_irq_chip_data(irq);
+ return irq_get_chip_data(irq);
}
/* Determine if the linux irq is an IPI */
@@ -650,7 +649,7 @@ static inline struct mpic * mpic_from_ipi(struct irq_data *d)
/* Get the mpic structure from the irq number */
static inline struct mpic * mpic_from_irq(unsigned int irq)
{
- return get_irq_chip_data(irq);
+ return irq_get_chip_data(irq);
}
/* Get the mpic structure from the irq data */
@@ -738,7 +737,7 @@ static void mpic_unmask_ht_irq(struct irq_data *d)
mpic_unmask_irq(d);
- if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
+ if (irqd_is_level_type(d))
mpic_ht_end_irq(mpic, src);
}
@@ -748,7 +747,7 @@ static unsigned int mpic_startup_ht_irq(struct irq_data *d)
unsigned int src = mpic_irq_to_hw(d->irq);
mpic_unmask_irq(d);
- mpic_startup_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
+ mpic_startup_ht_interrupt(mpic, src, irqd_is_level_type(d));
return 0;
}
@@ -758,7 +757,7 @@ static void mpic_shutdown_ht_irq(struct irq_data *d)
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
- mpic_shutdown_ht_interrupt(mpic, src, irq_to_desc(d->irq)->status);
+ mpic_shutdown_ht_interrupt(mpic, src);
mpic_mask_irq(d);
}
@@ -775,7 +774,7 @@ static void mpic_end_ht_irq(struct irq_data *d)
* latched another edge interrupt coming in anyway
*/
- if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
+ if (irqd_is_level_type(d))
mpic_ht_end_irq(mpic, src);
mpic_eoi(mpic);
}
@@ -864,7 +863,6 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
struct mpic *mpic = mpic_from_irq_data(d);
unsigned int src = mpic_irq_to_hw(d->irq);
- struct irq_desc *desc = irq_to_desc(d->irq);
unsigned int vecpri, vold, vnew;
DBG("mpic: set_irq_type(mpic:@%p,virq:%d,src:0x%x,type:0x%x)\n",
@@ -879,10 +877,7 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
if (flow_type == IRQ_TYPE_NONE)
flow_type = IRQ_TYPE_LEVEL_LOW;
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
- if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
- desc->status |= IRQ_LEVEL;
+ irqd_set_trigger_type(d, flow_type);
if (mpic_is_ht_interrupt(mpic, src))
vecpri = MPIC_VECPRI_POLARITY_POSITIVE |
@@ -897,7 +892,7 @@ int mpic_set_irq_type(struct irq_data *d, unsigned int flow_type)
if (vold != vnew)
mpic_irq_write(src, MPIC_INFO(IRQ_VECTOR_PRI), vnew);
- return 0;
+ return IRQ_SET_MASK_OK_NOCOPY;;
}
void mpic_set_vector(unsigned int virq, unsigned int vector)
@@ -983,8 +978,8 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
WARN_ON(!(mpic->flags & MPIC_PRIMARY));
DBG("mpic: mapping as IPI\n");
- set_irq_chip_data(virq, mpic);
- set_irq_chip_and_handler(virq, &mpic->hc_ipi,
+ irq_set_chip_data(virq, mpic);
+ irq_set_chip_and_handler(virq, &mpic->hc_ipi,
handle_percpu_irq);
return 0;
}
@@ -1006,11 +1001,11 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
DBG("mpic: mapping to irq chip @%p\n", chip);
- set_irq_chip_data(virq, mpic);
- set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq);
+ irq_set_chip_data(virq, mpic);
+ irq_set_chip_and_handler(virq, chip, handle_fasteoi_irq);
/* Set default irq type */
- set_irq_type(virq, IRQ_TYPE_NONE);
+ irq_set_irq_type(virq, IRQ_TYPE_NONE);
/* If the MPIC was reset, then all vectors have already been
* initialized. Otherwise, a per source lazy initialization
diff --git a/arch/powerpc/sysdev/mpic_pasemi_msi.c b/arch/powerpc/sysdev/mpic_pasemi_msi.c
index 0b7794acfce..38e62382070 100644
--- a/arch/powerpc/sysdev/mpic_pasemi_msi.c
+++ b/arch/powerpc/sysdev/mpic_pasemi_msi.c
@@ -81,7 +81,7 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)
if (entry->irq == NO_IRQ)
continue;
- set_irq_msi(entry->irq, NULL);
+ irq_set_msi_desc(entry->irq, NULL);
msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
virq_to_hw(entry->irq), ALLOC_CHUNK);
irq_dispose_mapping(entry->irq);
@@ -131,9 +131,9 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
*/
mpic_set_vector(virq, 0);
- set_irq_msi(virq, entry);
- set_irq_chip(virq, &mpic_pasemi_msi_chip);
- set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
+ irq_set_msi_desc(virq, entry);
+ irq_set_chip(virq, &mpic_pasemi_msi_chip);
+ irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
pr_debug("pasemi_msi: allocated virq 0x%x (hw 0x%x) " \
"addr 0x%x\n", virq, hwirq, msg.address_lo);
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index 71900ac7827..9a7aa0ed9c1 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -129,7 +129,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
if (entry->irq == NO_IRQ)
continue;
- set_irq_msi(entry->irq, NULL);
+ irq_set_msi_desc(entry->irq, NULL);
msi_bitmap_free_hwirqs(&msi_mpic->msi_bitmap,
virq_to_hw(entry->irq), 1);
irq_dispose_mapping(entry->irq);
@@ -166,9 +166,9 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return -ENOSPC;
}
- set_irq_msi(virq, entry);
- set_irq_chip(virq, &mpic_u3msi_chip);
- set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
+ irq_set_msi_desc(virq, entry);
+ irq_set_chip(virq, &mpic_u3msi_chip);
+ irq_set_irq_type(virq, IRQ_TYPE_EDGE_RISING);
pr_debug("u3msi: allocated virq 0x%x (hw 0x%x) addr 0x%lx\n",
virq, hwirq, (unsigned long)addr);
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index bc61ebb8987..e9c633c7c08 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -213,11 +213,12 @@ static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
{
int level1;
- irq_to_desc(virq)->status |= IRQ_LEVEL;
+ irq_set_status_flags(virq, IRQ_LEVEL);
level1 = (hwirq & MV64x60_LEVEL1_MASK) >> MV64x60_LEVEL1_OFFSET;
BUG_ON(level1 > MV64x60_LEVEL1_GPP);
- set_irq_chip_and_handler(virq, mv64x60_chips[level1], handle_level_irq);
+ irq_set_chip_and_handler(virq, mv64x60_chips[level1],
+ handle_level_irq);
return 0;
}
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 8c9ded8ea07..832d6924ad1 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -189,7 +189,7 @@ static inline void qe_ic_write(volatile __be32 __iomem * base, unsigned int reg
static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
{
- return get_irq_chip_data(virq);
+ return irq_get_chip_data(virq);
}
static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
@@ -267,10 +267,10 @@ static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
/* Default chip */
chip = &qe_ic->hc_irq;
- set_irq_chip_data(virq, qe_ic);
- irq_to_desc(virq)->status |= IRQ_LEVEL;
+ irq_set_chip_data(virq, qe_ic);
+ irq_set_status_flags(virq, IRQ_LEVEL);
- set_irq_chip_and_handler(virq, chip, handle_level_irq);
+ irq_set_chip_and_handler(virq, chip, handle_level_irq);
return 0;
}
@@ -386,13 +386,13 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
- set_irq_data(qe_ic->virq_low, qe_ic);
- set_irq_chained_handler(qe_ic->virq_low, low_handler);
+ irq_set_handler_data(qe_ic->virq_low, qe_ic);
+ irq_set_chained_handler(qe_ic->virq_low, low_handler);
if (qe_ic->virq_high != NO_IRQ &&
qe_ic->virq_high != qe_ic->virq_low) {
- set_irq_data(qe_ic->virq_high, qe_ic);
- set_irq_chained_handler(qe_ic->virq_high, high_handler);
+ irq_set_handler_data(qe_ic->virq_high, qe_ic);
+ irq_set_chained_handler(qe_ic->virq_high, high_handler);
}
}
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 02c91db9003..4d18658116e 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -391,8 +391,8 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
DBG("%s(%d, 0x%lx)\n", __func__, virq, hw);
if ((virq >= 1) && (virq <= 4)){
irq = virq + IRQ_PCI_INTAD_BASE - 1;
- irq_to_desc(irq)->status |= IRQ_LEVEL;
- set_irq_chip(irq, &tsi108_pci_irq);
+ irq_set_status_flags(irq, IRQ_LEVEL);
+ irq_set_chip(irq, &tsi108_pci_irq);
}
return 0;
}
@@ -431,7 +431,7 @@ void __init tsi108_pci_int_init(struct device_node *node)
void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = get_pci_source();
if (cascade_irq != NO_IRQ)
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 835f7958b23..5d913851662 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -57,7 +57,6 @@ struct uic {
static void uic_unmask_irq(struct irq_data *d)
{
- struct irq_desc *desc = irq_to_desc(d->irq);
struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags;
@@ -66,7 +65,7 @@ static void uic_unmask_irq(struct irq_data *d)
sr = 1 << (31-src);
spin_lock_irqsave(&uic->lock, flags);
/* ack level-triggered interrupts here */
- if (desc->status & IRQ_LEVEL)
+ if (irqd_is_level_type(d))
mtdcr(uic->dcrbase + UIC_SR, sr);
er = mfdcr(uic->dcrbase + UIC_ER);
er |= sr;
@@ -101,7 +100,6 @@ static void uic_ack_irq(struct irq_data *d)
static void uic_mask_ack_irq(struct irq_data *d)
{
- struct irq_desc *desc = irq_to_desc(d->irq);
struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(d->irq);
unsigned long flags;
@@ -120,7 +118,7 @@ static void uic_mask_ack_irq(struct irq_data *d)
* level interrupts are ack'ed after the actual
* isr call in the uic_unmask_irq()
*/
- if (!(desc->status & IRQ_LEVEL))
+ if (!irqd_is_level_type(d))
mtdcr(uic->dcrbase + UIC_SR, sr);
spin_unlock_irqrestore(&uic->lock, flags);
}
@@ -129,7 +127,6 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
{
struct uic *uic = irq_data_get_irq_chip_data(d);
unsigned int src = uic_irq_to_hw(d->irq);
- struct irq_desc *desc = irq_to_desc(d->irq);
unsigned long flags;
int trigger, polarity;
u32 tr, pr, mask;
@@ -166,11 +163,6 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type)
mtdcr(uic->dcrbase + UIC_PR, pr);
mtdcr(uic->dcrbase + UIC_TR, tr);
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
- if (!trigger)
- desc->status |= IRQ_LEVEL;
-
spin_unlock_irqrestore(&uic->lock, flags);
return 0;
@@ -190,13 +182,13 @@ static int uic_host_map(struct irq_host *h, unsigned int virq,
{
struct uic *uic = h->host_data;
- set_irq_chip_data(virq, uic);
+ irq_set_chip_data(virq, uic);
/* Despite the name, handle_level_irq() works for both level
* and edge irqs on UIC. FIXME: check this is correct */
- set_irq_chip_and_handler(virq, &uic_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(virq, &uic_irq_chip, handle_level_irq);
/* Set default irq type */
- set_irq_type(virq, IRQ_TYPE_NONE);
+ irq_set_irq_type(virq, IRQ_TYPE_NONE);
return 0;
}
@@ -220,17 +212,18 @@ static struct irq_host_ops uic_host_ops = {
void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
- struct uic *uic = get_irq_data(virq);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+ struct irq_data *idata = irq_desc_get_irq_data(desc);
+ struct uic *uic = irq_get_handler_data(virq);
u32 msr;
int src;
int subvirq;
raw_spin_lock(&desc->lock);
- if (desc->status & IRQ_LEVEL)
- chip->irq_mask(&desc->irq_data);
+ if (irqd_is_level_type(idata))
+ chip->irq_mask(idata);
else
- chip->irq_mask_ack(&desc->irq_data);
+ chip->irq_mask_ack(idata);
raw_spin_unlock(&desc->lock);
msr = mfdcr(uic->dcrbase + UIC_MSR);
@@ -244,10 +237,10 @@ void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
uic_irq_ret:
raw_spin_lock(&desc->lock);
- if (desc->status & IRQ_LEVEL)
- chip->irq_ack(&desc->irq_data);
- if (!(desc->status & IRQ_DISABLED) && chip->irq_unmask)
- chip->irq_unmask(&desc->irq_data);
+ if (irqd_is_level_type(idata))
+ chip->irq_ack(idata);
+ if (!irqd_irq_disabled(idata) && chip->irq_unmask)
+ chip->irq_unmask(idata);
raw_spin_unlock(&desc->lock);
}
@@ -336,8 +329,8 @@ void __init uic_init_tree(void)
cascade_virq = irq_of_parse_and_map(np, 0);
- set_irq_data(cascade_virq, uic);
- set_irq_chained_handler(cascade_virq, uic_irq_cascade);
+ irq_set_handler_data(cascade_virq, uic);
+ irq_set_chained_handler(cascade_virq, uic_irq_cascade);
/* FIXME: setup critical cascade?? */
}
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 7436f3ed4df..0a13fc19e28 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -79,12 +79,6 @@ static void xilinx_intc_mask(struct irq_data *d)
static int xilinx_intc_set_type(struct irq_data *d, unsigned int flow_type)
{
- struct irq_desc *desc = irq_to_desc(d->irq);
-
- desc->status &= ~(IRQ_TYPE_SENSE_MASK | IRQ_LEVEL);
- desc->status |= flow_type & IRQ_TYPE_SENSE_MASK;
- if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW))
- desc->status |= IRQ_LEVEL;
return 0;
}
@@ -170,15 +164,15 @@ static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
irq_hw_number_t irq)
{
- set_irq_chip_data(virq, h->host_data);
+ irq_set_chip_data(virq, h->host_data);
if (xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_HIGH ||
xilinx_intc_typetable[irq] == IRQ_TYPE_LEVEL_LOW) {
- set_irq_chip_and_handler(virq, &xilinx_intc_level_irqchip,
- handle_level_irq);
+ irq_set_chip_and_handler(virq, &xilinx_intc_level_irqchip,
+ handle_level_irq);
} else {
- set_irq_chip_and_handler(virq, &xilinx_intc_edge_irqchip,
- handle_edge_irq);
+ irq_set_chip_and_handler(virq, &xilinx_intc_edge_irqchip,
+ handle_edge_irq);
}
return 0;
}
@@ -229,7 +223,7 @@ int xilinx_intc_get_irq(void)
*/
static void xilinx_i8259_cascade(unsigned int irq, struct irq_desc *desc)
{
- struct irq_chip *chip = get_irq_desc_chip(desc);
+ struct irq_chip *chip = irq_desc_get_chip(desc);
unsigned int cascade_irq = i8259_irq();
if (cascade_irq)
@@ -256,7 +250,7 @@ static void __init xilinx_i8259_setup_cascade(void)
}
i8259_init(cascade_node, 0);
- set_irq_chained_handler(cascade_irq, xilinx_i8259_cascade);
+ irq_set_chained_handler(cascade_irq, xilinx_i8259_cascade);
/* Program irq 7 (usb/audio), 14/15 (ide) to level sensitive */
/* This looks like a dirty hack to me --gcl */
diff --git a/arch/score/Kconfig b/arch/score/Kconfig
index 27b2295f41f..e73bc781cc1 100644
--- a/arch/score/Kconfig
+++ b/arch/score/Kconfig
@@ -3,6 +3,7 @@ menu "Machine selection"
config SCORE
def_bool y
select HAVE_GENERIC_HARDIRQS
+ select GENERIC_IRQ_SHOW
choice
prompt "System type"
diff --git a/arch/score/include/asm/irqflags.h b/arch/score/include/asm/irqflags.h
index 5c7563891e2..37c6ac9dd6e 100644
--- a/arch/score/include/asm/irqflags.h
+++ b/arch/score/include/asm/irqflags.h
@@ -29,7 +29,7 @@ static inline unsigned long arch_local_save_flags(void)
static inline unsigned long arch_local_irq_save(void)
{
- unsigned long flags
+ unsigned long flags;
asm volatile(
" mfcr r8, cr0 \n"
diff --git a/arch/score/kernel/irq.c b/arch/score/kernel/irq.c
index 47647dde09c..d4196732c65 100644
--- a/arch/score/kernel/irq.c
+++ b/arch/score/kernel/irq.c
@@ -52,9 +52,9 @@ asmlinkage void do_IRQ(int irq)
irq_exit();
}
-static void score_mask(unsigned int irq_nr)
+static void score_mask(struct irq_data *d)
{
- unsigned int irq_source = 63 - irq_nr;
+ unsigned int irq_source = 63 - d->irq;
if (irq_source < 32)
__raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) | \
@@ -64,9 +64,9 @@ static void score_mask(unsigned int irq_nr)
(1 << (irq_source - 32))), SCORE_PIC + INT_MASKH);
}
-static void score_unmask(unsigned int irq_nr)
+static void score_unmask(struct irq_data *d)
{
- unsigned int irq_source = 63 - irq_nr;
+ unsigned int irq_source = 63 - d->irq;
if (irq_source < 32)
__raw_writel((__raw_readl(SCORE_PIC + INT_MASKL) & \
@@ -78,9 +78,9 @@ static void score_unmask(unsigned int irq_nr)
struct irq_chip score_irq_chip = {
.name = "Score7-level",
- .mask = score_mask,
- .mask_ack = score_mask,
- .unmask = score_unmask,
+ .irq_mask = score_mask,
+ .irq_mask_ack = score_mask,
+ .irq_unmask = score_unmask,
};
/*
@@ -92,7 +92,7 @@ void __init init_IRQ(void)
unsigned long target_addr;
for (index = 0; index < NR_IRQS; ++index)
- set_irq_chip_and_handler(index, &score_irq_chip,
+ irq_set_chip_and_handler(index, &score_irq_chip,
handle_level_irq);
for (target_addr = IRQ_VECTOR_BASE_ADDR;
@@ -109,40 +109,3 @@ void __init init_IRQ(void)
: : "r" (EXCEPTION_VECTOR_BASE_ADDR | \
VECTOR_ADDRESS_OFFSET_MODE16));
}
-
-/*
- * Generic, controller-independent functions:
- */
-int show_interrupts(struct seq_file *p, void *v)
-{
- int i = *(loff_t *)v, cpu;
- struct irqaction *action;
- unsigned long flags;
-
- if (i == 0) {
- seq_puts(p, " ");
- for_each_online_cpu(cpu)
- seq_printf(p, "CPU%d ", cpu);
- seq_putc(p, '\n');
- }
-
- if (i < NR_IRQS) {
- spin_lock_irqsave(&irq_desc[i].lock, flags);
- action = irq_desc[i].action;
- if (!action)
- goto unlock;
-
- seq_printf(p, "%3d: ", i);
- seq_printf(p, "%10u ", kstat_irqs(i));
- seq_printf(p, " %8s", irq_desc[i].chip->name ? : "-");
- seq_printf(p, " %s", action->name);
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
-unlock:
- spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- }
-
- return 0;
-}
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index 9af3c8d0776..bc439de48cd 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -23,7 +23,6 @@ config SUPERH
select HAVE_SPARSE_IRQ
select RTC_LIB
select GENERIC_ATOMIC64
- select GENERIC_HARDIRQS_NO_DEPRECATED
select GENERIC_IRQ_SHOW
help
The SuperH is a RISC processor targeted for use in embedded systems
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c
index efba450a051..93f5039099b 100644
--- a/arch/sh/boards/board-magicpanelr2.c
+++ b/arch/sh/boards/board-magicpanelr2.c
@@ -388,12 +388,12 @@ static void __init init_mpr2_IRQ(void)
{
plat_irq_setup_pins(IRQ_MODE_IRQ); /* install handlers for IRQ0-5 */
- set_irq_type(32, IRQ_TYPE_LEVEL_LOW); /* IRQ0 CAN1 */
- set_irq_type(33, IRQ_TYPE_LEVEL_LOW); /* IRQ1 CAN2 */
- set_irq_type(34, IRQ_TYPE_LEVEL_LOW); /* IRQ2 CAN3 */
- set_irq_type(35, IRQ_TYPE_LEVEL_LOW); /* IRQ3 SMSC9115 */
- set_irq_type(36, IRQ_TYPE_EDGE_RISING); /* IRQ4 touchscreen */
- set_irq_type(37, IRQ_TYPE_EDGE_FALLING); /* IRQ5 touchscreen */
+ irq_set_irq_type(32, IRQ_TYPE_LEVEL_LOW); /* IRQ0 CAN1 */
+ irq_set_irq_type(33, IRQ_TYPE_LEVEL_LOW); /* IRQ1 CAN2 */
+ irq_set_irq_type(34, IRQ_TYPE_LEVEL_LOW); /* IRQ2 CAN3 */
+ irq_set_irq_type(35, IRQ_TYPE_LEVEL_LOW); /* IRQ3 SMSC9115 */
+ irq_set_irq_type(36, IRQ_TYPE_EDGE_RISING); /* IRQ4 touchscreen */
+ irq_set_irq_type(37, IRQ_TYPE_EDGE_FALLING); /* IRQ5 touchscreen */
intc_set_priority(32, 13); /* IRQ0 CAN1 */
intc_set_priority(33, 13); /* IRQ0 CAN2 */
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 3e5fc3bbf3e..636d8318a72 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -14,8 +14,8 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/sh_flctl.h>
#include <linux/delay.h>
@@ -423,7 +423,7 @@ static struct resource sdhi0_cn3_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -453,7 +453,7 @@ static struct resource sdhi1_cn7_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0x04cf0000,
- .end = 0x04cf01ff,
+ .end = 0x04cf00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/sh/boards/mach-cayman/irq.c b/arch/sh/boards/mach-cayman/irq.c
index d7ac5af9d10..311bcebdbd0 100644
--- a/arch/sh/boards/mach-cayman/irq.c
+++ b/arch/sh/boards/mach-cayman/irq.c
@@ -149,8 +149,8 @@ void init_cayman_irq(void)
}
for (i = 0; i < NR_EXT_IRQS; i++) {
- set_irq_chip_and_handler(START_EXT_IRQS + i, &cayman_irq_type,
- handle_level_irq);
+ irq_set_chip_and_handler(START_EXT_IRQS + i,
+ &cayman_irq_type, handle_level_irq);
}
/* Setup the SMSC interrupt */
diff --git a/arch/sh/boards/mach-dreamcast/irq.c b/arch/sh/boards/mach-dreamcast/irq.c
index 72e7ac9549d..78cf2ab89d7 100644
--- a/arch/sh/boards/mach-dreamcast/irq.c
+++ b/arch/sh/boards/mach-dreamcast/irq.c
@@ -161,7 +161,6 @@ void systemasic_irq_init(void)
return;
}
- set_irq_chip_and_handler(i, &systemasic_int,
- handle_level_irq);
+ irq_set_chip_and_handler(i, &systemasic_int, handle_level_irq);
}
}
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index e44480ce2ea..fd4ff25f23b 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -11,9 +11,9 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/platform_device.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/gpio.h>
#include <linux/interrupt.h>
@@ -464,7 +464,7 @@ static struct i2c_board_info ts_i2c_clients = {
.irq = IRQ0,
};
-#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
/* SDHI0 */
static void sdhi0_set_pwr(struct platform_device *pdev, int state)
{
@@ -482,7 +482,7 @@ static struct resource sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -522,7 +522,7 @@ static struct resource sdhi1_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0x04cf0000,
- .end = 0x04cf01ff,
+ .end = 0x04cf00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -880,7 +880,7 @@ static struct platform_device *ecovec_devices[] __initdata = {
&ceu0_device,
&ceu1_device,
&keysc_device,
-#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
&sdhi0_device,
#if !defined(CONFIG_MMC_SH_MMCIF)
&sdhi1_device,
@@ -1102,7 +1102,7 @@ static int __init arch_setup(void)
/* enable TouchScreen */
i2c_register_board_info(0, &ts_i2c_clients, 1);
- set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(IRQ0, IRQ_TYPE_LEVEL_LOW);
}
/* enable CEU0 */
@@ -1162,7 +1162,7 @@ static int __init arch_setup(void)
gpio_direction_input(GPIO_PTR5);
gpio_direction_input(GPIO_PTR6);
-#ifdef CONFIG_MFD_SH_MOBILE_SDHI
+#if defined(CONFIG_MMC_TMIO) || defined(CONFIG_MMC_TMIO_MODULE)
/* enable SDHI0 on CN11 (needs DS2.4 set to ON) */
gpio_request(GPIO_FN_SDHI0CD, NULL);
gpio_request(GPIO_FN_SDHI0WP, NULL);
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 7504daaa85d..8b4abbbd147 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -10,8 +10,8 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/onenand.h>
@@ -354,7 +354,7 @@ static struct resource kfr2r09_sh_sdhi0_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/sh/boards/mach-microdev/irq.c b/arch/sh/boards/mach-microdev/irq.c
index c35001fd903..4fb00369f0e 100644
--- a/arch/sh/boards/mach-microdev/irq.c
+++ b/arch/sh/boards/mach-microdev/irq.c
@@ -117,7 +117,7 @@ static struct irq_chip microdev_irq_type = {
static void __init make_microdev_irq(unsigned int irq)
{
disable_irq_nosync(irq);
- set_irq_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(irq, &microdev_irq_type, handle_level_irq);
disable_microdev_irq(irq_get_irq_data(irq));
}
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 03a7ffe729d..184fde16913 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -12,8 +12,8 @@
#include <linux/interrupt.h>
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
#include <linux/i2c.h>
@@ -399,7 +399,7 @@ static struct resource sdhi_cn9_resources[] = {
[0] = {
.name = "SDHI",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c
index 9070d7e6070..0db058e709e 100644
--- a/arch/sh/boards/mach-se/7206/irq.c
+++ b/arch/sh/boards/mach-se/7206/irq.c
@@ -92,9 +92,8 @@ static void eoi_se7206_irq(struct irq_data *data)
{
unsigned short sts0,sts1;
unsigned int irq = data->irq;
- struct irq_desc *desc = irq_to_desc(irq);
- if (!(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+ if (!irqd_irq_disabled(data) && !irqd_irq_inprogress(data))
enable_se7206_irq(data);
/* FPGA isr clear */
sts0 = __raw_readw(INTSTS0);
@@ -126,7 +125,7 @@ static struct irq_chip se7206_irq_chip __read_mostly = {
static void make_se7206_irq(unsigned int irq)
{
disable_irq_nosync(irq);
- set_irq_chip_and_handler_name(irq, &se7206_irq_chip,
+ irq_set_chip_and_handler_name(irq, &se7206_irq_chip,
handle_level_irq, "level");
disable_se7206_irq(irq_get_irq_data(irq));
}
diff --git a/arch/sh/boards/mach-se/7343/irq.c b/arch/sh/boards/mach-se/7343/irq.c
index 76255a19417..fd45ffc4834 100644
--- a/arch/sh/boards/mach-se/7343/irq.c
+++ b/arch/sh/boards/mach-se/7343/irq.c
@@ -67,19 +67,20 @@ void __init init_7343se_IRQ(void)
return;
se7343_fpga_irq[i] = irq;
- set_irq_chip_and_handler_name(se7343_fpga_irq[i],
+ irq_set_chip_and_handler_name(se7343_fpga_irq[i],
&se7343_irq_chip,
- handle_level_irq, "level");
+ handle_level_irq,
+ "level");
- set_irq_chip_data(se7343_fpga_irq[i], (void *)i);
+ irq_set_chip_data(se7343_fpga_irq[i], (void *)i);
}
- set_irq_chained_handler(IRQ0_IRQ, se7343_irq_demux);
- set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
- set_irq_chained_handler(IRQ1_IRQ, se7343_irq_demux);
- set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
- set_irq_chained_handler(IRQ4_IRQ, se7343_irq_demux);
- set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW);
- set_irq_chained_handler(IRQ5_IRQ, se7343_irq_demux);
- set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ0_IRQ, se7343_irq_demux);
+ irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ1_IRQ, se7343_irq_demux);
+ irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ4_IRQ, se7343_irq_demux);
+ irq_set_irq_type(IRQ4_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ5_IRQ, se7343_irq_demux);
+ irq_set_irq_type(IRQ5_IRQ, IRQ_TYPE_LEVEL_LOW);
}
diff --git a/arch/sh/boards/mach-se/7722/irq.c b/arch/sh/boards/mach-se/7722/irq.c
index c013f95628e..aac92f21ebd 100644
--- a/arch/sh/boards/mach-se/7722/irq.c
+++ b/arch/sh/boards/mach-se/7722/irq.c
@@ -67,16 +67,17 @@ void __init init_se7722_IRQ(void)
return;
se7722_fpga_irq[i] = irq;
- set_irq_chip_and_handler_name(se7722_fpga_irq[i],
+ irq_set_chip_and_handler_name(se7722_fpga_irq[i],
&se7722_irq_chip,
- handle_level_irq, "level");
+ handle_level_irq,
+ "level");
- set_irq_chip_data(se7722_fpga_irq[i], (void *)i);
+ irq_set_chip_data(se7722_fpga_irq[i], (void *)i);
}
- set_irq_chained_handler(IRQ0_IRQ, se7722_irq_demux);
- set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ0_IRQ, se7722_irq_demux);
+ irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
- set_irq_chained_handler(IRQ1_IRQ, se7722_irq_demux);
- set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ1_IRQ, se7722_irq_demux);
+ irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
}
diff --git a/arch/sh/boards/mach-se/7724/irq.c b/arch/sh/boards/mach-se/7724/irq.c
index 5bd87c22b65..c6342ce7768 100644
--- a/arch/sh/boards/mach-se/7724/irq.c
+++ b/arch/sh/boards/mach-se/7724/irq.c
@@ -140,17 +140,16 @@ void __init init_se7724_IRQ(void)
return;
}
- set_irq_chip_and_handler_name(irq,
- &se7724_irq_chip,
+ irq_set_chip_and_handler_name(irq, &se7724_irq_chip,
handle_level_irq, "level");
}
- set_irq_chained_handler(IRQ0_IRQ, se7724_irq_demux);
- set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ0_IRQ, se7724_irq_demux);
+ irq_set_irq_type(IRQ0_IRQ, IRQ_TYPE_LEVEL_LOW);
- set_irq_chained_handler(IRQ1_IRQ, se7724_irq_demux);
- set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ1_IRQ, se7724_irq_demux);
+ irq_set_irq_type(IRQ1_IRQ, IRQ_TYPE_LEVEL_LOW);
- set_irq_chained_handler(IRQ2_IRQ, se7724_irq_demux);
- set_irq_type(IRQ2_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(IRQ2_IRQ, se7724_irq_demux);
+ irq_set_irq_type(IRQ2_IRQ, IRQ_TYPE_LEVEL_LOW);
}
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index c8bcf6a19b5..12357671023 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -14,8 +14,8 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/mmc/host.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mtd/physmap.h>
#include <linux/delay.h>
#include <linux/smc91x.h>
@@ -456,7 +456,7 @@ static struct resource sdhi0_cn7_resources[] = {
[0] = {
.name = "SDHI0",
.start = 0x04ce0000,
- .end = 0x04ce01ff,
+ .end = 0x04ce00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -488,7 +488,7 @@ static struct resource sdhi1_cn8_resources[] = {
[0] = {
.name = "SDHI1",
.start = 0x04cf0000,
- .end = 0x04cf01ff,
+ .end = 0x04cf00ff,
.flags = IORESOURCE_MEM,
},
[1] = {
diff --git a/arch/sh/boards/mach-x3proto/gpio.c b/arch/sh/boards/mach-x3proto/gpio.c
index 239e7406625..f33b2b57019 100644
--- a/arch/sh/boards/mach-x3proto/gpio.c
+++ b/arch/sh/boards/mach-x3proto/gpio.c
@@ -102,8 +102,8 @@ int __init x3proto_gpio_setup(void)
spin_lock_irqsave(&x3proto_gpio_lock, flags);
x3proto_gpio_irq_map[i] = irq;
- set_irq_chip_and_handler_name(irq, &dummy_irq_chip,
- handle_simple_irq, "gpio");
+ irq_set_chip_and_handler_name(irq, &dummy_irq_chip,
+ handle_simple_irq, "gpio");
spin_unlock_irqrestore(&x3proto_gpio_lock, flags);
}
@@ -113,8 +113,8 @@ int __init x3proto_gpio_setup(void)
x3proto_gpio_chip.base + x3proto_gpio_chip.ngpio,
ilsel);
- set_irq_chained_handler(ilsel, x3proto_gpio_irq_handler);
- set_irq_wake(ilsel, 1);
+ irq_set_chained_handler(ilsel, x3proto_gpio_irq_handler);
+ irq_set_irq_wake(ilsel, 1);
return 0;
diff --git a/arch/sh/cchips/hd6446x/hd64461.c b/arch/sh/cchips/hd6446x/hd64461.c
index 177a10b25ca..eb4ea4d44d5 100644
--- a/arch/sh/cchips/hd6446x/hd64461.c
+++ b/arch/sh/cchips/hd6446x/hd64461.c
@@ -107,12 +107,12 @@ int __init setup_hd64461(void)
return -EINVAL;
}
- set_irq_chip_and_handler(i, &hd64461_irq_chip,
+ irq_set_chip_and_handler(i, &hd64461_irq_chip,
handle_level_irq);
}
- set_irq_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux);
- set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
+ irq_set_chained_handler(CONFIG_HD64461_IRQ, hd64461_irq_demux);
+ irq_set_irq_type(CONFIG_HD64461_IRQ, IRQ_TYPE_LEVEL_LOW);
#ifdef CONFIG_HD64461_ENABLER
printk(KERN_INFO "HD64461: enabling PCMCIA devices\n");
diff --git a/arch/sh/kernel/cpu/irq/imask.c b/arch/sh/kernel/cpu/irq/imask.c
index 32c825c9488..39b6a24c159 100644
--- a/arch/sh/kernel/cpu/irq/imask.c
+++ b/arch/sh/kernel/cpu/irq/imask.c
@@ -80,6 +80,6 @@ static struct irq_chip imask_irq_chip = {
void make_imask_irq(unsigned int irq)
{
- set_irq_chip_and_handler_name(irq, &imask_irq_chip,
- handle_level_irq, "level");
+ irq_set_chip_and_handler_name(irq, &imask_irq_chip, handle_level_irq,
+ "level");
}
diff --git a/arch/sh/kernel/cpu/irq/intc-sh5.c b/arch/sh/kernel/cpu/irq/intc-sh5.c
index 5af48f8357e..9e056a3a0c7 100644
--- a/arch/sh/kernel/cpu/irq/intc-sh5.c
+++ b/arch/sh/kernel/cpu/irq/intc-sh5.c
@@ -135,7 +135,7 @@ void __init plat_irq_setup(void)
/* Set default: per-line enable/disable, priority driven ack/eoi */
for (i = 0; i < NR_INTC_IRQS; i++)
- set_irq_chip_and_handler(i, &intc_irq_type, handle_level_irq);
+ irq_set_chip_and_handler(i, &intc_irq_type, handle_level_irq);
/* Disable all interrupts and set all priorities to 0 to avoid trouble */
diff --git a/arch/sh/kernel/cpu/irq/ipr.c b/arch/sh/kernel/cpu/irq/ipr.c
index 7516c35ee51..5de6dff5c21 100644
--- a/arch/sh/kernel/cpu/irq/ipr.c
+++ b/arch/sh/kernel/cpu/irq/ipr.c
@@ -74,9 +74,9 @@ void register_ipr_controller(struct ipr_desc *desc)
}
disable_irq_nosync(p->irq);
- set_irq_chip_and_handler_name(p->irq, &desc->chip,
- handle_level_irq, "level");
- set_irq_chip_data(p->irq, p);
+ irq_set_chip_and_handler_name(p->irq, &desc->chip,
+ handle_level_irq, "level");
+ irq_set_chip_data(p->irq, p);
disable_ipr_irq(irq_get_irq_data(p->irq));
}
}
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index f766e6bf370..e560d102215 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -51,7 +51,8 @@ config SPARC64
select HAVE_PERF_EVENTS
select PERF_USE_VMALLOC
select HAVE_GENERIC_HARDIRQS
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ select GENERIC_IRQ_SHOW
+ select IRQ_PREFLOW_FASTEOI
config ARCH_DEFCONFIG
string
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index 2f475d7c0b5..9d897b6db98 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -403,8 +403,9 @@
#define __NR_name_to_handle_at 332
#define __NR_open_by_handle_at 333
#define __NR_clock_adjtime 334
+#define __NR_syncfs 335
-#define NR_syscalls 335
+#define NR_syscalls 336
#ifdef __32bit_syscall_numbers__
/* Sparc 32-bit only has the "setresuid32", "getresuid32" variants,
diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c
index 2abace076c7..773091ac71a 100644
--- a/arch/sparc/kernel/auxio_64.c
+++ b/arch/sparc/kernel/auxio_64.c
@@ -93,7 +93,7 @@ void auxio_set_lte(int on)
}
EXPORT_SYMBOL(auxio_set_lte);
-static struct of_device_id __initdata auxio_match[] = {
+static const struct of_device_id auxio_match[] = {
{
.name = "auxio",
},
diff --git a/arch/sparc/kernel/central.c b/arch/sparc/kernel/central.c
index 136d3718a74..7eef3f74196 100644
--- a/arch/sparc/kernel/central.c
+++ b/arch/sparc/kernel/central.c
@@ -140,7 +140,7 @@ out_free:
goto out;
}
-static struct of_device_id __initdata clock_board_match[] = {
+static const struct of_device_id clock_board_match[] = {
{
.name = "clock-board",
},
@@ -245,7 +245,7 @@ out_free:
goto out;
}
-static struct of_device_id __initdata fhc_match[] = {
+static const struct of_device_id fhc_match[] = {
{
.name = "fhc",
},
diff --git a/arch/sparc/kernel/ds.c b/arch/sparc/kernel/ds.c
index 4a700f4b79c..3add4de8a1a 100644
--- a/arch/sparc/kernel/ds.c
+++ b/arch/sparc/kernel/ds.c
@@ -1218,7 +1218,7 @@ static int ds_remove(struct vio_dev *vdev)
return 0;
}
-static struct vio_device_id __initdata ds_match[] = {
+static const struct vio_device_id ds_match[] = {
{
.type = "domain-services-port",
},
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index 1504df8ddf7..906ee3e24cc 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1283,7 +1283,7 @@ linux_syscall_trace:
.globl ret_from_fork
ret_from_fork:
call schedule_tail
- mov %g3, %o0
+ ld [%g3 + TI_TASK], %o0
b ret_sys_call
ld [%sp + STACKFRAME_SZ + PT_I0], %o0
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index eb16e3b8a2d..b1d275ce343 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -162,47 +162,14 @@ void irq_free(unsigned int irq)
/*
* /proc/interrupts printing:
*/
-
-int show_interrupts(struct seq_file *p, void *v)
+int arch_show_interrupts(struct seq_file *p, int prec)
{
- int i = *(loff_t *) v, j;
- struct irqaction * action;
- unsigned long flags;
+ int j;
- if (i == 0) {
- seq_printf(p, " ");
- for_each_online_cpu(j)
- seq_printf(p, "CPU%d ",j);
- seq_putc(p, '\n');
- }
-
- if (i < NR_IRQS) {
- raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
- action = irq_desc[i].action;
- if (!action)
- goto skip;
- seq_printf(p, "%3d: ",i);
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(i));
-#else
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-#endif
- seq_printf(p, " %9s", irq_desc[i].irq_data.chip->name);
- seq_printf(p, " %s", action->name);
-
- for (action=action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
-skip:
- raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
- } else if (i == NR_IRQS) {
- seq_printf(p, "NMI: ");
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
- seq_printf(p, " Non-maskable interrupts\n");
- }
+ seq_printf(p, "NMI: ");
+ for_each_online_cpu(j)
+ seq_printf(p, "%10u ", cpu_data(j).__nmi_count);
+ seq_printf(p, " Non-maskable interrupts\n");
return 0;
}
@@ -344,10 +311,6 @@ static void sun4u_irq_disable(struct irq_data *data)
static void sun4u_irq_eoi(struct irq_data *data)
{
struct irq_handler_data *handler_data = data->handler_data;
- struct irq_desc *desc = irq_desc + data->irq;
-
- if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- return;
if (likely(handler_data))
upa_writeq(ICLR_IDLE, handler_data->iclr);
@@ -402,12 +365,8 @@ static void sun4v_irq_disable(struct irq_data *data)
static void sun4v_irq_eoi(struct irq_data *data)
{
unsigned int ino = irq_table[data->irq].dev_ino;
- struct irq_desc *desc = irq_desc + data->irq;
int err;
- if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- return;
-
err = sun4v_intr_setstate(ino, HV_INTR_STATE_IDLE);
if (err != HV_EOK)
printk(KERN_ERR "sun4v_intr_setstate(%x): "
@@ -481,13 +440,9 @@ static void sun4v_virq_disable(struct irq_data *data)
static void sun4v_virq_eoi(struct irq_data *data)
{
- struct irq_desc *desc = irq_desc + data->irq;
unsigned long dev_handle, dev_ino;
int err;
- if (unlikely(desc->status & (IRQ_DISABLED|IRQ_INPROGRESS)))
- return;
-
dev_handle = irq_table[data->irq].dev_handle;
dev_ino = irq_table[data->irq].dev_ino;
@@ -505,6 +460,7 @@ static struct irq_chip sun4u_irq = {
.irq_disable = sun4u_irq_disable,
.irq_eoi = sun4u_irq_eoi,
.irq_set_affinity = sun4u_set_affinity,
+ .flags = IRQCHIP_EOI_IF_HANDLED,
};
static struct irq_chip sun4v_irq = {
@@ -513,6 +469,7 @@ static struct irq_chip sun4v_irq = {
.irq_disable = sun4v_irq_disable,
.irq_eoi = sun4v_irq_eoi,
.irq_set_affinity = sun4v_set_affinity,
+ .flags = IRQCHIP_EOI_IF_HANDLED,
};
static struct irq_chip sun4v_virq = {
@@ -521,30 +478,28 @@ static struct irq_chip sun4v_virq = {
.irq_disable = sun4v_virq_disable,
.irq_eoi = sun4v_virq_eoi,
.irq_set_affinity = sun4v_virt_set_affinity,
+ .flags = IRQCHIP_EOI_IF_HANDLED,
};
-static void pre_flow_handler(unsigned int irq, struct irq_desc *desc)
+static void pre_flow_handler(struct irq_data *d)
{
- struct irq_handler_data *handler_data = get_irq_data(irq);
- unsigned int ino = irq_table[irq].dev_ino;
+ struct irq_handler_data *handler_data = irq_data_get_irq_handler_data(d);
+ unsigned int ino = irq_table[d->irq].dev_ino;
handler_data->pre_handler(ino, handler_data->arg1, handler_data->arg2);
-
- handle_fasteoi_irq(irq, desc);
}
void irq_install_pre_handler(int irq,
void (*func)(unsigned int, void *, void *),
void *arg1, void *arg2)
{
- struct irq_handler_data *handler_data = get_irq_data(irq);
- struct irq_desc *desc = irq_desc + irq;
+ struct irq_handler_data *handler_data = irq_get_handler_data(irq);
handler_data->pre_handler = func;
handler_data->arg1 = arg1;
handler_data->arg2 = arg2;
- desc->handle_irq = pre_flow_handler;
+ __irq_set_preflow_handler(irq, pre_flow_handler);
}
unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
@@ -562,13 +517,11 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
if (!irq) {
irq = irq_alloc(0, ino);
bucket_set_irq(__pa(bucket), irq);
- set_irq_chip_and_handler_name(irq,
- &sun4u_irq,
- handle_fasteoi_irq,
- "IVEC");
+ irq_set_chip_and_handler_name(irq, &sun4u_irq,
+ handle_fasteoi_irq, "IVEC");
}
- handler_data = get_irq_data(irq);
+ handler_data = irq_get_handler_data(irq);
if (unlikely(handler_data))
goto out;
@@ -577,7 +530,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap)
prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n");
prom_halt();
}
- set_irq_data(irq, handler_data);
+ irq_set_handler_data(irq, handler_data);
handler_data->imap = imap;
handler_data->iclr = iclr;
@@ -600,12 +553,11 @@ static unsigned int sun4v_build_common(unsigned long sysino,
if (!irq) {
irq = irq_alloc(0, sysino);
bucket_set_irq(__pa(bucket), irq);
- set_irq_chip_and_handler_name(irq, chip,
- handle_fasteoi_irq,
+ irq_set_chip_and_handler_name(irq, chip, handle_fasteoi_irq,
"IVEC");
}
- handler_data = get_irq_data(irq);
+ handler_data = irq_get_handler_data(irq);
if (unlikely(handler_data))
goto out;
@@ -614,7 +566,7 @@ static unsigned int sun4v_build_common(unsigned long sysino,
prom_printf("IRQ: kzalloc(irq_handler_data) failed.\n");
prom_halt();
}
- set_irq_data(irq, handler_data);
+ irq_set_handler_data(irq, handler_data);
/* Catch accidental accesses to these things. IMAP/ICLR handling
* is done by hypervisor calls on sun4v platforms, not by direct
@@ -639,7 +591,6 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
struct irq_handler_data *handler_data;
unsigned long hv_err, cookie;
struct ino_bucket *bucket;
- struct irq_desc *desc;
unsigned int irq;
bucket = kzalloc(sizeof(struct ino_bucket), GFP_ATOMIC);
@@ -660,8 +611,7 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
irq = irq_alloc(devhandle, devino);
bucket_set_irq(__pa(bucket), irq);
- set_irq_chip_and_handler_name(irq, &sun4v_virq,
- handle_fasteoi_irq,
+ irq_set_chip_and_handler_name(irq, &sun4v_virq, handle_fasteoi_irq,
"IVEC");
handler_data = kzalloc(sizeof(struct irq_handler_data), GFP_ATOMIC);
@@ -672,10 +622,8 @@ unsigned int sun4v_build_virq(u32 devhandle, unsigned int devino)
* especially wrt. locking, we do not let request_irq() enable
* the interrupt.
*/
- desc = irq_desc + irq;
- desc->status |= IRQ_NOAUTOEN;
-
- set_irq_data(irq, handler_data);
+ irq_set_status_flags(irq, IRQ_NOAUTOEN);
+ irq_set_handler_data(irq, handler_data);
/* Catch accidental accesses to these things. IMAP/ICLR handling
* is done by hypervisor calls on sun4v platforms, not by direct
@@ -734,7 +682,6 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs)
orig_sp = set_hardirq_stack();
while (bucket_pa) {
- struct irq_desc *desc;
unsigned long next_pa;
unsigned int irq;
@@ -742,10 +689,7 @@ void __irq_entry handler_irq(int pil, struct pt_regs *regs)
irq = bucket_get_irq(bucket_pa);
bucket_clear_chain_pa(bucket_pa);
- desc = irq_desc + irq;
-
- if (!(desc->status & IRQ_DISABLED))
- desc->handle_irq(irq, desc);
+ generic_handle_irq(irq);
bucket_pa = next_pa;
}
@@ -788,19 +732,18 @@ void fixup_irqs(void)
unsigned int irq;
for (irq = 0; irq < NR_IRQS; irq++) {
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_data *data = irq_desc_get_irq_data(desc);
unsigned long flags;
- raw_spin_lock_irqsave(&irq_desc[irq].lock, flags);
- if (irq_desc[irq].action &&
- !(irq_desc[irq].status & IRQ_PER_CPU)) {
- struct irq_data *data = irq_get_irq_data(irq);
-
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ if (desc->action && !irqd_is_per_cpu(data)) {
if (data->chip->irq_set_affinity)
data->chip->irq_set_affinity(data,
- data->affinity,
- false);
+ data->affinity,
+ false);
}
- raw_spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
}
tick_ops->disable_irq();
@@ -1038,5 +981,5 @@ void __init init_IRQ(void)
: "i" (PSTATE_IE)
: "g1");
- irq_desc[0].action = &timer_irq_action;
+ irq_to_desc(0)->action = &timer_irq_action;
}
diff --git a/arch/sparc/kernel/mdesc.c b/arch/sparc/kernel/mdesc.c
index 6addb914fcc..56db06432ce 100644
--- a/arch/sparc/kernel/mdesc.c
+++ b/arch/sparc/kernel/mdesc.c
@@ -107,7 +107,7 @@ static struct mdesc_handle * __init mdesc_memblock_alloc(unsigned int mdesc_size
return hp;
}
-static void mdesc_memblock_free(struct mdesc_handle *hp)
+static void __init mdesc_memblock_free(struct mdesc_handle *hp)
{
unsigned int alloc_size;
unsigned long start;
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 44f41e312f7..713dc91020a 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -1012,7 +1012,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
void arch_teardown_msi_irq(unsigned int irq)
{
- struct msi_desc *entry = get_irq_msi(irq);
+ struct msi_desc *entry = irq_get_msi_desc(irq);
struct pci_dev *pdev = entry->dev;
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
diff --git a/arch/sparc/kernel/pci_fire.c b/arch/sparc/kernel/pci_fire.c
index 3d70f8326ef..d29a32fcc5e 100644
--- a/arch/sparc/kernel/pci_fire.c
+++ b/arch/sparc/kernel/pci_fire.c
@@ -496,7 +496,7 @@ out_err:
return err;
}
-static struct of_device_id __initdata fire_match[] = {
+static const struct of_device_id fire_match[] = {
{
.name = "pci",
.compatible = "pciex108e,80f0",
diff --git a/arch/sparc/kernel/pci_msi.c b/arch/sparc/kernel/pci_msi.c
index 550e937720e..30982e9ab62 100644
--- a/arch/sparc/kernel/pci_msi.c
+++ b/arch/sparc/kernel/pci_msi.c
@@ -30,13 +30,10 @@ static irqreturn_t sparc64_msiq_interrupt(int irq, void *cookie)
err = ops->dequeue_msi(pbm, msiqid, &head, &msi);
if (likely(err > 0)) {
- struct irq_desc *desc;
unsigned int irq;
irq = pbm->msi_irq_table[msi - pbm->msi_first];
- desc = irq_desc + irq;
-
- desc->handle_irq(irq, desc);
+ generic_handle_irq(irq);
}
if (unlikely(err < 0))
@@ -136,8 +133,8 @@ static int sparc64_setup_msi_irq(unsigned int *irq_p,
if (!*irq_p)
goto out_err;
- set_irq_chip_and_handler_name(*irq_p, &msi_irq,
- handle_simple_irq, "MSI");
+ irq_set_chip_and_handler_name(*irq_p, &msi_irq, handle_simple_irq,
+ "MSI");
err = alloc_msi(pbm);
if (unlikely(err < 0))
@@ -163,7 +160,7 @@ static int sparc64_setup_msi_irq(unsigned int *irq_p,
}
msg.data = msi;
- set_irq_msi(*irq_p, entry);
+ irq_set_msi_desc(*irq_p, entry);
write_msi_msg(*irq_p, &msg);
return 0;
@@ -172,7 +169,7 @@ out_msi_free:
free_msi(pbm, msi);
out_irq_free:
- set_irq_chip(*irq_p, NULL);
+ irq_set_chip(*irq_p, NULL);
irq_free(*irq_p);
*irq_p = 0;
@@ -211,7 +208,7 @@ static void sparc64_teardown_msi_irq(unsigned int irq,
free_msi(pbm, msi_num);
- set_irq_chip(irq, NULL);
+ irq_set_chip(irq, NULL);
irq_free(irq);
}
diff --git a/arch/sparc/kernel/pci_psycho.c b/arch/sparc/kernel/pci_psycho.c
index 56ee745064d..86ae08d9b6e 100644
--- a/arch/sparc/kernel/pci_psycho.c
+++ b/arch/sparc/kernel/pci_psycho.c
@@ -592,7 +592,7 @@ out_err:
return err;
}
-static struct of_device_id __initdata psycho_match[] = {
+static const struct of_device_id psycho_match[] = {
{
.name = "pci",
.compatible = "pci108e,8000",
diff --git a/arch/sparc/kernel/pci_sabre.c b/arch/sparc/kernel/pci_sabre.c
index 2857073342d..948068a083f 100644
--- a/arch/sparc/kernel/pci_sabre.c
+++ b/arch/sparc/kernel/pci_sabre.c
@@ -581,7 +581,7 @@ out_err:
return err;
}
-static struct of_device_id __initdata sabre_match[] = {
+static const struct of_device_id sabre_match[] = {
{
.name = "pci",
.compatible = "pci108e,a001",
diff --git a/arch/sparc/kernel/pci_schizo.c b/arch/sparc/kernel/pci_schizo.c
index 1d41af73a92..fecfcb2063c 100644
--- a/arch/sparc/kernel/pci_schizo.c
+++ b/arch/sparc/kernel/pci_schizo.c
@@ -1470,7 +1470,7 @@ static int __devinit schizo_probe(struct platform_device *op)
* and pci108e,8001. So list the chips in reverse chronological
* order.
*/
-static struct of_device_id __initdata schizo_match[] = {
+static const struct of_device_id schizo_match[] = {
{
.name = "pci",
.compatible = "pci108e,a801",
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 6cf53468178..b01a06e9ae4 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -998,7 +998,7 @@ out_err:
return err;
}
-static struct of_device_id __initdata pci_sun4v_match[] = {
+static const struct of_device_id pci_sun4v_match[] = {
{
.name = "pci",
.compatible = "SUNW,sun4v-pci",
diff --git a/arch/sparc/kernel/power.c b/arch/sparc/kernel/power.c
index cd725fe238b..cb4c0f57c02 100644
--- a/arch/sparc/kernel/power.c
+++ b/arch/sparc/kernel/power.c
@@ -52,7 +52,7 @@ static int __devinit power_probe(struct platform_device *op)
return 0;
}
-static struct of_device_id __initdata power_match[] = {
+static const struct of_device_id power_match[] = {
{
.name = "power",
},
diff --git a/arch/sparc/kernel/systbls_32.S b/arch/sparc/kernel/systbls_32.S
index 4b86eaf04fe..47ac73c32e8 100644
--- a/arch/sparc/kernel/systbls_32.S
+++ b/arch/sparc/kernel/systbls_32.S
@@ -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
diff --git a/arch/sparc/kernel/systbls_64.S b/arch/sparc/kernel/systbls_64.S
index 0331bafdf3a..4f3170c1ef4 100644
--- a/arch/sparc/kernel/systbls_64.S
+++ b/arch/sparc/kernel/systbls_64.S
@@ -85,6 +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
#endif /* CONFIG_COMPAT */
@@ -161,3 +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
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 95ec25faba3..2b8d54b2d85 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -442,7 +442,7 @@ static int __devinit rtc_probe(struct platform_device *op)
return platform_device_register(&rtc_cmos_device);
}
-static struct of_device_id __initdata rtc_match[] = {
+static const struct of_device_id rtc_match[] = {
{
.name = "rtc",
.compatible = "m5819",
@@ -487,7 +487,7 @@ static int __devinit bq4802_probe(struct platform_device *op)
return platform_device_register(&rtc_bq4802_device);
}
-static struct of_device_id __initdata bq4802_match[] = {
+static const struct of_device_id bq4802_match[] = {
{
.name = "rtc",
.compatible = "bq4802",
@@ -552,7 +552,7 @@ static int __devinit mostek_probe(struct platform_device *op)
return platform_device_register(&m48t59_rtc);
}
-static struct of_device_id __initdata mostek_match[] = {
+static const struct of_device_id mostek_match[] = {
{
.name = "eeprom",
},
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index f3b78701c21..6e2cdd5ae96 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -11,7 +11,7 @@ config TILE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select GENERIC_PENDING_IRQ if SMP
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ select GENERIC_IRQ_SHOW
# FIXME: investigate whether we need/want these options.
# select HAVE_IOREMAP_PROT
diff --git a/arch/tile/kernel/irq.c b/arch/tile/kernel/irq.c
index 0baa7580121..aa0134db2dd 100644
--- a/arch/tile/kernel/irq.c
+++ b/arch/tile/kernel/irq.c
@@ -241,14 +241,14 @@ void tile_irq_activate(unsigned int irq, int tile_irq_type)
irq_flow_handler_t handle = handle_level_irq;
if (tile_irq_type == TILE_IRQ_PERCPU)
handle = handle_percpu_irq;
- set_irq_chip_and_handler(irq, &tile_irq_chip, handle);
+ irq_set_chip_and_handler(irq, &tile_irq_chip, handle);
/*
* Flag interrupts that are hardware-cleared so that ack()
* won't clear them.
*/
if (tile_irq_type == TILE_IRQ_HW_CLEAR)
- set_irq_chip_data(irq, (void *)IS_HW_CLEARED);
+ irq_set_chip_data(irq, (void *)IS_HW_CLEARED);
}
EXPORT_SYMBOL(tile_irq_activate);
@@ -262,47 +262,6 @@ void ack_bad_irq(unsigned int irq)
* Generic, controller-independent functions:
*/
-int show_interrupts(struct seq_file *p, void *v)
-{
- int i = *(loff_t *) v, j;
- struct irqaction *action;
- unsigned long flags;
-
- if (i == 0) {
- seq_printf(p, " ");
- for (j = 0; j < NR_CPUS; j++)
- if (cpu_online(j))
- seq_printf(p, "CPU%-8d", j);
- seq_putc(p, '\n');
- }
-
- if (i < NR_IRQS) {
- struct irq_desc *desc = irq_to_desc(i);
-
- raw_spin_lock_irqsave(&desc->lock, flags);
- action = desc->action;
- if (!action)
- goto skip;
- seq_printf(p, "%3d: ", i);
-#ifndef CONFIG_SMP
- seq_printf(p, "%10u ", kstat_irqs(i));
-#else
- for_each_online_cpu(j)
- seq_printf(p, "%10u ", kstat_irqs_cpu(i, j));
-#endif
- seq_printf(p, " %14s", get_irq_desc_chip(desc)->name);
- seq_printf(p, " %s", action->name);
-
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
-skip:
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- }
- return 0;
-}
-
#if CHIP_HAS_IPI()
int create_irq(void)
{
diff --git a/arch/um/Kconfig.common b/arch/um/Kconfig.common
index 109ddc0071c..a9234838e8a 100644
--- a/arch/um/Kconfig.common
+++ b/arch/um/Kconfig.common
@@ -7,7 +7,6 @@ config UML
bool
default y
select HAVE_GENERIC_HARDIRQS
- select GENERIC_HARDIRQS_NO_DEPRECATED
select GENERIC_IRQ_SHOW
config MMU
diff --git a/arch/unicore32/Kconfig b/arch/unicore32/Kconfig
index 4a36db45fb3..d3a303246c9 100644
--- a/arch/unicore32/Kconfig
+++ b/arch/unicore32/Kconfig
@@ -10,7 +10,7 @@ config UNICORE32
select HAVE_KERNEL_LZMA
select GENERIC_FIND_FIRST_BIT
select GENERIC_IRQ_PROBE
- select GENERIC_HARDIRQS_NO_DEPRECATED
+ select GENERIC_IRQ_SHOW
select ARCH_WANT_FRAME_POINTERS
help
UniCore-32 is 32-bit Instruction Set Architecture,
diff --git a/arch/unicore32/kernel/irq.c b/arch/unicore32/kernel/irq.c
index b23624cf306..2aa30a364bb 100644
--- a/arch/unicore32/kernel/irq.c
+++ b/arch/unicore32/kernel/irq.c
@@ -321,24 +321,24 @@ void __init init_IRQ(void)
writel(1, INTC_ICCR);
for (irq = 0; irq < IRQ_GPIOHIGH; irq++) {
- set_irq_chip(irq, &puv3_low_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip(irq, &puv3_low_gpio_chip);
+ irq_set_handler(irq, handle_edge_irq);
irq_modify_status(irq,
IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN,
0);
}
for (irq = IRQ_GPIOHIGH + 1; irq < IRQ_GPIO0; irq++) {
- set_irq_chip(irq, &puv3_normal_chip);
- set_irq_handler(irq, handle_level_irq);
+ irq_set_chip(irq, &puv3_normal_chip);
+ irq_set_handler(irq, handle_level_irq);
irq_modify_status(irq,
IRQ_NOREQUEST | IRQ_NOAUTOEN,
IRQ_NOPROBE);
}
for (irq = IRQ_GPIO0; irq <= IRQ_GPIO27; irq++) {
- set_irq_chip(irq, &puv3_high_gpio_chip);
- set_irq_handler(irq, handle_edge_irq);
+ irq_set_chip(irq, &puv3_high_gpio_chip);
+ irq_set_handler(irq, handle_edge_irq);
irq_modify_status(irq,
IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN,
0);
@@ -347,56 +347,14 @@ void __init init_IRQ(void)
/*
* Install handler for GPIO 0-27 edge detect interrupts
*/
- set_irq_chip(IRQ_GPIOHIGH, &puv3_normal_chip);
- set_irq_chained_handler(IRQ_GPIOHIGH, puv3_gpio_handler);
+ irq_set_chip(IRQ_GPIOHIGH, &puv3_normal_chip);
+ irq_set_chained_handler(IRQ_GPIOHIGH, puv3_gpio_handler);
#ifdef CONFIG_PUV3_GPIO
puv3_init_gpio();
#endif
}
-int show_interrupts(struct seq_file *p, void *v)
-{
- int i = *(loff_t *) v, cpu;
- struct irq_desc *desc;
- struct irqaction *action;
- unsigned long flags;
-
- if (i == 0) {
- char cpuname[12];
-
- seq_printf(p, " ");
- for_each_present_cpu(cpu) {
- sprintf(cpuname, "CPU%d", cpu);
- seq_printf(p, " %10s", cpuname);
- }
- seq_putc(p, '\n');
- }
-
- if (i < nr_irqs) {
- desc = irq_to_desc(i);
- raw_spin_lock_irqsave(&desc->lock, flags);
- action = desc->action;
- if (!action)
- goto unlock;
-
- seq_printf(p, "%3d: ", i);
- for_each_present_cpu(cpu)
- seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu));
- seq_printf(p, " %10s", desc->irq_data.chip->name ? : "-");
- seq_printf(p, " %s", action->name);
- for (action = action->next; action; action = action->next)
- seq_printf(p, ", %s", action->name);
-
- seq_putc(p, '\n');
-unlock:
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- } else if (i == nr_irqs) {
- seq_printf(p, "Error in interrupt!\n");
- }
- return 0;
-}
-
/*
* do_IRQ handles all hardware IRQ's. Decoded IRQs should not
* come via this function. Instead, they should provide their
diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S
index adcf794b22e..be6d9e365a8 100644
--- a/arch/x86/crypto/aesni-intel_asm.S
+++ b/arch/x86/crypto/aesni-intel_asm.S
@@ -1612,6 +1612,7 @@ _zero_cipher_left_encrypt:
movdqa SHUF_MASK(%rip), %xmm10
PSHUFB_XMM %xmm10, %xmm0
+
ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn)
sub $16, %r11
add %r13, %r11
@@ -1634,7 +1635,9 @@ _zero_cipher_left_encrypt:
# GHASH computation for the last <16 byte block
sub %r13, %r11
add $16, %r11
- PSHUFB_XMM %xmm10, %xmm1
+
+ movdqa SHUF_MASK(%rip), %xmm10
+ PSHUFB_XMM %xmm10, %xmm0
# shuffle xmm0 back to output as ciphertext
diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c
index e0e6340c8da..2577613fb32 100644
--- a/arch/x86/crypto/aesni-intel_glue.c
+++ b/arch/x86/crypto/aesni-intel_glue.c
@@ -828,9 +828,15 @@ static int rfc4106_init(struct crypto_tfm *tfm)
struct cryptd_aead *cryptd_tfm;
struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *)
PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN);
+ struct crypto_aead *cryptd_child;
+ struct aesni_rfc4106_gcm_ctx *child_ctx;
cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0);
if (IS_ERR(cryptd_tfm))
return PTR_ERR(cryptd_tfm);
+
+ cryptd_child = cryptd_aead_child(cryptd_tfm);
+ child_ctx = aesni_rfc4106_gcm_ctx_get(cryptd_child);
+ memcpy(child_ctx, ctx, sizeof(*ctx));
ctx->cryptd_tfm = cryptd_tfm;
tfm->crt_aead.reqsize = sizeof(struct aead_request)
+ crypto_aead_reqsize(&cryptd_tfm->base);
@@ -923,6 +929,9 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
int ret = 0;
struct crypto_tfm *tfm = crypto_aead_tfm(parent);
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent);
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
+ struct aesni_rfc4106_gcm_ctx *child_ctx =
+ aesni_rfc4106_gcm_ctx_get(cryptd_child);
u8 *new_key_mem = NULL;
if (key_len < 4) {
@@ -966,6 +975,7 @@ static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key,
goto exit;
}
ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len);
+ memcpy(child_ctx, ctx, sizeof(*ctx));
exit:
kfree(new_key_mem);
return ret;
@@ -997,7 +1007,6 @@ static int rfc4106_encrypt(struct aead_request *req)
int ret;
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
- struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
if (!irq_fpu_usable()) {
struct aead_request *cryptd_req =
@@ -1006,6 +1015,7 @@ static int rfc4106_encrypt(struct aead_request *req)
aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
return crypto_aead_encrypt(cryptd_req);
} else {
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
kernel_fpu_begin();
ret = cryptd_child->base.crt_aead.encrypt(req);
kernel_fpu_end();
@@ -1018,7 +1028,6 @@ static int rfc4106_decrypt(struct aead_request *req)
int ret;
struct crypto_aead *tfm = crypto_aead_reqtfm(req);
struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm);
- struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
if (!irq_fpu_usable()) {
struct aead_request *cryptd_req =
@@ -1027,6 +1036,7 @@ static int rfc4106_decrypt(struct aead_request *req)
aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base);
return crypto_aead_decrypt(cryptd_req);
} else {
+ struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm);
kernel_fpu_begin();
ret = cryptd_child->base.crt_aead.decrypt(req);
kernel_fpu_end();
diff --git a/arch/x86/kernel/apb_timer.c b/arch/x86/kernel/apb_timer.c
index 1293c709ee8..cd1ffed4ee2 100644
--- a/arch/x86/kernel/apb_timer.c
+++ b/arch/x86/kernel/apb_timer.c
@@ -316,7 +316,7 @@ static void apbt_setup_irq(struct apbt_dev *adev)
irq_modify_status(adev->irq, 0, IRQ_MOVE_PCNTXT);
irq_set_affinity(adev->irq, cpumask_of(adev->cpu));
/* APB timer irqs are set up as mp_irqs, timer is edge type */
- __set_irq_handler(adev->irq, handle_edge_irq, 0, "edge");
+ __irq_set_handler(adev->irq, handle_edge_irq, 0, "edge");
if (system_state == SYSTEM_BOOTING) {
if (request_irq(adev->irq, apbt_interrupt_handler,
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c
index 215a3ce6106..141eb0de8b0 100644
--- a/arch/x86/xen/p2m.c
+++ b/arch/x86/xen/p2m.c
@@ -497,7 +497,7 @@ static bool alloc_p2m(unsigned long pfn)
return true;
}
-bool __early_alloc_p2m(unsigned long pfn)
+static bool __init __early_alloc_p2m(unsigned long pfn)
{
unsigned topidx, mididx, idx;
@@ -530,7 +530,7 @@ bool __early_alloc_p2m(unsigned long pfn)
}
return idx != 0;
}
-unsigned long set_phys_range_identity(unsigned long pfn_s,
+unsigned long __init set_phys_range_identity(unsigned long pfn_s,
unsigned long pfn_e)
{
unsigned long pfn;
@@ -671,7 +671,9 @@ int m2p_add_override(unsigned long mfn, struct page *page)
page->private = mfn;
page->index = pfn_to_mfn(pfn);
- __set_phys_to_machine(pfn, FOREIGN_FRAME(mfn));
+ if (unlikely(!set_phys_to_machine(pfn, FOREIGN_FRAME(mfn))))
+ return -ENOMEM;
+
if (!PageHighMem(page))
/* Just zap old mapping for now */
pte_clear(&init_mm, address, ptep);
@@ -709,7 +711,7 @@ int m2p_remove_override(struct page *page)
spin_lock_irqsave(&m2p_override_lock, flags);
list_del(&page->lru);
spin_unlock_irqrestore(&m2p_override_lock, flags);
- __set_phys_to_machine(pfn, page->index);
+ set_phys_to_machine(pfn, page->index);
if (!PageHighMem(page))
set_pte_at(&init_mm, address, ptep,
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 1d730b5579a..7c275f5d0df 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -9,7 +9,6 @@ config XTENSA
select HAVE_IDE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
- select GENERIC_HARDIRQS_NO_DEPRECATED
help
Xtensa processors are 32-bit RISC machines designed by Tensilica
primarily for embedded systems. These processors are both
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index a18e497f1c3..31e9e10f657 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -824,11 +824,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
device->backlight->props.brightness =
acpi_video_get_brightness(device->backlight);
- result = sysfs_create_link(&device->backlight->dev.kobj,
- &device->dev->dev.kobj, "device");
- if (result)
- printk(KERN_ERR PREFIX "Create sysfs link\n");
-
device->cooling_dev = thermal_cooling_device_register("LCD",
device->dev, &video_cooling_ops);
if (IS_ERR(device->cooling_dev)) {
@@ -1381,7 +1376,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
"Cant remove video notify handler\n");
}
if (device->backlight) {
- sysfs_remove_link(&device->backlight->dev.kobj, "device");
backlight_device_unregister(device->backlight);
device->backlight = NULL;
}
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 5253b271b3f..f6b3f995f58 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -167,7 +167,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0);
if (irq)
- set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
/* Setup expansion bus chip selects */
*data->cs0_cfg = data->cs0_bits;
diff --git a/drivers/ata/pata_palmld.c b/drivers/ata/pata_palmld.c
index a2a73d95384..b86d7e22595 100644
--- a/drivers/ata/pata_palmld.c
+++ b/drivers/ata/pata_palmld.c
@@ -33,6 +33,11 @@
#define DRV_NAME "pata_palmld"
+static struct gpio palmld_hdd_gpios[] = {
+ { GPIO_NR_PALMLD_IDE_PWEN, GPIOF_INIT_HIGH, "HDD Power" },
+ { GPIO_NR_PALMLD_IDE_RESET, GPIOF_INIT_LOW, "HDD Reset" },
+};
+
static struct scsi_host_template palmld_sht = {
ATA_PIO_SHT(DRV_NAME),
};
@@ -52,28 +57,23 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev)
/* allocate host */
host = ata_host_alloc(&pdev->dev, 1);
- if (!host)
- return -ENOMEM;
+ if (!host) {
+ ret = -ENOMEM;
+ goto err1;
+ }
/* remap drive's physical memory address */
mem = devm_ioremap(&pdev->dev, PALMLD_IDE_PHYS, 0x1000);
- if (!mem)
- return -ENOMEM;
+ if (!mem) {
+ ret = -ENOMEM;
+ goto err1;
+ }
/* request and activate power GPIO, IRQ GPIO */
- ret = gpio_request(GPIO_NR_PALMLD_IDE_PWEN, "HDD PWR");
+ ret = gpio_request_array(palmld_hdd_gpios,
+ ARRAY_SIZE(palmld_hdd_gpios));
if (ret)
goto err1;
- ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_PWEN, 1);
- if (ret)
- goto err2;
-
- ret = gpio_request(GPIO_NR_PALMLD_IDE_RESET, "HDD RST");
- if (ret)
- goto err2;
- ret = gpio_direction_output(GPIO_NR_PALMLD_IDE_RESET, 0);
- if (ret)
- goto err3;
/* reset the drive */
gpio_set_value(GPIO_NR_PALMLD_IDE_RESET, 0);
@@ -96,13 +96,15 @@ static __devinit int palmld_pata_probe(struct platform_device *pdev)
ata_sff_std_ports(&ap->ioaddr);
/* activate host */
- return ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING,
+ ret = ata_host_activate(host, 0, NULL, IRQF_TRIGGER_RISING,
&palmld_sht);
+ if (ret)
+ goto err2;
+
+ return ret;
-err3:
- gpio_free(GPIO_NR_PALMLD_IDE_RESET);
err2:
- gpio_free(GPIO_NR_PALMLD_IDE_PWEN);
+ gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
err1:
return ret;
}
@@ -116,8 +118,7 @@ static __devexit int palmld_pata_remove(struct platform_device *dev)
/* power down the HDD */
gpio_set_value(GPIO_NR_PALMLD_IDE_PWEN, 0);
- gpio_free(GPIO_NR_PALMLD_IDE_RESET);
- gpio_free(GPIO_NR_PALMLD_IDE_PWEN);
+ gpio_free_array(palmld_hdd_gpios, ARRAY_SIZE(palmld_hdd_gpios));
return 0;
}
diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c
index baeaf938d55..1b9d10d9c5d 100644
--- a/drivers/ata/pata_rb532_cf.c
+++ b/drivers/ata/pata_rb532_cf.c
@@ -60,10 +60,10 @@ static irqreturn_t rb532_pata_irq_handler(int irq, void *dev_instance)
struct rb532_cf_info *info = ah->private_data;
if (gpio_get_value(info->gpio_line)) {
- set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
ata_sff_interrupt(info->irq, dev_instance);
} else {
- set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
}
return IRQ_HANDLED;
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 25ef1a4556e..cd0ff66469b 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -165,7 +165,6 @@ static uint32_t fpga_tx(struct solos_card *);
static irqreturn_t solos_irq(int irq, void *dev_id);
static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci);
static int list_vccs(int vci);
-static void release_vccs(struct atm_dev *dev);
static int atm_init(struct solos_card *, struct device *);
static void atm_remove(struct solos_card *);
static int send_command(struct solos_card *card, int dev, const char *buf, size_t size);
@@ -384,7 +383,6 @@ static int process_status(struct solos_card *card, int port, struct sk_buff *skb
/* Anything but 'Showtime' is down */
if (strcmp(state_str, "Showtime")) {
atm_dev_signal_change(card->atmdev[port], ATM_PHY_SIG_LOST);
- release_vccs(card->atmdev[port]);
dev_info(&card->dev->dev, "Port %d: %s\n", port, state_str);
return 0;
}
@@ -697,7 +695,7 @@ void solos_bh(unsigned long card_arg)
size);
}
if (atmdebug) {
- dev_info(&card->dev->dev, "Received: device %d\n", port);
+ dev_info(&card->dev->dev, "Received: port %d\n", port);
dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
size, le16_to_cpu(header->vpi),
le16_to_cpu(header->vci));
@@ -710,8 +708,8 @@ void solos_bh(unsigned long card_arg)
le16_to_cpu(header->vci));
if (!vcc) {
if (net_ratelimit())
- dev_warn(&card->dev->dev, "Received packet for unknown VCI.VPI %d.%d on port %d\n",
- le16_to_cpu(header->vci), le16_to_cpu(header->vpi),
+ dev_warn(&card->dev->dev, "Received packet for unknown VPI.VCI %d.%d on port %d\n",
+ le16_to_cpu(header->vpi), le16_to_cpu(header->vci),
port);
continue;
}
@@ -830,28 +828,6 @@ static int list_vccs(int vci)
return num_found;
}
-static void release_vccs(struct atm_dev *dev)
-{
- int i;
-
- write_lock_irq(&vcc_sklist_lock);
- for (i = 0; i < VCC_HTABLE_SIZE; i++) {
- struct hlist_head *head = &vcc_hash[i];
- struct hlist_node *node, *tmp;
- struct sock *s;
- struct atm_vcc *vcc;
-
- sk_for_each_safe(s, node, tmp, head) {
- vcc = atm_sk(s);
- if (vcc->dev == dev) {
- vcc_release_async(vcc, -EPIPE);
- sk_del_node_init(s);
- }
- }
- }
- write_unlock_irq(&vcc_sklist_lock);
-}
-
static int popen(struct atm_vcc *vcc)
{
@@ -1018,8 +994,15 @@ static uint32_t fpga_tx(struct solos_card *card)
/* Clean up and free oldskb now it's gone */
if (atmdebug) {
+ struct pkt_hdr *header = (void *)oldskb->data;
+ int size = le16_to_cpu(header->size);
+
+ skb_pull(oldskb, sizeof(*header));
dev_info(&card->dev->dev, "Transmitted: port %d\n",
port);
+ dev_info(&card->dev->dev, "size: %d VPI: %d VCI: %d\n",
+ size, le16_to_cpu(header->vpi),
+ le16_to_cpu(header->vci));
print_buffer(oldskb);
}
@@ -1262,7 +1245,7 @@ static int atm_init(struct solos_card *card, struct device *parent)
card->atmdev[i]->ci_range.vci_bits = 16;
card->atmdev[i]->dev_data = card;
card->atmdev[i]->phy_data = (void *)(unsigned long)i;
- atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_UNKNOWN);
+ atm_dev_signal_change(card->atmdev[i], ATM_PHY_SIG_FOUND);
skb = alloc_skb(sizeof(*header), GFP_ATOMIC);
if (!skb) {
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c
index f0ae63d2df6..76210ba401a 100644
--- a/drivers/block/drbd/drbd_bitmap.c
+++ b/drivers/block/drbd/drbd_bitmap.c
@@ -29,8 +29,6 @@
#include <linux/slab.h>
#include <asm/kmap_types.h>
-#include <asm-generic/bitops/le.h>
-
#include "drbd_int.h"
@@ -1184,10 +1182,10 @@ static unsigned long __bm_find_next(struct drbd_conf *mdev, unsigned long bm_fo,
p_addr = __bm_map_pidx(b, bm_bit_to_page_idx(b, bm_fo), km);
if (find_zero_bit)
- i = generic_find_next_zero_le_bit(p_addr,
+ i = find_next_zero_bit_le(p_addr,
PAGE_SIZE*8, bm_fo & BITS_PER_PAGE_MASK);
else
- i = generic_find_next_le_bit(p_addr,
+ i = find_next_bit_le(p_addr,
PAGE_SIZE*8, bm_fo & BITS_PER_PAGE_MASK);
__bm_unmap(p_addr, km);
@@ -1287,9 +1285,9 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s,
last_page_nr = page_nr;
}
if (val)
- c += (0 == generic___test_and_set_le_bit(bitnr & BITS_PER_PAGE_MASK, p_addr));
+ c += (0 == __test_and_set_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr));
else
- c -= (0 != generic___test_and_clear_le_bit(bitnr & BITS_PER_PAGE_MASK, p_addr));
+ c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr));
}
if (p_addr)
__bm_unmap(p_addr, km);
@@ -1438,7 +1436,7 @@ int drbd_bm_test_bit(struct drbd_conf *mdev, const unsigned long bitnr)
bm_print_lock_info(mdev);
if (bitnr < b->bm_bits) {
p_addr = bm_map_pidx(b, bm_bit_to_page_idx(b, bitnr));
- i = generic_test_le_bit(bitnr & BITS_PER_PAGE_MASK, p_addr) ? 1 : 0;
+ i = test_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr) ? 1 : 0;
bm_unmap(p_addr);
} else if (bitnr == b->bm_bits) {
i = -1;
@@ -1482,7 +1480,7 @@ int drbd_bm_count_bits(struct drbd_conf *mdev, const unsigned long s, const unsi
ERR_IF (bitnr >= b->bm_bits) {
dev_err(DEV, "bitnr=%lu bm_bits=%lu\n", bitnr, b->bm_bits);
} else {
- c += (0 != generic_test_le_bit(bitnr - (page_nr << (PAGE_SHIFT+3)), p_addr));
+ c += (0 != test_bit_le(bitnr - (page_nr << (PAGE_SHIFT+3)), p_addr));
}
}
if (p_addr)
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index 1f46f1cd922..7beb0e25f1e 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -980,7 +980,7 @@ int tpm_open(struct inode *inode, struct file *file)
return -EBUSY;
}
- chip->data_buffer = kmalloc(TPM_BUFSIZE * sizeof(u8), GFP_KERNEL);
+ chip->data_buffer = kzalloc(TPM_BUFSIZE, GFP_KERNEL);
if (chip->data_buffer == NULL) {
clear_bit(0, &chip->is_open);
put_device(chip->dev);
diff --git a/drivers/connector/cn_queue.c b/drivers/connector/cn_queue.c
index 55653aba673..c42c9d51779 100644
--- a/drivers/connector/cn_queue.c
+++ b/drivers/connector/cn_queue.c
@@ -31,24 +31,9 @@
#include <linux/connector.h>
#include <linux/delay.h>
-void cn_queue_wrapper(struct work_struct *work)
-{
- struct cn_callback_entry *cbq =
- container_of(work, struct cn_callback_entry, work);
- struct cn_callback_data *d = &cbq->data;
- struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(d->skb));
- struct netlink_skb_parms *nsp = &NETLINK_CB(d->skb);
-
- d->callback(msg, nsp);
-
- kfree_skb(d->skb);
- d->skb = NULL;
-
- kfree(d->free);
-}
-
static struct cn_callback_entry *
-cn_queue_alloc_callback_entry(const char *name, struct cb_id *id,
+cn_queue_alloc_callback_entry(struct cn_queue_dev *dev, const char *name,
+ struct cb_id *id,
void (*callback)(struct cn_msg *, struct netlink_skb_parms *))
{
struct cn_callback_entry *cbq;
@@ -59,17 +44,23 @@ cn_queue_alloc_callback_entry(const char *name, struct cb_id *id,
return NULL;
}
+ atomic_set(&cbq->refcnt, 1);
+
+ atomic_inc(&dev->refcnt);
+ cbq->pdev = dev;
+
snprintf(cbq->id.name, sizeof(cbq->id.name), "%s", name);
memcpy(&cbq->id.id, id, sizeof(struct cb_id));
- cbq->data.callback = callback;
-
- INIT_WORK(&cbq->work, &cn_queue_wrapper);
+ cbq->callback = callback;
return cbq;
}
-static void cn_queue_free_callback(struct cn_callback_entry *cbq)
+void cn_queue_release_callback(struct cn_callback_entry *cbq)
{
- flush_workqueue(cbq->pdev->cn_queue);
+ if (!atomic_dec_and_test(&cbq->refcnt))
+ return;
+
+ atomic_dec(&cbq->pdev->refcnt);
kfree(cbq);
}
@@ -85,13 +76,10 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
struct cn_callback_entry *cbq, *__cbq;
int found = 0;
- cbq = cn_queue_alloc_callback_entry(name, id, callback);
+ cbq = cn_queue_alloc_callback_entry(dev, name, id, callback);
if (!cbq)
return -ENOMEM;
- atomic_inc(&dev->refcnt);
- cbq->pdev = dev;
-
spin_lock_bh(&dev->queue_lock);
list_for_each_entry(__cbq, &dev->queue_list, callback_entry) {
if (cn_cb_equal(&__cbq->id.id, id)) {
@@ -104,8 +92,7 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
spin_unlock_bh(&dev->queue_lock);
if (found) {
- cn_queue_free_callback(cbq);
- atomic_dec(&dev->refcnt);
+ cn_queue_release_callback(cbq);
return -EINVAL;
}
@@ -130,10 +117,8 @@ void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id)
}
spin_unlock_bh(&dev->queue_lock);
- if (found) {
- cn_queue_free_callback(cbq);
- atomic_dec(&dev->refcnt);
- }
+ if (found)
+ cn_queue_release_callback(cbq);
}
struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls)
@@ -151,12 +136,6 @@ struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *nls)
dev->nls = nls;
- dev->cn_queue = alloc_ordered_workqueue(dev->name, 0);
- if (!dev->cn_queue) {
- kfree(dev);
- return NULL;
- }
-
return dev;
}
@@ -164,9 +143,6 @@ void cn_queue_free_dev(struct cn_queue_dev *dev)
{
struct cn_callback_entry *cbq, *n;
- flush_workqueue(dev->cn_queue);
- destroy_workqueue(dev->cn_queue);
-
spin_lock_bh(&dev->queue_lock);
list_for_each_entry_safe(cbq, n, &dev->queue_list, callback_entry)
list_del(&cbq->callback_entry);
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index f7554de3be5..d77005849af 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -122,51 +122,28 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
*/
static int cn_call_callback(struct sk_buff *skb)
{
- struct cn_callback_entry *__cbq, *__new_cbq;
+ struct cn_callback_entry *i, *cbq = NULL;
struct cn_dev *dev = &cdev;
struct cn_msg *msg = NLMSG_DATA(nlmsg_hdr(skb));
+ struct netlink_skb_parms *nsp = &NETLINK_CB(skb);
int err = -ENODEV;
spin_lock_bh(&dev->cbdev->queue_lock);
- list_for_each_entry(__cbq, &dev->cbdev->queue_list, callback_entry) {
- if (cn_cb_equal(&__cbq->id.id, &msg->id)) {
- if (likely(!work_pending(&__cbq->work) &&
- __cbq->data.skb == NULL)) {
- __cbq->data.skb = skb;
-
- if (queue_work(dev->cbdev->cn_queue,
- &__cbq->work))
- err = 0;
- else
- err = -EINVAL;
- } else {
- struct cn_callback_data *d;
-
- err = -ENOMEM;
- __new_cbq = kzalloc(sizeof(struct cn_callback_entry), GFP_ATOMIC);
- if (__new_cbq) {
- d = &__new_cbq->data;
- d->skb = skb;
- d->callback = __cbq->data.callback;
- d->free = __new_cbq;
-
- INIT_WORK(&__new_cbq->work,
- &cn_queue_wrapper);
-
- if (queue_work(dev->cbdev->cn_queue,
- &__new_cbq->work))
- err = 0;
- else {
- kfree(__new_cbq);
- err = -EINVAL;
- }
- }
- }
+ list_for_each_entry(i, &dev->cbdev->queue_list, callback_entry) {
+ if (cn_cb_equal(&i->id.id, &msg->id)) {
+ atomic_inc(&i->refcnt);
+ cbq = i;
break;
}
}
spin_unlock_bh(&dev->cbdev->queue_lock);
+ if (cbq != NULL) {
+ cbq->callback(msg, nsp);
+ kfree_skb(skb);
+ cn_queue_release_callback(cbq);
+ }
+
return err;
}
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index dd8ebc75b66..ab8a4eff072 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -94,9 +94,9 @@ static struct ipu_irq_map *src2map(unsigned int src)
return NULL;
}
-static void ipu_irq_unmask(unsigned int irq)
+static void ipu_irq_unmask(struct irq_data *d)
{
- struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
struct ipu_irq_bank *bank;
uint32_t reg;
unsigned long lock_flags;
@@ -106,7 +106,7 @@ static void ipu_irq_unmask(unsigned int irq)
bank = map->bank;
if (!bank) {
spin_unlock_irqrestore(&bank_lock, lock_flags);
- pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
return;
}
@@ -117,9 +117,9 @@ static void ipu_irq_unmask(unsigned int irq)
spin_unlock_irqrestore(&bank_lock, lock_flags);
}
-static void ipu_irq_mask(unsigned int irq)
+static void ipu_irq_mask(struct irq_data *d)
{
- struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
struct ipu_irq_bank *bank;
uint32_t reg;
unsigned long lock_flags;
@@ -129,7 +129,7 @@ static void ipu_irq_mask(unsigned int irq)
bank = map->bank;
if (!bank) {
spin_unlock_irqrestore(&bank_lock, lock_flags);
- pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
return;
}
@@ -140,9 +140,9 @@ static void ipu_irq_mask(unsigned int irq)
spin_unlock_irqrestore(&bank_lock, lock_flags);
}
-static void ipu_irq_ack(unsigned int irq)
+static void ipu_irq_ack(struct irq_data *d)
{
- struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
struct ipu_irq_bank *bank;
unsigned long lock_flags;
@@ -151,7 +151,7 @@ static void ipu_irq_ack(unsigned int irq)
bank = map->bank;
if (!bank) {
spin_unlock_irqrestore(&bank_lock, lock_flags);
- pr_err("IPU: %s(%u) - unmapped!\n", __func__, irq);
+ pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
return;
}
@@ -167,7 +167,7 @@ static void ipu_irq_ack(unsigned int irq)
*/
bool ipu_irq_status(unsigned int irq)
{
- struct ipu_irq_map *map = get_irq_chip_data(irq);
+ struct ipu_irq_map *map = irq_get_chip_data(irq);
struct ipu_irq_bank *bank;
unsigned long lock_flags;
bool ret;
@@ -269,7 +269,7 @@ int ipu_irq_unmap(unsigned int source)
/* Chained IRQ handler for IPU error interrupt */
static void ipu_irq_err(unsigned int irq, struct irq_desc *desc)
{
- struct ipu *ipu = get_irq_data(irq);
+ struct ipu *ipu = irq_get_handler_data(irq);
u32 status;
int i, line;
@@ -310,7 +310,7 @@ static void ipu_irq_err(unsigned int irq, struct irq_desc *desc)
/* Chained IRQ handler for IPU function interrupt */
static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc)
{
- struct ipu *ipu = get_irq_data(irq);
+ struct ipu *ipu = irq_desc_get_handler_data(desc);
u32 status;
int i, line;
@@ -345,10 +345,10 @@ static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc)
}
static struct irq_chip ipu_irq_chip = {
- .name = "ipu_irq",
- .ack = ipu_irq_ack,
- .mask = ipu_irq_mask,
- .unmask = ipu_irq_unmask,
+ .name = "ipu_irq",
+ .irq_ack = ipu_irq_ack,
+ .irq_mask = ipu_irq_mask,
+ .irq_unmask = ipu_irq_unmask,
};
/* Install the IRQ handler */
@@ -366,26 +366,26 @@ int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
int ret;
irq = irq_base + i;
- ret = set_irq_chip(irq, &ipu_irq_chip);
+ ret = irq_set_chip(irq, &ipu_irq_chip);
if (ret < 0)
return ret;
- ret = set_irq_chip_data(irq, irq_map + i);
+ ret = irq_set_chip_data(irq, irq_map + i);
if (ret < 0)
return ret;
irq_map[i].ipu = ipu;
irq_map[i].irq = irq;
irq_map[i].source = -EINVAL;
- set_irq_handler(irq, handle_level_irq);
+ irq_set_handler(irq, handle_level_irq);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
#endif
}
- set_irq_data(ipu->irq_fn, ipu);
- set_irq_chained_handler(ipu->irq_fn, ipu_irq_fn);
+ irq_set_handler_data(ipu->irq_fn, ipu);
+ irq_set_chained_handler(ipu->irq_fn, ipu_irq_fn);
- set_irq_data(ipu->irq_err, ipu);
- set_irq_chained_handler(ipu->irq_err, ipu_irq_err);
+ irq_set_handler_data(ipu->irq_err, ipu);
+ irq_set_chained_handler(ipu->irq_err, ipu_irq_err);
return 0;
}
@@ -397,17 +397,17 @@ void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev)
irq_base = pdata->irq_base;
- set_irq_chained_handler(ipu->irq_fn, NULL);
- set_irq_data(ipu->irq_fn, NULL);
+ irq_set_chained_handler(ipu->irq_fn, NULL);
+ irq_set_handler_data(ipu->irq_fn, NULL);
- set_irq_chained_handler(ipu->irq_err, NULL);
- set_irq_data(ipu->irq_err, NULL);
+ irq_set_chained_handler(ipu->irq_err, NULL);
+ irq_set_handler_data(ipu->irq_err, NULL);
for (irq = irq_base; irq < irq_base + CONFIG_MX3_IPU_IRQS; irq++) {
#ifdef CONFIG_ARM
set_irq_flags(irq, 0);
#endif
- set_irq_chip(irq, NULL);
- set_irq_chip_data(irq, NULL);
+ irq_set_chip(irq, NULL);
+ irq_set_chip_data(irq, NULL);
}
}
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index 0be30e978c8..31e71c4fc83 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -2679,7 +2679,7 @@ static int __init amd64_edac_init(void)
mcis = kzalloc(amd_nb_num() * sizeof(mcis[0]), GFP_KERNEL);
ecc_stngs = kzalloc(amd_nb_num() * sizeof(ecc_stngs[0]), GFP_KERNEL);
if (!(mcis && ecc_stngs))
- goto err_ret;
+ goto err_free;
msrs = msrs_alloc();
if (!msrs)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index d8d0cda2641..d3b29530554 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -414,4 +414,9 @@ config GPIO_JANZ_TTL
This driver provides support for driving the pins in output
mode only. Input mode is not supported.
+config AB8500_GPIO
+ bool "ST-Ericsson AB8500 Mixed Signal Circuit gpio functions"
+ depends on AB8500_CORE && BROKEN
+ help
+ Select this to enable the AB8500 IC GPIO driver
endif
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 3351cf87b0e..becef595435 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_GPIO_JANZ_TTL) += janz-ttl.o
obj-$(CONFIG_GPIO_SX150X) += sx150x.o
obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o
obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o
+obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o
diff --git a/drivers/gpio/ab8500-gpio.c b/drivers/gpio/ab8500-gpio.c
new file mode 100644
index 00000000000..e7b834d054b
--- /dev/null
+++ b/drivers/gpio/ab8500-gpio.c
@@ -0,0 +1,522 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Author: BIBEK BASU <bibek.basu@stericsson.com>
+ * License terms: GNU General Public License (GPL) version 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/types.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500.h>
+#include <linux/mfd/ab8500/gpio.h>
+
+/*
+ * GPIO registers offset
+ * Bank: 0x10
+ */
+#define AB8500_GPIO_SEL1_REG 0x00
+#define AB8500_GPIO_SEL2_REG 0x01
+#define AB8500_GPIO_SEL3_REG 0x02
+#define AB8500_GPIO_SEL4_REG 0x03
+#define AB8500_GPIO_SEL5_REG 0x04
+#define AB8500_GPIO_SEL6_REG 0x05
+
+#define AB8500_GPIO_DIR1_REG 0x10
+#define AB8500_GPIO_DIR2_REG 0x11
+#define AB8500_GPIO_DIR3_REG 0x12
+#define AB8500_GPIO_DIR4_REG 0x13
+#define AB8500_GPIO_DIR5_REG 0x14
+#define AB8500_GPIO_DIR6_REG 0x15
+
+#define AB8500_GPIO_OUT1_REG 0x20
+#define AB8500_GPIO_OUT2_REG 0x21
+#define AB8500_GPIO_OUT3_REG 0x22
+#define AB8500_GPIO_OUT4_REG 0x23
+#define AB8500_GPIO_OUT5_REG 0x24
+#define AB8500_GPIO_OUT6_REG 0x25
+
+#define AB8500_GPIO_PUD1_REG 0x30
+#define AB8500_GPIO_PUD2_REG 0x31
+#define AB8500_GPIO_PUD3_REG 0x32
+#define AB8500_GPIO_PUD4_REG 0x33
+#define AB8500_GPIO_PUD5_REG 0x34
+#define AB8500_GPIO_PUD6_REG 0x35
+
+#define AB8500_GPIO_IN1_REG 0x40
+#define AB8500_GPIO_IN2_REG 0x41
+#define AB8500_GPIO_IN3_REG 0x42
+#define AB8500_GPIO_IN4_REG 0x43
+#define AB8500_GPIO_IN5_REG 0x44
+#define AB8500_GPIO_IN6_REG 0x45
+#define AB8500_GPIO_ALTFUN_REG 0x45
+#define ALTFUN_REG_INDEX 6
+#define AB8500_NUM_GPIO 42
+#define AB8500_NUM_VIR_GPIO_IRQ 16
+
+enum ab8500_gpio_action {
+ NONE,
+ STARTUP,
+ SHUTDOWN,
+ MASK,
+ UNMASK
+};
+
+struct ab8500_gpio {
+ struct gpio_chip chip;
+ struct ab8500 *parent;
+ struct device *dev;
+ struct mutex lock;
+ u32 irq_base;
+ enum ab8500_gpio_action irq_action;
+ u16 rising;
+ u16 falling;
+};
+/**
+ * to_ab8500_gpio() - get the pointer to ab8500_gpio
+ * @chip: Member of the structure ab8500_gpio
+ */
+static inline struct ab8500_gpio *to_ab8500_gpio(struct gpio_chip *chip)
+{
+ return container_of(chip, struct ab8500_gpio, chip);
+}
+
+static int ab8500_gpio_set_bits(struct gpio_chip *chip, u8 reg,
+ unsigned offset, int val)
+{
+ struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
+ u8 pos = offset % 8;
+ int ret;
+
+ reg = reg + (offset / 8);
+ ret = abx500_mask_and_set_register_interruptible(ab8500_gpio->dev,
+ AB8500_MISC, reg, 1 << pos, val << pos);
+ if (ret < 0)
+ dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
+ return ret;
+}
+/**
+ * ab8500_gpio_get() - Get the particular GPIO value
+ * @chip: Gpio device
+ * @offset: GPIO number to read
+ */
+static int ab8500_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
+ u8 mask = 1 << (offset % 8);
+ u8 reg = AB8500_GPIO_OUT1_REG + (offset / 8);
+ int ret;
+ u8 data;
+ ret = abx500_get_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
+ reg, &data);
+ if (ret < 0) {
+ dev_err(ab8500_gpio->dev, "%s read failed\n", __func__);
+ return ret;
+ }
+ return (data & mask) >> (offset % 8);
+}
+
+static void ab8500_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
+{
+ struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
+ int ret;
+ /* Write the data */
+ ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, 1);
+ if (ret < 0)
+ dev_err(ab8500_gpio->dev, "%s write failed\n", __func__);
+}
+
+static int ab8500_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
+ int val)
+{
+ int ret;
+ /* set direction as output */
+ ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 1);
+ if (ret < 0)
+ return ret;
+ /* disable pull down */
+ ret = ab8500_gpio_set_bits(chip, AB8500_GPIO_PUD1_REG, offset, 1);
+ if (ret < 0)
+ return ret;
+ /* set the output as 1 or 0 */
+ return ab8500_gpio_set_bits(chip, AB8500_GPIO_OUT1_REG, offset, val);
+
+}
+
+static int ab8500_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ /* set the register as input */
+ return ab8500_gpio_set_bits(chip, AB8500_GPIO_DIR1_REG, offset, 0);
+}
+
+static int ab8500_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ /*
+ * Only some GPIOs are interrupt capable, and they are
+ * organized in discontiguous clusters:
+ *
+ * GPIO6 to GPIO13
+ * GPIO24 and GPIO25
+ * GPIO36 to GPIO41
+ */
+ static struct ab8500_gpio_irq_cluster {
+ int start;
+ int end;
+ } clusters[] = {
+ {.start = 6, .end = 13},
+ {.start = 24, .end = 25},
+ {.start = 36, .end = 41},
+ };
+ struct ab8500_gpio *ab8500_gpio = to_ab8500_gpio(chip);
+ int base = ab8500_gpio->irq_base;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(clusters); i++) {
+ struct ab8500_gpio_irq_cluster *cluster = &clusters[i];
+
+ if (offset >= cluster->start && offset <= cluster->end)
+ return base + offset - cluster->start;
+
+ /* Advance by the number of gpios in this cluster */
+ base += cluster->end - cluster->start + 1;
+ }
+
+ return -EINVAL;
+}
+
+static struct gpio_chip ab8500gpio_chip = {
+ .label = "ab8500_gpio",
+ .owner = THIS_MODULE,
+ .direction_input = ab8500_gpio_direction_input,
+ .get = ab8500_gpio_get,
+ .direction_output = ab8500_gpio_direction_output,
+ .set = ab8500_gpio_set,
+ .to_irq = ab8500_gpio_to_irq,
+};
+
+static unsigned int irq_to_rising(unsigned int irq)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ int offset = irq - ab8500_gpio->irq_base;
+ int new_irq = offset + AB8500_INT_GPIO6R
+ + ab8500_gpio->parent->irq_base;
+ return new_irq;
+}
+
+static unsigned int irq_to_falling(unsigned int irq)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ int offset = irq - ab8500_gpio->irq_base;
+ int new_irq = offset + AB8500_INT_GPIO6F
+ + ab8500_gpio->parent->irq_base;
+ return new_irq;
+
+}
+
+static unsigned int rising_to_irq(unsigned int irq, void *dev)
+{
+ struct ab8500_gpio *ab8500_gpio = dev;
+ int offset = irq - AB8500_INT_GPIO6R
+ - ab8500_gpio->parent->irq_base ;
+ int new_irq = offset + ab8500_gpio->irq_base;
+ return new_irq;
+}
+
+static unsigned int falling_to_irq(unsigned int irq, void *dev)
+{
+ struct ab8500_gpio *ab8500_gpio = dev;
+ int offset = irq - AB8500_INT_GPIO6F
+ - ab8500_gpio->parent->irq_base ;
+ int new_irq = offset + ab8500_gpio->irq_base;
+ return new_irq;
+
+}
+
+/*
+ * IRQ handler
+ */
+
+static irqreturn_t handle_rising(int irq, void *dev)
+{
+
+ handle_nested_irq(rising_to_irq(irq , dev));
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t handle_falling(int irq, void *dev)
+{
+
+ handle_nested_irq(falling_to_irq(irq, dev));
+ return IRQ_HANDLED;
+}
+
+static void ab8500_gpio_irq_lock(unsigned int irq)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ mutex_lock(&ab8500_gpio->lock);
+}
+
+static void ab8500_gpio_irq_sync_unlock(unsigned int irq)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ int offset = irq - ab8500_gpio->irq_base;
+ bool rising = ab8500_gpio->rising & BIT(offset);
+ bool falling = ab8500_gpio->falling & BIT(offset);
+ int ret;
+
+ switch (ab8500_gpio->irq_action) {
+ case STARTUP:
+ if (rising)
+ ret = request_threaded_irq(irq_to_rising(irq),
+ NULL, handle_rising,
+ IRQF_TRIGGER_RISING,
+ "ab8500-gpio-r", ab8500_gpio);
+ if (falling)
+ ret = request_threaded_irq(irq_to_falling(irq),
+ NULL, handle_falling,
+ IRQF_TRIGGER_FALLING,
+ "ab8500-gpio-f", ab8500_gpio);
+ break;
+ case SHUTDOWN:
+ if (rising)
+ free_irq(irq_to_rising(irq), ab8500_gpio);
+ if (falling)
+ free_irq(irq_to_falling(irq), ab8500_gpio);
+ break;
+ case MASK:
+ if (rising)
+ disable_irq(irq_to_rising(irq));
+ if (falling)
+ disable_irq(irq_to_falling(irq));
+ break;
+ case UNMASK:
+ if (rising)
+ enable_irq(irq_to_rising(irq));
+ if (falling)
+ enable_irq(irq_to_falling(irq));
+ break;
+ case NONE:
+ break;
+ }
+ ab8500_gpio->irq_action = NONE;
+ ab8500_gpio->rising &= ~(BIT(offset));
+ ab8500_gpio->falling &= ~(BIT(offset));
+ mutex_unlock(&ab8500_gpio->lock);
+}
+
+
+static void ab8500_gpio_irq_mask(unsigned int irq)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ ab8500_gpio->irq_action = MASK;
+}
+
+static void ab8500_gpio_irq_unmask(unsigned int irq)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ ab8500_gpio->irq_action = UNMASK;
+}
+
+static int ab8500_gpio_irq_set_type(unsigned int irq, unsigned int type)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ int offset = irq - ab8500_gpio->irq_base;
+
+ if (type == IRQ_TYPE_EDGE_BOTH) {
+ ab8500_gpio->rising = BIT(offset);
+ ab8500_gpio->falling = BIT(offset);
+ } else if (type == IRQ_TYPE_EDGE_RISING) {
+ ab8500_gpio->rising = BIT(offset);
+ } else {
+ ab8500_gpio->falling = BIT(offset);
+ }
+ return 0;
+}
+
+unsigned int ab8500_gpio_irq_startup(unsigned int irq)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ ab8500_gpio->irq_action = STARTUP;
+ return 0;
+}
+
+void ab8500_gpio_irq_shutdown(unsigned int irq)
+{
+ struct ab8500_gpio *ab8500_gpio = get_irq_chip_data(irq);
+ ab8500_gpio->irq_action = SHUTDOWN;
+}
+
+static struct irq_chip ab8500_gpio_irq_chip = {
+ .name = "ab8500-gpio",
+ .startup = ab8500_gpio_irq_startup,
+ .shutdown = ab8500_gpio_irq_shutdown,
+ .bus_lock = ab8500_gpio_irq_lock,
+ .bus_sync_unlock = ab8500_gpio_irq_sync_unlock,
+ .mask = ab8500_gpio_irq_mask,
+ .unmask = ab8500_gpio_irq_unmask,
+ .set_type = ab8500_gpio_irq_set_type,
+};
+
+static int ab8500_gpio_irq_init(struct ab8500_gpio *ab8500_gpio)
+{
+ u32 base = ab8500_gpio->irq_base;
+ int irq;
+
+ for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ ; irq++) {
+ set_irq_chip_data(irq, ab8500_gpio);
+ set_irq_chip_and_handler(irq, &ab8500_gpio_irq_chip,
+ handle_simple_irq);
+ set_irq_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, IRQF_VALID);
+#else
+ set_irq_noprobe(irq);
+#endif
+ }
+
+ return 0;
+}
+
+static void ab8500_gpio_irq_remove(struct ab8500_gpio *ab8500_gpio)
+{
+ int base = ab8500_gpio->irq_base;
+ int irq;
+
+ for (irq = base; irq < base + AB8500_NUM_VIR_GPIO_IRQ; irq++) {
+#ifdef CONFIG_ARM
+ set_irq_flags(irq, 0);
+#endif
+ set_irq_chip_and_handler(irq, NULL, NULL);
+ set_irq_chip_data(irq, NULL);
+ }
+}
+
+static int __devinit ab8500_gpio_probe(struct platform_device *pdev)
+{
+ struct ab8500_platform_data *ab8500_pdata =
+ dev_get_platdata(pdev->dev.parent);
+ struct ab8500_gpio_platform_data *pdata;
+ struct ab8500_gpio *ab8500_gpio;
+ int ret;
+ int i;
+
+ pdata = ab8500_pdata->gpio;
+ if (!pdata) {
+ dev_err(&pdev->dev, "gpio platform data missing\n");
+ return -ENODEV;
+ }
+
+ ab8500_gpio = kzalloc(sizeof(struct ab8500_gpio), GFP_KERNEL);
+ if (ab8500_gpio == NULL) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ return -ENOMEM;
+ }
+ ab8500_gpio->dev = &pdev->dev;
+ ab8500_gpio->parent = dev_get_drvdata(pdev->dev.parent);
+ ab8500_gpio->chip = ab8500gpio_chip;
+ ab8500_gpio->chip.ngpio = AB8500_NUM_GPIO;
+ ab8500_gpio->chip.dev = &pdev->dev;
+ ab8500_gpio->chip.base = pdata->gpio_base;
+ ab8500_gpio->irq_base = pdata->irq_base;
+ /* initialize the lock */
+ mutex_init(&ab8500_gpio->lock);
+ /*
+ * AB8500 core will handle and clear the IRQ
+ * configre GPIO based on config-reg value.
+ * These values are for selecting the PINs as
+ * GPIO or alternate function
+ */
+ for (i = AB8500_GPIO_SEL1_REG; i <= AB8500_GPIO_SEL6_REG; i++) {
+ ret = abx500_set_register_interruptible(ab8500_gpio->dev,
+ AB8500_MISC, i,
+ pdata->config_reg[i]);
+ if (ret < 0)
+ goto out_free;
+ }
+ ret = abx500_set_register_interruptible(ab8500_gpio->dev, AB8500_MISC,
+ AB8500_GPIO_ALTFUN_REG,
+ pdata->config_reg[ALTFUN_REG_INDEX]);
+ if (ret < 0)
+ goto out_free;
+
+ ret = ab8500_gpio_irq_init(ab8500_gpio);
+ if (ret)
+ goto out_free;
+ ret = gpiochip_add(&ab8500_gpio->chip);
+ if (ret) {
+ dev_err(&pdev->dev, "unable to add gpiochip: %d\n",
+ ret);
+ goto out_rem_irq;
+ }
+ platform_set_drvdata(pdev, ab8500_gpio);
+ return 0;
+
+out_rem_irq:
+ ab8500_gpio_irq_remove(ab8500_gpio);
+out_free:
+ mutex_destroy(&ab8500_gpio->lock);
+ kfree(ab8500_gpio);
+ return ret;
+}
+
+/*
+ * ab8500_gpio_remove() - remove Ab8500-gpio driver
+ * @pdev : Platform device registered
+ */
+static int __devexit ab8500_gpio_remove(struct platform_device *pdev)
+{
+ struct ab8500_gpio *ab8500_gpio = platform_get_drvdata(pdev);
+ int ret;
+
+ ret = gpiochip_remove(&ab8500_gpio->chip);
+ if (ret < 0) {
+ dev_err(ab8500_gpio->dev, "unable to remove gpiochip:\
+ %d\n", ret);
+ return ret;
+ }
+
+ platform_set_drvdata(pdev, NULL);
+ mutex_destroy(&ab8500_gpio->lock);
+ kfree(ab8500_gpio);
+
+ return 0;
+}
+
+static struct platform_driver ab8500_gpio_driver = {
+ .driver = {
+ .name = "ab8500-gpio",
+ .owner = THIS_MODULE,
+ },
+ .probe = ab8500_gpio_probe,
+ .remove = __devexit_p(ab8500_gpio_remove),
+};
+
+static int __init ab8500_gpio_init(void)
+{
+ return platform_driver_register(&ab8500_gpio_driver);
+}
+arch_initcall(ab8500_gpio_init);
+
+static void __exit ab8500_gpio_exit(void)
+{
+ platform_driver_unregister(&ab8500_gpio_driver);
+}
+module_exit(ab8500_gpio_exit);
+
+MODULE_AUTHOR("BIBEK BASU <bibek.basu@stericsson.com>");
+MODULE_DESCRIPTION("Driver allows to use AB8500 unused pins\
+ to be used as GPIO");
+MODULE_ALIAS("AB8500 GPIO driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index f141a1de519..89aa9fb743a 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -116,7 +116,7 @@ static int fan_alarm_init(struct gpio_fan_data *fan_data,
return 0;
INIT_WORK(&fan_data->alarm_work, fan_alarm_notify);
- set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH);
err = request_irq(alarm_irq, fan_alarm_irq_handler, IRQF_SHARED,
"GPIO fan alarm", fan_data);
if (err)
diff --git a/drivers/input/keyboard/lm8323.c b/drivers/input/keyboard/lm8323.c
index b732870ecc8..71f744a8e68 100644
--- a/drivers/input/keyboard/lm8323.c
+++ b/drivers/input/keyboard/lm8323.c
@@ -809,7 +809,7 @@ static int lm8323_suspend(struct device *dev)
struct lm8323_chip *lm = i2c_get_clientdata(client);
int i;
- set_irq_wake(client->irq, 0);
+ irq_set_irq_wake(client->irq, 0);
disable_irq(client->irq);
mutex_lock(&lm->lock);
@@ -838,7 +838,7 @@ static int lm8323_resume(struct device *dev)
led_classdev_resume(&lm->pwm[i].cdev);
enable_irq(client->irq);
- set_irq_wake(client->irq, 1);
+ irq_set_irq_wake(client->irq, 1);
return 0;
}
diff --git a/drivers/input/serio/ams_delta_serio.c b/drivers/input/serio/ams_delta_serio.c
index ebe95532567..4b2a42f9f0b 100644
--- a/drivers/input/serio/ams_delta_serio.c
+++ b/drivers/input/serio/ams_delta_serio.c
@@ -149,7 +149,7 @@ static int __init ams_delta_serio_init(void)
* at FIQ level, switch back from edge to simple interrupt handler
* to avoid bad interaction.
*/
- set_irq_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
+ irq_set_handler(gpio_to_irq(AMS_DELTA_GPIO_PIN_KEYBRD_CLK),
handle_simple_irq);
serio_register_port(ams_delta_serio);
diff --git a/drivers/input/touchscreen/mainstone-wm97xx.c b/drivers/input/touchscreen/mainstone-wm97xx.c
index b6b8b1c7ece..3242e707625 100644
--- a/drivers/input/touchscreen/mainstone-wm97xx.c
+++ b/drivers/input/touchscreen/mainstone-wm97xx.c
@@ -219,7 +219,7 @@ static int wm97xx_acc_startup(struct wm97xx *wm)
}
wm->pen_irq = gpio_to_irq(irq);
- set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(wm->pen_irq, IRQ_TYPE_EDGE_BOTH);
} else /* pen irq not supported */
pen_int = 0;
diff --git a/drivers/input/touchscreen/zylonite-wm97xx.c b/drivers/input/touchscreen/zylonite-wm97xx.c
index 04884986764..5b0f15ec874 100644
--- a/drivers/input/touchscreen/zylonite-wm97xx.c
+++ b/drivers/input/touchscreen/zylonite-wm97xx.c
@@ -193,7 +193,7 @@ static int zylonite_wm97xx_probe(struct platform_device *pdev)
gpio_touch_irq = mfp_to_gpio(MFP_PIN_GPIO26);
wm->pen_irq = IRQ_GPIO(gpio_touch_irq);
- set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(IRQ_GPIO(gpio_touch_irq), IRQ_TYPE_EDGE_BOTH);
wm97xx_config_gpio(wm, WM97XX_GPIO_13, WM97XX_GPIO_IN,
WM97XX_GPIO_POL_HIGH,
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index bca2af2e376..c987033714f 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -153,7 +153,7 @@ static struct i2c_adapter * u3_0;
static struct i2c_adapter * u3_1;
static struct i2c_adapter * k2;
static struct i2c_client * fcu;
-static struct cpu_pid_state cpu_state[2];
+static struct cpu_pid_state processor_state[2];
static struct basckside_pid_params backside_params;
static struct backside_pid_state backside_state;
static struct drives_pid_state drives_state;
@@ -664,8 +664,8 @@ static int read_eeprom(int cpu, struct mpu_data *out)
static void fetch_cpu_pumps_minmax(void)
{
- struct cpu_pid_state *state0 = &cpu_state[0];
- struct cpu_pid_state *state1 = &cpu_state[1];
+ struct cpu_pid_state *state0 = &processor_state[0];
+ struct cpu_pid_state *state1 = &processor_state[1];
u16 pump_min = 0, pump_max = 0xffff;
u16 tmp[4];
@@ -717,17 +717,17 @@ static ssize_t show_##name(struct device *dev, struct device_attribute *attr, ch
return sprintf(buf, "%d", data); \
}
-BUILD_SHOW_FUNC_FIX(cpu0_temperature, cpu_state[0].last_temp)
-BUILD_SHOW_FUNC_FIX(cpu0_voltage, cpu_state[0].voltage)
-BUILD_SHOW_FUNC_FIX(cpu0_current, cpu_state[0].current_a)
-BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, cpu_state[0].rpm)
-BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, cpu_state[0].intake_rpm)
+BUILD_SHOW_FUNC_FIX(cpu0_temperature, processor_state[0].last_temp)
+BUILD_SHOW_FUNC_FIX(cpu0_voltage, processor_state[0].voltage)
+BUILD_SHOW_FUNC_FIX(cpu0_current, processor_state[0].current_a)
+BUILD_SHOW_FUNC_INT(cpu0_exhaust_fan_rpm, processor_state[0].rpm)
+BUILD_SHOW_FUNC_INT(cpu0_intake_fan_rpm, processor_state[0].intake_rpm)
-BUILD_SHOW_FUNC_FIX(cpu1_temperature, cpu_state[1].last_temp)
-BUILD_SHOW_FUNC_FIX(cpu1_voltage, cpu_state[1].voltage)
-BUILD_SHOW_FUNC_FIX(cpu1_current, cpu_state[1].current_a)
-BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, cpu_state[1].rpm)
-BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, cpu_state[1].intake_rpm)
+BUILD_SHOW_FUNC_FIX(cpu1_temperature, processor_state[1].last_temp)
+BUILD_SHOW_FUNC_FIX(cpu1_voltage, processor_state[1].voltage)
+BUILD_SHOW_FUNC_FIX(cpu1_current, processor_state[1].current_a)
+BUILD_SHOW_FUNC_INT(cpu1_exhaust_fan_rpm, processor_state[1].rpm)
+BUILD_SHOW_FUNC_INT(cpu1_intake_fan_rpm, processor_state[1].intake_rpm)
BUILD_SHOW_FUNC_FIX(backside_temperature, backside_state.last_temp)
BUILD_SHOW_FUNC_INT(backside_fan_pwm, backside_state.pwm)
@@ -919,8 +919,8 @@ static void do_cpu_pid(struct cpu_pid_state *state, s32 temp, s32 power)
static void do_monitor_cpu_combined(void)
{
- struct cpu_pid_state *state0 = &cpu_state[0];
- struct cpu_pid_state *state1 = &cpu_state[1];
+ struct cpu_pid_state *state0 = &processor_state[0];
+ struct cpu_pid_state *state1 = &processor_state[1];
s32 temp0, power0, temp1, power1;
s32 temp_combi, power_combi;
int rc, intake, pump;
@@ -1150,7 +1150,7 @@ static void do_monitor_cpu_rack(struct cpu_pid_state *state)
/*
* Initialize the state structure for one CPU control loop
*/
-static int init_cpu_state(struct cpu_pid_state *state, int index)
+static int init_processor_state(struct cpu_pid_state *state, int index)
{
int err;
@@ -1205,7 +1205,7 @@ static int init_cpu_state(struct cpu_pid_state *state, int index)
/*
* Dispose of the state data for one CPU control loop
*/
-static void dispose_cpu_state(struct cpu_pid_state *state)
+static void dispose_processor_state(struct cpu_pid_state *state)
{
if (state->monitor == NULL)
return;
@@ -1804,9 +1804,9 @@ static int main_control_loop(void *x)
set_pwm_fan(SLOTS_FAN_PWM_INDEX, SLOTS_FAN_DEFAULT_PWM);
/* Initialize ADCs */
- initialize_adc(&cpu_state[0]);
- if (cpu_state[1].monitor != NULL)
- initialize_adc(&cpu_state[1]);
+ initialize_adc(&processor_state[0]);
+ if (processor_state[1].monitor != NULL)
+ initialize_adc(&processor_state[1]);
fcu_tickle_ticks = FCU_TICKLE_TICKS;
@@ -1833,14 +1833,14 @@ static int main_control_loop(void *x)
if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
do_monitor_cpu_combined();
else if (cpu_pid_type == CPU_PID_TYPE_RACKMAC) {
- do_monitor_cpu_rack(&cpu_state[0]);
- if (cpu_state[1].monitor != NULL)
- do_monitor_cpu_rack(&cpu_state[1]);
+ do_monitor_cpu_rack(&processor_state[0]);
+ if (processor_state[1].monitor != NULL)
+ do_monitor_cpu_rack(&processor_state[1]);
// better deal with UP
} else {
- do_monitor_cpu_split(&cpu_state[0]);
- if (cpu_state[1].monitor != NULL)
- do_monitor_cpu_split(&cpu_state[1]);
+ do_monitor_cpu_split(&processor_state[0]);
+ if (processor_state[1].monitor != NULL)
+ do_monitor_cpu_split(&processor_state[1]);
// better deal with UP
}
/* Then, the rest */
@@ -1885,8 +1885,8 @@ static int main_control_loop(void *x)
*/
static void dispose_control_loops(void)
{
- dispose_cpu_state(&cpu_state[0]);
- dispose_cpu_state(&cpu_state[1]);
+ dispose_processor_state(&processor_state[0]);
+ dispose_processor_state(&processor_state[1]);
dispose_backside_state(&backside_state);
dispose_drives_state(&drives_state);
dispose_slots_state(&slots_state);
@@ -1928,12 +1928,12 @@ static int create_control_loops(void)
/* Create control loops for everything. If any fail, everything
* fails
*/
- if (init_cpu_state(&cpu_state[0], 0))
+ if (init_processor_state(&processor_state[0], 0))
goto fail;
if (cpu_pid_type == CPU_PID_TYPE_COMBINED)
fetch_cpu_pumps_minmax();
- if (cpu_count > 1 && init_cpu_state(&cpu_state[1], 1))
+ if (cpu_count > 1 && init_processor_state(&processor_state[1], 1))
goto fail;
if (init_backside_state(&backside_state))
goto fail;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 06ecea751a3..8b66e04c2ea 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1777,12 +1777,6 @@ int md_integrity_register(mddev_t *mddev)
continue;
if (rdev->raid_disk < 0)
continue;
- /*
- * If at least one rdev is not integrity capable, we can not
- * enable data integrity for the md device.
- */
- if (!bdev_get_integrity(rdev->bdev))
- return -EINVAL;
if (!reference) {
/* Use the first rdev as the reference */
reference = rdev;
@@ -1793,6 +1787,8 @@ int md_integrity_register(mddev_t *mddev)
rdev->bdev->bd_disk) < 0)
return -EINVAL;
}
+ if (!reference || !bdev_get_integrity(reference->bdev))
+ return 0;
/*
* All component devices are integrity capable and have matching
* profiles, register the common profile for the md device.
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c
index 767406c9529..700d420a59a 100644
--- a/drivers/memstick/host/r592.c
+++ b/drivers/memstick/host/r592.c
@@ -23,7 +23,7 @@
#include <linux/swab.h>
#include "r592.h"
-static int enable_dma = 1;
+static int r592_enable_dma = 1;
static int debug;
static const char *tpc_names[] = {
@@ -267,7 +267,7 @@ static void r592_stop_dma(struct r592_device *dev, int error)
/* Test if hardware supports DMA */
static void r592_check_dma(struct r592_device *dev)
{
- dev->dma_capable = enable_dma &&
+ dev->dma_capable = r592_enable_dma &&
(r592_read_reg(dev, R592_FIFO_DMA_SETTINGS) &
R592_FIFO_DMA_SETTINGS_CAP);
}
@@ -898,7 +898,7 @@ static void __exit r592_module_exit(void)
module_init(r592_module_init);
module_exit(r592_module_exit);
-module_param(enable_dma, bool, S_IRUGO);
+module_param_named(enable_dma, r592_enable_dma, bool, S_IRUGO);
MODULE_PARM_DESC(enable_dma, "Enable usage of the DMA (default)");
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug level (0-3)");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index e986f91fff9..e2fea580585 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -60,15 +60,6 @@ config MFD_ASIC3
This driver supports the ASIC3 multifunction chip found on many
PDAs (mainly iPAQ and HTC based ones)
-config MFD_SH_MOBILE_SDHI
- bool "Support for SuperH Mobile SDHI"
- depends on SUPERH || ARCH_SHMOBILE
- select MFD_CORE
- select TMIO_MMC_DMA
- ---help---
- This driver supports the SDHI hardware block found in many
- SuperH Mobile SoCs.
-
config MFD_DAVINCI_VOICECODEC
tristate
select MFD_CORE
@@ -266,11 +257,6 @@ config MFD_TMIO
bool
default n
-config TMIO_MMC_DMA
- bool
- select DMA_ENGINE
- select DMADEVICES
-
config MFD_T7L66XB
bool "Support Toshiba T7L66XB"
depends on ARM && HAVE_CLK
@@ -592,7 +578,7 @@ config AB3550_CORE
config MFD_CS5535
tristate "Support for CS5535 and CS5536 southbridge core functions"
select MFD_CORE
- depends on PCI
+ depends on PCI && X86
---help---
This is the core driver for CS5535/CS5536 MFD functions. This is
necessary for using the board's GPIO and MFGPT functionality.
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index ef489f25340..419caa9d7dc 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -6,7 +6,6 @@
obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o
obj-$(CONFIG_MFD_SM501) += sm501.o
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
-obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o
obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 62e33e2258d..67d01c93828 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -362,6 +362,15 @@ static void ab8500_irq_remove(struct ab8500 *ab8500)
}
}
+static struct resource ab8500_gpio_resources[] = {
+ {
+ .name = "GPIO_INT6",
+ .start = AB8500_INT_GPIO6R,
+ .end = AB8500_INT_GPIO41F,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
static struct resource ab8500_gpadc_resources[] = {
{
.name = "HW_CONV_END",
@@ -596,6 +605,11 @@ static struct mfd_cell ab8500_devs[] = {
.name = "ab8500-regulator",
},
{
+ .name = "ab8500-gpio",
+ .num_resources = ARRAY_SIZE(ab8500_gpio_resources),
+ .resources = ab8500_gpio_resources,
+ },
+ {
.name = "ab8500-gpadc",
.num_resources = ARRAY_SIZE(ab8500_gpadc_resources),
.resources = ab8500_gpadc_resources,
diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c
index 6820327adf4..821e6b86afd 100644
--- a/drivers/mfd/ab8500-i2c.c
+++ b/drivers/mfd/ab8500-i2c.c
@@ -97,7 +97,7 @@ static void __exit ab8500_i2c_exit(void)
{
platform_driver_unregister(&ab8500_i2c_driver);
}
-subsys_initcall(ab8500_i2c_init);
+arch_initcall(ab8500_i2c_init);
module_exit(ab8500_i2c_exit);
MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
diff --git a/drivers/misc/sgi-gru/grufile.c b/drivers/misc/sgi-gru/grufile.c
index 28852dfa310..20e4e9395b6 100644
--- a/drivers/misc/sgi-gru/grufile.c
+++ b/drivers/misc/sgi-gru/grufile.c
@@ -373,7 +373,7 @@ static int gru_chiplet_setup_tlb_irq(int chiplet, char *irq_name,
if (gru_irq_count[chiplet] == 0) {
gru_chip[chiplet].name = irq_name;
- ret = set_irq_chip(irq, &gru_chip[chiplet]);
+ ret = irq_set_chip(irq, &gru_chip[chiplet]);
if (ret) {
printk(KERN_ERR "%s: set_irq_chip failed, errno=%d\n",
GRU_DRIVER_ID_STR, -ret);
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index 5ec8eddfcf6..f5cedeccad4 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -1875,7 +1875,7 @@ static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
unsigned int tot_sz, int max_scatter)
{
unsigned int dev_addr, i, cnt, sz, ssz;
- struct timespec ts1, ts2, ts;
+ struct timespec ts1, ts2;
int ret;
sz = test->area.max_tfr;
@@ -1912,7 +1912,6 @@ static int mmc_test_seq_perf(struct mmc_test_card *test, int write,
}
getnstimeofday(&ts2);
- ts = timespec_sub(ts2, ts1);
mmc_test_print_avg_rate(test, sz, cnt, &ts1, &ts2);
return 0;
diff --git a/drivers/mmc/core/sd_ops.c b/drivers/mmc/core/sd_ops.c
index 797cdb5887f..76af349c14b 100644
--- a/drivers/mmc/core/sd_ops.c
+++ b/drivers/mmc/core/sd_ops.c
@@ -9,6 +9,7 @@
* your option) any later version.
*/
+#include <linux/slab.h>
#include <linux/types.h>
#include <linux/scatterlist.h>
@@ -252,6 +253,7 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
struct mmc_command cmd;
struct mmc_data data;
struct scatterlist sg;
+ void *data_buf;
BUG_ON(!card);
BUG_ON(!card->host);
@@ -263,6 +265,13 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
if (err)
return err;
+ /* dma onto stack is unsafe/nonportable, but callers to this
+ * routine normally provide temporary on-stack buffers ...
+ */
+ data_buf = kmalloc(sizeof(card->raw_scr), GFP_KERNEL);
+ if (data_buf == NULL)
+ return -ENOMEM;
+
memset(&mrq, 0, sizeof(struct mmc_request));
memset(&cmd, 0, sizeof(struct mmc_command));
memset(&data, 0, sizeof(struct mmc_data));
@@ -280,12 +289,15 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
data.sg = &sg;
data.sg_len = 1;
- sg_init_one(&sg, scr, 8);
+ sg_init_one(&sg, data_buf, 8);
mmc_set_data_timeout(&data, card);
mmc_wait_for_req(card->host, &mrq);
+ memcpy(scr, data_buf, sizeof(card->raw_scr));
+ kfree(data_buf);
+
if (cmd.error)
return cmd.error;
if (data.error)
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
index 1a21c6427a1..94df40531c3 100644
--- a/drivers/mmc/host/Kconfig
+++ b/drivers/mmc/host/Kconfig
@@ -439,13 +439,25 @@ config MMC_SDRICOH_CS
To compile this driver as a module, choose M here: the
module will be called sdricoh_cs.
+config MMC_TMIO_CORE
+ tristate
+
config MMC_TMIO
tristate "Toshiba Mobile IO Controller (TMIO) MMC/SD function support"
- depends on MFD_TMIO || MFD_ASIC3 || MFD_SH_MOBILE_SDHI
+ depends on MFD_TMIO || MFD_ASIC3
+ select MMC_TMIO_CORE
help
This provides support for the SD/MMC cell found in TC6393XB,
T7L66XB and also HTC ASIC3
+config MMC_SDHI
+ tristate "SH-Mobile SDHI SD/SDIO controller support"
+ depends on SUPERH || ARCH_SHMOBILE
+ select MMC_TMIO_CORE
+ help
+ This provides support for the SDHI SD/SDIO controller found in
+ SuperH and ARM SH-Mobile SoCs
+
config MMC_CB710
tristate "ENE CB710 MMC/SD Interface support"
depends on PCI
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index 30aa6867745..4f1df0aae57 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -29,7 +29,13 @@ endif
obj-$(CONFIG_MMC_S3C) += s3cmci.o
obj-$(CONFIG_MMC_SDRICOH_CS) += sdricoh_cs.o
obj-$(CONFIG_MMC_TMIO) += tmio_mmc.o
-obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
+obj-$(CONFIG_MMC_TMIO_CORE) += tmio_mmc_core.o
+tmio_mmc_core-y := tmio_mmc_pio.o
+ifneq ($(CONFIG_MMC_SDHI),n)
+tmio_mmc_core-y += tmio_mmc_dma.o
+endif
+obj-$(CONFIG_MMC_SDHI) += sh_mobile_sdhi.o
+obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
obj-$(CONFIG_MMC_DW) += dw_mmc.o
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 5a614069cb0..87e1f57ec9b 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -316,7 +316,7 @@ static void dw_mci_idmac_stop_dma(struct dw_mci *host)
/* Stop the IDMAC running */
temp = mci_readl(host, BMOD);
- temp &= ~SDMMC_IDMAC_ENABLE;
+ temp &= ~(SDMMC_IDMAC_ENABLE | SDMMC_IDMAC_FB);
mci_writel(host, BMOD, temp);
}
@@ -385,7 +385,7 @@ static void dw_mci_idmac_start_dma(struct dw_mci *host, unsigned int sg_len)
/* Enable the IDMAC */
temp = mci_readl(host, BMOD);
- temp |= SDMMC_IDMAC_ENABLE;
+ temp |= SDMMC_IDMAC_ENABLE | SDMMC_IDMAC_FB;
mci_writel(host, BMOD, temp);
/* Start it running */
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 5bbb87d1025..b4a7e4fba90 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -68,6 +68,12 @@ static struct variant_data variant_arm = {
.datalength_bits = 16,
};
+static struct variant_data variant_arm_extended_fifo = {
+ .fifosize = 128 * 4,
+ .fifohalfsize = 64 * 4,
+ .datalength_bits = 16,
+};
+
static struct variant_data variant_u300 = {
.fifosize = 16 * 4,
.fifohalfsize = 8 * 4,
@@ -1277,10 +1283,15 @@ static int mmci_resume(struct amba_device *dev)
static struct amba_id mmci_ids[] = {
{
.id = 0x00041180,
- .mask = 0x000fffff,
+ .mask = 0xff0fffff,
.data = &variant_arm,
},
{
+ .id = 0x01041180,
+ .mask = 0xff0fffff,
+ .data = &variant_arm_extended_fifo,
+ },
+ {
.id = 0x00041181,
.mask = 0x000fffff,
.data = &variant_arm,
diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c
index 5530def54e5..e2aecb7f1d5 100644
--- a/drivers/mmc/host/of_mmc_spi.c
+++ b/drivers/mmc/host/of_mmc_spi.c
@@ -15,9 +15,11 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
+#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
#include <linux/spi/spi.h>
#include <linux/spi/mmc_spi.h>
#include <linux/mmc/core.h>
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 3b524856797..a19967d0bfc 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -16,14 +16,40 @@
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdhci-pltfm.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/sdio.h>
#include <mach/hardware.h>
#include <mach/esdhc.h>
#include "sdhci.h"
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"
+/* VENDOR SPEC register */
+#define SDHCI_VENDOR_SPEC 0xC0
+#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
+
+#define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0)
+/*
+ * The CMDTYPE of the CMD register (offset 0xE) should be set to
+ * "11" when the STOP CMD12 is issued on imx53 to abort one
+ * open ended multi-blk IO. Otherwise the TC INT wouldn't
+ * be generated.
+ * In exact block transfer, the controller doesn't complete the
+ * operations automatically as required at the end of the
+ * transfer and remains on hold if the abort command is not sent.
+ * As a result, the TC flag is not asserted and SW received timeout
+ * exeception. Bit1 of Vendor Spec registor is used to fix it.
+ */
+#define ESDHC_FLAG_MULTIBLK_NO_INT (1 << 1)
+
+struct pltfm_imx_data {
+ int flags;
+ u32 scratchpad;
+};
+
static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
{
void __iomem *base = host->ioaddr + (reg & ~0x3);
@@ -34,10 +60,14 @@ static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, i
static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
/* fake CARD_PRESENT flag on mx25/35 */
u32 val = readl(host->ioaddr + reg);
- if (unlikely(reg == SDHCI_PRESENT_STATE)) {
+ if (unlikely((reg == SDHCI_PRESENT_STATE)
+ && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) {
struct esdhc_platform_data *boarddata =
host->mmc->parent->platform_data;
@@ -55,13 +85,26 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
{
- if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE))
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
+ if (unlikely((reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)
+ && (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP)))
/*
* these interrupts won't work with a custom card_detect gpio
* (only applied to mx25/35)
*/
val &= ~(SDHCI_INT_CARD_REMOVE | SDHCI_INT_CARD_INSERT);
+ if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
+ && (reg == SDHCI_INT_STATUS)
+ && (val & SDHCI_INT_DATA_END))) {
+ u32 v;
+ v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ v &= ~SDHCI_VENDOR_SPEC_SDIO_QUIRK;
+ writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+ }
+
writel(val, host->ioaddr + reg);
}
@@ -76,6 +119,7 @@ static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
switch (reg) {
case SDHCI_TRANSFER_MODE:
@@ -83,10 +127,22 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
* Postpone this write, we must do it together with a
* command write that is down below.
*/
- pltfm_host->scratchpad = val;
+ if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
+ && (host->cmd->opcode == SD_IO_RW_EXTENDED)
+ && (host->cmd->data->blocks > 1)
+ && (host->cmd->data->flags & MMC_DATA_READ)) {
+ u32 v;
+ v = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ v |= SDHCI_VENDOR_SPEC_SDIO_QUIRK;
+ writel(v, host->ioaddr + SDHCI_VENDOR_SPEC);
+ }
+ imx_data->scratchpad = val;
return;
case SDHCI_COMMAND:
- writel(val << 16 | pltfm_host->scratchpad,
+ if ((host->cmd->opcode == MMC_STOP_TRANSMISSION)
+ && (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
+ val |= SDHCI_CMD_ABORTCMD;
+ writel(val << 16 | imx_data->scratchpad,
host->ioaddr + SDHCI_TRANSFER_MODE);
return;
case SDHCI_BLOCK_SIZE:
@@ -146,7 +202,9 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
}
static struct sdhci_ops sdhci_esdhc_ops = {
+ .read_l = esdhc_readl_le,
.read_w = esdhc_readw_le,
+ .write_l = esdhc_writel_le,
.write_w = esdhc_writew_le,
.write_b = esdhc_writeb_le,
.set_clock = esdhc_set_clock,
@@ -168,6 +226,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
struct clk *clk;
int err;
+ struct pltfm_imx_data *imx_data;
clk = clk_get(mmc_dev(host->mmc), NULL);
if (IS_ERR(clk)) {
@@ -177,7 +236,15 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
clk_enable(clk);
pltfm_host->clk = clk;
- if (cpu_is_mx35() || cpu_is_mx51())
+ imx_data = kzalloc(sizeof(struct pltfm_imx_data), GFP_KERNEL);
+ if (!imx_data) {
+ clk_disable(pltfm_host->clk);
+ clk_put(pltfm_host->clk);
+ return -ENOMEM;
+ }
+ pltfm_host->priv = imx_data;
+
+ if (!cpu_is_mx25())
host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
if (cpu_is_mx25() || cpu_is_mx35()) {
@@ -187,6 +254,9 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
}
+ if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51()))
+ imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
+
if (boarddata) {
err = gpio_request_one(boarddata->wp_gpio, GPIOF_IN, "ESDHC_WP");
if (err) {
@@ -214,8 +284,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
goto no_card_detect_irq;
}
- sdhci_esdhc_ops.write_l = esdhc_writel_le;
- sdhci_esdhc_ops.read_l = esdhc_readl_le;
+ imx_data->flags |= ESDHC_FLAG_GPIO_FOR_CD_WP;
/* Now we have a working card_detect again */
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
@@ -227,6 +296,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
no_card_detect_pin:
boarddata->cd_gpio = err;
not_supported:
+ kfree(imx_data);
return 0;
}
@@ -234,6 +304,7 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
struct esdhc_platform_data *boarddata = host->mmc->parent->platform_data;
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
if (boarddata && gpio_is_valid(boarddata->wp_gpio))
gpio_free(boarddata->wp_gpio);
@@ -247,6 +318,7 @@ static void esdhc_pltfm_exit(struct sdhci_host *host)
clk_disable(pltfm_host->clk);
clk_put(pltfm_host->clk);
+ kfree(imx_data);
}
struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index c55aae828aa..c3b08f11194 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -23,8 +23,7 @@
SDHCI_QUIRK_NONSTANDARD_CLOCK | \
SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | \
SDHCI_QUIRK_PIO_NEEDS_DELAY | \
- SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET | \
- SDHCI_QUIRK_NO_CARD_NO_RESET)
+ SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
#define ESDHC_SYSTEM_CONTROL 0x2c
#define ESDHC_CLOCK_MASK 0x0000fff0
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 08161f690ae..ba40d6d035c 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -74,7 +74,8 @@ static unsigned int esdhc_of_get_min_clock(struct sdhci_host *host)
struct sdhci_of_data sdhci_esdhc = {
/* card detection could be handled via GPIO */
- .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION,
+ .quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_BROKEN_CARD_DETECTION
+ | SDHCI_QUIRK_NO_CARD_NO_RESET,
.ops = {
.read_l = sdhci_be32bs_readl,
.read_w = esdhc_readw,
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 2f8d46854ac..a136be70634 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -1016,16 +1016,14 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
struct sdhci_pci_chip *chip;
struct sdhci_pci_slot *slot;
- u8 slots, rev, first_bar;
+ u8 slots, first_bar;
int ret, i;
BUG_ON(pdev == NULL);
BUG_ON(ent == NULL);
- pci_read_config_byte(pdev, PCI_CLASS_REVISION, &rev);
-
dev_info(&pdev->dev, "SDHCI controller found [%04x:%04x] (rev %x)\n",
- (int)pdev->vendor, (int)pdev->device, (int)rev);
+ (int)pdev->vendor, (int)pdev->device, (int)pdev->revision);
ret = pci_read_config_byte(pdev, PCI_SLOT_INFO, &slots);
if (ret)
diff --git a/drivers/mmc/host/sdhci-pltfm.h b/drivers/mmc/host/sdhci-pltfm.h
index ea2e44d9be5..2b37016ad0a 100644
--- a/drivers/mmc/host/sdhci-pltfm.h
+++ b/drivers/mmc/host/sdhci-pltfm.h
@@ -17,7 +17,7 @@
struct sdhci_pltfm_host {
struct clk *clk;
- u32 scratchpad; /* to handle quirks across io-accessor calls */
+ void *priv; /* to handle quirks across io-accessor calls */
};
extern struct sdhci_pltfm_data sdhci_cns3xxx_pdata;
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index d70c54c7b70..60a4c97d3d1 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -50,7 +50,7 @@ static irqreturn_t sdhci_gpio_irq(int irq, void *dev_id)
/* val == 1 -> card removed, val == 0 -> card inserted */
/* if card removed - set irq for low level, else vice versa */
gpio_irq_type = val ? IRQF_TRIGGER_LOW : IRQF_TRIGGER_HIGH;
- set_irq_type(irq, gpio_irq_type);
+ irq_set_irq_type(irq, gpio_irq_type);
if (sdhci->data->card_power_gpio >= 0) {
if (!sdhci->data->power_always_enb) {
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index 6e0969e4065..25e8bde600d 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -45,6 +45,7 @@
#define SDHCI_CMD_CRC 0x08
#define SDHCI_CMD_INDEX 0x10
#define SDHCI_CMD_DATA 0x20
+#define SDHCI_CMD_ABORTCMD 0xC0
#define SDHCI_CMD_RESP_NONE 0x00
#define SDHCI_CMD_RESP_LONG 0x01
diff --git a/drivers/mfd/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 53a63024bf1..cc701236d16 100644
--- a/drivers/mfd/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -23,51 +23,30 @@
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/mmc/host.h>
-#include <linux/mfd/core.h>
+#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
-#include <linux/mfd/sh_mobile_sdhi.h>
#include <linux/sh_dma.h>
+#include "tmio_mmc.h"
+
struct sh_mobile_sdhi {
struct clk *clk;
struct tmio_mmc_data mmc_data;
- struct mfd_cell cell_mmc;
struct sh_dmae_slave param_tx;
struct sh_dmae_slave param_rx;
struct tmio_mmc_dma dma_priv;
};
-static struct resource sh_mobile_sdhi_resources[] = {
- {
- .start = 0x000,
- .end = 0x1ff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = 0,
- .end = 0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct mfd_cell sh_mobile_sdhi_cell = {
- .name = "tmio-mmc",
- .num_resources = ARRAY_SIZE(sh_mobile_sdhi_resources),
- .resources = sh_mobile_sdhi_resources,
-};
-
-static void sh_mobile_sdhi_set_pwr(struct platform_device *tmio, int state)
+static void sh_mobile_sdhi_set_pwr(struct platform_device *pdev, int state)
{
- struct platform_device *pdev = to_platform_device(tmio->dev.parent);
struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
if (p && p->set_pwr)
p->set_pwr(pdev, state);
}
-static int sh_mobile_sdhi_get_cd(struct platform_device *tmio)
+static int sh_mobile_sdhi_get_cd(struct platform_device *pdev)
{
- struct platform_device *pdev = to_platform_device(tmio->dev.parent);
struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
if (p && p->get_cd)
@@ -81,20 +60,9 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
struct sh_mobile_sdhi *priv;
struct tmio_mmc_data *mmc_data;
struct sh_mobile_sdhi_info *p = pdev->dev.platform_data;
- struct resource *mem;
+ struct tmio_mmc_host *host;
char clk_name[8];
- int ret, irq;
-
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!mem)
- dev_err(&pdev->dev, "missing MEM resource\n");
-
- irq = platform_get_irq(pdev, 0);
- if (irq < 0)
- dev_err(&pdev->dev, "missing IRQ resource\n");
-
- if (!mem || (irq < 0))
- return -EINVAL;
+ int ret;
priv = kzalloc(sizeof(struct sh_mobile_sdhi), GFP_KERNEL);
if (priv == NULL) {
@@ -109,8 +77,7 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev, "cannot get clock \"%s\"\n", clk_name);
ret = PTR_ERR(priv->clk);
- kfree(priv);
- return ret;
+ goto eclkget;
}
clk_enable(priv->clk);
@@ -123,6 +90,15 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
mmc_data->flags = p->tmio_flags;
mmc_data->ocr_mask = p->tmio_ocr_mask;
mmc_data->capabilities |= p->tmio_caps;
+
+ if (p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) {
+ priv->param_tx.slave_id = p->dma_slave_tx;
+ priv->param_rx.slave_id = p->dma_slave_rx;
+ priv->dma_priv.chan_priv_tx = &priv->param_tx;
+ priv->dma_priv.chan_priv_rx = &priv->param_rx;
+ priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
+ mmc_data->dma = &priv->dma_priv;
+ }
}
/*
@@ -136,36 +112,30 @@ static int __devinit sh_mobile_sdhi_probe(struct platform_device *pdev)
*/
mmc_data->flags |= TMIO_MMC_SDIO_IRQ;
- if (p && p->dma_slave_tx >= 0 && p->dma_slave_rx >= 0) {
- priv->param_tx.slave_id = p->dma_slave_tx;
- priv->param_rx.slave_id = p->dma_slave_rx;
- priv->dma_priv.chan_priv_tx = &priv->param_tx;
- priv->dma_priv.chan_priv_rx = &priv->param_rx;
- priv->dma_priv.alignment_shift = 1; /* 2-byte alignment */
- mmc_data->dma = &priv->dma_priv;
- }
+ ret = tmio_mmc_host_probe(&host, pdev, mmc_data);
+ if (ret < 0)
+ goto eprobe;
- memcpy(&priv->cell_mmc, &sh_mobile_sdhi_cell, sizeof(priv->cell_mmc));
- priv->cell_mmc.mfd_data = mmc_data;
+ pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
+ (unsigned long)host->ctl, host->irq);
- platform_set_drvdata(pdev, priv);
-
- ret = mfd_add_devices(&pdev->dev, pdev->id,
- &priv->cell_mmc, 1, mem, irq);
- if (ret) {
- clk_disable(priv->clk);
- clk_put(priv->clk);
- kfree(priv);
- }
+ return ret;
+eprobe:
+ clk_disable(priv->clk);
+ clk_put(priv->clk);
+eclkget:
+ kfree(priv);
return ret;
}
static int sh_mobile_sdhi_remove(struct platform_device *pdev)
{
- struct sh_mobile_sdhi *priv = platform_get_drvdata(pdev);
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct sh_mobile_sdhi *priv = container_of(host->pdata, struct sh_mobile_sdhi, mmc_data);
- mfd_remove_devices(&pdev->dev);
+ tmio_mmc_host_remove(host);
clk_disable(priv->clk);
clk_put(priv->clk);
kfree(priv);
@@ -198,3 +168,4 @@ module_exit(sh_mobile_sdhi_exit);
MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
MODULE_AUTHOR("Magnus Damm");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:sh_mobile_sdhi");
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index ab1adeabdd2..79c568461d5 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -1,8 +1,8 @@
/*
- * linux/drivers/mmc/tmio_mmc.c
+ * linux/drivers/mmc/host/tmio_mmc.c
*
- * Copyright (C) 2004 Ian Molton
- * Copyright (C) 2007 Ian Molton
+ * Copyright (C) 2007 Ian Molton
+ * Copyright (C) 2004 Ian Molton
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -11,1182 +11,17 @@
* Driver for the MMC / SD / SDIO cell found in:
*
* TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
- *
- * This driver draws mainly on scattered spec sheets, Reverse engineering
- * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit
- * support). (Further 4 bit support from a later datasheet).
- *
- * TODO:
- * Investigate using a workqueue for PIO transfers
- * Eliminate FIXMEs
- * SDIO support
- * Better Power management
- * Handle MMC errors better
- * double buffer support
- *
*/
-#include <linux/delay.h>
#include <linux/device.h>
-#include <linux/dmaengine.h>
-#include <linux/highmem.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/irq.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
#include <linux/module.h>
#include <linux/pagemap.h>
#include <linux/scatterlist.h>
-#include <linux/workqueue.h>
-#include <linux/spinlock.h>
-
-#define CTL_SD_CMD 0x00
-#define CTL_ARG_REG 0x04
-#define CTL_STOP_INTERNAL_ACTION 0x08
-#define CTL_XFER_BLK_COUNT 0xa
-#define CTL_RESPONSE 0x0c
-#define CTL_STATUS 0x1c
-#define CTL_IRQ_MASK 0x20
-#define CTL_SD_CARD_CLK_CTL 0x24
-#define CTL_SD_XFER_LEN 0x26
-#define CTL_SD_MEM_CARD_OPT 0x28
-#define CTL_SD_ERROR_DETAIL_STATUS 0x2c
-#define CTL_SD_DATA_PORT 0x30
-#define CTL_TRANSACTION_CTL 0x34
-#define CTL_SDIO_STATUS 0x36
-#define CTL_SDIO_IRQ_MASK 0x38
-#define CTL_RESET_SD 0xe0
-#define CTL_SDIO_REGS 0x100
-#define CTL_CLK_AND_WAIT_CTL 0x138
-#define CTL_RESET_SDIO 0x1e0
-
-/* Definitions for values the CTRL_STATUS register can take. */
-#define TMIO_STAT_CMDRESPEND 0x00000001
-#define TMIO_STAT_DATAEND 0x00000004
-#define TMIO_STAT_CARD_REMOVE 0x00000008
-#define TMIO_STAT_CARD_INSERT 0x00000010
-#define TMIO_STAT_SIGSTATE 0x00000020
-#define TMIO_STAT_WRPROTECT 0x00000080
-#define TMIO_STAT_CARD_REMOVE_A 0x00000100
-#define TMIO_STAT_CARD_INSERT_A 0x00000200
-#define TMIO_STAT_SIGSTATE_A 0x00000400
-#define TMIO_STAT_CMD_IDX_ERR 0x00010000
-#define TMIO_STAT_CRCFAIL 0x00020000
-#define TMIO_STAT_STOPBIT_ERR 0x00040000
-#define TMIO_STAT_DATATIMEOUT 0x00080000
-#define TMIO_STAT_RXOVERFLOW 0x00100000
-#define TMIO_STAT_TXUNDERRUN 0x00200000
-#define TMIO_STAT_CMDTIMEOUT 0x00400000
-#define TMIO_STAT_RXRDY 0x01000000
-#define TMIO_STAT_TXRQ 0x02000000
-#define TMIO_STAT_ILL_FUNC 0x20000000
-#define TMIO_STAT_CMD_BUSY 0x40000000
-#define TMIO_STAT_ILL_ACCESS 0x80000000
-
-/* Definitions for values the CTRL_SDIO_STATUS register can take. */
-#define TMIO_SDIO_STAT_IOIRQ 0x0001
-#define TMIO_SDIO_STAT_EXPUB52 0x4000
-#define TMIO_SDIO_STAT_EXWT 0x8000
-#define TMIO_SDIO_MASK_ALL 0xc007
-
-/* Define some IRQ masks */
-/* This is the mask used at reset by the chip */
-#define TMIO_MASK_ALL 0x837f031d
-#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND)
-#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND)
-#define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
- TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
-#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
-
-#define enable_mmc_irqs(host, i) \
- do { \
- u32 mask;\
- mask = sd_ctrl_read32((host), CTL_IRQ_MASK); \
- mask &= ~((i) & TMIO_MASK_IRQ); \
- sd_ctrl_write32((host), CTL_IRQ_MASK, mask); \
- } while (0)
-
-#define disable_mmc_irqs(host, i) \
- do { \
- u32 mask;\
- mask = sd_ctrl_read32((host), CTL_IRQ_MASK); \
- mask |= ((i) & TMIO_MASK_IRQ); \
- sd_ctrl_write32((host), CTL_IRQ_MASK, mask); \
- } while (0)
-
-#define ack_mmc_irqs(host, i) \
- do { \
- sd_ctrl_write32((host), CTL_STATUS, ~(i)); \
- } while (0)
-
-/* This is arbitrary, just noone needed any higher alignment yet */
-#define MAX_ALIGN 4
-
-struct tmio_mmc_host {
- void __iomem *ctl;
- unsigned long bus_shift;
- struct mmc_command *cmd;
- struct mmc_request *mrq;
- struct mmc_data *data;
- struct mmc_host *mmc;
- int irq;
- unsigned int sdio_irq_enabled;
-
- /* Callbacks for clock / power control */
- void (*set_pwr)(struct platform_device *host, int state);
- void (*set_clk_div)(struct platform_device *host, int state);
-
- /* pio related stuff */
- struct scatterlist *sg_ptr;
- struct scatterlist *sg_orig;
- unsigned int sg_len;
- unsigned int sg_off;
-
- struct platform_device *pdev;
-
- /* DMA support */
- struct dma_chan *chan_rx;
- struct dma_chan *chan_tx;
- struct tasklet_struct dma_complete;
- struct tasklet_struct dma_issue;
-#ifdef CONFIG_TMIO_MMC_DMA
- u8 bounce_buf[PAGE_CACHE_SIZE] __attribute__((aligned(MAX_ALIGN)));
- struct scatterlist bounce_sg;
-#endif
-
- /* Track lost interrupts */
- struct delayed_work delayed_reset_work;
- spinlock_t lock;
- unsigned long last_req_ts;
-};
-
-static void tmio_check_bounce_buffer(struct tmio_mmc_host *host);
-
-static u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr)
-{
- return readw(host->ctl + (addr << host->bus_shift));
-}
-
-static void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr,
- u16 *buf, int count)
-{
- readsw(host->ctl + (addr << host->bus_shift), buf, count);
-}
-
-static u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
-{
- return readw(host->ctl + (addr << host->bus_shift)) |
- readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
-}
-
-static void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val)
-{
- writew(val, host->ctl + (addr << host->bus_shift));
-}
-
-static void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr,
- u16 *buf, int count)
-{
- writesw(host->ctl + (addr << host->bus_shift), buf, count);
-}
-
-static void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val)
-{
- writew(val, host->ctl + (addr << host->bus_shift));
- writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
-}
-
-static void tmio_mmc_init_sg(struct tmio_mmc_host *host, struct mmc_data *data)
-{
- host->sg_len = data->sg_len;
- host->sg_ptr = data->sg;
- host->sg_orig = data->sg;
- host->sg_off = 0;
-}
-
-static int tmio_mmc_next_sg(struct tmio_mmc_host *host)
-{
- host->sg_ptr = sg_next(host->sg_ptr);
- host->sg_off = 0;
- return --host->sg_len;
-}
-
-static char *tmio_mmc_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
-{
- local_irq_save(*flags);
- return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
-}
-
-static void tmio_mmc_kunmap_atomic(struct scatterlist *sg, unsigned long *flags, void *virt)
-{
- kunmap_atomic(virt - sg->offset, KM_BIO_SRC_IRQ);
- local_irq_restore(*flags);
-}
-
-#ifdef CONFIG_MMC_DEBUG
-
-#define STATUS_TO_TEXT(a, status, i) \
- do { \
- if (status & TMIO_STAT_##a) { \
- if (i++) \
- printk(" | "); \
- printk(#a); \
- } \
- } while (0)
-
-void pr_debug_status(u32 status)
-{
- int i = 0;
- printk(KERN_DEBUG "status: %08x = ", status);
- STATUS_TO_TEXT(CARD_REMOVE, status, i);
- STATUS_TO_TEXT(CARD_INSERT, status, i);
- STATUS_TO_TEXT(SIGSTATE, status, i);
- STATUS_TO_TEXT(WRPROTECT, status, i);
- STATUS_TO_TEXT(CARD_REMOVE_A, status, i);
- STATUS_TO_TEXT(CARD_INSERT_A, status, i);
- STATUS_TO_TEXT(SIGSTATE_A, status, i);
- STATUS_TO_TEXT(CMD_IDX_ERR, status, i);
- STATUS_TO_TEXT(STOPBIT_ERR, status, i);
- STATUS_TO_TEXT(ILL_FUNC, status, i);
- STATUS_TO_TEXT(CMD_BUSY, status, i);
- STATUS_TO_TEXT(CMDRESPEND, status, i);
- STATUS_TO_TEXT(DATAEND, status, i);
- STATUS_TO_TEXT(CRCFAIL, status, i);
- STATUS_TO_TEXT(DATATIMEOUT, status, i);
- STATUS_TO_TEXT(CMDTIMEOUT, status, i);
- STATUS_TO_TEXT(RXOVERFLOW, status, i);
- STATUS_TO_TEXT(TXUNDERRUN, status, i);
- STATUS_TO_TEXT(RXRDY, status, i);
- STATUS_TO_TEXT(TXRQ, status, i);
- STATUS_TO_TEXT(ILL_ACCESS, status, i);
- printk("\n");
-}
-
-#else
-#define pr_debug_status(s) do { } while (0)
-#endif
-
-static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
-{
- struct tmio_mmc_host *host = mmc_priv(mmc);
-
- if (enable) {
- host->sdio_irq_enabled = 1;
- sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
- sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
- (TMIO_SDIO_MASK_ALL & ~TMIO_SDIO_STAT_IOIRQ));
- } else {
- sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, TMIO_SDIO_MASK_ALL);
- sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
- host->sdio_irq_enabled = 0;
- }
-}
-
-static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
-{
- u32 clk = 0, clock;
-
- if (new_clock) {
- for (clock = host->mmc->f_min, clk = 0x80000080;
- new_clock >= (clock<<1); clk >>= 1)
- clock <<= 1;
- clk |= 0x100;
- }
-
- if (host->set_clk_div)
- host->set_clk_div(host->pdev, (clk>>22) & 1);
-
- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff);
-}
-
-static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
-{
- struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
-
- /*
- * Testing on sh-mobile showed that SDIO IRQs are unmasked when
- * CTL_CLK_AND_WAIT_CTL gets written, so we have to disable the
- * device IRQ here and restore the SDIO IRQ mask before
- * re-enabling the device IRQ.
- */
- if (pdata->flags & TMIO_MMC_SDIO_IRQ)
- disable_irq(host->irq);
- sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
- msleep(10);
- if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
- tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
- enable_irq(host->irq);
- }
- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~0x0100 &
- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
- msleep(10);
-}
-
-static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
-{
- struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
-
- sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
- sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
- msleep(10);
- /* see comment in tmio_mmc_clk_stop above */
- if (pdata->flags & TMIO_MMC_SDIO_IRQ)
- disable_irq(host->irq);
- sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
- msleep(10);
- if (pdata->flags & TMIO_MMC_SDIO_IRQ) {
- tmio_mmc_enable_sdio_irq(host->mmc, host->sdio_irq_enabled);
- enable_irq(host->irq);
- }
-}
-
-static void reset(struct tmio_mmc_host *host)
-{
- /* FIXME - should we set stop clock reg here */
- sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
- sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
- msleep(10);
- sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
- sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
- msleep(10);
-}
-
-static void tmio_mmc_reset_work(struct work_struct *work)
-{
- struct tmio_mmc_host *host = container_of(work, struct tmio_mmc_host,
- delayed_reset_work.work);
- struct mmc_request *mrq;
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
- mrq = host->mrq;
-
- /* request already finished */
- if (!mrq
- || time_is_after_jiffies(host->last_req_ts +
- msecs_to_jiffies(2000))) {
- spin_unlock_irqrestore(&host->lock, flags);
- return;
- }
-
- dev_warn(&host->pdev->dev,
- "timeout waiting for hardware interrupt (CMD%u)\n",
- mrq->cmd->opcode);
-
- if (host->data)
- host->data->error = -ETIMEDOUT;
- else if (host->cmd)
- host->cmd->error = -ETIMEDOUT;
- else
- mrq->cmd->error = -ETIMEDOUT;
-
- host->cmd = NULL;
- host->data = NULL;
- host->mrq = NULL;
-
- spin_unlock_irqrestore(&host->lock, flags);
-
- reset(host);
-
- mmc_request_done(host->mmc, mrq);
-}
-
-static void
-tmio_mmc_finish_request(struct tmio_mmc_host *host)
-{
- struct mmc_request *mrq = host->mrq;
-
- if (!mrq)
- return;
-
- host->mrq = NULL;
- host->cmd = NULL;
- host->data = NULL;
-
- cancel_delayed_work(&host->delayed_reset_work);
-
- mmc_request_done(host->mmc, mrq);
-}
-
-/* These are the bitmasks the tmio chip requires to implement the MMC response
- * types. Note that R1 and R6 are the same in this scheme. */
-#define APP_CMD 0x0040
-#define RESP_NONE 0x0300
-#define RESP_R1 0x0400
-#define RESP_R1B 0x0500
-#define RESP_R2 0x0600
-#define RESP_R3 0x0700
-#define DATA_PRESENT 0x0800
-#define TRANSFER_READ 0x1000
-#define TRANSFER_MULTI 0x2000
-#define SECURITY_CMD 0x4000
-
-static int
-tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
-{
- struct mmc_data *data = host->data;
- int c = cmd->opcode;
-
- /* Command 12 is handled by hardware */
- if (cmd->opcode == 12 && !cmd->arg) {
- sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001);
- return 0;
- }
-
- switch (mmc_resp_type(cmd)) {
- case MMC_RSP_NONE: c |= RESP_NONE; break;
- case MMC_RSP_R1: c |= RESP_R1; break;
- case MMC_RSP_R1B: c |= RESP_R1B; break;
- case MMC_RSP_R2: c |= RESP_R2; break;
- case MMC_RSP_R3: c |= RESP_R3; break;
- default:
- pr_debug("Unknown response type %d\n", mmc_resp_type(cmd));
- return -EINVAL;
- }
-
- host->cmd = cmd;
-
-/* FIXME - this seems to be ok commented out but the spec suggest this bit
- * should be set when issuing app commands.
- * if(cmd->flags & MMC_FLAG_ACMD)
- * c |= APP_CMD;
- */
- if (data) {
- c |= DATA_PRESENT;
- if (data->blocks > 1) {
- sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x100);
- c |= TRANSFER_MULTI;
- }
- if (data->flags & MMC_DATA_READ)
- c |= TRANSFER_READ;
- }
-
- enable_mmc_irqs(host, TMIO_MASK_CMD);
-
- /* Fire off the command */
- sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg);
- sd_ctrl_write16(host, CTL_SD_CMD, c);
-
- return 0;
-}
-
-/*
- * This chip always returns (at least?) as much data as you ask for.
- * I'm unsure what happens if you ask for less than a block. This should be
- * looked into to ensure that a funny length read doesnt hose the controller.
- */
-static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
-{
- struct mmc_data *data = host->data;
- void *sg_virt;
- unsigned short *buf;
- unsigned int count;
- unsigned long flags;
-
- if (!data) {
- pr_debug("Spurious PIO IRQ\n");
- return;
- }
-
- sg_virt = tmio_mmc_kmap_atomic(host->sg_ptr, &flags);
- buf = (unsigned short *)(sg_virt + host->sg_off);
-
- count = host->sg_ptr->length - host->sg_off;
- if (count > data->blksz)
- count = data->blksz;
-
- pr_debug("count: %08x offset: %08x flags %08x\n",
- count, host->sg_off, data->flags);
-
- /* Transfer the data */
- if (data->flags & MMC_DATA_READ)
- sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
- else
- sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
-
- host->sg_off += count;
-
- tmio_mmc_kunmap_atomic(host->sg_ptr, &flags, sg_virt);
-
- if (host->sg_off == host->sg_ptr->length)
- tmio_mmc_next_sg(host);
-
- return;
-}
-
-/* needs to be called with host->lock held */
-static void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
-{
- struct mmc_data *data = host->data;
- struct mmc_command *stop;
-
- host->data = NULL;
-
- if (!data) {
- dev_warn(&host->pdev->dev, "Spurious data end IRQ\n");
- return;
- }
- stop = data->stop;
-
- /* FIXME - return correct transfer count on errors */
- if (!data->error)
- data->bytes_xfered = data->blocks * data->blksz;
- else
- data->bytes_xfered = 0;
-
- pr_debug("Completed data request\n");
-
- /*
- * FIXME: other drivers allow an optional stop command of any given type
- * which we dont do, as the chip can auto generate them.
- * Perhaps we can be smarter about when to use auto CMD12 and
- * only issue the auto request when we know this is the desired
- * stop command, allowing fallback to the stop command the
- * upper layers expect. For now, we do what works.
- */
-
- if (data->flags & MMC_DATA_READ) {
- if (!host->chan_rx)
- disable_mmc_irqs(host, TMIO_MASK_READOP);
- else
- tmio_check_bounce_buffer(host);
- dev_dbg(&host->pdev->dev, "Complete Rx request %p\n",
- host->mrq);
- } else {
- if (!host->chan_tx)
- disable_mmc_irqs(host, TMIO_MASK_WRITEOP);
- dev_dbg(&host->pdev->dev, "Complete Tx request %p\n",
- host->mrq);
- }
-
- if (stop) {
- if (stop->opcode == 12 && !stop->arg)
- sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000);
- else
- BUG();
- }
-
- tmio_mmc_finish_request(host);
-}
-
-static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
-{
- struct mmc_data *data;
- spin_lock(&host->lock);
- data = host->data;
-
- if (!data)
- goto out;
-
- if (host->chan_tx && (data->flags & MMC_DATA_WRITE)) {
- /*
- * Has all data been written out yet? Testing on SuperH showed,
- * that in most cases the first interrupt comes already with the
- * BUSY status bit clear, but on some operations, like mount or
- * in the beginning of a write / sync / umount, there is one
- * DATAEND interrupt with the BUSY bit set, in this cases
- * waiting for one more interrupt fixes the problem.
- */
- if (!(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_CMD_BUSY)) {
- disable_mmc_irqs(host, TMIO_STAT_DATAEND);
- tasklet_schedule(&host->dma_complete);
- }
- } else if (host->chan_rx && (data->flags & MMC_DATA_READ)) {
- disable_mmc_irqs(host, TMIO_STAT_DATAEND);
- tasklet_schedule(&host->dma_complete);
- } else {
- tmio_mmc_do_data_irq(host);
- }
-out:
- spin_unlock(&host->lock);
-}
-
-static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
- unsigned int stat)
-{
- struct mmc_command *cmd = host->cmd;
- int i, addr;
-
- spin_lock(&host->lock);
-
- if (!host->cmd) {
- pr_debug("Spurious CMD irq\n");
- goto out;
- }
-
- host->cmd = NULL;
-
- /* This controller is sicker than the PXA one. Not only do we need to
- * drop the top 8 bits of the first response word, we also need to
- * modify the order of the response for short response command types.
- */
-
- for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4)
- cmd->resp[i] = sd_ctrl_read32(host, addr);
-
- if (cmd->flags & MMC_RSP_136) {
- cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24);
- cmd->resp[1] = (cmd->resp[1] << 8) | (cmd->resp[2] >> 24);
- cmd->resp[2] = (cmd->resp[2] << 8) | (cmd->resp[3] >> 24);
- cmd->resp[3] <<= 8;
- } else if (cmd->flags & MMC_RSP_R3) {
- cmd->resp[0] = cmd->resp[3];
- }
-
- if (stat & TMIO_STAT_CMDTIMEOUT)
- cmd->error = -ETIMEDOUT;
- else if (stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC)
- cmd->error = -EILSEQ;
-
- /* If there is data to handle we enable data IRQs here, and
- * we will ultimatley finish the request in the data_end handler.
- * If theres no data or we encountered an error, finish now.
- */
- if (host->data && !cmd->error) {
- if (host->data->flags & MMC_DATA_READ) {
- if (!host->chan_rx)
- enable_mmc_irqs(host, TMIO_MASK_READOP);
- } else {
- if (!host->chan_tx)
- enable_mmc_irqs(host, TMIO_MASK_WRITEOP);
- else
- tasklet_schedule(&host->dma_issue);
- }
- } else {
- tmio_mmc_finish_request(host);
- }
-
-out:
- spin_unlock(&host->lock);
-
- return;
-}
-
-static irqreturn_t tmio_mmc_irq(int irq, void *devid)
-{
- struct tmio_mmc_host *host = devid;
- struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
- unsigned int ireg, irq_mask, status;
- unsigned int sdio_ireg, sdio_irq_mask, sdio_status;
-
- pr_debug("MMC IRQ begin\n");
-
- status = sd_ctrl_read32(host, CTL_STATUS);
- irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
- ireg = status & TMIO_MASK_IRQ & ~irq_mask;
-
- sdio_ireg = 0;
- if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) {
- sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
- sdio_irq_mask = sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK);
- sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL & ~sdio_irq_mask;
-
- sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL);
-
- if (sdio_ireg && !host->sdio_irq_enabled) {
- pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
- sdio_status, sdio_irq_mask, sdio_ireg);
- tmio_mmc_enable_sdio_irq(host->mmc, 0);
- goto out;
- }
- if (host->mmc->caps & MMC_CAP_SDIO_IRQ &&
- sdio_ireg & TMIO_SDIO_STAT_IOIRQ)
- mmc_signal_sdio_irq(host->mmc);
-
- if (sdio_ireg)
- goto out;
- }
-
- pr_debug_status(status);
- pr_debug_status(ireg);
-
- if (!ireg) {
- disable_mmc_irqs(host, status & ~irq_mask);
-
- pr_warning("tmio_mmc: Spurious irq, disabling! "
- "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
- pr_debug_status(status);
-
- goto out;
- }
-
- while (ireg) {
- /* Card insert / remove attempts */
- if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
- ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
- TMIO_STAT_CARD_REMOVE);
- mmc_detect_change(host->mmc, msecs_to_jiffies(100));
- }
-
- /* CRC and other errors */
-/* if (ireg & TMIO_STAT_ERR_IRQ)
- * handled |= tmio_error_irq(host, irq, stat);
- */
-
- /* Command completion */
- if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) {
- ack_mmc_irqs(host,
- TMIO_STAT_CMDRESPEND |
- TMIO_STAT_CMDTIMEOUT);
- tmio_mmc_cmd_irq(host, status);
- }
-
- /* Data transfer */
- if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
- ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
- tmio_mmc_pio_irq(host);
- }
-
- /* Data transfer completion */
- if (ireg & TMIO_STAT_DATAEND) {
- ack_mmc_irqs(host, TMIO_STAT_DATAEND);
- tmio_mmc_data_irq(host);
- }
-
- /* Check status - keep going until we've handled it all */
- status = sd_ctrl_read32(host, CTL_STATUS);
- irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
- ireg = status & TMIO_MASK_IRQ & ~irq_mask;
-
- pr_debug("Status at end of loop: %08x\n", status);
- pr_debug_status(status);
- }
- pr_debug("MMC IRQ end\n");
-
-out:
- return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_TMIO_MMC_DMA
-static void tmio_check_bounce_buffer(struct tmio_mmc_host *host)
-{
- if (host->sg_ptr == &host->bounce_sg) {
- unsigned long flags;
- void *sg_vaddr = tmio_mmc_kmap_atomic(host->sg_orig, &flags);
- memcpy(sg_vaddr, host->bounce_buf, host->bounce_sg.length);
- tmio_mmc_kunmap_atomic(host->sg_orig, &flags, sg_vaddr);
- }
-}
-
-static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
-{
-#if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE)
- /* Switch DMA mode on or off - SuperH specific? */
- sd_ctrl_write16(host, 0xd8, enable ? 2 : 0);
-#endif
-}
-
-static void tmio_dma_complete(void *arg)
-{
- struct tmio_mmc_host *host = arg;
-
- dev_dbg(&host->pdev->dev, "Command completed\n");
-
- if (!host->data)
- dev_warn(&host->pdev->dev, "NULL data in DMA completion!\n");
- else
- enable_mmc_irqs(host, TMIO_STAT_DATAEND);
-}
-
-static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
-{
- struct scatterlist *sg = host->sg_ptr, *sg_tmp;
- struct dma_async_tx_descriptor *desc = NULL;
- struct dma_chan *chan = host->chan_rx;
- struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
- dma_cookie_t cookie;
- int ret, i;
- bool aligned = true, multiple = true;
- unsigned int align = (1 << pdata->dma->alignment_shift) - 1;
-
- for_each_sg(sg, sg_tmp, host->sg_len, i) {
- if (sg_tmp->offset & align)
- aligned = false;
- if (sg_tmp->length & align) {
- multiple = false;
- break;
- }
- }
-
- if ((!aligned && (host->sg_len > 1 || sg->length > PAGE_CACHE_SIZE ||
- align >= MAX_ALIGN)) || !multiple) {
- ret = -EINVAL;
- goto pio;
- }
-
- /* The only sg element can be unaligned, use our bounce buffer then */
- if (!aligned) {
- sg_init_one(&host->bounce_sg, host->bounce_buf, sg->length);
- host->sg_ptr = &host->bounce_sg;
- sg = host->sg_ptr;
- }
-
- ret = dma_map_sg(chan->device->dev, sg, host->sg_len, DMA_FROM_DEVICE);
- if (ret > 0)
- desc = chan->device->device_prep_slave_sg(chan, sg, ret,
- DMA_FROM_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-
- if (desc) {
- desc->callback = tmio_dma_complete;
- desc->callback_param = host;
- cookie = dmaengine_submit(desc);
- dma_async_issue_pending(chan);
- }
- dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
- __func__, host->sg_len, ret, cookie, host->mrq);
-
-pio:
- if (!desc) {
- /* DMA failed, fall back to PIO */
- if (ret >= 0)
- ret = -EIO;
- host->chan_rx = NULL;
- dma_release_channel(chan);
- /* Free the Tx channel too */
- chan = host->chan_tx;
- if (chan) {
- host->chan_tx = NULL;
- dma_release_channel(chan);
- }
- dev_warn(&host->pdev->dev,
- "DMA failed: %d, falling back to PIO\n", ret);
- tmio_mmc_enable_dma(host, false);
- }
-
- dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
- desc, cookie, host->sg_len);
-}
-
-static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
-{
- struct scatterlist *sg = host->sg_ptr, *sg_tmp;
- struct dma_async_tx_descriptor *desc = NULL;
- struct dma_chan *chan = host->chan_tx;
- struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
- dma_cookie_t cookie;
- int ret, i;
- bool aligned = true, multiple = true;
- unsigned int align = (1 << pdata->dma->alignment_shift) - 1;
-
- for_each_sg(sg, sg_tmp, host->sg_len, i) {
- if (sg_tmp->offset & align)
- aligned = false;
- if (sg_tmp->length & align) {
- multiple = false;
- break;
- }
- }
-
- if ((!aligned && (host->sg_len > 1 || sg->length > PAGE_CACHE_SIZE ||
- align >= MAX_ALIGN)) || !multiple) {
- ret = -EINVAL;
- goto pio;
- }
-
- /* The only sg element can be unaligned, use our bounce buffer then */
- if (!aligned) {
- unsigned long flags;
- void *sg_vaddr = tmio_mmc_kmap_atomic(sg, &flags);
- sg_init_one(&host->bounce_sg, host->bounce_buf, sg->length);
- memcpy(host->bounce_buf, sg_vaddr, host->bounce_sg.length);
- tmio_mmc_kunmap_atomic(sg, &flags, sg_vaddr);
- host->sg_ptr = &host->bounce_sg;
- sg = host->sg_ptr;
- }
-
- ret = dma_map_sg(chan->device->dev, sg, host->sg_len, DMA_TO_DEVICE);
- if (ret > 0)
- desc = chan->device->device_prep_slave_sg(chan, sg, ret,
- DMA_TO_DEVICE, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
-
- if (desc) {
- desc->callback = tmio_dma_complete;
- desc->callback_param = host;
- cookie = dmaengine_submit(desc);
- }
- dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
- __func__, host->sg_len, ret, cookie, host->mrq);
-
-pio:
- if (!desc) {
- /* DMA failed, fall back to PIO */
- if (ret >= 0)
- ret = -EIO;
- host->chan_tx = NULL;
- dma_release_channel(chan);
- /* Free the Rx channel too */
- chan = host->chan_rx;
- if (chan) {
- host->chan_rx = NULL;
- dma_release_channel(chan);
- }
- dev_warn(&host->pdev->dev,
- "DMA failed: %d, falling back to PIO\n", ret);
- tmio_mmc_enable_dma(host, false);
- }
-
- dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__,
- desc, cookie);
-}
-
-static void tmio_mmc_start_dma(struct tmio_mmc_host *host,
- struct mmc_data *data)
-{
- if (data->flags & MMC_DATA_READ) {
- if (host->chan_rx)
- tmio_mmc_start_dma_rx(host);
- } else {
- if (host->chan_tx)
- tmio_mmc_start_dma_tx(host);
- }
-}
-
-static void tmio_issue_tasklet_fn(unsigned long priv)
-{
- struct tmio_mmc_host *host = (struct tmio_mmc_host *)priv;
- struct dma_chan *chan = host->chan_tx;
-
- dma_async_issue_pending(chan);
-}
-
-static void tmio_tasklet_fn(unsigned long arg)
-{
- struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg;
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
-
- if (!host->data)
- goto out;
-
- if (host->data->flags & MMC_DATA_READ)
- dma_unmap_sg(host->chan_rx->device->dev,
- host->sg_ptr, host->sg_len,
- DMA_FROM_DEVICE);
- else
- dma_unmap_sg(host->chan_tx->device->dev,
- host->sg_ptr, host->sg_len,
- DMA_TO_DEVICE);
-
- tmio_mmc_do_data_irq(host);
-out:
- spin_unlock_irqrestore(&host->lock, flags);
-}
-
-/* It might be necessary to make filter MFD specific */
-static bool tmio_mmc_filter(struct dma_chan *chan, void *arg)
-{
- dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg);
- chan->private = arg;
- return true;
-}
-
-static void tmio_mmc_request_dma(struct tmio_mmc_host *host,
- struct tmio_mmc_data *pdata)
-{
- /* We can only either use DMA for both Tx and Rx or not use it at all */
- if (pdata->dma) {
- dma_cap_mask_t mask;
-
- dma_cap_zero(mask);
- dma_cap_set(DMA_SLAVE, mask);
-
- host->chan_tx = dma_request_channel(mask, tmio_mmc_filter,
- pdata->dma->chan_priv_tx);
- dev_dbg(&host->pdev->dev, "%s: TX: got channel %p\n", __func__,
- host->chan_tx);
-
- if (!host->chan_tx)
- return;
-
- host->chan_rx = dma_request_channel(mask, tmio_mmc_filter,
- pdata->dma->chan_priv_rx);
- dev_dbg(&host->pdev->dev, "%s: RX: got channel %p\n", __func__,
- host->chan_rx);
-
- if (!host->chan_rx) {
- dma_release_channel(host->chan_tx);
- host->chan_tx = NULL;
- return;
- }
-
- tasklet_init(&host->dma_complete, tmio_tasklet_fn, (unsigned long)host);
- tasklet_init(&host->dma_issue, tmio_issue_tasklet_fn, (unsigned long)host);
-
- tmio_mmc_enable_dma(host, true);
- }
-}
-
-static void tmio_mmc_release_dma(struct tmio_mmc_host *host)
-{
- if (host->chan_tx) {
- struct dma_chan *chan = host->chan_tx;
- host->chan_tx = NULL;
- dma_release_channel(chan);
- }
- if (host->chan_rx) {
- struct dma_chan *chan = host->chan_rx;
- host->chan_rx = NULL;
- dma_release_channel(chan);
- }
-}
-#else
-static void tmio_check_bounce_buffer(struct tmio_mmc_host *host)
-{
-}
-
-static void tmio_mmc_start_dma(struct tmio_mmc_host *host,
- struct mmc_data *data)
-{
-}
-
-static void tmio_mmc_request_dma(struct tmio_mmc_host *host,
- struct tmio_mmc_data *pdata)
-{
- host->chan_tx = NULL;
- host->chan_rx = NULL;
-}
-
-static void tmio_mmc_release_dma(struct tmio_mmc_host *host)
-{
-}
-#endif
-
-static int tmio_mmc_start_data(struct tmio_mmc_host *host,
- struct mmc_data *data)
-{
- struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
-
- pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
- data->blksz, data->blocks);
-
- /* Some hardware cannot perform 2 byte requests in 4 bit mode */
- if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) {
- int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES;
-
- if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) {
- pr_err("%s: %d byte block unsupported in 4 bit mode\n",
- mmc_hostname(host->mmc), data->blksz);
- return -EINVAL;
- }
- }
-
- tmio_mmc_init_sg(host, data);
- host->data = data;
-
- /* Set transfer length / blocksize */
- sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz);
- sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks);
-
- tmio_mmc_start_dma(host, data);
-
- return 0;
-}
-
-/* Process requests from the MMC layer */
-static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
-{
- struct tmio_mmc_host *host = mmc_priv(mmc);
- int ret;
-
- if (host->mrq)
- pr_debug("request not null\n");
-
- host->last_req_ts = jiffies;
- wmb();
- host->mrq = mrq;
-
- if (mrq->data) {
- ret = tmio_mmc_start_data(host, mrq->data);
- if (ret)
- goto fail;
- }
-
- ret = tmio_mmc_start_command(host, mrq->cmd);
- if (!ret) {
- schedule_delayed_work(&host->delayed_reset_work,
- msecs_to_jiffies(2000));
- return;
- }
-
-fail:
- host->mrq = NULL;
- mrq->cmd->error = ret;
- mmc_request_done(mmc, mrq);
-}
-
-/* Set MMC clock / power.
- * Note: This controller uses a simple divider scheme therefore it cannot
- * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
- * MMC wont run that fast, it has to be clocked at 12MHz which is the next
- * slowest setting.
- */
-static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
-{
- struct tmio_mmc_host *host = mmc_priv(mmc);
-
- if (ios->clock)
- tmio_mmc_set_clock(host, ios->clock);
-
- /* Power sequence - OFF -> ON -> UP */
- switch (ios->power_mode) {
- case MMC_POWER_OFF: /* power down SD bus */
- if (host->set_pwr)
- host->set_pwr(host->pdev, 0);
- tmio_mmc_clk_stop(host);
- break;
- case MMC_POWER_ON: /* power up SD bus */
- if (host->set_pwr)
- host->set_pwr(host->pdev, 1);
- break;
- case MMC_POWER_UP: /* start bus clock */
- tmio_mmc_clk_start(host);
- break;
- }
-
- switch (ios->bus_width) {
- case MMC_BUS_WIDTH_1:
- sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
- break;
- case MMC_BUS_WIDTH_4:
- sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
- break;
- }
-
- /* Let things settle. delay taken from winCE driver */
- udelay(140);
-}
-
-static int tmio_mmc_get_ro(struct mmc_host *mmc)
-{
- struct tmio_mmc_host *host = mmc_priv(mmc);
- struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
-
- return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
- (sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT)) ? 0 : 1;
-}
-
-static int tmio_mmc_get_cd(struct mmc_host *mmc)
-{
- struct tmio_mmc_host *host = mmc_priv(mmc);
- struct tmio_mmc_data *pdata = mfd_get_data(host->pdev);
-
- if (!pdata->get_cd)
- return -ENOSYS;
- else
- return pdata->get_cd(host->pdev);
-}
-
-static const struct mmc_host_ops tmio_mmc_ops = {
- .request = tmio_mmc_request,
- .set_ios = tmio_mmc_set_ios,
- .get_ro = tmio_mmc_get_ro,
- .get_cd = tmio_mmc_get_cd,
- .enable_sdio_irq = tmio_mmc_enable_sdio_irq,
-};
+#include "tmio_mmc.h"
#ifdef CONFIG_PM
static int tmio_mmc_suspend(struct platform_device *dev, pm_message_t state)
@@ -1227,138 +62,54 @@ out:
#define tmio_mmc_resume NULL
#endif
-static int __devinit tmio_mmc_probe(struct platform_device *dev)
+static int __devinit tmio_mmc_probe(struct platform_device *pdev)
{
- const struct mfd_cell *cell = mfd_get_cell(dev);
+ const struct mfd_cell *cell = mfd_get_cell(pdev);
struct tmio_mmc_data *pdata;
- struct resource *res_ctl;
struct tmio_mmc_host *host;
- struct mmc_host *mmc;
int ret = -EINVAL;
- u32 irq_mask = TMIO_MASK_CMD;
- if (dev->num_resources != 2)
+ if (pdev->num_resources != 2)
goto out;
- res_ctl = platform_get_resource(dev, IORESOURCE_MEM, 0);
- if (!res_ctl)
- goto out;
-
- pdata = mfd_get_data(dev);
+ pdata = mfd_get_data(pdev);
if (!pdata || !pdata->hclk)
goto out;
- ret = -ENOMEM;
-
- mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &dev->dev);
- if (!mmc)
- goto out;
-
- host = mmc_priv(mmc);
- host->mmc = mmc;
- host->pdev = dev;
- platform_set_drvdata(dev, mmc);
-
- host->set_pwr = pdata->set_pwr;
- host->set_clk_div = pdata->set_clk_div;
-
- /* SD control register space size is 0x200, 0x400 for bus_shift=1 */
- host->bus_shift = resource_size(res_ctl) >> 10;
-
- host->ctl = ioremap(res_ctl->start, resource_size(res_ctl));
- if (!host->ctl)
- goto host_free;
-
- mmc->ops = &tmio_mmc_ops;
- mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
- mmc->f_max = pdata->hclk;
- mmc->f_min = mmc->f_max / 512;
- mmc->max_segs = 32;
- mmc->max_blk_size = 512;
- mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
- mmc->max_segs;
- mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
- mmc->max_seg_size = mmc->max_req_size;
- if (pdata->ocr_mask)
- mmc->ocr_avail = pdata->ocr_mask;
- else
- mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
-
/* Tell the MFD core we are ready to be enabled */
if (cell->enable) {
- ret = cell->enable(dev);
+ ret = cell->enable(pdev);
if (ret)
- goto unmap_ctl;
+ goto out;
}
- tmio_mmc_clk_stop(host);
- reset(host);
-
- ret = platform_get_irq(dev, 0);
- if (ret >= 0)
- host->irq = ret;
- else
- goto cell_disable;
-
- disable_mmc_irqs(host, TMIO_MASK_ALL);
- if (pdata->flags & TMIO_MMC_SDIO_IRQ)
- tmio_mmc_enable_sdio_irq(mmc, 0);
-
- ret = request_irq(host->irq, tmio_mmc_irq, IRQF_DISABLED |
- IRQF_TRIGGER_FALLING, dev_name(&dev->dev), host);
+ ret = tmio_mmc_host_probe(&host, pdev, pdata);
if (ret)
goto cell_disable;
- spin_lock_init(&host->lock);
-
- /* Init delayed work for request timeouts */
- INIT_DELAYED_WORK(&host->delayed_reset_work, tmio_mmc_reset_work);
-
- /* See if we also get DMA */
- tmio_mmc_request_dma(host, pdata);
-
- mmc_add_host(mmc);
-
pr_info("%s at 0x%08lx irq %d\n", mmc_hostname(host->mmc),
(unsigned long)host->ctl, host->irq);
- /* Unmask the IRQs we want to know about */
- if (!host->chan_rx)
- irq_mask |= TMIO_MASK_READOP;
- if (!host->chan_tx)
- irq_mask |= TMIO_MASK_WRITEOP;
- enable_mmc_irqs(host, irq_mask);
-
return 0;
cell_disable:
if (cell->disable)
- cell->disable(dev);
-unmap_ctl:
- iounmap(host->ctl);
-host_free:
- mmc_free_host(mmc);
+ cell->disable(pdev);
out:
return ret;
}
-static int __devexit tmio_mmc_remove(struct platform_device *dev)
+static int __devexit tmio_mmc_remove(struct platform_device *pdev)
{
- const struct mfd_cell *cell = mfd_get_cell(dev);
- struct mmc_host *mmc = platform_get_drvdata(dev);
+ const struct mfd_cell *cell = mfd_get_cell(pdev);
+ struct mmc_host *mmc = platform_get_drvdata(pdev);
- platform_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
if (mmc) {
- struct tmio_mmc_host *host = mmc_priv(mmc);
- mmc_remove_host(mmc);
- cancel_delayed_work_sync(&host->delayed_reset_work);
- tmio_mmc_release_dma(host);
- free_irq(host->irq, host);
+ tmio_mmc_host_remove(mmc_priv(mmc));
if (cell->disable)
- cell->disable(dev);
- iounmap(host->ctl);
- mmc_free_host(mmc);
+ cell->disable(pdev);
}
return 0;
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
new file mode 100644
index 00000000000..099ed49a259
--- /dev/null
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -0,0 +1,123 @@
+/*
+ * linux/drivers/mmc/host/tmio_mmc.h
+ *
+ * Copyright (C) 2007 Ian Molton
+ * Copyright (C) 2004 Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for the MMC / SD / SDIO cell found in:
+ *
+ * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
+ */
+
+#ifndef TMIO_MMC_H
+#define TMIO_MMC_H
+
+#include <linux/highmem.h>
+#include <linux/mmc/tmio.h>
+#include <linux/pagemap.h>
+
+/* Definitions for values the CTRL_SDIO_STATUS register can take. */
+#define TMIO_SDIO_STAT_IOIRQ 0x0001
+#define TMIO_SDIO_STAT_EXPUB52 0x4000
+#define TMIO_SDIO_STAT_EXWT 0x8000
+#define TMIO_SDIO_MASK_ALL 0xc007
+
+/* Define some IRQ masks */
+/* This is the mask used at reset by the chip */
+#define TMIO_MASK_ALL 0x837f031d
+#define TMIO_MASK_READOP (TMIO_STAT_RXRDY | TMIO_STAT_DATAEND)
+#define TMIO_MASK_WRITEOP (TMIO_STAT_TXRQ | TMIO_STAT_DATAEND)
+#define TMIO_MASK_CMD (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT | \
+ TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT)
+#define TMIO_MASK_IRQ (TMIO_MASK_READOP | TMIO_MASK_WRITEOP | TMIO_MASK_CMD)
+
+struct tmio_mmc_data;
+
+struct tmio_mmc_host {
+ void __iomem *ctl;
+ unsigned long bus_shift;
+ struct mmc_command *cmd;
+ struct mmc_request *mrq;
+ struct mmc_data *data;
+ struct mmc_host *mmc;
+ int irq;
+ unsigned int sdio_irq_enabled;
+
+ /* Callbacks for clock / power control */
+ void (*set_pwr)(struct platform_device *host, int state);
+ void (*set_clk_div)(struct platform_device *host, int state);
+
+ /* pio related stuff */
+ struct scatterlist *sg_ptr;
+ struct scatterlist *sg_orig;
+ unsigned int sg_len;
+ unsigned int sg_off;
+
+ struct platform_device *pdev;
+ struct tmio_mmc_data *pdata;
+
+ /* DMA support */
+ bool force_pio;
+ struct dma_chan *chan_rx;
+ struct dma_chan *chan_tx;
+ struct tasklet_struct dma_complete;
+ struct tasklet_struct dma_issue;
+ struct scatterlist bounce_sg;
+ u8 *bounce_buf;
+
+ /* Track lost interrupts */
+ struct delayed_work delayed_reset_work;
+ spinlock_t lock;
+ unsigned long last_req_ts;
+};
+
+int tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ struct platform_device *pdev,
+ struct tmio_mmc_data *pdata);
+void tmio_mmc_host_remove(struct tmio_mmc_host *host);
+void tmio_mmc_do_data_irq(struct tmio_mmc_host *host);
+
+void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
+void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i);
+
+static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
+ unsigned long *flags)
+{
+ local_irq_save(*flags);
+ return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+}
+
+static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
+ unsigned long *flags, void *virt)
+{
+ kunmap_atomic(virt - sg->offset, KM_BIO_SRC_IRQ);
+ local_irq_restore(*flags);
+}
+
+#if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE)
+void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data);
+void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata);
+void tmio_mmc_release_dma(struct tmio_mmc_host *host);
+#else
+static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host,
+ struct mmc_data *data)
+{
+}
+
+static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host,
+ struct tmio_mmc_data *pdata)
+{
+ host->chan_tx = NULL;
+ host->chan_rx = NULL;
+}
+
+static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host)
+{
+}
+#endif
+
+#endif
diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c
new file mode 100644
index 00000000000..d3de74ab633
--- /dev/null
+++ b/drivers/mmc/host/tmio_mmc_dma.c
@@ -0,0 +1,317 @@
+/*
+ * linux/drivers/mmc/tmio_mmc_dma.c
+ *
+ * Copyright (C) 2010-2011 Guennadi Liakhovetski
+ *
+ * This program is free software; you can 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 function for TMIO MMC implementations
+ */
+
+#include <linux/device.h>
+#include <linux/dmaengine.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/tmio.h>
+#include <linux/pagemap.h>
+#include <linux/scatterlist.h>
+
+#include "tmio_mmc.h"
+
+#define TMIO_MMC_MIN_DMA_LEN 8
+
+static void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable)
+{
+#if defined(CONFIG_SUPERH) || defined(CONFIG_ARCH_SHMOBILE)
+ /* Switch DMA mode on or off - SuperH specific? */
+ writew(enable ? 2 : 0, host->ctl + (0xd8 << host->bus_shift));
+#endif
+}
+
+static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host)
+{
+ struct scatterlist *sg = host->sg_ptr, *sg_tmp;
+ struct dma_async_tx_descriptor *desc = NULL;
+ struct dma_chan *chan = host->chan_rx;
+ struct tmio_mmc_data *pdata = host->pdata;
+ dma_cookie_t cookie;
+ int ret, i;
+ bool aligned = true, multiple = true;
+ unsigned int align = (1 << pdata->dma->alignment_shift) - 1;
+
+ for_each_sg(sg, sg_tmp, host->sg_len, i) {
+ if (sg_tmp->offset & align)
+ aligned = false;
+ if (sg_tmp->length & align) {
+ multiple = false;
+ break;
+ }
+ }
+
+ if ((!aligned && (host->sg_len > 1 || sg->length > PAGE_CACHE_SIZE ||
+ (align & PAGE_MASK))) || !multiple) {
+ ret = -EINVAL;
+ goto pio;
+ }
+
+ if (sg->length < TMIO_MMC_MIN_DMA_LEN) {
+ host->force_pio = true;
+ return;
+ }
+
+ tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_RXRDY);
+
+ /* The only sg element can be unaligned, use our bounce buffer then */
+ if (!aligned) {
+ sg_init_one(&host->bounce_sg, host->bounce_buf, sg->length);
+ host->sg_ptr = &host->bounce_sg;
+ sg = host->sg_ptr;
+ }
+
+ ret = dma_map_sg(chan->device->dev, sg, host->sg_len, DMA_FROM_DEVICE);
+ if (ret > 0)
+ desc = chan->device->device_prep_slave_sg(chan, sg, ret,
+ DMA_FROM_DEVICE, DMA_CTRL_ACK);
+
+ if (desc) {
+ cookie = dmaengine_submit(desc);
+ if (cookie < 0) {
+ desc = NULL;
+ ret = cookie;
+ }
+ }
+ dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
+ __func__, host->sg_len, ret, cookie, host->mrq);
+
+pio:
+ if (!desc) {
+ /* DMA failed, fall back to PIO */
+ if (ret >= 0)
+ ret = -EIO;
+ host->chan_rx = NULL;
+ dma_release_channel(chan);
+ /* Free the Tx channel too */
+ chan = host->chan_tx;
+ if (chan) {
+ host->chan_tx = NULL;
+ dma_release_channel(chan);
+ }
+ dev_warn(&host->pdev->dev,
+ "DMA failed: %d, falling back to PIO\n", ret);
+ tmio_mmc_enable_dma(host, false);
+ }
+
+ dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
+ desc, cookie, host->sg_len);
+}
+
+static void tmio_mmc_start_dma_tx(struct tmio_mmc_host *host)
+{
+ struct scatterlist *sg = host->sg_ptr, *sg_tmp;
+ struct dma_async_tx_descriptor *desc = NULL;
+ struct dma_chan *chan = host->chan_tx;
+ struct tmio_mmc_data *pdata = host->pdata;
+ dma_cookie_t cookie;
+ int ret, i;
+ bool aligned = true, multiple = true;
+ unsigned int align = (1 << pdata->dma->alignment_shift) - 1;
+
+ for_each_sg(sg, sg_tmp, host->sg_len, i) {
+ if (sg_tmp->offset & align)
+ aligned = false;
+ if (sg_tmp->length & align) {
+ multiple = false;
+ break;
+ }
+ }
+
+ if ((!aligned && (host->sg_len > 1 || sg->length > PAGE_CACHE_SIZE ||
+ (align & PAGE_MASK))) || !multiple) {
+ ret = -EINVAL;
+ goto pio;
+ }
+
+ if (sg->length < TMIO_MMC_MIN_DMA_LEN) {
+ host->force_pio = true;
+ return;
+ }
+
+ tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_TXRQ);
+
+ /* The only sg element can be unaligned, use our bounce buffer then */
+ if (!aligned) {
+ unsigned long flags;
+ void *sg_vaddr = tmio_mmc_kmap_atomic(sg, &flags);
+ sg_init_one(&host->bounce_sg, host->bounce_buf, sg->length);
+ memcpy(host->bounce_buf, sg_vaddr, host->bounce_sg.length);
+ tmio_mmc_kunmap_atomic(sg, &flags, sg_vaddr);
+ host->sg_ptr = &host->bounce_sg;
+ sg = host->sg_ptr;
+ }
+
+ ret = dma_map_sg(chan->device->dev, sg, host->sg_len, DMA_TO_DEVICE);
+ if (ret > 0)
+ desc = chan->device->device_prep_slave_sg(chan, sg, ret,
+ DMA_TO_DEVICE, DMA_CTRL_ACK);
+
+ if (desc) {
+ cookie = dmaengine_submit(desc);
+ if (cookie < 0) {
+ desc = NULL;
+ ret = cookie;
+ }
+ }
+ dev_dbg(&host->pdev->dev, "%s(): mapped %d -> %d, cookie %d, rq %p\n",
+ __func__, host->sg_len, ret, cookie, host->mrq);
+
+pio:
+ if (!desc) {
+ /* DMA failed, fall back to PIO */
+ if (ret >= 0)
+ ret = -EIO;
+ host->chan_tx = NULL;
+ dma_release_channel(chan);
+ /* Free the Rx channel too */
+ chan = host->chan_rx;
+ if (chan) {
+ host->chan_rx = NULL;
+ dma_release_channel(chan);
+ }
+ dev_warn(&host->pdev->dev,
+ "DMA failed: %d, falling back to PIO\n", ret);
+ tmio_mmc_enable_dma(host, false);
+ }
+
+ dev_dbg(&host->pdev->dev, "%s(): desc %p, cookie %d\n", __func__,
+ desc, cookie);
+}
+
+void tmio_mmc_start_dma(struct tmio_mmc_host *host,
+ struct mmc_data *data)
+{
+ if (data->flags & MMC_DATA_READ) {
+ if (host->chan_rx)
+ tmio_mmc_start_dma_rx(host);
+ } else {
+ if (host->chan_tx)
+ tmio_mmc_start_dma_tx(host);
+ }
+}
+
+static void tmio_mmc_issue_tasklet_fn(unsigned long priv)
+{
+ struct tmio_mmc_host *host = (struct tmio_mmc_host *)priv;
+ struct dma_chan *chan = NULL;
+
+ spin_lock_irq(&host->lock);
+
+ if (host && host->data) {
+ if (host->data->flags & MMC_DATA_READ)
+ chan = host->chan_rx;
+ else
+ chan = host->chan_tx;
+ }
+
+ spin_unlock_irq(&host->lock);
+
+ tmio_mmc_enable_mmc_irqs(host, TMIO_STAT_DATAEND);
+
+ if (chan)
+ dma_async_issue_pending(chan);
+}
+
+static void tmio_mmc_tasklet_fn(unsigned long arg)
+{
+ struct tmio_mmc_host *host = (struct tmio_mmc_host *)arg;
+
+ spin_lock_irq(&host->lock);
+
+ if (!host->data)
+ goto out;
+
+ if (host->data->flags & MMC_DATA_READ)
+ dma_unmap_sg(host->chan_rx->device->dev,
+ host->sg_ptr, host->sg_len,
+ DMA_FROM_DEVICE);
+ else
+ dma_unmap_sg(host->chan_tx->device->dev,
+ host->sg_ptr, host->sg_len,
+ DMA_TO_DEVICE);
+
+ tmio_mmc_do_data_irq(host);
+out:
+ spin_unlock_irq(&host->lock);
+}
+
+/* It might be necessary to make filter MFD specific */
+static bool tmio_mmc_filter(struct dma_chan *chan, void *arg)
+{
+ dev_dbg(chan->device->dev, "%s: slave data %p\n", __func__, arg);
+ chan->private = arg;
+ return true;
+}
+
+void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata)
+{
+ /* We can only either use DMA for both Tx and Rx or not use it at all */
+ if (pdata->dma) {
+ dma_cap_mask_t mask;
+
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ host->chan_tx = dma_request_channel(mask, tmio_mmc_filter,
+ pdata->dma->chan_priv_tx);
+ dev_dbg(&host->pdev->dev, "%s: TX: got channel %p\n", __func__,
+ host->chan_tx);
+
+ if (!host->chan_tx)
+ return;
+
+ host->chan_rx = dma_request_channel(mask, tmio_mmc_filter,
+ pdata->dma->chan_priv_rx);
+ dev_dbg(&host->pdev->dev, "%s: RX: got channel %p\n", __func__,
+ host->chan_rx);
+
+ if (!host->chan_rx)
+ goto ereqrx;
+
+ host->bounce_buf = (u8 *)__get_free_page(GFP_KERNEL | GFP_DMA);
+ if (!host->bounce_buf)
+ goto ebouncebuf;
+
+ tasklet_init(&host->dma_complete, tmio_mmc_tasklet_fn, (unsigned long)host);
+ tasklet_init(&host->dma_issue, tmio_mmc_issue_tasklet_fn, (unsigned long)host);
+
+ tmio_mmc_enable_dma(host, true);
+
+ return;
+ebouncebuf:
+ dma_release_channel(host->chan_rx);
+ host->chan_rx = NULL;
+ereqrx:
+ dma_release_channel(host->chan_tx);
+ host->chan_tx = NULL;
+ return;
+ }
+}
+
+void tmio_mmc_release_dma(struct tmio_mmc_host *host)
+{
+ if (host->chan_tx) {
+ struct dma_chan *chan = host->chan_tx;
+ host->chan_tx = NULL;
+ dma_release_channel(chan);
+ }
+ if (host->chan_rx) {
+ struct dma_chan *chan = host->chan_rx;
+ host->chan_rx = NULL;
+ dma_release_channel(chan);
+ }
+ if (host->bounce_buf) {
+ free_pages((unsigned long)host->bounce_buf, 0);
+ host->bounce_buf = NULL;
+ }
+}
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
new file mode 100644
index 00000000000..6ae8d2f00ec
--- /dev/null
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -0,0 +1,897 @@
+/*
+ * linux/drivers/mmc/host/tmio_mmc_pio.c
+ *
+ * Copyright (C) 2011 Guennadi Liakhovetski
+ * Copyright (C) 2007 Ian Molton
+ * Copyright (C) 2004 Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for the MMC / SD / SDIO IP found in:
+ *
+ * TC6393XB, TC6391XB, TC6387XB, T7L66XB, ASIC3, SH-Mobile SoCs
+ *
+ * This driver draws mainly on scattered spec sheets, Reverse engineering
+ * of the toshiba e800 SD driver and some parts of the 2.4 ASIC3 driver (4 bit
+ * support). (Further 4 bit support from a later datasheet).
+ *
+ * TODO:
+ * Investigate using a workqueue for PIO transfers
+ * Eliminate FIXMEs
+ * SDIO support
+ * Better Power management
+ * Handle MMC errors better
+ * double buffer support
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/highmem.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/mfd/tmio.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/tmio.h>
+#include <linux/module.h>
+#include <linux/pagemap.h>
+#include <linux/platform_device.h>
+#include <linux/scatterlist.h>
+#include <linux/workqueue.h>
+#include <linux/spinlock.h>
+
+#include "tmio_mmc.h"
+
+static u16 sd_ctrl_read16(struct tmio_mmc_host *host, int addr)
+{
+ return readw(host->ctl + (addr << host->bus_shift));
+}
+
+static void sd_ctrl_read16_rep(struct tmio_mmc_host *host, int addr,
+ u16 *buf, int count)
+{
+ readsw(host->ctl + (addr << host->bus_shift), buf, count);
+}
+
+static u32 sd_ctrl_read32(struct tmio_mmc_host *host, int addr)
+{
+ return readw(host->ctl + (addr << host->bus_shift)) |
+ readw(host->ctl + ((addr + 2) << host->bus_shift)) << 16;
+}
+
+static void sd_ctrl_write16(struct tmio_mmc_host *host, int addr, u16 val)
+{
+ writew(val, host->ctl + (addr << host->bus_shift));
+}
+
+static void sd_ctrl_write16_rep(struct tmio_mmc_host *host, int addr,
+ u16 *buf, int count)
+{
+ writesw(host->ctl + (addr << host->bus_shift), buf, count);
+}
+
+static void sd_ctrl_write32(struct tmio_mmc_host *host, int addr, u32 val)
+{
+ writew(val, host->ctl + (addr << host->bus_shift));
+ writew(val >> 16, host->ctl + ((addr + 2) << host->bus_shift));
+}
+
+void tmio_mmc_enable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
+{
+ u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) & ~(i & TMIO_MASK_IRQ);
+ sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
+}
+
+void tmio_mmc_disable_mmc_irqs(struct tmio_mmc_host *host, u32 i)
+{
+ u32 mask = sd_ctrl_read32(host, CTL_IRQ_MASK) | (i & TMIO_MASK_IRQ);
+ sd_ctrl_write32(host, CTL_IRQ_MASK, mask);
+}
+
+static void tmio_mmc_ack_mmc_irqs(struct tmio_mmc_host *host, u32 i)
+{
+ sd_ctrl_write32(host, CTL_STATUS, ~i);
+}
+
+static void tmio_mmc_init_sg(struct tmio_mmc_host *host, struct mmc_data *data)
+{
+ host->sg_len = data->sg_len;
+ host->sg_ptr = data->sg;
+ host->sg_orig = data->sg;
+ host->sg_off = 0;
+}
+
+static int tmio_mmc_next_sg(struct tmio_mmc_host *host)
+{
+ host->sg_ptr = sg_next(host->sg_ptr);
+ host->sg_off = 0;
+ return --host->sg_len;
+}
+
+#ifdef CONFIG_MMC_DEBUG
+
+#define STATUS_TO_TEXT(a, status, i) \
+ do { \
+ if (status & TMIO_STAT_##a) { \
+ if (i++) \
+ printk(" | "); \
+ printk(#a); \
+ } \
+ } while (0)
+
+static void pr_debug_status(u32 status)
+{
+ int i = 0;
+ printk(KERN_DEBUG "status: %08x = ", status);
+ STATUS_TO_TEXT(CARD_REMOVE, status, i);
+ STATUS_TO_TEXT(CARD_INSERT, status, i);
+ STATUS_TO_TEXT(SIGSTATE, status, i);
+ STATUS_TO_TEXT(WRPROTECT, status, i);
+ STATUS_TO_TEXT(CARD_REMOVE_A, status, i);
+ STATUS_TO_TEXT(CARD_INSERT_A, status, i);
+ STATUS_TO_TEXT(SIGSTATE_A, status, i);
+ STATUS_TO_TEXT(CMD_IDX_ERR, status, i);
+ STATUS_TO_TEXT(STOPBIT_ERR, status, i);
+ STATUS_TO_TEXT(ILL_FUNC, status, i);
+ STATUS_TO_TEXT(CMD_BUSY, status, i);
+ STATUS_TO_TEXT(CMDRESPEND, status, i);
+ STATUS_TO_TEXT(DATAEND, status, i);
+ STATUS_TO_TEXT(CRCFAIL, status, i);
+ STATUS_TO_TEXT(DATATIMEOUT, status, i);
+ STATUS_TO_TEXT(CMDTIMEOUT, status, i);
+ STATUS_TO_TEXT(RXOVERFLOW, status, i);
+ STATUS_TO_TEXT(TXUNDERRUN, status, i);
+ STATUS_TO_TEXT(RXRDY, status, i);
+ STATUS_TO_TEXT(TXRQ, status, i);
+ STATUS_TO_TEXT(ILL_ACCESS, status, i);
+ printk("\n");
+}
+
+#else
+#define pr_debug_status(s) do { } while (0)
+#endif
+
+static void tmio_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ if (enable) {
+ host->sdio_irq_enabled = 1;
+ sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0001);
+ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK,
+ (TMIO_SDIO_MASK_ALL & ~TMIO_SDIO_STAT_IOIRQ));
+ } else {
+ sd_ctrl_write16(host, CTL_SDIO_IRQ_MASK, TMIO_SDIO_MASK_ALL);
+ sd_ctrl_write16(host, CTL_TRANSACTION_CTL, 0x0000);
+ host->sdio_irq_enabled = 0;
+ }
+}
+
+static void tmio_mmc_set_clock(struct tmio_mmc_host *host, int new_clock)
+{
+ u32 clk = 0, clock;
+
+ if (new_clock) {
+ for (clock = host->mmc->f_min, clk = 0x80000080;
+ new_clock >= (clock<<1); clk >>= 1)
+ clock <<= 1;
+ clk |= 0x100;
+ }
+
+ if (host->set_clk_div)
+ host->set_clk_div(host->pdev, (clk>>22) & 1);
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, clk & 0x1ff);
+}
+
+static void tmio_mmc_clk_stop(struct tmio_mmc_host *host)
+{
+ struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
+
+ /* implicit BUG_ON(!res) */
+ if (resource_size(res) > 0x100) {
+ sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0000);
+ msleep(10);
+ }
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, ~0x0100 &
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+ msleep(10);
+}
+
+static void tmio_mmc_clk_start(struct tmio_mmc_host *host)
+{
+ struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
+
+ sd_ctrl_write16(host, CTL_SD_CARD_CLK_CTL, 0x0100 |
+ sd_ctrl_read16(host, CTL_SD_CARD_CLK_CTL));
+ msleep(10);
+
+ /* implicit BUG_ON(!res) */
+ if (resource_size(res) > 0x100) {
+ sd_ctrl_write16(host, CTL_CLK_AND_WAIT_CTL, 0x0100);
+ msleep(10);
+ }
+}
+
+static void tmio_mmc_reset(struct tmio_mmc_host *host)
+{
+ struct resource *res = platform_get_resource(host->pdev, IORESOURCE_MEM, 0);
+
+ /* FIXME - should we set stop clock reg here */
+ sd_ctrl_write16(host, CTL_RESET_SD, 0x0000);
+ /* implicit BUG_ON(!res) */
+ if (resource_size(res) > 0x100)
+ sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0000);
+ msleep(10);
+ sd_ctrl_write16(host, CTL_RESET_SD, 0x0001);
+ if (resource_size(res) > 0x100)
+ sd_ctrl_write16(host, CTL_RESET_SDIO, 0x0001);
+ msleep(10);
+}
+
+static void tmio_mmc_reset_work(struct work_struct *work)
+{
+ struct tmio_mmc_host *host = container_of(work, struct tmio_mmc_host,
+ delayed_reset_work.work);
+ struct mmc_request *mrq;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ mrq = host->mrq;
+
+ /* request already finished */
+ if (!mrq
+ || time_is_after_jiffies(host->last_req_ts +
+ msecs_to_jiffies(2000))) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ return;
+ }
+
+ dev_warn(&host->pdev->dev,
+ "timeout waiting for hardware interrupt (CMD%u)\n",
+ mrq->cmd->opcode);
+
+ if (host->data)
+ host->data->error = -ETIMEDOUT;
+ else if (host->cmd)
+ host->cmd->error = -ETIMEDOUT;
+ else
+ mrq->cmd->error = -ETIMEDOUT;
+
+ host->cmd = NULL;
+ host->data = NULL;
+ host->mrq = NULL;
+ host->force_pio = false;
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ tmio_mmc_reset(host);
+
+ mmc_request_done(host->mmc, mrq);
+}
+
+static void tmio_mmc_finish_request(struct tmio_mmc_host *host)
+{
+ struct mmc_request *mrq = host->mrq;
+
+ if (!mrq)
+ return;
+
+ host->mrq = NULL;
+ host->cmd = NULL;
+ host->data = NULL;
+ host->force_pio = false;
+
+ cancel_delayed_work(&host->delayed_reset_work);
+
+ mmc_request_done(host->mmc, mrq);
+}
+
+/* These are the bitmasks the tmio chip requires to implement the MMC response
+ * types. Note that R1 and R6 are the same in this scheme. */
+#define APP_CMD 0x0040
+#define RESP_NONE 0x0300
+#define RESP_R1 0x0400
+#define RESP_R1B 0x0500
+#define RESP_R2 0x0600
+#define RESP_R3 0x0700
+#define DATA_PRESENT 0x0800
+#define TRANSFER_READ 0x1000
+#define TRANSFER_MULTI 0x2000
+#define SECURITY_CMD 0x4000
+
+static int tmio_mmc_start_command(struct tmio_mmc_host *host, struct mmc_command *cmd)
+{
+ struct mmc_data *data = host->data;
+ int c = cmd->opcode;
+
+ /* Command 12 is handled by hardware */
+ if (cmd->opcode == 12 && !cmd->arg) {
+ sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x001);
+ return 0;
+ }
+
+ switch (mmc_resp_type(cmd)) {
+ case MMC_RSP_NONE: c |= RESP_NONE; break;
+ case MMC_RSP_R1: c |= RESP_R1; break;
+ case MMC_RSP_R1B: c |= RESP_R1B; break;
+ case MMC_RSP_R2: c |= RESP_R2; break;
+ case MMC_RSP_R3: c |= RESP_R3; break;
+ default:
+ pr_debug("Unknown response type %d\n", mmc_resp_type(cmd));
+ return -EINVAL;
+ }
+
+ host->cmd = cmd;
+
+/* FIXME - this seems to be ok commented out but the spec suggest this bit
+ * should be set when issuing app commands.
+ * if(cmd->flags & MMC_FLAG_ACMD)
+ * c |= APP_CMD;
+ */
+ if (data) {
+ c |= DATA_PRESENT;
+ if (data->blocks > 1) {
+ sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x100);
+ c |= TRANSFER_MULTI;
+ }
+ if (data->flags & MMC_DATA_READ)
+ c |= TRANSFER_READ;
+ }
+
+ tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_CMD);
+
+ /* Fire off the command */
+ sd_ctrl_write32(host, CTL_ARG_REG, cmd->arg);
+ sd_ctrl_write16(host, CTL_SD_CMD, c);
+
+ return 0;
+}
+
+/*
+ * This chip always returns (at least?) as much data as you ask for.
+ * I'm unsure what happens if you ask for less than a block. This should be
+ * looked into to ensure that a funny length read doesnt hose the controller.
+ */
+static void tmio_mmc_pio_irq(struct tmio_mmc_host *host)
+{
+ struct mmc_data *data = host->data;
+ void *sg_virt;
+ unsigned short *buf;
+ unsigned int count;
+ unsigned long flags;
+
+ if ((host->chan_tx || host->chan_rx) && !host->force_pio) {
+ pr_err("PIO IRQ in DMA mode!\n");
+ return;
+ } else if (!data) {
+ pr_debug("Spurious PIO IRQ\n");
+ return;
+ }
+
+ sg_virt = tmio_mmc_kmap_atomic(host->sg_ptr, &flags);
+ buf = (unsigned short *)(sg_virt + host->sg_off);
+
+ count = host->sg_ptr->length - host->sg_off;
+ if (count > data->blksz)
+ count = data->blksz;
+
+ pr_debug("count: %08x offset: %08x flags %08x\n",
+ count, host->sg_off, data->flags);
+
+ /* Transfer the data */
+ if (data->flags & MMC_DATA_READ)
+ sd_ctrl_read16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
+ else
+ sd_ctrl_write16_rep(host, CTL_SD_DATA_PORT, buf, count >> 1);
+
+ host->sg_off += count;
+
+ tmio_mmc_kunmap_atomic(host->sg_ptr, &flags, sg_virt);
+
+ if (host->sg_off == host->sg_ptr->length)
+ tmio_mmc_next_sg(host);
+
+ return;
+}
+
+static void tmio_mmc_check_bounce_buffer(struct tmio_mmc_host *host)
+{
+ if (host->sg_ptr == &host->bounce_sg) {
+ unsigned long flags;
+ void *sg_vaddr = tmio_mmc_kmap_atomic(host->sg_orig, &flags);
+ memcpy(sg_vaddr, host->bounce_buf, host->bounce_sg.length);
+ tmio_mmc_kunmap_atomic(host->sg_orig, &flags, sg_vaddr);
+ }
+}
+
+/* needs to be called with host->lock held */
+void tmio_mmc_do_data_irq(struct tmio_mmc_host *host)
+{
+ struct mmc_data *data = host->data;
+ struct mmc_command *stop;
+
+ host->data = NULL;
+
+ if (!data) {
+ dev_warn(&host->pdev->dev, "Spurious data end IRQ\n");
+ return;
+ }
+ stop = data->stop;
+
+ /* FIXME - return correct transfer count on errors */
+ if (!data->error)
+ data->bytes_xfered = data->blocks * data->blksz;
+ else
+ data->bytes_xfered = 0;
+
+ pr_debug("Completed data request\n");
+
+ /*
+ * FIXME: other drivers allow an optional stop command of any given type
+ * which we dont do, as the chip can auto generate them.
+ * Perhaps we can be smarter about when to use auto CMD12 and
+ * only issue the auto request when we know this is the desired
+ * stop command, allowing fallback to the stop command the
+ * upper layers expect. For now, we do what works.
+ */
+
+ if (data->flags & MMC_DATA_READ) {
+ if (host->chan_rx && !host->force_pio)
+ tmio_mmc_check_bounce_buffer(host);
+ dev_dbg(&host->pdev->dev, "Complete Rx request %p\n",
+ host->mrq);
+ } else {
+ dev_dbg(&host->pdev->dev, "Complete Tx request %p\n",
+ host->mrq);
+ }
+
+ if (stop) {
+ if (stop->opcode == 12 && !stop->arg)
+ sd_ctrl_write16(host, CTL_STOP_INTERNAL_ACTION, 0x000);
+ else
+ BUG();
+ }
+
+ tmio_mmc_finish_request(host);
+}
+
+static void tmio_mmc_data_irq(struct tmio_mmc_host *host)
+{
+ struct mmc_data *data;
+ spin_lock(&host->lock);
+ data = host->data;
+
+ if (!data)
+ goto out;
+
+ if (host->chan_tx && (data->flags & MMC_DATA_WRITE) && !host->force_pio) {
+ /*
+ * Has all data been written out yet? Testing on SuperH showed,
+ * that in most cases the first interrupt comes already with the
+ * BUSY status bit clear, but on some operations, like mount or
+ * in the beginning of a write / sync / umount, there is one
+ * DATAEND interrupt with the BUSY bit set, in this cases
+ * waiting for one more interrupt fixes the problem.
+ */
+ if (!(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_CMD_BUSY)) {
+ tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND);
+ tasklet_schedule(&host->dma_complete);
+ }
+ } else if (host->chan_rx && (data->flags & MMC_DATA_READ) && !host->force_pio) {
+ tmio_mmc_disable_mmc_irqs(host, TMIO_STAT_DATAEND);
+ tasklet_schedule(&host->dma_complete);
+ } else {
+ tmio_mmc_do_data_irq(host);
+ tmio_mmc_disable_mmc_irqs(host, TMIO_MASK_READOP | TMIO_MASK_WRITEOP);
+ }
+out:
+ spin_unlock(&host->lock);
+}
+
+static void tmio_mmc_cmd_irq(struct tmio_mmc_host *host,
+ unsigned int stat)
+{
+ struct mmc_command *cmd = host->cmd;
+ int i, addr;
+
+ spin_lock(&host->lock);
+
+ if (!host->cmd) {
+ pr_debug("Spurious CMD irq\n");
+ goto out;
+ }
+
+ host->cmd = NULL;
+
+ /* This controller is sicker than the PXA one. Not only do we need to
+ * drop the top 8 bits of the first response word, we also need to
+ * modify the order of the response for short response command types.
+ */
+
+ for (i = 3, addr = CTL_RESPONSE ; i >= 0 ; i--, addr += 4)
+ cmd->resp[i] = sd_ctrl_read32(host, addr);
+
+ if (cmd->flags & MMC_RSP_136) {
+ cmd->resp[0] = (cmd->resp[0] << 8) | (cmd->resp[1] >> 24);
+ cmd->resp[1] = (cmd->resp[1] << 8) | (cmd->resp[2] >> 24);
+ cmd->resp[2] = (cmd->resp[2] << 8) | (cmd->resp[3] >> 24);
+ cmd->resp[3] <<= 8;
+ } else if (cmd->flags & MMC_RSP_R3) {
+ cmd->resp[0] = cmd->resp[3];
+ }
+
+ if (stat & TMIO_STAT_CMDTIMEOUT)
+ cmd->error = -ETIMEDOUT;
+ else if (stat & TMIO_STAT_CRCFAIL && cmd->flags & MMC_RSP_CRC)
+ cmd->error = -EILSEQ;
+
+ /* If there is data to handle we enable data IRQs here, and
+ * we will ultimatley finish the request in the data_end handler.
+ * If theres no data or we encountered an error, finish now.
+ */
+ if (host->data && !cmd->error) {
+ if (host->data->flags & MMC_DATA_READ) {
+ if (host->force_pio || !host->chan_rx)
+ tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_READOP);
+ else
+ tasklet_schedule(&host->dma_issue);
+ } else {
+ if (host->force_pio || !host->chan_tx)
+ tmio_mmc_enable_mmc_irqs(host, TMIO_MASK_WRITEOP);
+ else
+ tasklet_schedule(&host->dma_issue);
+ }
+ } else {
+ tmio_mmc_finish_request(host);
+ }
+
+out:
+ spin_unlock(&host->lock);
+}
+
+static irqreturn_t tmio_mmc_irq(int irq, void *devid)
+{
+ struct tmio_mmc_host *host = devid;
+ struct tmio_mmc_data *pdata = host->pdata;
+ unsigned int ireg, irq_mask, status;
+ unsigned int sdio_ireg, sdio_irq_mask, sdio_status;
+
+ pr_debug("MMC IRQ begin\n");
+
+ status = sd_ctrl_read32(host, CTL_STATUS);
+ irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
+ ireg = status & TMIO_MASK_IRQ & ~irq_mask;
+
+ sdio_ireg = 0;
+ if (!ireg && pdata->flags & TMIO_MMC_SDIO_IRQ) {
+ sdio_status = sd_ctrl_read16(host, CTL_SDIO_STATUS);
+ sdio_irq_mask = sd_ctrl_read16(host, CTL_SDIO_IRQ_MASK);
+ sdio_ireg = sdio_status & TMIO_SDIO_MASK_ALL & ~sdio_irq_mask;
+
+ sd_ctrl_write16(host, CTL_SDIO_STATUS, sdio_status & ~TMIO_SDIO_MASK_ALL);
+
+ if (sdio_ireg && !host->sdio_irq_enabled) {
+ pr_warning("tmio_mmc: Spurious SDIO IRQ, disabling! 0x%04x 0x%04x 0x%04x\n",
+ sdio_status, sdio_irq_mask, sdio_ireg);
+ tmio_mmc_enable_sdio_irq(host->mmc, 0);
+ goto out;
+ }
+
+ if (host->mmc->caps & MMC_CAP_SDIO_IRQ &&
+ sdio_ireg & TMIO_SDIO_STAT_IOIRQ)
+ mmc_signal_sdio_irq(host->mmc);
+
+ if (sdio_ireg)
+ goto out;
+ }
+
+ pr_debug_status(status);
+ pr_debug_status(ireg);
+
+ if (!ireg) {
+ tmio_mmc_disable_mmc_irqs(host, status & ~irq_mask);
+
+ pr_warning("tmio_mmc: Spurious irq, disabling! "
+ "0x%08x 0x%08x 0x%08x\n", status, irq_mask, ireg);
+ pr_debug_status(status);
+
+ goto out;
+ }
+
+ while (ireg) {
+ /* Card insert / remove attempts */
+ if (ireg & (TMIO_STAT_CARD_INSERT | TMIO_STAT_CARD_REMOVE)) {
+ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_CARD_INSERT |
+ TMIO_STAT_CARD_REMOVE);
+ mmc_detect_change(host->mmc, msecs_to_jiffies(100));
+ }
+
+ /* CRC and other errors */
+/* if (ireg & TMIO_STAT_ERR_IRQ)
+ * handled |= tmio_error_irq(host, irq, stat);
+ */
+
+ /* Command completion */
+ if (ireg & (TMIO_STAT_CMDRESPEND | TMIO_STAT_CMDTIMEOUT)) {
+ tmio_mmc_ack_mmc_irqs(host,
+ TMIO_STAT_CMDRESPEND |
+ TMIO_STAT_CMDTIMEOUT);
+ tmio_mmc_cmd_irq(host, status);
+ }
+
+ /* Data transfer */
+ if (ireg & (TMIO_STAT_RXRDY | TMIO_STAT_TXRQ)) {
+ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_RXRDY | TMIO_STAT_TXRQ);
+ tmio_mmc_pio_irq(host);
+ }
+
+ /* Data transfer completion */
+ if (ireg & TMIO_STAT_DATAEND) {
+ tmio_mmc_ack_mmc_irqs(host, TMIO_STAT_DATAEND);
+ tmio_mmc_data_irq(host);
+ }
+
+ /* Check status - keep going until we've handled it all */
+ status = sd_ctrl_read32(host, CTL_STATUS);
+ irq_mask = sd_ctrl_read32(host, CTL_IRQ_MASK);
+ ireg = status & TMIO_MASK_IRQ & ~irq_mask;
+
+ pr_debug("Status at end of loop: %08x\n", status);
+ pr_debug_status(status);
+ }
+ pr_debug("MMC IRQ end\n");
+
+out:
+ return IRQ_HANDLED;
+}
+
+static int tmio_mmc_start_data(struct tmio_mmc_host *host,
+ struct mmc_data *data)
+{
+ struct tmio_mmc_data *pdata = host->pdata;
+
+ pr_debug("setup data transfer: blocksize %08x nr_blocks %d\n",
+ data->blksz, data->blocks);
+
+ /* Some hardware cannot perform 2 byte requests in 4 bit mode */
+ if (host->mmc->ios.bus_width == MMC_BUS_WIDTH_4) {
+ int blksz_2bytes = pdata->flags & TMIO_MMC_BLKSZ_2BYTES;
+
+ if (data->blksz < 2 || (data->blksz < 4 && !blksz_2bytes)) {
+ pr_err("%s: %d byte block unsupported in 4 bit mode\n",
+ mmc_hostname(host->mmc), data->blksz);
+ return -EINVAL;
+ }
+ }
+
+ tmio_mmc_init_sg(host, data);
+ host->data = data;
+
+ /* Set transfer length / blocksize */
+ sd_ctrl_write16(host, CTL_SD_XFER_LEN, data->blksz);
+ sd_ctrl_write16(host, CTL_XFER_BLK_COUNT, data->blocks);
+
+ tmio_mmc_start_dma(host, data);
+
+ return 0;
+}
+
+/* Process requests from the MMC layer */
+static void tmio_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ int ret;
+
+ if (host->mrq)
+ pr_debug("request not null\n");
+
+ host->last_req_ts = jiffies;
+ wmb();
+ host->mrq = mrq;
+
+ if (mrq->data) {
+ ret = tmio_mmc_start_data(host, mrq->data);
+ if (ret)
+ goto fail;
+ }
+
+ ret = tmio_mmc_start_command(host, mrq->cmd);
+ if (!ret) {
+ schedule_delayed_work(&host->delayed_reset_work,
+ msecs_to_jiffies(2000));
+ return;
+ }
+
+fail:
+ host->mrq = NULL;
+ host->force_pio = false;
+ mrq->cmd->error = ret;
+ mmc_request_done(mmc, mrq);
+}
+
+/* Set MMC clock / power.
+ * Note: This controller uses a simple divider scheme therefore it cannot
+ * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as
+ * MMC wont run that fast, it has to be clocked at 12MHz which is the next
+ * slowest setting.
+ */
+static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+
+ if (ios->clock)
+ tmio_mmc_set_clock(host, ios->clock);
+
+ /* Power sequence - OFF -> UP -> ON */
+ if (ios->power_mode == MMC_POWER_OFF || !ios->clock) {
+ /* power down SD bus */
+ if (ios->power_mode == MMC_POWER_OFF && host->set_pwr)
+ host->set_pwr(host->pdev, 0);
+ tmio_mmc_clk_stop(host);
+ } else if (ios->power_mode == MMC_POWER_UP) {
+ /* power up SD bus */
+ if (host->set_pwr)
+ host->set_pwr(host->pdev, 1);
+ } else {
+ /* start bus clock */
+ tmio_mmc_clk_start(host);
+ }
+
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_1:
+ sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x80e0);
+ break;
+ case MMC_BUS_WIDTH_4:
+ sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, 0x00e0);
+ break;
+ }
+
+ /* Let things settle. delay taken from winCE driver */
+ udelay(140);
+}
+
+static int tmio_mmc_get_ro(struct mmc_host *mmc)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct tmio_mmc_data *pdata = host->pdata;
+
+ return ((pdata->flags & TMIO_MMC_WRPROTECT_DISABLE) ||
+ !(sd_ctrl_read32(host, CTL_STATUS) & TMIO_STAT_WRPROTECT));
+}
+
+static int tmio_mmc_get_cd(struct mmc_host *mmc)
+{
+ struct tmio_mmc_host *host = mmc_priv(mmc);
+ struct tmio_mmc_data *pdata = host->pdata;
+
+ if (!pdata->get_cd)
+ return -ENOSYS;
+ else
+ return pdata->get_cd(host->pdev);
+}
+
+static const struct mmc_host_ops tmio_mmc_ops = {
+ .request = tmio_mmc_request,
+ .set_ios = tmio_mmc_set_ios,
+ .get_ro = tmio_mmc_get_ro,
+ .get_cd = tmio_mmc_get_cd,
+ .enable_sdio_irq = tmio_mmc_enable_sdio_irq,
+};
+
+int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
+ struct platform_device *pdev,
+ struct tmio_mmc_data *pdata)
+{
+ struct tmio_mmc_host *_host;
+ struct mmc_host *mmc;
+ struct resource *res_ctl;
+ int ret;
+ u32 irq_mask = TMIO_MASK_CMD;
+
+ res_ctl = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res_ctl)
+ return -EINVAL;
+
+ mmc = mmc_alloc_host(sizeof(struct tmio_mmc_host), &pdev->dev);
+ if (!mmc)
+ return -ENOMEM;
+
+ _host = mmc_priv(mmc);
+ _host->pdata = pdata;
+ _host->mmc = mmc;
+ _host->pdev = pdev;
+ platform_set_drvdata(pdev, mmc);
+
+ _host->set_pwr = pdata->set_pwr;
+ _host->set_clk_div = pdata->set_clk_div;
+
+ /* SD control register space size is 0x200, 0x400 for bus_shift=1 */
+ _host->bus_shift = resource_size(res_ctl) >> 10;
+
+ _host->ctl = ioremap(res_ctl->start, resource_size(res_ctl));
+ if (!_host->ctl) {
+ ret = -ENOMEM;
+ goto host_free;
+ }
+
+ mmc->ops = &tmio_mmc_ops;
+ mmc->caps = MMC_CAP_4_BIT_DATA | pdata->capabilities;
+ mmc->f_max = pdata->hclk;
+ mmc->f_min = mmc->f_max / 512;
+ mmc->max_segs = 32;
+ mmc->max_blk_size = 512;
+ mmc->max_blk_count = (PAGE_CACHE_SIZE / mmc->max_blk_size) *
+ mmc->max_segs;
+ mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
+ mmc->max_seg_size = mmc->max_req_size;
+ if (pdata->ocr_mask)
+ mmc->ocr_avail = pdata->ocr_mask;
+ else
+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ tmio_mmc_clk_stop(_host);
+ tmio_mmc_reset(_host);
+
+ ret = platform_get_irq(pdev, 0);
+ if (ret < 0)
+ goto unmap_ctl;
+
+ _host->irq = ret;
+
+ tmio_mmc_disable_mmc_irqs(_host, TMIO_MASK_ALL);
+ if (pdata->flags & TMIO_MMC_SDIO_IRQ)
+ tmio_mmc_enable_sdio_irq(mmc, 0);
+
+ ret = request_irq(_host->irq, tmio_mmc_irq, IRQF_DISABLED |
+ IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), _host);
+ if (ret)
+ goto unmap_ctl;
+
+ spin_lock_init(&_host->lock);
+
+ /* Init delayed work for request timeouts */
+ INIT_DELAYED_WORK(&_host->delayed_reset_work, tmio_mmc_reset_work);
+
+ /* See if we also get DMA */
+ tmio_mmc_request_dma(_host, pdata);
+
+ mmc_add_host(mmc);
+
+ /* Unmask the IRQs we want to know about */
+ if (!_host->chan_rx)
+ irq_mask |= TMIO_MASK_READOP;
+ if (!_host->chan_tx)
+ irq_mask |= TMIO_MASK_WRITEOP;
+
+ tmio_mmc_enable_mmc_irqs(_host, irq_mask);
+
+ *host = _host;
+
+ return 0;
+
+unmap_ctl:
+ iounmap(_host->ctl);
+host_free:
+ mmc_free_host(mmc);
+
+ return ret;
+}
+EXPORT_SYMBOL(tmio_mmc_host_probe);
+
+void tmio_mmc_host_remove(struct tmio_mmc_host *host)
+{
+ mmc_remove_host(host->mmc);
+ cancel_delayed_work_sync(&host->delayed_reset_work);
+ tmio_mmc_release_dma(host);
+ free_irq(host->irq, host);
+ iounmap(host->ctl);
+ mmc_free_host(host->mmc);
+}
+EXPORT_SYMBOL(tmio_mmc_host_remove);
+
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/via-sdmmc.c b/drivers/mmc/host/via-sdmmc.c
index 8c5b4881ccd..4dfe2c02ea9 100644
--- a/drivers/mmc/host/via-sdmmc.c
+++ b/drivers/mmc/host/via-sdmmc.c
@@ -1087,14 +1087,13 @@ static int __devinit via_sd_probe(struct pci_dev *pcidev,
struct mmc_host *mmc;
struct via_crdr_mmc_host *sdhost;
u32 base, len;
- u8 rev, gatt;
+ u8 gatt;
int ret;
- pci_read_config_byte(pcidev, PCI_CLASS_REVISION, &rev);
pr_info(DRV_NAME
": VIA SDMMC controller found at %s [%04x:%04x] (rev %x)\n",
pci_name(pcidev), (int)pcidev->vendor, (int)pcidev->device,
- (int)rev);
+ (int)pcidev->revision);
ret = pci_enable_device(pcidev);
if (ret)
diff --git a/drivers/net/atlx/atl2.c b/drivers/net/atlx/atl2.c
index e637e9f28fd..937ef1afa5d 100644
--- a/drivers/net/atlx/atl2.c
+++ b/drivers/net/atlx/atl2.c
@@ -1996,13 +1996,15 @@ static int atl2_set_eeprom(struct net_device *netdev,
if (!eeprom_buff)
return -ENOMEM;
- ptr = (u32 *)eeprom_buff;
+ ptr = eeprom_buff;
if (eeprom->offset & 3) {
/* need read/modify/write of first changed EEPROM word */
/* only the second byte of the word is being modified */
- if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0])))
- return -EIO;
+ if (!atl2_read_eeprom(hw, first_dword*4, &(eeprom_buff[0]))) {
+ ret_val = -EIO;
+ goto out;
+ }
ptr++;
}
if (((eeprom->offset + eeprom->len) & 3)) {
@@ -2011,18 +2013,22 @@ static int atl2_set_eeprom(struct net_device *netdev,
* only the first byte of the word is being modified
*/
if (!atl2_read_eeprom(hw, last_dword * 4,
- &(eeprom_buff[last_dword - first_dword])))
- return -EIO;
+ &(eeprom_buff[last_dword - first_dword]))) {
+ ret_val = -EIO;
+ goto out;
+ }
}
/* Device's eeprom is always little-endian, word addressable */
memcpy(ptr, bytes, eeprom->len);
for (i = 0; i < last_dword - first_dword + 1; i++) {
- if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i]))
- return -EIO;
+ if (!atl2_write_eeprom(hw, ((first_dword+i)*4), eeprom_buff[i])) {
+ ret_val = -EIO;
+ goto out;
+ }
}
-
+ out:
kfree(eeprom_buff);
return ret_val;
}
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 22abfb39d81..68d45ba2d9b 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -1237,8 +1237,17 @@ static int bfin_mac_enable(struct phy_device *phydev)
if (phydev->interface == PHY_INTERFACE_MODE_RMII) {
opmode |= RMII; /* For Now only 100MBit are supported */
-#if (defined(CONFIG_BF537) || defined(CONFIG_BF536)) && CONFIG_BF_REV_0_2
- opmode |= TE;
+#if defined(CONFIG_BF537) || defined(CONFIG_BF536)
+ if (__SILICON_REVISION__ < 3) {
+ /*
+ * This isn't publicly documented (fun times!), but in
+ * silicon <=0.2, the RX and TX pins are clocked together.
+ * So in order to recv, we must enable the transmit side
+ * as well. This will cause a spurious TX interrupt too,
+ * but we can easily consume that.
+ */
+ opmode |= TE;
+ }
#endif
}
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index d1865cc9731..8e6d618b530 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -8317,7 +8317,7 @@ static const struct net_device_ops bnx2_netdev_ops = {
#endif
};
-static void inline vlan_features_add(struct net_device *dev, u32 flags)
+static inline void vlan_features_add(struct net_device *dev, u32 flags)
{
dev->vlan_features |= flags;
}
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index 118c28aa471..4b3e3587840 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -74,7 +74,7 @@ struct tlb_client_info {
* packets to a Client that the Hash function
* gave this entry index.
*/
- u32 tx_bytes; /* Each Client acumulates the BytesTx that
+ u32 tx_bytes; /* Each Client accumulates the BytesTx that
* were tranmitted to it, and after each
* CallBack the LoadHistory is devided
* by the balance interval
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
index 110eda01843..31552959aed 100644
--- a/drivers/net/can/c_can/c_can.c
+++ b/drivers/net/can/c_can/c_can.c
@@ -588,14 +588,9 @@ static void c_can_chip_config(struct net_device *dev)
{
struct c_can_priv *priv = netdev_priv(dev);
- if (priv->can.ctrlmode & CAN_CTRLMODE_ONE_SHOT)
- /* disable automatic retransmission */
- priv->write_reg(priv, &priv->regs->control,
- CONTROL_DISABLE_AR);
- else
- /* enable automatic retransmission */
- priv->write_reg(priv, &priv->regs->control,
- CONTROL_ENABLE_AR);
+ /* enable automatic retransmission */
+ priv->write_reg(priv, &priv->regs->control,
+ CONTROL_ENABLE_AR);
if (priv->can.ctrlmode & (CAN_CTRLMODE_LISTENONLY &
CAN_CTRLMODE_LOOPBACK)) {
@@ -704,7 +699,6 @@ static void c_can_do_tx(struct net_device *dev)
for (/* nix */; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) {
msg_obj_no = get_tx_echo_msg_obj(priv);
- c_can_inval_msg_object(dev, 0, msg_obj_no);
val = c_can_read_reg32(priv, &priv->regs->txrqst1);
if (!(val & (1 << msg_obj_no))) {
can_get_echo_skb(dev,
@@ -713,6 +707,7 @@ static void c_can_do_tx(struct net_device *dev)
&priv->regs->ifregs[0].msg_cntrl)
& IF_MCONT_DLC_MASK;
stats->tx_packets++;
+ c_can_inval_msg_object(dev, 0, msg_obj_no);
}
}
@@ -1112,8 +1107,7 @@ struct net_device *alloc_c_can_dev(void)
priv->can.bittiming_const = &c_can_bittiming_const;
priv->can.do_set_mode = c_can_set_mode;
priv->can.do_get_berr_counter = c_can_get_berr_counter;
- priv->can.ctrlmode_supported = CAN_CTRLMODE_ONE_SHOT |
- CAN_CTRLMODE_LOOPBACK |
+ priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
CAN_CTRLMODE_LISTENONLY |
CAN_CTRLMODE_BERR_REPORTING;
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c
index e629b961ae2..cc90824f2c9 100644
--- a/drivers/net/can/c_can/c_can_platform.c
+++ b/drivers/net/can/c_can/c_can_platform.c
@@ -73,7 +73,8 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
void __iomem *addr;
struct net_device *dev;
struct c_can_priv *priv;
- struct resource *mem, *irq;
+ struct resource *mem;
+ int irq;
#ifdef CONFIG_HAVE_CLK
struct clk *clk;
@@ -88,8 +89,8 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
/* get the platform data */
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (!mem || (irq <= 0)) {
+ irq = platform_get_irq(pdev, 0);
+ if (!mem || irq <= 0) {
ret = -ENODEV;
goto exit_free_clk;
}
@@ -117,7 +118,7 @@ static int __devinit c_can_plat_probe(struct platform_device *pdev)
priv = netdev_priv(dev);
- dev->irq = irq->start;
+ dev->irq = irq;
priv->regs = addr;
#ifdef CONFIG_HAVE_CLK
priv->can.clock.freq = clk_get_rate(clk);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 4d538a4e9d5..91089314329 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1983,14 +1983,20 @@ static int set_coalesce(struct net_device *dev, struct ethtool_coalesce *c)
{
struct port_info *pi = netdev_priv(dev);
struct adapter *adapter = pi->adapter;
- struct qset_params *qsp = &adapter->params.sge.qset[0];
- struct sge_qset *qs = &adapter->sge.qs[0];
+ struct qset_params *qsp;
+ struct sge_qset *qs;
+ int i;
if (c->rx_coalesce_usecs * 10 > M_NEWTIMER)
return -EINVAL;
- qsp->coalesce_usecs = c->rx_coalesce_usecs;
- t3_update_qset_coalesce(qs, qsp);
+ for (i = 0; i < pi->nqsets; i++) {
+ qsp = &adapter->params.sge.qset[i];
+ qs = &adapter->sge.qs[i];
+ qsp->coalesce_usecs = c->rx_coalesce_usecs;
+ t3_update_qset_coalesce(qs, qsp);
+ }
+
return 0;
}
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 31770811360..b7af5bab993 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -621,9 +621,9 @@ static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
/* change in wol state, update IRQ state */
if (!dm->wake_state)
- set_irq_wake(dm->irq_wake, 1);
+ irq_set_irq_wake(dm->irq_wake, 1);
else if (dm->wake_state & !opts)
- set_irq_wake(dm->irq_wake, 0);
+ irq_set_irq_wake(dm->irq_wake, 0);
}
dm->wake_state = opts;
@@ -1424,13 +1424,13 @@ dm9000_probe(struct platform_device *pdev)
} else {
/* test to see if irq is really wakeup capable */
- ret = set_irq_wake(db->irq_wake, 1);
+ ret = irq_set_irq_wake(db->irq_wake, 1);
if (ret) {
dev_err(db->dev, "irq %d cannot set wakeup (%d)\n",
db->irq_wake, ret);
ret = 0;
} else {
- set_irq_wake(db->irq_wake, 0);
+ irq_set_irq_wake(db->irq_wake, 0);
db->wake_supported = 1;
}
}
diff --git a/drivers/net/irda/via-ircc.c b/drivers/net/irda/via-ircc.c
index 67c0ad42d81..186cd28a61c 100644
--- a/drivers/net/irda/via-ircc.c
+++ b/drivers/net/irda/via-ircc.c
@@ -75,15 +75,9 @@ static int dongle_id = 0; /* default: probe */
/* We can't guess the type of connected dongle, user *must* supply it. */
module_param(dongle_id, int, 0);
-/* FIXME : we should not need this, because instances should be automatically
- * managed by the PCI layer. Especially that we seem to only be using the
- * first entry. Jean II */
-/* Max 4 instances for now */
-static struct via_ircc_cb *dev_self[] = { NULL, NULL, NULL, NULL };
-
/* Some prototypes */
-static int via_ircc_open(int i, chipio_t * info, unsigned int id);
-static int via_ircc_close(struct via_ircc_cb *self);
+static int via_ircc_open(struct pci_dev *pdev, chipio_t * info,
+ unsigned int id);
static int via_ircc_dma_receive(struct via_ircc_cb *self);
static int via_ircc_dma_receive_complete(struct via_ircc_cb *self,
int iobase);
@@ -215,7 +209,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
pci_write_config_byte(pcidev,0x42,(bTmp | 0xf0));
pci_write_config_byte(pcidev,0x5a,0xc0);
WriteLPCReg(0x28, 0x70 );
- if (via_ircc_open(0, &info,0x3076) == 0)
+ if (via_ircc_open(pcidev, &info, 0x3076) == 0)
rc=0;
} else
rc = -ENODEV; //IR not turn on
@@ -254,7 +248,7 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
info.irq=FirIRQ;
info.dma=FirDRQ1;
info.dma2=FirDRQ0;
- if (via_ircc_open(0, &info,0x3096) == 0)
+ if (via_ircc_open(pcidev, &info, 0x3096) == 0)
rc=0;
} else
rc = -ENODEV; //IR not turn on !!!!!
@@ -264,48 +258,10 @@ static int __devinit via_init_one (struct pci_dev *pcidev, const struct pci_devi
return rc;
}
-/*
- * Function via_ircc_clean ()
- *
- * Close all configured chips
- *
- */
-static void via_ircc_clean(void)
-{
- int i;
-
- IRDA_DEBUG(3, "%s()\n", __func__);
-
- for (i=0; i < ARRAY_SIZE(dev_self); i++) {
- if (dev_self[i])
- via_ircc_close(dev_self[i]);
- }
-}
-
-static void __devexit via_remove_one (struct pci_dev *pdev)
-{
- IRDA_DEBUG(3, "%s()\n", __func__);
-
- /* FIXME : This is ugly. We should use pci_get_drvdata(pdev);
- * to get our driver instance and call directly via_ircc_close().
- * See vlsi_ir for details...
- * Jean II */
- via_ircc_clean();
-
- /* FIXME : This should be in via_ircc_close(), because here we may
- * theoritically disable still configured devices :-( - Jean II */
- pci_disable_device(pdev);
-}
-
static void __exit via_ircc_cleanup(void)
{
IRDA_DEBUG(3, "%s()\n", __func__);
- /* FIXME : This should be redundant, as pci_unregister_driver()
- * should call via_remove_one() on each device.
- * Jean II */
- via_ircc_clean();
-
/* Cleanup all instances of the driver */
pci_unregister_driver (&via_driver);
}
@@ -324,12 +280,13 @@ static const struct net_device_ops via_ircc_fir_ops = {
};
/*
- * Function via_ircc_open (iobase, irq)
+ * Function via_ircc_open(pdev, iobase, irq)
*
* Open driver instance
*
*/
-static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
+static __devinit int via_ircc_open(struct pci_dev *pdev, chipio_t * info,
+ unsigned int id)
{
struct net_device *dev;
struct via_ircc_cb *self;
@@ -337,9 +294,6 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
IRDA_DEBUG(3, "%s()\n", __func__);
- if (i >= ARRAY_SIZE(dev_self))
- return -ENOMEM;
-
/* Allocate new instance of the driver */
dev = alloc_irdadev(sizeof(struct via_ircc_cb));
if (dev == NULL)
@@ -349,13 +303,8 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
self->netdev = dev;
spin_lock_init(&self->lock);
- /* FIXME : We should store our driver instance in the PCI layer,
- * using pci_set_drvdata(), not in this array.
- * See vlsi_ir for details... - Jean II */
- /* FIXME : 'i' is always 0 (see via_init_one()) :-( - Jean II */
- /* Need to store self somewhere */
- dev_self[i] = self;
- self->index = i;
+ pci_set_drvdata(pdev, self);
+
/* Initialize Resource */
self->io.cfg_base = info->cfg_base;
self->io.fir_base = info->fir_base;
@@ -414,7 +363,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
/* Allocate memory if needed */
self->rx_buff.head =
- dma_alloc_coherent(NULL, self->rx_buff.truesize,
+ dma_alloc_coherent(&pdev->dev, self->rx_buff.truesize,
&self->rx_buff_dma, GFP_KERNEL);
if (self->rx_buff.head == NULL) {
err = -ENOMEM;
@@ -423,7 +372,7 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
memset(self->rx_buff.head, 0, self->rx_buff.truesize);
self->tx_buff.head =
- dma_alloc_coherent(NULL, self->tx_buff.truesize,
+ dma_alloc_coherent(&pdev->dev, self->tx_buff.truesize,
&self->tx_buff_dma, GFP_KERNEL);
if (self->tx_buff.head == NULL) {
err = -ENOMEM;
@@ -455,33 +404,32 @@ static __devinit int via_ircc_open(int i, chipio_t * info, unsigned int id)
via_hw_init(self);
return 0;
err_out4:
- dma_free_coherent(NULL, self->tx_buff.truesize,
+ dma_free_coherent(&pdev->dev, self->tx_buff.truesize,
self->tx_buff.head, self->tx_buff_dma);
err_out3:
- dma_free_coherent(NULL, self->rx_buff.truesize,
+ dma_free_coherent(&pdev->dev, self->rx_buff.truesize,
self->rx_buff.head, self->rx_buff_dma);
err_out2:
release_region(self->io.fir_base, self->io.fir_ext);
err_out1:
+ pci_set_drvdata(pdev, NULL);
free_netdev(dev);
- dev_self[i] = NULL;
return err;
}
/*
- * Function via_ircc_close (self)
+ * Function via_remove_one(pdev)
*
* Close driver instance
*
*/
-static int via_ircc_close(struct via_ircc_cb *self)
+static void __devexit via_remove_one(struct pci_dev *pdev)
{
+ struct via_ircc_cb *self = pci_get_drvdata(pdev);
int iobase;
IRDA_DEBUG(3, "%s()\n", __func__);
- IRDA_ASSERT(self != NULL, return -1;);
-
iobase = self->io.fir_base;
ResetChip(iobase, 5); //hardware reset.
@@ -493,16 +441,16 @@ static int via_ircc_close(struct via_ircc_cb *self)
__func__, self->io.fir_base);
release_region(self->io.fir_base, self->io.fir_ext);
if (self->tx_buff.head)
- dma_free_coherent(NULL, self->tx_buff.truesize,
+ dma_free_coherent(&pdev->dev, self->tx_buff.truesize,
self->tx_buff.head, self->tx_buff_dma);
if (self->rx_buff.head)
- dma_free_coherent(NULL, self->rx_buff.truesize,
+ dma_free_coherent(&pdev->dev, self->rx_buff.truesize,
self->rx_buff.head, self->rx_buff_dma);
- dev_self[self->index] = NULL;
+ pci_set_drvdata(pdev, NULL);
free_netdev(self->netdev);
- return 0;
+ pci_disable_device(pdev);
}
/*
diff --git a/drivers/net/jme.c b/drivers/net/jme.c
index f690474f440..994c80939c7 100644
--- a/drivers/net/jme.c
+++ b/drivers/net/jme.c
@@ -273,7 +273,7 @@ jme_clear_pm(struct jme_adapter *jme)
{
jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs);
pci_set_power_state(jme->pdev, PCI_D0);
- pci_enable_wake(jme->pdev, PCI_D0, false);
+ device_set_wakeup_enable(&jme->pdev->dev, false);
}
static int
@@ -2538,6 +2538,8 @@ jme_set_wol(struct net_device *netdev,
jwrite32(jme, JME_PMCS, jme->reg_pmcs);
+ device_set_wakeup_enable(&jme->pdev->dev, jme->reg_pmcs);
+
return 0;
}
@@ -3172,9 +3174,9 @@ jme_shutdown(struct pci_dev *pdev)
}
#ifdef CONFIG_PM
-static int
-jme_suspend(struct pci_dev *pdev, pm_message_t state)
+static int jme_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct jme_adapter *jme = netdev_priv(netdev);
@@ -3206,22 +3208,18 @@ jme_suspend(struct pci_dev *pdev, pm_message_t state)
tasklet_hi_enable(&jme->rxclean_task);
tasklet_hi_enable(&jme->rxempty_task);
- pci_save_state(pdev);
jme_powersave_phy(jme);
- pci_enable_wake(jme->pdev, PCI_D3hot, true);
- pci_set_power_state(pdev, PCI_D3hot);
return 0;
}
-static int
-jme_resume(struct pci_dev *pdev)
+static int jme_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct net_device *netdev = pci_get_drvdata(pdev);
struct jme_adapter *jme = netdev_priv(netdev);
- jme_clear_pm(jme);
- pci_restore_state(pdev);
+ jwrite32(jme, JME_PMCS, 0xFFFF0000 | jme->reg_pmcs);
jme_phy_on(jme);
if (test_bit(JME_FLAG_SSET, &jme->flags))
@@ -3238,6 +3236,13 @@ jme_resume(struct pci_dev *pdev)
return 0;
}
+
+static SIMPLE_DEV_PM_OPS(jme_pm_ops, jme_suspend, jme_resume);
+#define JME_PM_OPS (&jme_pm_ops)
+
+#else
+
+#define JME_PM_OPS NULL
#endif
static DEFINE_PCI_DEVICE_TABLE(jme_pci_tbl) = {
@@ -3251,11 +3256,8 @@ static struct pci_driver jme_driver = {
.id_table = jme_pci_tbl,
.probe = jme_init_one,
.remove = __devexit_p(jme_remove_one),
-#ifdef CONFIG_PM
- .suspend = jme_suspend,
- .resume = jme_resume,
-#endif /* CONFIG_PM */
.shutdown = jme_shutdown,
+ .driver.pm = JME_PM_OPS,
};
static int __init
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 540a8dcbcc4..7f7d5708a65 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -4898,7 +4898,7 @@ static netdev_tx_t netdev_tx(struct sk_buff *skb, struct net_device *dev)
goto unlock;
}
skb_copy_and_csum_dev(org_skb, skb->data);
- org_skb->ip_summed = 0;
+ org_skb->ip_summed = CHECKSUM_NONE;
skb->len = org_skb->len;
copy_old_skb(org_skb, skb);
}
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 5762ebde445..4f158baa024 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -742,6 +742,9 @@ int mlx4_en_start_port(struct net_device *dev)
0, MLX4_PROT_ETH))
mlx4_warn(mdev, "Failed Attaching Broadcast\n");
+ /* Must redo promiscuous mode setup. */
+ priv->flags &= ~(MLX4_EN_FLAG_PROMISC | MLX4_EN_FLAG_MC_PROMISC);
+
/* Schedule multicast task to populate multicast list */
queue_work(mdev->workqueue, &priv->mcast_task);
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index 506cfd0372e..1ad1f6029af 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -603,7 +603,9 @@ int mlx4_init_eq_table(struct mlx4_dev *dev)
}
for (i = 0; i < dev->caps.num_comp_vectors; ++i) {
- err = mlx4_create_eq(dev, dev->caps.num_cqs + MLX4_NUM_SPARE_EQE,
+ err = mlx4_create_eq(dev, dev->caps.num_cqs -
+ dev->caps.reserved_cqs +
+ MLX4_NUM_SPARE_EQE,
(dev->flags & MLX4_FLAG_MSI_X) ? i : 0,
&priv->eq_table.eq[i]);
if (err) {
diff --git a/drivers/net/mlx4/mcg.c b/drivers/net/mlx4/mcg.c
index e71372aa9cc..37150b2f642 100644
--- a/drivers/net/mlx4/mcg.c
+++ b/drivers/net/mlx4/mcg.c
@@ -469,7 +469,6 @@ static int remove_promisc_qp(struct mlx4_dev *dev, u8 vep_num, u8 port,
/*remove from list of promisc qps */
list_del(&pqp->list);
- kfree(pqp);
/* set the default entry not to include the removed one */
mailbox = mlx4_alloc_cmd_mailbox(dev);
@@ -528,6 +527,8 @@ out_mailbox:
out_list:
if (back_to_list)
list_add_tail(&pqp->list, &s_steer->promisc_qps[steer]);
+ else
+ kfree(pqp);
out_mutex:
mutex_unlock(&priv->mcg_table.mutex);
return err;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 1f4e8680a96..673dc600c89 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1312,17 +1312,26 @@ myri10ge_unmap_rx_page(struct pci_dev *pdev,
* page into an skb */
static inline int
-myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
- int bytes, int len, __wsum csum)
+myri10ge_rx_done(struct myri10ge_slice_state *ss, int len, __wsum csum,
+ int lro_enabled)
{
struct myri10ge_priv *mgp = ss->mgp;
struct sk_buff *skb;
struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME];
- int i, idx, hlen, remainder;
+ struct myri10ge_rx_buf *rx;
+ int i, idx, hlen, remainder, bytes;
struct pci_dev *pdev = mgp->pdev;
struct net_device *dev = mgp->dev;
u8 *va;
+ if (len <= mgp->small_bytes) {
+ rx = &ss->rx_small;
+ bytes = mgp->small_bytes;
+ } else {
+ rx = &ss->rx_big;
+ bytes = mgp->big_bytes;
+ }
+
len += MXGEFW_PAD;
idx = rx->cnt & rx->mask;
va = page_address(rx->info[idx].page) + rx->info[idx].page_offset;
@@ -1341,7 +1350,7 @@ myri10ge_rx_done(struct myri10ge_slice_state *ss, struct myri10ge_rx_buf *rx,
remainder -= MYRI10GE_ALLOC_SIZE;
}
- if (dev->features & NETIF_F_LRO) {
+ if (lro_enabled) {
rx_frags[0].page_offset += MXGEFW_PAD;
rx_frags[0].size -= MXGEFW_PAD;
len -= MXGEFW_PAD;
@@ -1463,7 +1472,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
{
struct myri10ge_rx_done *rx_done = &ss->rx_done;
struct myri10ge_priv *mgp = ss->mgp;
- struct net_device *netdev = mgp->dev;
+
unsigned long rx_bytes = 0;
unsigned long rx_packets = 0;
unsigned long rx_ok;
@@ -1474,18 +1483,18 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
u16 length;
__wsum checksum;
+ /*
+ * Prevent compiler from generating more than one ->features memory
+ * access to avoid theoretical race condition with functions that
+ * change NETIF_F_LRO flag at runtime.
+ */
+ bool lro_enabled = ACCESS_ONCE(mgp->dev->features) & NETIF_F_LRO;
+
while (rx_done->entry[idx].length != 0 && work_done < budget) {
length = ntohs(rx_done->entry[idx].length);
rx_done->entry[idx].length = 0;
checksum = csum_unfold(rx_done->entry[idx].checksum);
- if (length <= mgp->small_bytes)
- rx_ok = myri10ge_rx_done(ss, &ss->rx_small,
- mgp->small_bytes,
- length, checksum);
- else
- rx_ok = myri10ge_rx_done(ss, &ss->rx_big,
- mgp->big_bytes,
- length, checksum);
+ rx_ok = myri10ge_rx_done(ss, length, checksum, lro_enabled);
rx_packets += rx_ok;
rx_bytes += rx_ok * (unsigned long)length;
cnt++;
@@ -1497,7 +1506,7 @@ myri10ge_clean_rx_done(struct myri10ge_slice_state *ss, int budget)
ss->stats.rx_packets += rx_packets;
ss->stats.rx_bytes += rx_bytes;
- if (netdev->features & NETIF_F_LRO)
+ if (lro_enabled)
lro_flush_all(&rx_done->lro_mgr);
/* restock receive rings if needed */
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 653d308e0f5..3bdcc803ec6 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -871,7 +871,7 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
struct netxen_adapter *adapter = netdev_priv(netdev);
int hw_lro;
- if (data & ~ETH_FLAG_LRO)
+ if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
return -EINVAL;
if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 993c52c82ae..e870c0698bb 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -442,11 +442,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
u32 flags, phy_interface_t interface)
{
struct device *d = &phydev->dev;
+ int err;
/* Assume that if there is no driver, that it doesn't
* exist, and we should use the genphy driver. */
if (NULL == d->driver) {
- int err;
d->driver = &genphy_driver.driver;
err = d->driver->probe(d);
@@ -474,7 +474,11 @@ static int phy_attach_direct(struct net_device *dev, struct phy_device *phydev,
/* Do initial configuration here, now that
* we have certain key parameters
* (dev_flags and interface) */
- return phy_init_hw(phydev);
+ err = phy_init_hw(phydev);
+ if (err)
+ phy_detach(phydev);
+
+ return err;
}
/**
diff --git a/drivers/net/qlcnic/qlcnic_ethtool.c b/drivers/net/qlcnic/qlcnic_ethtool.c
index 4c14510e2a8..45b2755d6cb 100644
--- a/drivers/net/qlcnic/qlcnic_ethtool.c
+++ b/drivers/net/qlcnic/qlcnic_ethtool.c
@@ -1003,7 +1003,7 @@ static int qlcnic_set_flags(struct net_device *netdev, u32 data)
struct qlcnic_adapter *adapter = netdev_priv(netdev);
int hw_lro;
- if (data & ~ETH_FLAG_LRO)
+ if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
return -EINVAL;
if (!(adapter->capabilities & QLCNIC_FW_CAPABILITY_HW_LRO))
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 2ad6364103e..356e74d20b8 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -6726,7 +6726,7 @@ static int s2io_ethtool_set_flags(struct net_device *dev, u32 data)
int rc = 0;
int changed = 0;
- if (data & ~ETH_FLAG_LRO)
+ if (ethtool_invalid_flags(dev, data, ETH_FLAG_LRO))
return -EINVAL;
if (data & ETH_FLAG_LRO) {
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index ebec88882c3..73c942d85f0 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -48,9 +48,9 @@
#include <net/ip.h>
#include <asm/system.h>
-#include <asm/io.h>
+#include <linux/io.h>
#include <asm/byteorder.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#ifdef CONFIG_SPARC
#include <asm/idprom.h>
@@ -13118,7 +13118,7 @@ done:
static struct pci_dev * __devinit tg3_find_peer(struct tg3 *);
-static void inline vlan_features_add(struct net_device *dev, unsigned long flags)
+static inline void vlan_features_add(struct net_device *dev, unsigned long flags)
{
dev->vlan_features |= flags;
}
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 6f600cced6e..3ec22c30779 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -433,4 +433,19 @@ config USB_SIERRA_NET
To compile this driver as a module, choose M here: the
module will be called sierra_net.
+config USB_VL600
+ tristate "LG VL600 modem dongle"
+ depends on USB_NET_CDCETHER
+ select USB_ACM
+ help
+ Select this if you want to use an LG Electronics 4G/LTE usb modem
+ called VL600. This driver only handles the ethernet
+ interface exposed by the modem firmware. To establish a connection
+ you will first need a userspace program that sends the right
+ command to the modem through its CDC ACM port, and most
+ likely also a DHCP client. See this thread about using the
+ 4G modem from Verizon:
+
+ http://ubuntuforums.org/showpost.php?p=10589647&postcount=17
+
endmenu
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index cac17030118..c7ec8a5f0a9 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -27,4 +27,5 @@ obj-$(CONFIG_USB_IPHETH) += ipheth.o
obj-$(CONFIG_USB_SIERRA_NET) += sierra_net.o
obj-$(CONFIG_USB_NET_CX82310_ETH) += cx82310_eth.o
obj-$(CONFIG_USB_NET_CDC_NCM) += cdc_ncm.o
+obj-$(CONFIG_USB_VL600) += lg-vl600.o
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 9a60e415d76..51c259b6927 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -378,7 +378,7 @@ static void dumpspeed(struct usbnet *dev, __le32 *speeds)
__le32_to_cpu(speeds[1]) / 1000);
}
-static void cdc_status(struct usbnet *dev, struct urb *urb)
+void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
{
struct usb_cdc_notification *event;
@@ -418,8 +418,9 @@ static void cdc_status(struct usbnet *dev, struct urb *urb)
break;
}
}
+EXPORT_SYMBOL_GPL(usbnet_cdc_status);
-static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
+int usbnet_cdc_bind(struct usbnet *dev, struct usb_interface *intf)
{
int status;
struct cdc_state *info = (void *) &dev->data;
@@ -441,6 +442,7 @@ static int cdc_bind(struct usbnet *dev, struct usb_interface *intf)
*/
return 0;
}
+EXPORT_SYMBOL_GPL(usbnet_cdc_bind);
static int cdc_manage_power(struct usbnet *dev, int on)
{
@@ -452,18 +454,18 @@ static const struct driver_info cdc_info = {
.description = "CDC Ethernet Device",
.flags = FLAG_ETHER,
// .check_connect = cdc_check_connect,
- .bind = cdc_bind,
+ .bind = usbnet_cdc_bind,
.unbind = usbnet_cdc_unbind,
- .status = cdc_status,
+ .status = usbnet_cdc_status,
.manage_power = cdc_manage_power,
};
static const struct driver_info mbm_info = {
.description = "Mobile Broadband Network Device",
.flags = FLAG_WWAN,
- .bind = cdc_bind,
+ .bind = usbnet_cdc_bind,
.unbind = usbnet_cdc_unbind,
- .status = cdc_status,
+ .status = usbnet_cdc_status,
.manage_power = cdc_manage_power,
};
@@ -560,6 +562,13 @@ static const struct usb_device_id products [] = {
.driver_info = 0,
},
+/* LG Electronics VL600 wants additional headers on every frame */
+{
+ USB_DEVICE_AND_INTERFACE_INFO(0x1004, 0x61aa, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+ .driver_info = 0,
+},
+
/*
* WHITELIST!!!
*
diff --git a/drivers/net/usb/lg-vl600.c b/drivers/net/usb/lg-vl600.c
new file mode 100644
index 00000000000..1d83ccfd727
--- /dev/null
+++ b/drivers/net/usb/lg-vl600.c
@@ -0,0 +1,346 @@
+/*
+ * Ethernet interface part of the LG VL600 LTE modem (4G dongle)
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Author: Andrzej Zaborowski <balrogg@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.
+ *
+ * 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/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/usb.h>
+#include <linux/usb/cdc.h>
+#include <linux/usb/usbnet.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/inetdevice.h>
+
+/*
+ * The device has a CDC ACM port for modem control (it claims to be
+ * CDC ACM anyway) and a CDC Ethernet port for actual network data.
+ * It will however ignore data on both ports that is not encapsulated
+ * in a specific way, any data returned is also encapsulated the same
+ * way. The headers don't seem to follow any popular standard.
+ *
+ * This driver adds and strips these headers from the ethernet frames
+ * sent/received from the CDC Ethernet port. The proprietary header
+ * replaces the standard ethernet header in a packet so only actual
+ * ethernet frames are allowed. The headers allow some form of
+ * multiplexing by using non standard values of the .h_proto field.
+ * Windows/Mac drivers do send a couple of such frames to the device
+ * during initialisation, with protocol set to 0x0906 or 0x0b06 and (what
+ * seems to be) a flag in the .dummy_flags. This doesn't seem necessary
+ * for modem operation but can possibly be used for GPS or other funcitons.
+ */
+
+struct vl600_frame_hdr {
+ __le32 len;
+ __le32 serial;
+ __le32 pkt_cnt;
+ __le32 dummy_flags;
+ __le32 dummy;
+ __le32 magic;
+} __attribute__((packed));
+
+struct vl600_pkt_hdr {
+ __le32 dummy[2];
+ __le32 len;
+ __be16 h_proto;
+} __attribute__((packed));
+
+struct vl600_state {
+ struct sk_buff *current_rx_buf;
+};
+
+static int vl600_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+ int ret;
+ struct vl600_state *s = kzalloc(sizeof(struct vl600_state), GFP_KERNEL);
+
+ if (!s)
+ return -ENOMEM;
+
+ ret = usbnet_cdc_bind(dev, intf);
+ if (ret) {
+ kfree(s);
+ return ret;
+ }
+
+ dev->driver_priv = s;
+
+ /* ARP packets don't go through, but they're also of no use. The
+ * subnet has only two hosts anyway: us and the gateway / DHCP
+ * server (probably simulated by modem firmware or network operator)
+ * whose address changes everytime we connect to the intarwebz and
+ * who doesn't bother answering ARP requests either. So hardware
+ * addresses have no meaning, the destination and the source of every
+ * packet depend only on whether it is on the IN or OUT endpoint. */
+ dev->net->flags |= IFF_NOARP;
+
+ return ret;
+}
+
+static void vl600_unbind(struct usbnet *dev, struct usb_interface *intf)
+{
+ struct vl600_state *s = dev->driver_priv;
+
+ if (s->current_rx_buf)
+ dev_kfree_skb(s->current_rx_buf);
+
+ kfree(s);
+
+ return usbnet_cdc_unbind(dev, intf);
+}
+
+static int vl600_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+{
+ struct vl600_frame_hdr *frame;
+ struct vl600_pkt_hdr *packet;
+ struct ethhdr *ethhdr;
+ int packet_len, count;
+ struct sk_buff *buf = skb;
+ struct sk_buff *clone;
+ struct vl600_state *s = dev->driver_priv;
+
+ /* Frame lengths are generally 4B multiplies but every couple of
+ * hours there's an odd number of bytes sized yet correct frame,
+ * so don't require this. */
+
+ /* Allow a packet (or multiple packets batched together) to be
+ * split across many frames. We don't allow a new batch to
+ * begin in the same frame another one is ending however, and no
+ * leading or trailing pad bytes. */
+ if (s->current_rx_buf) {
+ frame = (struct vl600_frame_hdr *) s->current_rx_buf->data;
+ if (skb->len + s->current_rx_buf->len >
+ le32_to_cpup(&frame->len)) {
+ netif_err(dev, ifup, dev->net, "Fragment too long\n");
+ dev->net->stats.rx_length_errors++;
+ goto error;
+ }
+
+ buf = s->current_rx_buf;
+ memcpy(skb_put(buf, skb->len), skb->data, skb->len);
+ } else if (skb->len < 4) {
+ netif_err(dev, ifup, dev->net, "Frame too short\n");
+ dev->net->stats.rx_length_errors++;
+ goto error;
+ }
+
+ 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. */
+
+ if (buf->len < sizeof(*frame) ||
+ buf->len != le32_to_cpup(&frame->len)) {
+ /* Save this fragment for later assembly */
+ if (s->current_rx_buf)
+ return 0;
+
+ s->current_rx_buf = skb_copy_expand(skb, 0,
+ le32_to_cpup(&frame->len), GFP_ATOMIC);
+ if (!s->current_rx_buf) {
+ netif_err(dev, ifup, dev->net, "Reserving %i bytes "
+ "for packet assembly failed.\n",
+ le32_to_cpup(&frame->len));
+ dev->net->stats.rx_errors++;
+ }
+
+ return 0;
+ }
+
+ count = le32_to_cpup(&frame->pkt_cnt);
+
+ skb_pull(buf, sizeof(*frame));
+
+ while (count--) {
+ if (buf->len < sizeof(*packet)) {
+ netif_err(dev, ifup, dev->net, "Packet too short\n");
+ goto error;
+ }
+
+ packet = (struct vl600_pkt_hdr *) buf->data;
+ packet_len = sizeof(*packet) + le32_to_cpup(&packet->len);
+ if (packet_len > buf->len) {
+ netif_err(dev, ifup, dev->net,
+ "Bad packet length stored in header\n");
+ goto error;
+ }
+
+ /* Packet header is same size as the ethernet header
+ * (sizeof(*packet) == sizeof(*ethhdr)), additionally
+ * the h_proto field is in the same place so we just leave it
+ * alone and fill in the remaining fields.
+ */
+ ethhdr = (struct ethhdr *) skb->data;
+ if (be16_to_cpup(&ethhdr->h_proto) == ETH_P_ARP &&
+ buf->len > 0x26) {
+ /* Copy the addresses from packet contents */
+ memcpy(ethhdr->h_source,
+ &buf->data[sizeof(*ethhdr) + 0x8],
+ ETH_ALEN);
+ memcpy(ethhdr->h_dest,
+ &buf->data[sizeof(*ethhdr) + 0x12],
+ ETH_ALEN);
+ } else {
+ memset(ethhdr->h_source, 0, ETH_ALEN);
+ memcpy(ethhdr->h_dest, dev->net->dev_addr, ETH_ALEN);
+ }
+
+ if (count) {
+ /* Not the last packet in this batch */
+ clone = skb_clone(buf, GFP_ATOMIC);
+ if (!clone)
+ goto error;
+
+ skb_trim(clone, packet_len);
+ usbnet_skb_return(dev, clone);
+
+ skb_pull(buf, (packet_len + 3) & ~3);
+ } else {
+ skb_trim(buf, packet_len);
+
+ if (s->current_rx_buf) {
+ usbnet_skb_return(dev, buf);
+ s->current_rx_buf = NULL;
+ return 0;
+ }
+
+ return 1;
+ }
+ }
+
+error:
+ if (s->current_rx_buf) {
+ dev_kfree_skb_any(s->current_rx_buf);
+ s->current_rx_buf = NULL;
+ }
+ dev->net->stats.rx_errors++;
+ return 0;
+}
+
+static struct sk_buff *vl600_tx_fixup(struct usbnet *dev,
+ struct sk_buff *skb, gfp_t flags)
+{
+ struct sk_buff *ret;
+ struct vl600_frame_hdr *frame;
+ struct vl600_pkt_hdr *packet;
+ static uint32_t serial = 1;
+ int orig_len = skb->len - sizeof(struct ethhdr);
+ int full_len = (skb->len + sizeof(struct vl600_frame_hdr) + 3) & ~3;
+
+ frame = (struct vl600_frame_hdr *) skb->data;
+ if (skb->len > sizeof(*frame) && skb->len == le32_to_cpup(&frame->len))
+ return skb; /* Already encapsulated? */
+
+ if (skb->len < sizeof(struct ethhdr))
+ /* Drop, device can only deal with ethernet packets */
+ return NULL;
+
+ if (!skb_cloned(skb)) {
+ int headroom = skb_headroom(skb);
+ int tailroom = skb_tailroom(skb);
+
+ if (tailroom >= full_len - skb->len - sizeof(*frame) &&
+ headroom >= sizeof(*frame))
+ /* There's enough head and tail room */
+ goto encapsulate;
+
+ if (headroom + tailroom + skb->len >= full_len) {
+ /* There's enough total room, just readjust */
+ skb->data = memmove(skb->head + sizeof(*frame),
+ skb->data, skb->len);
+ skb_set_tail_pointer(skb, skb->len);
+ goto encapsulate;
+ }
+ }
+
+ /* Alloc a new skb with the required size */
+ ret = skb_copy_expand(skb, sizeof(struct vl600_frame_hdr), full_len -
+ skb->len - sizeof(struct vl600_frame_hdr), flags);
+ dev_kfree_skb_any(skb);
+ if (!ret)
+ return ret;
+ skb = ret;
+
+encapsulate:
+ /* Packet header is same size as ethernet packet header
+ * (sizeof(*packet) == sizeof(struct ethhdr)), additionally the
+ * h_proto field is in the same place so we just leave it alone and
+ * overwrite the remaining fields.
+ */
+ packet = (struct vl600_pkt_hdr *) skb->data;
+ memset(&packet->dummy, 0, sizeof(packet->dummy));
+ packet->len = cpu_to_le32(orig_len);
+
+ frame = (struct vl600_frame_hdr *) skb_push(skb, sizeof(*frame));
+ memset(frame, 0, sizeof(*frame));
+ frame->len = cpu_to_le32(full_len);
+ frame->serial = cpu_to_le32(serial++);
+ frame->pkt_cnt = cpu_to_le32(1);
+
+ if (skb->len < full_len) /* Pad */
+ skb_put(skb, full_len - skb->len);
+
+ return skb;
+}
+
+static const struct driver_info vl600_info = {
+ .description = "LG VL600 modem",
+ .flags = FLAG_ETHER | FLAG_RX_ASSEMBLE,
+ .bind = vl600_bind,
+ .unbind = vl600_unbind,
+ .status = usbnet_cdc_status,
+ .rx_fixup = vl600_rx_fixup,
+ .tx_fixup = vl600_tx_fixup,
+};
+
+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) &vl600_info,
+ },
+ {}, /* End */
+};
+MODULE_DEVICE_TABLE(usb, products);
+
+static struct usb_driver lg_vl600_driver = {
+ .name = "lg-vl600",
+ .id_table = products,
+ .probe = usbnet_probe,
+ .disconnect = usbnet_disconnect,
+ .suspend = usbnet_suspend,
+ .resume = usbnet_resume,
+};
+
+static int __init vl600_init(void)
+{
+ return usb_register(&lg_vl600_driver);
+}
+module_init(vl600_init);
+
+static void __exit vl600_exit(void)
+{
+ usb_deregister(&lg_vl600_driver);
+}
+module_exit(vl600_exit);
+
+MODULE_AUTHOR("Anrzej Zaborowski");
+MODULE_DESCRIPTION("LG-VL600 modem's ethernet link");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 95c41d56631..cf58b768256 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -387,8 +387,12 @@ static int rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
{
if (dev->driver_info->rx_fixup &&
- !dev->driver_info->rx_fixup (dev, skb))
- goto error;
+ !dev->driver_info->rx_fixup (dev, skb)) {
+ /* With RX_ASSEMBLE, rx_fixup() must update counters */
+ if (!(dev->driver_info->flags & FLAG_RX_ASSEMBLE))
+ dev->net->stats.rx_errors++;
+ goto done;
+ }
// else network stack removes extra byte if we forced a short packet
if (skb->len) {
@@ -401,8 +405,8 @@ static inline void rx_process (struct usbnet *dev, struct sk_buff *skb)
}
netif_dbg(dev, rx_err, dev->net, "drop\n");
-error:
dev->net->stats.rx_errors++;
+done:
skb_queue_tail(&dev->done, skb);
}
diff --git a/drivers/net/vmxnet3/vmxnet3_ethtool.c b/drivers/net/vmxnet3/vmxnet3_ethtool.c
index 81254be85b9..51f2ef142a5 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethtool.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c
@@ -304,8 +304,8 @@ vmxnet3_set_flags(struct net_device *netdev, u32 data)
u8 lro_present = (netdev->features & NETIF_F_LRO) == 0 ? 0 : 1;
unsigned long flags;
- if (data & ~ETH_FLAG_LRO)
- return -EOPNOTSUPP;
+ if (ethtool_invalid_flags(netdev, data, ETH_FLAG_LRO))
+ return -EINVAL;
if (lro_requested ^ lro_present) {
/* toggle the LRO feature*/
diff --git a/drivers/net/vxge/vxge-ethtool.c b/drivers/net/vxge/vxge-ethtool.c
index 1dd3a21b3a4..c5eb034107f 100644
--- a/drivers/net/vxge/vxge-ethtool.c
+++ b/drivers/net/vxge/vxge-ethtool.c
@@ -1117,8 +1117,8 @@ static int vxge_set_flags(struct net_device *dev, u32 data)
struct vxgedev *vdev = netdev_priv(dev);
enum vxge_hw_status status;
- if (data & ~ETH_FLAG_RXHASH)
- return -EOPNOTSUPP;
+ if (ethtool_invalid_flags(dev, data, ETH_FLAG_RXHASH))
+ return -EINVAL;
if (!!(data & ETH_FLAG_RXHASH) == vdev->devh->config.rth_en)
return 0;
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 18d24b7b1e3..7ecc0bda57b 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -649,8 +649,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
goto err_free_common;
}
- set_irq_type(gpio_to_irq(p54spi_gpio_irq),
- IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
disable_irq(gpio_to_irq(p54spi_gpio_irq));
diff --git a/drivers/net/wireless/wl1251/sdio.c b/drivers/net/wireless/wl1251/sdio.c
index d550b5e68d3..f51a0241a44 100644
--- a/drivers/net/wireless/wl1251/sdio.c
+++ b/drivers/net/wireless/wl1251/sdio.c
@@ -265,7 +265,7 @@ static int wl1251_sdio_probe(struct sdio_func *func,
goto disable;
}
- set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
disable_irq(wl->irq);
wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq;
diff --git a/drivers/net/wireless/wl1251/spi.c b/drivers/net/wireless/wl1251/spi.c
index ac872b38960..af6448c4d3e 100644
--- a/drivers/net/wireless/wl1251/spi.c
+++ b/drivers/net/wireless/wl1251/spi.c
@@ -286,7 +286,7 @@ static int __devinit wl1251_spi_probe(struct spi_device *spi)
goto out_free;
}
- set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING);
disable_irq(wl->irq);
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index deeec32a580..103095bbe8c 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -340,7 +340,7 @@ static int __init eisa_probe(struct parisc_device *dev)
/* Reserve IRQ2 */
setup_irq(2, &irq2_action);
for (i = 0; i < 16; i++) {
- set_irq_chip_and_handler(i, &eisa_interrupt_type,
+ irq_set_chip_and_handler(i, &eisa_interrupt_type,
handle_simple_irq);
}
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c
index ef31080cf59..1bab5a2cd35 100644
--- a/drivers/parisc/gsc.c
+++ b/drivers/parisc/gsc.c
@@ -152,8 +152,8 @@ int gsc_assign_irq(struct irq_chip *type, void *data)
if (irq > GSC_IRQ_MAX)
return NO_IRQ;
- set_irq_chip_and_handler(irq, type, handle_simple_irq);
- set_irq_chip_data(irq, data);
+ irq_set_chip_and_handler(irq, type, handle_simple_irq);
+ irq_set_chip_data(irq, data);
return irq++;
}
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index a4d8ff66a63..e3b76d409de 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -355,7 +355,8 @@ int superio_fixup_irq(struct pci_dev *pcidev)
#endif
for (i = 0; i < 16; i++) {
- set_irq_chip_and_handler(i, &superio_interrupt_type, handle_simple_irq);
+ irq_set_chip_and_handler(i, &superio_interrupt_type,
+ handle_simple_irq);
}
/*
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c
index 09933eb9126..12e02bf92c4 100644
--- a/drivers/pci/dmar.c
+++ b/drivers/pci/dmar.c
@@ -1226,7 +1226,7 @@ const char *dmar_get_fault_reason(u8 fault_reason, int *fault_type)
void dmar_msi_unmask(struct irq_data *data)
{
- struct intel_iommu *iommu = irq_data_get_irq_data(data);
+ struct intel_iommu *iommu = irq_data_get_irq_handler_data(data);
unsigned long flag;
/* unmask it */
@@ -1240,7 +1240,7 @@ void dmar_msi_unmask(struct irq_data *data)
void dmar_msi_mask(struct irq_data *data)
{
unsigned long flag;
- struct intel_iommu *iommu = irq_data_get_irq_data(data);
+ struct intel_iommu *iommu = irq_data_get_irq_handler_data(data);
/* mask it */
spin_lock_irqsave(&iommu->register_lock, flag);
@@ -1252,7 +1252,7 @@ void dmar_msi_mask(struct irq_data *data)
void dmar_msi_write(int irq, struct msi_msg *msg)
{
- struct intel_iommu *iommu = get_irq_data(irq);
+ struct intel_iommu *iommu = irq_get_handler_data(irq);
unsigned long flag;
spin_lock_irqsave(&iommu->register_lock, flag);
@@ -1264,7 +1264,7 @@ void dmar_msi_write(int irq, struct msi_msg *msg)
void dmar_msi_read(int irq, struct msi_msg *msg)
{
- struct intel_iommu *iommu = get_irq_data(irq);
+ struct intel_iommu *iommu = irq_get_handler_data(irq);
unsigned long flag;
spin_lock_irqsave(&iommu->register_lock, flag);
@@ -1382,12 +1382,12 @@ int dmar_set_interrupt(struct intel_iommu *iommu)
return -EINVAL;
}
- set_irq_data(irq, iommu);
+ irq_set_handler_data(irq, iommu);
iommu->irq = irq;
ret = arch_setup_dmar_msi(irq);
if (ret) {
- set_irq_data(irq, NULL);
+ irq_set_handler_data(irq, NULL);
iommu->irq = 0;
destroy_irq(irq);
return ret;
diff --git a/drivers/pci/htirq.c b/drivers/pci/htirq.c
index 834842aa5bb..db057b6fe0c 100644
--- a/drivers/pci/htirq.c
+++ b/drivers/pci/htirq.c
@@ -34,7 +34,7 @@ struct ht_irq_cfg {
void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
{
- struct ht_irq_cfg *cfg = get_irq_data(irq);
+ struct ht_irq_cfg *cfg = irq_get_handler_data(irq);
unsigned long flags;
spin_lock_irqsave(&ht_irq_lock, flags);
if (cfg->msg.address_lo != msg->address_lo) {
@@ -53,13 +53,13 @@ void write_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
void fetch_ht_irq_msg(unsigned int irq, struct ht_irq_msg *msg)
{
- struct ht_irq_cfg *cfg = get_irq_data(irq);
+ struct ht_irq_cfg *cfg = irq_get_handler_data(irq);
*msg = cfg->msg;
}
void mask_ht_irq(struct irq_data *data)
{
- struct ht_irq_cfg *cfg = irq_data_get_irq_data(data);
+ struct ht_irq_cfg *cfg = irq_data_get_irq_handler_data(data);
struct ht_irq_msg msg = cfg->msg;
msg.address_lo |= 1;
@@ -68,7 +68,7 @@ void mask_ht_irq(struct irq_data *data)
void unmask_ht_irq(struct irq_data *data)
{
- struct ht_irq_cfg *cfg = irq_data_get_irq_data(data);
+ struct ht_irq_cfg *cfg = irq_data_get_irq_handler_data(data);
struct ht_irq_msg msg = cfg->msg;
msg.address_lo &= ~1;
@@ -126,7 +126,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
kfree(cfg);
return -EBUSY;
}
- set_irq_data(irq, cfg);
+ irq_set_handler_data(irq, cfg);
if (arch_setup_ht_irq(irq, dev) < 0) {
ht_destroy_irq(irq);
@@ -162,9 +162,9 @@ void ht_destroy_irq(unsigned int irq)
{
struct ht_irq_cfg *cfg;
- cfg = get_irq_data(irq);
- set_irq_chip(irq, NULL);
- set_irq_data(irq, NULL);
+ cfg = irq_get_handler_data(irq);
+ irq_set_chip(irq, NULL);
+ irq_set_handler_data(irq, NULL);
destroy_irq(irq);
kfree(cfg);
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index a4115f1afe1..7da3bef60d8 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -1206,7 +1206,7 @@ void free_dmar_iommu(struct intel_iommu *iommu)
iommu_disable_translation(iommu);
if (iommu->irq) {
- set_irq_data(iommu->irq, NULL);
+ irq_set_handler_data(iommu->irq, NULL);
/* This will mask the irq */
free_irq(iommu->irq, iommu);
destroy_irq(iommu->irq);
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index ec87cd66f3e..a22557b2028 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -50,7 +50,7 @@ static DEFINE_SPINLOCK(irq_2_ir_lock);
static struct irq_2_iommu *irq_2_iommu(unsigned int irq)
{
- struct irq_cfg *cfg = get_irq_chip_data(irq);
+ struct irq_cfg *cfg = irq_get_chip_data(irq);
return cfg ? &cfg->irq_2_iommu : NULL;
}
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 44b0aeee83e..2f10328bf66 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -236,7 +236,7 @@ void __read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
void read_msi_msg(unsigned int irq, struct msi_msg *msg)
{
- struct msi_desc *entry = get_irq_msi(irq);
+ struct msi_desc *entry = irq_get_msi_desc(irq);
__read_msi_msg(entry, msg);
}
@@ -253,7 +253,7 @@ void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg)
{
- struct msi_desc *entry = get_irq_msi(irq);
+ struct msi_desc *entry = irq_get_msi_desc(irq);
__get_cached_msi_msg(entry, msg);
}
@@ -297,7 +297,7 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
void write_msi_msg(unsigned int irq, struct msi_msg *msg)
{
- struct msi_desc *entry = get_irq_msi(irq);
+ struct msi_desc *entry = irq_get_msi_desc(irq);
__write_msi_msg(entry, msg);
}
@@ -354,7 +354,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
if (!dev->msi_enabled)
return;
- entry = get_irq_msi(dev->irq);
+ entry = irq_get_msi_desc(dev->irq);
pos = entry->msi_attrib.pos;
pci_intx_for_msi(dev, 0);
@@ -519,7 +519,7 @@ static void msix_program_entries(struct pci_dev *dev,
PCI_MSIX_ENTRY_VECTOR_CTRL;
entries[i].vector = entry->irq;
- set_irq_msi(entry->irq, entry);
+ irq_set_msi_desc(entry->irq, entry);
entry->masked = readl(entry->mask_base + offset);
msix_mask_irq(entry, 1);
i++;
diff --git a/drivers/pcmcia/bfin_cf_pcmcia.c b/drivers/pcmcia/bfin_cf_pcmcia.c
index eae9cbe37a3..49221395101 100644
--- a/drivers/pcmcia/bfin_cf_pcmcia.c
+++ b/drivers/pcmcia/bfin_cf_pcmcia.c
@@ -235,7 +235,7 @@ static int __devinit bfin_cf_probe(struct platform_device *pdev)
cf->irq = irq;
cf->socket.pci_irq = irq;
- set_irq_type(irq, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(irq, IRQF_TRIGGER_LOW);
io_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
attr_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
index 27575e6378a..01757f18a20 100644
--- a/drivers/pcmcia/db1xxx_ss.c
+++ b/drivers/pcmcia/db1xxx_ss.c
@@ -181,7 +181,7 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
/* all other (older) Db1x00 boards use a GPIO to show
* card detection status: use both-edge triggers.
*/
- set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(sock->insert_irq, IRQ_TYPE_EDGE_BOTH);
ret = request_irq(sock->insert_irq, db1000_pcmcia_cdirq,
0, "pcmcia_carddetect", sock);
diff --git a/drivers/pcmcia/pxa2xx_colibri.c b/drivers/pcmcia/pxa2xx_colibri.c
index a52039564e7..443cb7fc872 100644
--- a/drivers/pcmcia/pxa2xx_colibri.c
+++ b/drivers/pcmcia/pxa2xx_colibri.c
@@ -34,14 +34,24 @@
#define COLIBRI320_DETECT_GPIO 81
#define COLIBRI320_READY_GPIO 29
-static struct {
- int reset_gpio;
- int ppen_gpio;
- int bvd1_gpio;
- int bvd2_gpio;
- int detect_gpio;
- int ready_gpio;
-} colibri_pcmcia_gpio;
+enum {
+ DETECT = 0,
+ READY = 1,
+ BVD1 = 2,
+ BVD2 = 3,
+ PPEN = 4,
+ RESET = 5,
+};
+
+/* Contents of this array are configured on-the-fly in init function */
+static struct gpio colibri_pcmcia_gpios[] = {
+ { 0, GPIOF_IN, "PCMCIA Detect" },
+ { 0, GPIOF_IN, "PCMCIA Ready" },
+ { 0, GPIOF_IN, "PCMCIA BVD1" },
+ { 0, GPIOF_IN, "PCMCIA BVD2" },
+ { 0, GPIOF_INIT_LOW, "PCMCIA PPEN" },
+ { 0, GPIOF_INIT_HIGH,"PCMCIA Reset" },
+};
static struct pcmcia_irqs colibri_irqs[] = {
{
@@ -54,88 +64,42 @@ static int colibri_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
- ret = gpio_request(colibri_pcmcia_gpio.detect_gpio, "DETECT");
+ ret = gpio_request_array(colibri_pcmcia_gpios,
+ ARRAY_SIZE(colibri_pcmcia_gpios));
if (ret)
goto err1;
- ret = gpio_direction_input(colibri_pcmcia_gpio.detect_gpio);
- if (ret)
- goto err2;
-
- ret = gpio_request(colibri_pcmcia_gpio.ready_gpio, "READY");
- if (ret)
- goto err2;
- ret = gpio_direction_input(colibri_pcmcia_gpio.ready_gpio);
- if (ret)
- goto err3;
- ret = gpio_request(colibri_pcmcia_gpio.bvd1_gpio, "BVD1");
- if (ret)
- goto err3;
- ret = gpio_direction_input(colibri_pcmcia_gpio.bvd1_gpio);
- if (ret)
- goto err4;
+ colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpios[DETECT].gpio);
+ skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpios[READY].gpio);
- ret = gpio_request(colibri_pcmcia_gpio.bvd2_gpio, "BVD2");
- if (ret)
- goto err4;
- ret = gpio_direction_input(colibri_pcmcia_gpio.bvd2_gpio);
- if (ret)
- goto err5;
-
- ret = gpio_request(colibri_pcmcia_gpio.ppen_gpio, "PPEN");
- if (ret)
- goto err5;
- ret = gpio_direction_output(colibri_pcmcia_gpio.ppen_gpio, 0);
- if (ret)
- goto err6;
-
- ret = gpio_request(colibri_pcmcia_gpio.reset_gpio, "RESET");
- if (ret)
- goto err6;
- ret = gpio_direction_output(colibri_pcmcia_gpio.reset_gpio, 1);
+ ret = soc_pcmcia_request_irqs(skt, colibri_irqs,
+ ARRAY_SIZE(colibri_irqs));
if (ret)
- goto err7;
-
- colibri_irqs[0].irq = gpio_to_irq(colibri_pcmcia_gpio.detect_gpio);
- skt->socket.pci_irq = gpio_to_irq(colibri_pcmcia_gpio.ready_gpio);
+ goto err2;
- return soc_pcmcia_request_irqs(skt, colibri_irqs,
- ARRAY_SIZE(colibri_irqs));
+ return ret;
-err7:
- gpio_free(colibri_pcmcia_gpio.detect_gpio);
-err6:
- gpio_free(colibri_pcmcia_gpio.ready_gpio);
-err5:
- gpio_free(colibri_pcmcia_gpio.bvd1_gpio);
-err4:
- gpio_free(colibri_pcmcia_gpio.bvd2_gpio);
-err3:
- gpio_free(colibri_pcmcia_gpio.reset_gpio);
err2:
- gpio_free(colibri_pcmcia_gpio.ppen_gpio);
+ gpio_free_array(colibri_pcmcia_gpios,
+ ARRAY_SIZE(colibri_pcmcia_gpios));
err1:
return ret;
}
static void colibri_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
- gpio_free(colibri_pcmcia_gpio.detect_gpio);
- gpio_free(colibri_pcmcia_gpio.ready_gpio);
- gpio_free(colibri_pcmcia_gpio.bvd1_gpio);
- gpio_free(colibri_pcmcia_gpio.bvd2_gpio);
- gpio_free(colibri_pcmcia_gpio.reset_gpio);
- gpio_free(colibri_pcmcia_gpio.ppen_gpio);
+ gpio_free_array(colibri_pcmcia_gpios,
+ ARRAY_SIZE(colibri_pcmcia_gpios));
}
static void colibri_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
struct pcmcia_state *state)
{
- state->detect = !!gpio_get_value(colibri_pcmcia_gpio.detect_gpio);
- state->ready = !!gpio_get_value(colibri_pcmcia_gpio.ready_gpio);
- state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpio.bvd1_gpio);
- state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpio.bvd2_gpio);
+ state->detect = !!gpio_get_value(colibri_pcmcia_gpios[DETECT].gpio);
+ state->ready = !!gpio_get_value(colibri_pcmcia_gpios[READY].gpio);
+ state->bvd1 = !!gpio_get_value(colibri_pcmcia_gpios[BVD1].gpio);
+ state->bvd2 = !!gpio_get_value(colibri_pcmcia_gpios[BVD2].gpio);
state->wrprot = 0;
state->vs_3v = 1;
state->vs_Xv = 0;
@@ -145,9 +109,10 @@ static int
colibri_pcmcia_configure_socket(struct soc_pcmcia_socket *skt,
const socket_state_t *state)
{
- gpio_set_value(colibri_pcmcia_gpio.ppen_gpio,
+ gpio_set_value(colibri_pcmcia_gpios[PPEN].gpio,
!(state->Vcc == 33 && state->Vpp < 50));
- gpio_set_value(colibri_pcmcia_gpio.reset_gpio, state->flags & SS_RESET);
+ gpio_set_value(colibri_pcmcia_gpios[RESET].gpio,
+ state->flags & SS_RESET);
return 0;
}
@@ -190,20 +155,20 @@ static int __init colibri_pcmcia_init(void)
/* Colibri PXA270 */
if (machine_is_colibri()) {
- colibri_pcmcia_gpio.reset_gpio = COLIBRI270_RESET_GPIO;
- colibri_pcmcia_gpio.ppen_gpio = COLIBRI270_PPEN_GPIO;
- colibri_pcmcia_gpio.bvd1_gpio = COLIBRI270_BVD1_GPIO;
- colibri_pcmcia_gpio.bvd2_gpio = COLIBRI270_BVD2_GPIO;
- colibri_pcmcia_gpio.detect_gpio = COLIBRI270_DETECT_GPIO;
- colibri_pcmcia_gpio.ready_gpio = COLIBRI270_READY_GPIO;
+ colibri_pcmcia_gpios[RESET].gpio = COLIBRI270_RESET_GPIO;
+ colibri_pcmcia_gpios[PPEN].gpio = COLIBRI270_PPEN_GPIO;
+ colibri_pcmcia_gpios[BVD1].gpio = COLIBRI270_BVD1_GPIO;
+ colibri_pcmcia_gpios[BVD2].gpio = COLIBRI270_BVD2_GPIO;
+ colibri_pcmcia_gpios[DETECT].gpio = COLIBRI270_DETECT_GPIO;
+ colibri_pcmcia_gpios[READY].gpio = COLIBRI270_READY_GPIO;
/* Colibri PXA320 */
} else if (machine_is_colibri320()) {
- colibri_pcmcia_gpio.reset_gpio = COLIBRI320_RESET_GPIO;
- colibri_pcmcia_gpio.ppen_gpio = COLIBRI320_PPEN_GPIO;
- colibri_pcmcia_gpio.bvd1_gpio = COLIBRI320_BVD1_GPIO;
- colibri_pcmcia_gpio.bvd2_gpio = COLIBRI320_BVD2_GPIO;
- colibri_pcmcia_gpio.detect_gpio = COLIBRI320_DETECT_GPIO;
- colibri_pcmcia_gpio.ready_gpio = COLIBRI320_READY_GPIO;
+ colibri_pcmcia_gpios[RESET].gpio = COLIBRI320_RESET_GPIO;
+ colibri_pcmcia_gpios[PPEN].gpio = COLIBRI320_PPEN_GPIO;
+ colibri_pcmcia_gpios[BVD1].gpio = COLIBRI320_BVD1_GPIO;
+ colibri_pcmcia_gpios[BVD2].gpio = COLIBRI320_BVD2_GPIO;
+ colibri_pcmcia_gpios[DETECT].gpio = COLIBRI320_DETECT_GPIO;
+ colibri_pcmcia_gpios[READY].gpio = COLIBRI320_READY_GPIO;
}
ret = platform_device_add_data(colibri_pcmcia_device,
diff --git a/drivers/pcmcia/pxa2xx_palmld.c b/drivers/pcmcia/pxa2xx_palmld.c
index 6fb6f7f0672..69f73670949 100644
--- a/drivers/pcmcia/pxa2xx_palmld.c
+++ b/drivers/pcmcia/pxa2xx_palmld.c
@@ -4,7 +4,7 @@
* Driver for Palm LifeDrive PCMCIA
*
* Copyright (C) 2006 Alex Osborne <ato@meshy.org>
- * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -20,49 +20,27 @@
#include <mach/palmld.h>
#include "soc_common.h"
+static struct gpio palmld_pcmcia_gpios[] = {
+ { GPIO_NR_PALMLD_PCMCIA_POWER, GPIOF_INIT_LOW, "PCMCIA Power" },
+ { GPIO_NR_PALMLD_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
+ { GPIO_NR_PALMLD_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
+};
+
static int palmld_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
- ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_POWER, "PCMCIA PWR");
- if (ret)
- goto err1;
- ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_POWER, 0);
- if (ret)
- goto err2;
-
- ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_RESET, "PCMCIA RST");
- if (ret)
- goto err2;
- ret = gpio_direction_output(GPIO_NR_PALMLD_PCMCIA_RESET, 1);
- if (ret)
- goto err3;
-
- ret = gpio_request(GPIO_NR_PALMLD_PCMCIA_READY, "PCMCIA RDY");
- if (ret)
- goto err3;
- ret = gpio_direction_input(GPIO_NR_PALMLD_PCMCIA_READY);
- if (ret)
- goto err4;
+ ret = gpio_request_array(palmld_pcmcia_gpios,
+ ARRAY_SIZE(palmld_pcmcia_gpios));
skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMLD_PCMCIA_READY);
- return 0;
-err4:
- gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
-err3:
- gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
-err2:
- gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
-err1:
return ret;
}
static void palmld_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
- gpio_free(GPIO_NR_PALMLD_PCMCIA_READY);
- gpio_free(GPIO_NR_PALMLD_PCMCIA_RESET);
- gpio_free(GPIO_NR_PALMLD_PCMCIA_POWER);
+ gpio_free_array(palmld_pcmcia_gpios, ARRAY_SIZE(palmld_pcmcia_gpios));
}
static void palmld_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
diff --git a/drivers/pcmcia/pxa2xx_palmtc.c b/drivers/pcmcia/pxa2xx_palmtc.c
index 459a232d66b..d0ad6a76bbd 100644
--- a/drivers/pcmcia/pxa2xx_palmtc.c
+++ b/drivers/pcmcia/pxa2xx_palmtc.c
@@ -4,7 +4,7 @@
* Driver for Palm Tungsten|C PCMCIA
*
* Copyright (C) 2008 Alex Osborne <ato@meshy.org>
- * Copyright (C) 2009 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2009-2011 Marek Vasut <marek.vasut@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -21,79 +21,30 @@
#include <mach/palmtc.h>
#include "soc_common.h"
+static struct gpio palmtc_pcmcia_gpios[] = {
+ { GPIO_NR_PALMTC_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" },
+ { GPIO_NR_PALMTC_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
+ { GPIO_NR_PALMTC_PCMCIA_POWER3, GPIOF_INIT_LOW, "PCMCIA Power 3" },
+ { GPIO_NR_PALMTC_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
+ { GPIO_NR_PALMTC_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
+ { GPIO_NR_PALMTC_PCMCIA_PWRREADY, GPIOF_IN, "PCMCIA Power Ready" },
+};
+
static int palmtc_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
- ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER1, "PCMCIA PWR1");
- if (ret)
- goto err1;
- ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER1, 0);
- if (ret)
- goto err2;
-
- ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER2, "PCMCIA PWR2");
- if (ret)
- goto err2;
- ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER2, 0);
- if (ret)
- goto err3;
-
- ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_POWER3, "PCMCIA PWR3");
- if (ret)
- goto err3;
- ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_POWER3, 0);
- if (ret)
- goto err4;
-
- ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_RESET, "PCMCIA RST");
- if (ret)
- goto err4;
- ret = gpio_direction_output(GPIO_NR_PALMTC_PCMCIA_RESET, 1);
- if (ret)
- goto err5;
-
- ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_READY, "PCMCIA RDY");
- if (ret)
- goto err5;
- ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_READY);
- if (ret)
- goto err6;
-
- ret = gpio_request(GPIO_NR_PALMTC_PCMCIA_PWRREADY, "PCMCIA PWRRDY");
- if (ret)
- goto err6;
- ret = gpio_direction_input(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
- if (ret)
- goto err7;
+ ret = gpio_request_array(palmtc_pcmcia_gpios,
+ ARRAY_SIZE(palmtc_pcmcia_gpios));
skt->socket.pci_irq = IRQ_GPIO(GPIO_NR_PALMTC_PCMCIA_READY);
- return 0;
-err7:
- gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
-err6:
- gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
-err5:
- gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
-err4:
- gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
-err3:
- gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
-err2:
- gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
-err1:
return ret;
}
static void palmtc_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
- gpio_free(GPIO_NR_PALMTC_PCMCIA_PWRREADY);
- gpio_free(GPIO_NR_PALMTC_PCMCIA_READY);
- gpio_free(GPIO_NR_PALMTC_PCMCIA_RESET);
- gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER3);
- gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER2);
- gpio_free(GPIO_NR_PALMTC_PCMCIA_POWER1);
+ gpio_free_array(palmtc_pcmcia_gpios, ARRAY_SIZE(palmtc_pcmcia_gpios));
}
static void palmtc_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
diff --git a/drivers/pcmcia/pxa2xx_palmtx.c b/drivers/pcmcia/pxa2xx_palmtx.c
index b07b247a399..1a258045040 100644
--- a/drivers/pcmcia/pxa2xx_palmtx.c
+++ b/drivers/pcmcia/pxa2xx_palmtx.c
@@ -3,7 +3,7 @@
*
* Driver for Palm T|X PCMCIA
*
- * Copyright (C) 2007-2008 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2007-2011 Marek Vasut <marek.vasut@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -13,67 +13,34 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/gpio.h>
#include <asm/mach-types.h>
-
-#include <mach/gpio.h>
#include <mach/palmtx.h>
-
#include "soc_common.h"
+static struct gpio palmtx_pcmcia_gpios[] = {
+ { GPIO_NR_PALMTX_PCMCIA_POWER1, GPIOF_INIT_LOW, "PCMCIA Power 1" },
+ { GPIO_NR_PALMTX_PCMCIA_POWER2, GPIOF_INIT_LOW, "PCMCIA Power 2" },
+ { GPIO_NR_PALMTX_PCMCIA_RESET, GPIOF_INIT_HIGH,"PCMCIA Reset" },
+ { GPIO_NR_PALMTX_PCMCIA_READY, GPIOF_IN, "PCMCIA Ready" },
+};
+
static int palmtx_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
{
int ret;
- ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER1, "PCMCIA PWR1");
- if (ret)
- goto err1;
- ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER1, 0);
- if (ret)
- goto err2;
-
- ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_POWER2, "PCMCIA PWR2");
- if (ret)
- goto err2;
- ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_POWER2, 0);
- if (ret)
- goto err3;
-
- ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_RESET, "PCMCIA RST");
- if (ret)
- goto err3;
- ret = gpio_direction_output(GPIO_NR_PALMTX_PCMCIA_RESET, 1);
- if (ret)
- goto err4;
-
- ret = gpio_request(GPIO_NR_PALMTX_PCMCIA_READY, "PCMCIA RDY");
- if (ret)
- goto err4;
- ret = gpio_direction_input(GPIO_NR_PALMTX_PCMCIA_READY);
- if (ret)
- goto err5;
+ ret = gpio_request_array(palmtx_pcmcia_gpios,
+ ARRAY_SIZE(palmtx_pcmcia_gpios));
skt->socket.pci_irq = gpio_to_irq(GPIO_NR_PALMTX_PCMCIA_READY);
- return 0;
-err5:
- gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
-err4:
- gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
-err3:
- gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
-err2:
- gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
-err1:
return ret;
}
static void palmtx_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
- gpio_free(GPIO_NR_PALMTX_PCMCIA_READY);
- gpio_free(GPIO_NR_PALMTX_PCMCIA_RESET);
- gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER2);
- gpio_free(GPIO_NR_PALMTX_PCMCIA_POWER1);
+ gpio_free_array(palmtx_pcmcia_gpios, ARRAY_SIZE(palmtx_pcmcia_gpios));
}
static void palmtx_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c
index 55627eccee8..435002dfc3c 100644
--- a/drivers/pcmcia/pxa2xx_vpac270.c
+++ b/drivers/pcmcia/pxa2xx_vpac270.c
@@ -3,8 +3,7 @@
*
* Driver for Voipac PXA270 PCMCIA and CF sockets
*
- * Copyright (C) 2010
- * Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2010-2011 Marek Vasut <marek.vasut@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -22,6 +21,19 @@
#include "soc_common.h"
+static struct gpio vpac270_pcmcia_gpios[] = {
+ { GPIO84_VPAC270_PCMCIA_CD, GPIOF_IN, "PCMCIA Card Detect" },
+ { GPIO35_VPAC270_PCMCIA_RDY, GPIOF_IN, "PCMCIA Ready" },
+ { GPIO107_VPAC270_PCMCIA_PPEN, GPIOF_INIT_LOW, "PCMCIA PPEN" },
+ { GPIO11_VPAC270_PCMCIA_RESET, GPIOF_INIT_LOW, "PCMCIA Reset" },
+};
+
+static struct gpio vpac270_cf_gpios[] = {
+ { GPIO17_VPAC270_CF_CD, GPIOF_IN, "CF Card Detect" },
+ { GPIO12_VPAC270_CF_RDY, GPIOF_IN, "CF Ready" },
+ { GPIO16_VPAC270_CF_RESET, GPIOF_INIT_LOW, "CF Reset" },
+};
+
static struct pcmcia_irqs cd_irqs[] = {
{
.sock = 0,
@@ -40,96 +52,34 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
int ret;
if (skt->nr == 0) {
- ret = gpio_request(GPIO84_VPAC270_PCMCIA_CD, "PCMCIA CD");
- if (ret)
- goto err1;
- ret = gpio_direction_input(GPIO84_VPAC270_PCMCIA_CD);
- if (ret)
- goto err2;
-
- ret = gpio_request(GPIO35_VPAC270_PCMCIA_RDY, "PCMCIA RDY");
- if (ret)
- goto err2;
- ret = gpio_direction_input(GPIO35_VPAC270_PCMCIA_RDY);
- if (ret)
- goto err3;
-
- ret = gpio_request(GPIO107_VPAC270_PCMCIA_PPEN, "PCMCIA PPEN");
- if (ret)
- goto err3;
- ret = gpio_direction_output(GPIO107_VPAC270_PCMCIA_PPEN, 0);
- if (ret)
- goto err4;
-
- ret = gpio_request(GPIO11_VPAC270_PCMCIA_RESET, "PCMCIA RESET");
- if (ret)
- goto err4;
- ret = gpio_direction_output(GPIO11_VPAC270_PCMCIA_RESET, 0);
- if (ret)
- goto err5;
+ ret = gpio_request_array(vpac270_pcmcia_gpios,
+ ARRAY_SIZE(vpac270_pcmcia_gpios));
skt->socket.pci_irq = gpio_to_irq(GPIO35_VPAC270_PCMCIA_RDY);
- return soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
-
-err5:
- gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
-err4:
- gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
-err3:
- gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
-err2:
- gpio_free(GPIO84_VPAC270_PCMCIA_CD);
-err1:
- return ret;
-
+ if (!ret)
+ ret = soc_pcmcia_request_irqs(skt, &cd_irqs[0], 1);
} else {
- ret = gpio_request(GPIO17_VPAC270_CF_CD, "CF CD");
- if (ret)
- goto err6;
- ret = gpio_direction_input(GPIO17_VPAC270_CF_CD);
- if (ret)
- goto err7;
-
- ret = gpio_request(GPIO12_VPAC270_CF_RDY, "CF RDY");
- if (ret)
- goto err7;
- ret = gpio_direction_input(GPIO12_VPAC270_CF_RDY);
- if (ret)
- goto err8;
-
- ret = gpio_request(GPIO16_VPAC270_CF_RESET, "CF RESET");
- if (ret)
- goto err8;
- ret = gpio_direction_output(GPIO16_VPAC270_CF_RESET, 0);
- if (ret)
- goto err9;
+ ret = gpio_request_array(vpac270_cf_gpios,
+ ARRAY_SIZE(vpac270_cf_gpios));
skt->socket.pci_irq = gpio_to_irq(GPIO12_VPAC270_CF_RDY);
- return soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
-
-err9:
- gpio_free(GPIO16_VPAC270_CF_RESET);
-err8:
- gpio_free(GPIO12_VPAC270_CF_RDY);
-err7:
- gpio_free(GPIO17_VPAC270_CF_CD);
-err6:
- return ret;
-
+ if (!ret)
+ ret = soc_pcmcia_request_irqs(skt, &cd_irqs[1], 1);
}
+
+ return ret;
}
static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt)
{
- gpio_free(GPIO11_VPAC270_PCMCIA_RESET);
- gpio_free(GPIO107_VPAC270_PCMCIA_PPEN);
- gpio_free(GPIO35_VPAC270_PCMCIA_RDY);
- gpio_free(GPIO84_VPAC270_PCMCIA_CD);
- gpio_free(GPIO16_VPAC270_CF_RESET);
- gpio_free(GPIO12_VPAC270_CF_RDY);
- gpio_free(GPIO17_VPAC270_CF_CD);
+ if (skt->nr == 0)
+ gpio_request_array(vpac270_pcmcia_gpios,
+ ARRAY_SIZE(vpac270_pcmcia_gpios));
+ else
+ gpio_request_array(vpac270_cf_gpios,
+ ARRAY_SIZE(vpac270_cf_gpios));
}
static void vpac270_pcmcia_socket_state(struct soc_pcmcia_socket *skt,
diff --git a/drivers/pcmcia/sa1100_nanoengine.c b/drivers/pcmcia/sa1100_nanoengine.c
index 3d2652e2f5a..93b9c9ba57c 100644
--- a/drivers/pcmcia/sa1100_nanoengine.c
+++ b/drivers/pcmcia/sa1100_nanoengine.c
@@ -86,7 +86,7 @@ static int nanoengine_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
GPDR &= ~nano_skts[i].input_pins;
GPDR |= nano_skts[i].output_pins;
GPCR = nano_skts[i].clear_outputs;
- set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(nano_skts[i].transition_pins, IRQ_TYPE_EDGE_BOTH);
skt->socket.pci_irq = nano_skts[i].pci_irq;
return soc_pcmcia_request_irqs(skt,
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index 5a9a392eacd..768f9572a8c 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -155,11 +155,11 @@ static int soc_common_pcmcia_config_skt(
*/
if (skt->irq_state != 1 && state->io_irq) {
skt->irq_state = 1;
- set_irq_type(skt->socket.pci_irq,
- IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(skt->socket.pci_irq,
+ IRQ_TYPE_EDGE_FALLING);
} else if (skt->irq_state == 1 && state->io_irq == 0) {
skt->irq_state = 0;
- set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
+ irq_set_irq_type(skt->socket.pci_irq, IRQ_TYPE_NONE);
}
skt->cs_state = *state;
@@ -537,7 +537,7 @@ int soc_pcmcia_request_irqs(struct soc_pcmcia_socket *skt,
IRQF_DISABLED, irqs[i].str, skt);
if (res)
break;
- set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
+ irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
}
if (res) {
@@ -570,7 +570,7 @@ void soc_pcmcia_disable_irqs(struct soc_pcmcia_socket *skt,
for (i = 0; i < nr; i++)
if (irqs[i].sock == skt->nr)
- set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
+ irq_set_irq_type(irqs[i].irq, IRQ_TYPE_NONE);
}
EXPORT_SYMBOL(soc_pcmcia_disable_irqs);
@@ -581,8 +581,8 @@ void soc_pcmcia_enable_irqs(struct soc_pcmcia_socket *skt,
for (i = 0; i < nr; i++)
if (irqs[i].sock == skt->nr) {
- set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
- set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(irqs[i].irq, IRQ_TYPE_EDGE_BOTH);
}
}
EXPORT_SYMBOL(soc_pcmcia_enable_irqs);
diff --git a/drivers/pcmcia/xxs1500_ss.c b/drivers/pcmcia/xxs1500_ss.c
index 3b67a1b6a19..379f4218857 100644
--- a/drivers/pcmcia/xxs1500_ss.c
+++ b/drivers/pcmcia/xxs1500_ss.c
@@ -274,7 +274,7 @@ static int __devinit xxs1500_pcmcia_probe(struct platform_device *pdev)
* edge detector.
*/
irq = gpio_to_irq(GPIO_CDA);
- set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
ret = request_irq(irq, cdirq, 0, "pcmcia_carddetect", sock);
if (ret) {
dev_err(&pdev->dev, "cannot setup cd irq\n");
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig
index 222dfb737b1..2ee442c2a5d 100644
--- a/drivers/platform/x86/Kconfig
+++ b/drivers/platform/x86/Kconfig
@@ -101,6 +101,19 @@ config DELL_WMI
To compile this driver as a module, choose M here: the module will
be called dell-wmi.
+config DELL_WMI_AIO
+ tristate "WMI Hotkeys for Dell All-In-One series"
+ depends on ACPI_WMI
+ depends on INPUT
+ select INPUT_SPARSEKMAP
+ ---help---
+ Say Y here if you want to support WMI-based hotkeys on Dell
+ All-In-One machines.
+
+ To compile this driver as a module, choose M here: the module will
+ be called dell-wmi.
+
+
config FUJITSU_LAPTOP
tristate "Fujitsu Laptop Extras"
depends on ACPI
@@ -438,23 +451,53 @@ config EEEPC_LAPTOP
Bluetooth, backlight and allows powering on/off some other
devices.
- If you have an Eee PC laptop, say Y or M here.
+ If you have an Eee PC laptop, say Y or M here. If this driver
+ doesn't work on your Eee PC, try eeepc-wmi instead.
-config EEEPC_WMI
- tristate "Eee PC WMI Hotkey Driver (EXPERIMENTAL)"
+config ASUS_WMI
+ tristate "ASUS WMI Driver (EXPERIMENTAL)"
depends on ACPI_WMI
depends on INPUT
+ depends on HWMON
depends on EXPERIMENTAL
depends on BACKLIGHT_CLASS_DEVICE
depends on RFKILL || RFKILL = n
+ depends on HOTPLUG_PCI
select INPUT_SPARSEKMAP
select LEDS_CLASS
select NEW_LEDS
---help---
- Say Y here if you want to support WMI-based hotkeys on Eee PC laptops.
+ Say Y here if you have a WMI aware Asus laptop (like Eee PCs or new
+ Asus Notebooks).
To compile this driver as a module, choose M here: the module will
- be called eeepc-wmi.
+ be called asus-wmi.
+
+config ASUS_NB_WMI
+ tristate "Asus Notebook WMI Driver (EXPERIMENTAL)"
+ depends on ASUS_WMI
+ ---help---
+ This is a driver for newer Asus notebooks. It adds extra features
+ like wireless radio and bluetooth control, leds, hotkeys, backlight...
+
+ For more informations, see
+ <file:Documentation/ABI/testing/sysfs-platform-asus-wmi>
+
+ If you have an ACPI-WMI compatible Asus Notebook, say Y or M
+ here.
+
+config EEEPC_WMI
+ tristate "Eee PC WMI Driver (EXPERIMENTAL)"
+ depends on ASUS_WMI
+ ---help---
+ This is a driver for newer Eee PC laptops. It adds extra features
+ like wireless radio and bluetooth control, leds, hotkeys, backlight...
+
+ For more informations, see
+ <file:Documentation/ABI/testing/sysfs-platform-asus-wmi>
+
+ If you have an ACPI-WMI compatible Eee PC laptop (>= 1000), say Y or M
+ here.
config ACPI_WMI
tristate "WMI"
@@ -616,6 +659,21 @@ config GPIO_INTEL_PMIC
Say Y here to support GPIO via the SCU IPC interface
on Intel MID platforms.
+config INTEL_MID_POWER_BUTTON
+ tristate "power button driver for Intel MID platforms"
+ depends on INTEL_SCU_IPC && INPUT
+ help
+ This driver handles the power button on the Intel MID platforms.
+
+ If unsure, say N.
+
+config INTEL_MFLD_THERMAL
+ tristate "Thermal driver for Intel Medfield platform"
+ depends on INTEL_SCU_IPC && THERMAL
+ help
+ Say Y here to enable thermal driver support for the Intel Medfield
+ platform.
+
config RAR_REGISTER
bool "Restricted Access Region Register Driver"
depends on PCI && X86_MRST
@@ -672,4 +730,26 @@ config XO1_RFKILL
Support for enabling/disabling the WLAN interface on the OLPC XO-1
laptop.
+config XO15_EBOOK
+ tristate "OLPC XO-1.5 ebook switch"
+ depends on ACPI && INPUT
+ ---help---
+ Support for the ebook switch on the OLPC XO-1.5 laptop.
+
+ This switch is triggered as the screen is rotated and folded down to
+ convert the device into ebook form.
+
+config SAMSUNG_LAPTOP
+ tristate "Samsung Laptop driver"
+ depends on RFKILL && BACKLIGHT_CLASS_DEVICE && X86
+ ---help---
+ This module implements a driver for a wide range of different
+ Samsung laptops. It offers control over the different
+ function keys, wireless LED, LCD backlight level, and
+ sometimes provides a "performance_control" sysfs file to allow
+ the performance level of the laptop to be changed.
+
+ To compile this driver as a module, choose M here: the module
+ will be called samsung-laptop.
+
endif # X86_PLATFORM_DEVICES
diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile
index 299aefb3e74..029e8861d08 100644
--- a/drivers/platform/x86/Makefile
+++ b/drivers/platform/x86/Makefile
@@ -3,6 +3,8 @@
# x86 Platform-Specific Drivers
#
obj-$(CONFIG_ASUS_LAPTOP) += asus-laptop.o
+obj-$(CONFIG_ASUS_WMI) += asus-wmi.o
+obj-$(CONFIG_ASUS_NB_WMI) += asus-nb-wmi.o
obj-$(CONFIG_EEEPC_LAPTOP) += eeepc-laptop.o
obj-$(CONFIG_EEEPC_WMI) += eeepc-wmi.o
obj-$(CONFIG_MSI_LAPTOP) += msi-laptop.o
@@ -10,6 +12,7 @@ obj-$(CONFIG_ACPI_CMPC) += classmate-laptop.o
obj-$(CONFIG_COMPAL_LAPTOP) += compal-laptop.o
obj-$(CONFIG_DELL_LAPTOP) += dell-laptop.o
obj-$(CONFIG_DELL_WMI) += dell-wmi.o
+obj-$(CONFIG_DELL_WMI_AIO) += dell-wmi-aio.o
obj-$(CONFIG_ACER_WMI) += acer-wmi.o
obj-$(CONFIG_ACERHDF) += acerhdf.o
obj-$(CONFIG_HP_ACCEL) += hp_accel.o
@@ -29,9 +32,13 @@ obj-$(CONFIG_TOPSTAR_LAPTOP) += topstar-laptop.o
obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o
obj-$(CONFIG_TOSHIBA_BT_RFKILL) += toshiba_bluetooth.o
obj-$(CONFIG_INTEL_SCU_IPC) += intel_scu_ipc.o
-obj-$(CONFIG_INTEL_SCU_IPC_UTIL)+= intel_scu_ipcutil.o
+obj-$(CONFIG_INTEL_SCU_IPC_UTIL) += intel_scu_ipcutil.o
+obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
obj-$(CONFIG_RAR_REGISTER) += intel_rar_register.o
obj-$(CONFIG_INTEL_IPS) += intel_ips.o
obj-$(CONFIG_GPIO_INTEL_PMIC) += intel_pmic_gpio.o
obj-$(CONFIG_XO1_RFKILL) += xo1-rfkill.o
+obj-$(CONFIG_XO15_EBOOK) += xo15-ebook.o
obj-$(CONFIG_IBM_RTL) += ibm_rtl.o
+obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop.o
+obj-$(CONFIG_INTEL_MFLD_THERMAL) += intel_mid_thermal.o
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c
index c9784705f6a..5ea6c3477d1 100644
--- a/drivers/platform/x86/acer-wmi.c
+++ b/drivers/platform/x86/acer-wmi.c
@@ -22,6 +22,8 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
@@ -46,12 +48,6 @@ MODULE_AUTHOR("Carlos Corbacho");
MODULE_DESCRIPTION("Acer Laptop WMI Extras Driver");
MODULE_LICENSE("GPL");
-#define ACER_LOGPREFIX "acer-wmi: "
-#define ACER_ERR KERN_ERR ACER_LOGPREFIX
-#define ACER_NOTICE KERN_NOTICE ACER_LOGPREFIX
-#define ACER_INFO KERN_INFO ACER_LOGPREFIX
-#define ACER_WARNING KERN_WARNING ACER_LOGPREFIX
-
/*
* Magic Number
* Meaning is unknown - this number is required for writing to ACPI for AMW0
@@ -84,7 +80,7 @@ MODULE_LICENSE("GPL");
#define AMW0_GUID1 "67C3371D-95A3-4C37-BB61-DD47B491DAAB"
#define AMW0_GUID2 "431F16ED-0C2B-444C-B267-27DEB140CF9C"
#define WMID_GUID1 "6AF4F258-B401-42FD-BE91-3D4AC2D7C0D3"
-#define WMID_GUID2 "95764E09-FB56-4e83-B31A-37761F60994A"
+#define WMID_GUID2 "95764E09-FB56-4E83-B31A-37761F60994A"
#define WMID_GUID3 "61EF69EA-865C-4BC3-A502-A0DEBA0CB531"
/*
@@ -93,7 +89,7 @@ MODULE_LICENSE("GPL");
#define ACERWMID_EVENT_GUID "676AA15E-6A47-4D9F-A2CC-1E6D18D14026"
MODULE_ALIAS("wmi:67C3371D-95A3-4C37-BB61-DD47B491DAAB");
-MODULE_ALIAS("wmi:6AF4F258-B401-42fd-BE91-3D4AC2D7C0D3");
+MODULE_ALIAS("wmi:6AF4F258-B401-42Fd-BE91-3D4AC2D7C0D3");
MODULE_ALIAS("wmi:676AA15E-6A47-4D9F-A2CC-1E6D18D14026");
enum acer_wmi_event_ids {
@@ -108,7 +104,7 @@ static const struct key_entry acer_wmi_keymap[] = {
{KE_KEY, 0x23, {KEY_PROG3} }, /* P_Key */
{KE_KEY, 0x24, {KEY_PROG4} }, /* Social networking_Key */
{KE_KEY, 0x64, {KEY_SWITCHVIDEOMODE} }, /* Display Switch */
- {KE_KEY, 0x82, {KEY_F22} }, /* Touch Pad On/Off */
+ {KE_KEY, 0x82, {KEY_TOUCHPAD_TOGGLE} }, /* Touch Pad On/Off */
{KE_END, 0}
};
@@ -221,6 +217,7 @@ struct acer_debug {
static struct rfkill *wireless_rfkill;
static struct rfkill *bluetooth_rfkill;
static struct rfkill *threeg_rfkill;
+static bool rfkill_inited;
/* Each low-level interface must define at least some of the following */
struct wmi_interface {
@@ -845,7 +842,7 @@ static void type_aa_dmi_decode(const struct dmi_header *header, void *dummy)
has_type_aa = true;
type_aa = (struct hotkey_function_type_aa *) header;
- printk(ACER_INFO "Function bitmap for Communication Button: 0x%x\n",
+ pr_info("Function bitmap for Communication Button: 0x%x\n",
type_aa->commun_func_bitmap);
if (type_aa->commun_func_bitmap & ACER_WMID3_GDS_WIRELESS)
@@ -991,6 +988,7 @@ static int __devinit acer_led_init(struct device *dev)
static void acer_led_exit(void)
{
+ set_u32(LED_OFF, ACER_CAP_MAILLED);
led_classdev_unregister(&mail_led);
}
@@ -1036,7 +1034,7 @@ static int __devinit acer_backlight_init(struct device *dev)
bd = backlight_device_register("acer-wmi", dev, NULL, &acer_bl_ops,
&props);
if (IS_ERR(bd)) {
- printk(ACER_ERR "Could not register Acer backlight device\n");
+ pr_err("Could not register Acer backlight device\n");
acer_backlight_device = NULL;
return PTR_ERR(bd);
}
@@ -1083,8 +1081,7 @@ static acpi_status wmid3_get_device_status(u32 *value, u16 device)
return AE_ERROR;
}
if (obj->buffer.length != 8) {
- printk(ACER_WARNING "Unknown buffer length %d\n",
- obj->buffer.length);
+ pr_warning("Unknown buffer length %d\n", obj->buffer.length);
kfree(obj);
return AE_ERROR;
}
@@ -1093,7 +1090,7 @@ static acpi_status wmid3_get_device_status(u32 *value, u16 device)
kfree(obj);
if (return_value.error_code || return_value.ec_return_value)
- printk(ACER_WARNING "Get Device Status failed: "
+ pr_warning("Get Device Status failed: "
"0x%x - 0x%x\n", return_value.error_code,
return_value.ec_return_value);
else
@@ -1161,9 +1158,13 @@ static int acer_rfkill_set(void *data, bool blocked)
{
acpi_status status;
u32 cap = (unsigned long)data;
- status = set_u32(!blocked, cap);
- if (ACPI_FAILURE(status))
- return -ENODEV;
+
+ if (rfkill_inited) {
+ status = set_u32(!blocked, cap);
+ if (ACPI_FAILURE(status))
+ return -ENODEV;
+ }
+
return 0;
}
@@ -1187,14 +1188,16 @@ static struct rfkill *acer_rfkill_register(struct device *dev,
return ERR_PTR(-ENOMEM);
status = get_device_status(&state, cap);
- if (ACPI_SUCCESS(status))
- rfkill_init_sw_state(rfkill_dev, !state);
err = rfkill_register(rfkill_dev);
if (err) {
rfkill_destroy(rfkill_dev);
return ERR_PTR(err);
}
+
+ if (ACPI_SUCCESS(status))
+ rfkill_set_sw_state(rfkill_dev, !state);
+
return rfkill_dev;
}
@@ -1229,14 +1232,19 @@ static int acer_rfkill_init(struct device *dev)
}
}
- schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ));
+ rfkill_inited = true;
+
+ if (ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID))
+ schedule_delayed_work(&acer_rfkill_work,
+ round_jiffies_relative(HZ));
return 0;
}
static void acer_rfkill_exit(void)
{
- cancel_delayed_work_sync(&acer_rfkill_work);
+ if (ec_raw_mode || !wmi_has_guid(ACERWMID_EVENT_GUID))
+ cancel_delayed_work_sync(&acer_rfkill_work);
rfkill_unregister(wireless_rfkill);
rfkill_destroy(wireless_rfkill);
@@ -1309,7 +1317,7 @@ static void acer_wmi_notify(u32 value, void *context)
status = wmi_get_event_data(value, &response);
if (status != AE_OK) {
- printk(ACER_WARNING "bad event status 0x%x\n", status);
+ pr_warning("bad event status 0x%x\n", status);
return;
}
@@ -1318,14 +1326,12 @@ static void acer_wmi_notify(u32 value, void *context)
if (!obj)
return;
if (obj->type != ACPI_TYPE_BUFFER) {
- printk(ACER_WARNING "Unknown response received %d\n",
- obj->type);
+ pr_warning("Unknown response received %d\n", obj->type);
kfree(obj);
return;
}
if (obj->buffer.length != 8) {
- printk(ACER_WARNING "Unknown buffer length %d\n",
- obj->buffer.length);
+ pr_warning("Unknown buffer length %d\n", obj->buffer.length);
kfree(obj);
return;
}
@@ -1335,13 +1341,26 @@ static void acer_wmi_notify(u32 value, void *context)
switch (return_value.function) {
case WMID_HOTKEY_EVENT:
+ if (return_value.device_state) {
+ u16 device_state = return_value.device_state;
+ pr_debug("deivces states: 0x%x\n", device_state);
+ if (has_cap(ACER_CAP_WIRELESS))
+ rfkill_set_sw_state(wireless_rfkill,
+ !(device_state & ACER_WMID3_GDS_WIRELESS));
+ if (has_cap(ACER_CAP_BLUETOOTH))
+ rfkill_set_sw_state(bluetooth_rfkill,
+ !(device_state & ACER_WMID3_GDS_BLUETOOTH));
+ if (has_cap(ACER_CAP_THREEG))
+ rfkill_set_sw_state(threeg_rfkill,
+ !(device_state & ACER_WMID3_GDS_THREEG));
+ }
if (!sparse_keymap_report_event(acer_wmi_input_dev,
return_value.key_num, 1, true))
- printk(ACER_WARNING "Unknown key number - 0x%x\n",
+ pr_warning("Unknown key number - 0x%x\n",
return_value.key_num);
break;
default:
- printk(ACER_WARNING "Unknown function number - %d - %d\n",
+ pr_warning("Unknown function number - %d - %d\n",
return_value.function, return_value.key_num);
break;
}
@@ -1370,8 +1389,7 @@ wmid3_set_lm_mode(struct lm_input_params *params,
return AE_ERROR;
}
if (obj->buffer.length != 4) {
- printk(ACER_WARNING "Unknown buffer length %d\n",
- obj->buffer.length);
+ pr_warning("Unknown buffer length %d\n", obj->buffer.length);
kfree(obj);
return AE_ERROR;
}
@@ -1396,11 +1414,11 @@ static int acer_wmi_enable_ec_raw(void)
status = wmid3_set_lm_mode(&params, &return_value);
if (return_value.error_code || return_value.ec_return_value)
- printk(ACER_WARNING "Enabling EC raw mode failed: "
+ pr_warning("Enabling EC raw mode failed: "
"0x%x - 0x%x\n", return_value.error_code,
return_value.ec_return_value);
else
- printk(ACER_INFO "Enabled EC raw mode");
+ pr_info("Enabled EC raw mode");
return status;
}
@@ -1419,7 +1437,7 @@ static int acer_wmi_enable_lm(void)
status = wmid3_set_lm_mode(&params, &return_value);
if (return_value.error_code || return_value.ec_return_value)
- printk(ACER_WARNING "Enabling Launch Manager failed: "
+ pr_warning("Enabling Launch Manager failed: "
"0x%x - 0x%x\n", return_value.error_code,
return_value.ec_return_value);
@@ -1553,6 +1571,7 @@ pm_message_t state)
if (has_cap(ACER_CAP_MAILLED)) {
get_u32(&value, ACER_CAP_MAILLED);
+ set_u32(LED_OFF, ACER_CAP_MAILLED);
data->mailled = value;
}
@@ -1580,6 +1599,17 @@ static int acer_platform_resume(struct platform_device *device)
return 0;
}
+static void acer_platform_shutdown(struct platform_device *device)
+{
+ struct acer_data *data = &interface->data;
+
+ if (!data)
+ return;
+
+ if (has_cap(ACER_CAP_MAILLED))
+ set_u32(LED_OFF, ACER_CAP_MAILLED);
+}
+
static struct platform_driver acer_platform_driver = {
.driver = {
.name = "acer-wmi",
@@ -1589,6 +1619,7 @@ static struct platform_driver acer_platform_driver = {
.remove = acer_platform_remove,
.suspend = acer_platform_suspend,
.resume = acer_platform_resume,
+ .shutdown = acer_platform_shutdown,
};
static struct platform_device *acer_platform_device;
@@ -1636,7 +1667,7 @@ static int create_debugfs(void)
{
interface->debug.root = debugfs_create_dir("acer-wmi", NULL);
if (!interface->debug.root) {
- printk(ACER_ERR "Failed to create debugfs directory");
+ pr_err("Failed to create debugfs directory");
return -ENOMEM;
}
@@ -1657,11 +1688,10 @@ static int __init acer_wmi_init(void)
{
int err;
- printk(ACER_INFO "Acer Laptop ACPI-WMI Extras\n");
+ pr_info("Acer Laptop ACPI-WMI Extras\n");
if (dmi_check_system(acer_blacklist)) {
- printk(ACER_INFO "Blacklisted hardware detected - "
- "not loading\n");
+ pr_info("Blacklisted hardware detected - not loading\n");
return -ENODEV;
}
@@ -1678,12 +1708,11 @@ static int __init acer_wmi_init(void)
if (wmi_has_guid(WMID_GUID2) && interface) {
if (ACPI_FAILURE(WMID_set_capabilities())) {
- printk(ACER_ERR "Unable to detect available WMID "
- "devices\n");
+ pr_err("Unable to detect available WMID devices\n");
return -ENODEV;
}
} else if (!wmi_has_guid(WMID_GUID2) && interface) {
- printk(ACER_ERR "No WMID device detection method found\n");
+ pr_err("No WMID device detection method found\n");
return -ENODEV;
}
@@ -1691,8 +1720,7 @@ static int __init acer_wmi_init(void)
interface = &AMW0_interface;
if (ACPI_FAILURE(AMW0_set_capabilities())) {
- printk(ACER_ERR "Unable to detect available AMW0 "
- "devices\n");
+ pr_err("Unable to detect available AMW0 devices\n");
return -ENODEV;
}
}
@@ -1701,8 +1729,7 @@ static int __init acer_wmi_init(void)
AMW0_find_mailled();
if (!interface) {
- printk(ACER_INFO "No or unsupported WMI interface, unable to "
- "load\n");
+ pr_err("No or unsupported WMI interface, unable to load\n");
return -ENODEV;
}
@@ -1710,22 +1737,22 @@ static int __init acer_wmi_init(void)
if (acpi_video_backlight_support() && has_cap(ACER_CAP_BRIGHTNESS)) {
interface->capability &= ~ACER_CAP_BRIGHTNESS;
- printk(ACER_INFO "Brightness must be controlled by "
+ pr_info("Brightness must be controlled by "
"generic video driver\n");
}
if (wmi_has_guid(WMID_GUID3)) {
if (ec_raw_mode) {
if (ACPI_FAILURE(acer_wmi_enable_ec_raw())) {
- printk(ACER_ERR "Cannot enable EC raw mode\n");
+ pr_err("Cannot enable EC raw mode\n");
return -ENODEV;
}
} else if (ACPI_FAILURE(acer_wmi_enable_lm())) {
- printk(ACER_ERR "Cannot enable Launch Manager mode\n");
+ pr_err("Cannot enable Launch Manager mode\n");
return -ENODEV;
}
} else if (ec_raw_mode) {
- printk(ACER_INFO "No WMID EC raw mode enable method\n");
+ pr_info("No WMID EC raw mode enable method\n");
}
if (wmi_has_guid(ACERWMID_EVENT_GUID)) {
@@ -1736,7 +1763,7 @@ static int __init acer_wmi_init(void)
err = platform_driver_register(&acer_platform_driver);
if (err) {
- printk(ACER_ERR "Unable to register platform driver.\n");
+ pr_err("Unable to register platform driver.\n");
goto error_platform_register;
}
@@ -1791,7 +1818,7 @@ static void __exit acer_wmi_exit(void)
platform_device_unregister(acer_platform_device);
platform_driver_unregister(&acer_platform_driver);
- printk(ACER_INFO "Acer Laptop WMI Extras unloaded\n");
+ pr_info("Acer Laptop WMI Extras unloaded\n");
return;
}
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 5a6f7d7575d..c53b3ff7978 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -29,7 +29,7 @@
* John Belmonte - ACPI code for Toshiba laptop was a good starting point.
* Eric Burghard - LED display support for W1N
* Josh Green - Light Sens support
- * Thomas Tuttle - His first patch for led support was very helpfull
+ * Thomas Tuttle - His first patch for led support was very helpful
* Sam Lin - GPS support
*/
@@ -50,6 +50,7 @@
#include <linux/input/sparse-keymap.h>
#include <linux/rfkill.h>
#include <linux/slab.h>
+#include <linux/dmi.h>
#include <acpi/acpi_drivers.h>
#include <acpi/acpi_bus.h>
@@ -157,46 +158,9 @@ MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot "
#define METHOD_BRIGHTNESS_SET "SPLV"
#define METHOD_BRIGHTNESS_GET "GPLV"
-/* Backlight */
-static acpi_handle lcd_switch_handle;
-static char *lcd_switch_paths[] = {
- "\\_SB.PCI0.SBRG.EC0._Q10", /* All new models */
- "\\_SB.PCI0.ISA.EC0._Q10", /* A1x */
- "\\_SB.PCI0.PX40.ECD0._Q10", /* L3C */
- "\\_SB.PCI0.PX40.EC0.Q10", /* M1A */
- "\\_SB.PCI0.LPCB.EC0._Q10", /* P30 */
- "\\_SB.PCI0.LPCB.EC0._Q0E", /* P30/P35 */
- "\\_SB.PCI0.PX40.Q10", /* S1x */
- "\\Q10"}; /* A2x, L2D, L3D, M2E */
-
/* Display */
#define METHOD_SWITCH_DISPLAY "SDSP"
-static acpi_handle display_get_handle;
-static char *display_get_paths[] = {
- /* A6B, A6K A6R A7D F3JM L4R M6R A3G M6A M6V VX-1 V6J V6V W3Z */
- "\\_SB.PCI0.P0P1.VGA.GETD",
- /* A3E A4K, A4D A4L A6J A7J A8J Z71V M9V S5A M5A z33A W1Jc W2V G1 */
- "\\_SB.PCI0.P0P2.VGA.GETD",
- /* A6V A6Q */
- "\\_SB.PCI0.P0P3.VGA.GETD",
- /* A6T, A6M */
- "\\_SB.PCI0.P0PA.VGA.GETD",
- /* L3C */
- "\\_SB.PCI0.PCI1.VGAC.NMAP",
- /* Z96F */
- "\\_SB.PCI0.VGA.GETD",
- /* A2D */
- "\\ACTD",
- /* A4G Z71A W1N W5A W5F M2N M3N M5N M6N S1N S5N */
- "\\ADVG",
- /* P30 */
- "\\DNXT",
- /* A2H D1 L2D L3D L3H L2E L5D L5C M1A M2E L4L W3V */
- "\\INFB",
- /* A3F A6F A3N A3L M6N W3N W6A */
- "\\SSTE"};
-
#define METHOD_ALS_CONTROL "ALSC" /* Z71A Z71V */
#define METHOD_ALS_LEVEL "ALSL" /* Z71A Z71V */
@@ -246,7 +210,6 @@ struct asus_laptop {
int wireless_status;
bool have_rsts;
- int lcd_state;
struct rfkill *gps_rfkill;
@@ -559,48 +522,6 @@ error:
/*
* Backlight device
*/
-static int asus_lcd_status(struct asus_laptop *asus)
-{
- return asus->lcd_state;
-}
-
-static int asus_lcd_set(struct asus_laptop *asus, int value)
-{
- int lcd = 0;
- acpi_status status = 0;
-
- lcd = !!value;
-
- if (lcd == asus_lcd_status(asus))
- return 0;
-
- if (!lcd_switch_handle)
- return -ENODEV;
-
- status = acpi_evaluate_object(lcd_switch_handle,
- NULL, NULL, NULL);
-
- if (ACPI_FAILURE(status)) {
- pr_warning("Error switching LCD\n");
- return -ENODEV;
- }
-
- asus->lcd_state = lcd;
- return 0;
-}
-
-static void lcd_blank(struct asus_laptop *asus, int blank)
-{
- struct backlight_device *bd = asus->backlight_device;
-
- asus->lcd_state = (blank == FB_BLANK_UNBLANK);
-
- if (bd) {
- bd->props.power = blank;
- backlight_update_status(bd);
- }
-}
-
static int asus_read_brightness(struct backlight_device *bd)
{
struct asus_laptop *asus = bl_get_data(bd);
@@ -628,16 +549,9 @@ static int asus_set_brightness(struct backlight_device *bd, int value)
static int update_bl_status(struct backlight_device *bd)
{
- struct asus_laptop *asus = bl_get_data(bd);
- int rv;
int value = bd->props.brightness;
- rv = asus_set_brightness(bd, value);
- if (rv)
- return rv;
-
- value = (bd->props.power == FB_BLANK_UNBLANK) ? 1 : 0;
- return asus_lcd_set(asus, value);
+ return asus_set_brightness(bd, value);
}
static const struct backlight_ops asusbl_ops = {
@@ -661,8 +575,7 @@ static int asus_backlight_init(struct asus_laptop *asus)
struct backlight_properties props;
if (acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_GET, NULL) ||
- acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL) ||
- !lcd_switch_handle)
+ acpi_check_handle(asus->handle, METHOD_BRIGHTNESS_SET, NULL))
return 0;
memset(&props, 0, sizeof(struct backlight_properties));
@@ -971,41 +884,6 @@ static void asus_set_display(struct asus_laptop *asus, int value)
return;
}
-static int read_display(struct asus_laptop *asus)
-{
- unsigned long long value = 0;
- acpi_status rv = AE_OK;
-
- /*
- * In most of the case, we know how to set the display, but sometime
- * we can't read it
- */
- if (display_get_handle) {
- rv = acpi_evaluate_integer(display_get_handle, NULL,
- NULL, &value);
- if (ACPI_FAILURE(rv))
- pr_warning("Error reading display status\n");
- }
-
- value &= 0x0F; /* needed for some models, shouldn't hurt others */
-
- return value;
-}
-
-/*
- * Now, *this* one could be more user-friendly, but so far, no-one has
- * complained. The significance of bits is the same as in store_disp()
- */
-static ssize_t show_disp(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct asus_laptop *asus = dev_get_drvdata(dev);
-
- if (!display_get_handle)
- return -ENODEV;
- return sprintf(buf, "%d\n", read_display(asus));
-}
-
/*
* Experimental support for display switching. As of now: 1 should activate
* the LCD output, 2 should do for CRT, 4 for TV-Out and 8 for DVI.
@@ -1247,15 +1125,6 @@ static void asus_acpi_notify(struct acpi_device *device, u32 event)
struct asus_laptop *asus = acpi_driver_data(device);
u16 count;
- /*
- * We need to tell the backlight device when the backlight power is
- * switched
- */
- if (event == ATKD_LCD_ON)
- lcd_blank(asus, FB_BLANK_UNBLANK);
- else if (event == ATKD_LCD_OFF)
- lcd_blank(asus, FB_BLANK_POWERDOWN);
-
/* TODO Find a better way to handle events count. */
count = asus->event_count[event % 128]++;
acpi_bus_generate_proc_event(asus->device, event, count);
@@ -1282,7 +1151,7 @@ static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR,
show_bluetooth, store_bluetooth);
static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax);
static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan);
-static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp);
+static DEVICE_ATTR(display, S_IWUSR, NULL, store_disp);
static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd);
static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl);
static DEVICE_ATTR(ls_switch, S_IRUGO | S_IWUSR, show_lssw, store_lssw);
@@ -1393,26 +1262,6 @@ static struct platform_driver platform_driver = {
}
};
-static int asus_handle_init(char *name, acpi_handle * handle,
- char **paths, int num_paths)
-{
- int i;
- acpi_status status;
-
- for (i = 0; i < num_paths; i++) {
- status = acpi_get_handle(NULL, paths[i], handle);
- if (ACPI_SUCCESS(status))
- return 0;
- }
-
- *handle = NULL;
- return -ENODEV;
-}
-
-#define ASUS_HANDLE_INIT(object) \
- asus_handle_init(#object, &object##_handle, object##_paths, \
- ARRAY_SIZE(object##_paths))
-
/*
* This function is used to initialize the context with right values. In this
* method, we can make all the detection we want, and modify the asus_laptop
@@ -1498,10 +1347,6 @@ static int asus_laptop_get_info(struct asus_laptop *asus)
if (!acpi_check_handle(asus->handle, METHOD_WL_STATUS, NULL))
asus->have_rsts = true;
- /* Scheduled for removal */
- ASUS_HANDLE_INIT(lcd_switch);
- ASUS_HANDLE_INIT(display_get);
-
kfree(model);
return AE_OK;
@@ -1553,10 +1398,23 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus)
asus_als_level(asus, asus->light_level);
}
- asus->lcd_state = 1; /* LCD should be on when the module load */
return result;
}
+static void __devinit asus_dmi_check(void)
+{
+ const char *model;
+
+ model = dmi_get_system_info(DMI_PRODUCT_NAME);
+ if (!model)
+ return;
+
+ /* On L1400B WLED control the sound card, don't mess with it ... */
+ if (strncmp(model, "L1400B", 6) == 0) {
+ wlan_status = -1;
+ }
+}
+
static bool asus_device_present;
static int __devinit asus_acpi_add(struct acpi_device *device)
@@ -1575,6 +1433,8 @@ static int __devinit asus_acpi_add(struct acpi_device *device)
device->driver_data = asus;
asus->device = device;
+ asus_dmi_check();
+
result = asus_acpi_init(asus);
if (result)
goto fail_platform;
diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
new file mode 100644
index 00000000000..0580d99b079
--- /dev/null
+++ b/drivers/platform/x86/asus-nb-wmi.c
@@ -0,0 +1,98 @@
+/*
+ * Asus Notebooks WMI hotkey driver
+ *
+ * Copyright(C) 2010 Corentin Chary <corentin.chary@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.
+ *
+ * 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
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+
+#include "asus-wmi.h"
+
+#define ASUS_NB_WMI_FILE "asus-nb-wmi"
+
+MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>");
+MODULE_DESCRIPTION("Asus Notebooks WMI Hotkey Driver");
+MODULE_LICENSE("GPL");
+
+#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C"
+
+MODULE_ALIAS("wmi:"ASUS_NB_WMI_EVENT_GUID);
+
+static const struct key_entry asus_nb_wmi_keymap[] = {
+ { KE_KEY, 0x30, { KEY_VOLUMEUP } },
+ { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
+ { KE_KEY, 0x32, { KEY_MUTE } },
+ { KE_KEY, 0x33, { KEY_DISPLAYTOGGLE } }, /* LCD on */
+ { KE_KEY, 0x34, { KEY_DISPLAY_OFF } }, /* LCD off */
+ { KE_KEY, 0x40, { KEY_PREVIOUSSONG } },
+ { KE_KEY, 0x41, { KEY_NEXTSONG } },
+ { KE_KEY, 0x43, { KEY_STOPCD } },
+ { KE_KEY, 0x45, { KEY_PLAYPAUSE } },
+ { KE_KEY, 0x4c, { KEY_MEDIA } },
+ { KE_KEY, 0x50, { KEY_EMAIL } },
+ { KE_KEY, 0x51, { KEY_WWW } },
+ { KE_KEY, 0x55, { KEY_CALC } },
+ { KE_KEY, 0x5C, { KEY_F15 } }, /* Power Gear key */
+ { KE_KEY, 0x5D, { KEY_WLAN } },
+ { KE_KEY, 0x5E, { KEY_WLAN } },
+ { KE_KEY, 0x5F, { KEY_WLAN } },
+ { KE_KEY, 0x60, { KEY_SWITCHVIDEOMODE } },
+ { KE_KEY, 0x61, { KEY_SWITCHVIDEOMODE } },
+ { KE_KEY, 0x62, { KEY_SWITCHVIDEOMODE } },
+ { KE_KEY, 0x63, { KEY_SWITCHVIDEOMODE } },
+ { KE_KEY, 0x6B, { KEY_TOUCHPAD_TOGGLE } },
+ { KE_KEY, 0x7E, { KEY_BLUETOOTH } },
+ { KE_KEY, 0x7D, { KEY_BLUETOOTH } },
+ { KE_KEY, 0x82, { KEY_CAMERA } },
+ { KE_KEY, 0x88, { KEY_RFKILL } },
+ { KE_KEY, 0x8A, { KEY_PROG1 } },
+ { KE_KEY, 0x95, { KEY_MEDIA } },
+ { KE_KEY, 0x99, { KEY_PHONE } },
+ { KE_KEY, 0xb5, { KEY_CALC } },
+ { KE_KEY, 0xc4, { KEY_KBDILLUMUP } },
+ { KE_KEY, 0xc5, { KEY_KBDILLUMDOWN } },
+ { KE_END, 0},
+};
+
+static struct asus_wmi_driver asus_nb_wmi_driver = {
+ .name = ASUS_NB_WMI_FILE,
+ .owner = THIS_MODULE,
+ .event_guid = ASUS_NB_WMI_EVENT_GUID,
+ .keymap = asus_nb_wmi_keymap,
+ .input_name = "Asus WMI hotkeys",
+ .input_phys = ASUS_NB_WMI_FILE "/input0",
+};
+
+
+static int __init asus_nb_wmi_init(void)
+{
+ return asus_wmi_register_driver(&asus_nb_wmi_driver);
+}
+
+static void __exit asus_nb_wmi_exit(void)
+{
+ asus_wmi_unregister_driver(&asus_nb_wmi_driver);
+}
+
+module_init(asus_nb_wmi_init);
+module_exit(asus_nb_wmi_exit);
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c
new file mode 100644
index 00000000000..efc776cb0c6
--- /dev/null
+++ b/drivers/platform/x86/asus-wmi.c
@@ -0,0 +1,1656 @@
+/*
+ * Asus PC WMI hotkey driver
+ *
+ * Copyright(C) 2010 Intel Corporation.
+ * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com>
+ *
+ * Portions based on wistron_btns.c:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * 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
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <linux/fb.h>
+#include <linux/backlight.h>
+#include <linux/leds.h>
+#include <linux/rfkill.h>
+#include <linux/pci.h>
+#include <linux/pci_hotplug.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/platform_device.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#include "asus-wmi.h"
+
+MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>, "
+ "Yong Wang <yong.y.wang@intel.com>");
+MODULE_DESCRIPTION("Asus Generic WMI Driver");
+MODULE_LICENSE("GPL");
+
+#define to_platform_driver(drv) \
+ (container_of((drv), struct platform_driver, driver))
+
+#define to_asus_wmi_driver(pdrv) \
+ (container_of((pdrv), struct asus_wmi_driver, platform_driver))
+
+#define ASUS_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
+
+#define NOTIFY_BRNUP_MIN 0x11
+#define NOTIFY_BRNUP_MAX 0x1f
+#define NOTIFY_BRNDOWN_MIN 0x20
+#define NOTIFY_BRNDOWN_MAX 0x2e
+
+/* WMI Methods */
+#define ASUS_WMI_METHODID_SPEC 0x43455053 /* BIOS SPECification */
+#define ASUS_WMI_METHODID_SFBD 0x44424653 /* Set First Boot Device */
+#define ASUS_WMI_METHODID_GLCD 0x44434C47 /* Get LCD status */
+#define ASUS_WMI_METHODID_GPID 0x44495047 /* Get Panel ID?? (Resol) */
+#define ASUS_WMI_METHODID_QMOD 0x444F4D51 /* Quiet MODe */
+#define ASUS_WMI_METHODID_SPLV 0x4C425053 /* Set Panel Light Value */
+#define ASUS_WMI_METHODID_SFUN 0x4E554653 /* FUNCtionalities */
+#define ASUS_WMI_METHODID_SDSP 0x50534453 /* Set DiSPlay output */
+#define ASUS_WMI_METHODID_GDSP 0x50534447 /* Get DiSPlay output */
+#define ASUS_WMI_METHODID_DEVP 0x50564544 /* DEVice Policy */
+#define ASUS_WMI_METHODID_OSVR 0x5256534F /* OS VeRsion */
+#define ASUS_WMI_METHODID_DSTS 0x53544344 /* Device STatuS */
+#define ASUS_WMI_METHODID_DSTS2 0x53545344 /* Device STatuS #2*/
+#define ASUS_WMI_METHODID_BSTS 0x53545342 /* Bios STatuS ? */
+#define ASUS_WMI_METHODID_DEVS 0x53564544 /* DEVice Set */
+#define ASUS_WMI_METHODID_CFVS 0x53564643 /* CPU Frequency Volt Set */
+#define ASUS_WMI_METHODID_KBFT 0x5446424B /* KeyBoard FilTer */
+#define ASUS_WMI_METHODID_INIT 0x54494E49 /* INITialize */
+#define ASUS_WMI_METHODID_HKEY 0x59454B48 /* Hot KEY ?? */
+
+#define ASUS_WMI_UNSUPPORTED_METHOD 0xFFFFFFFE
+
+/* Wireless */
+#define ASUS_WMI_DEVID_HW_SWITCH 0x00010001
+#define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002
+#define ASUS_WMI_DEVID_WLAN 0x00010011
+#define ASUS_WMI_DEVID_BLUETOOTH 0x00010013
+#define ASUS_WMI_DEVID_GPS 0x00010015
+#define ASUS_WMI_DEVID_WIMAX 0x00010017
+#define ASUS_WMI_DEVID_WWAN3G 0x00010019
+#define ASUS_WMI_DEVID_UWB 0x00010021
+
+/* Leds */
+/* 0x000200XX and 0x000400XX */
+
+/* Backlight and Brightness */
+#define ASUS_WMI_DEVID_BACKLIGHT 0x00050011
+#define ASUS_WMI_DEVID_BRIGHTNESS 0x00050012
+#define ASUS_WMI_DEVID_KBD_BACKLIGHT 0x00050021
+#define ASUS_WMI_DEVID_LIGHT_SENSOR 0x00050022 /* ?? */
+
+/* Misc */
+#define ASUS_WMI_DEVID_CAMERA 0x00060013
+
+/* Storage */
+#define ASUS_WMI_DEVID_CARDREADER 0x00080013
+
+/* Input */
+#define ASUS_WMI_DEVID_TOUCHPAD 0x00100011
+#define ASUS_WMI_DEVID_TOUCHPAD_LED 0x00100012
+
+/* Fan, Thermal */
+#define ASUS_WMI_DEVID_THERMAL_CTRL 0x00110011
+#define ASUS_WMI_DEVID_FAN_CTRL 0x00110012
+
+/* Power */
+#define ASUS_WMI_DEVID_PROCESSOR_STATE 0x00120012
+
+/* DSTS masks */
+#define ASUS_WMI_DSTS_STATUS_BIT 0x00000001
+#define ASUS_WMI_DSTS_UNKNOWN_BIT 0x00000002
+#define ASUS_WMI_DSTS_PRESENCE_BIT 0x00010000
+#define ASUS_WMI_DSTS_USER_BIT 0x00020000
+#define ASUS_WMI_DSTS_BIOS_BIT 0x00040000
+#define ASUS_WMI_DSTS_BRIGHTNESS_MASK 0x000000FF
+#define ASUS_WMI_DSTS_MAX_BRIGTH_MASK 0x0000FF00
+
+struct bios_args {
+ u32 arg0;
+ u32 arg1;
+} __packed;
+
+/*
+ * <platform>/ - debugfs root directory
+ * dev_id - current dev_id
+ * ctrl_param - current ctrl_param
+ * method_id - current method_id
+ * devs - call DEVS(dev_id, ctrl_param) and print result
+ * dsts - call DSTS(dev_id) and print result
+ * call - call method_id(dev_id, ctrl_param) and print result
+ */
+struct asus_wmi_debug {
+ struct dentry *root;
+ u32 method_id;
+ u32 dev_id;
+ u32 ctrl_param;
+};
+
+struct asus_rfkill {
+ struct asus_wmi *asus;
+ struct rfkill *rfkill;
+ u32 dev_id;
+};
+
+struct asus_wmi {
+ int dsts_id;
+ int spec;
+ int sfun;
+
+ struct input_dev *inputdev;
+ struct backlight_device *backlight_device;
+ struct device *hwmon_device;
+ struct platform_device *platform_device;
+
+ struct led_classdev tpd_led;
+ int tpd_led_wk;
+ struct workqueue_struct *led_workqueue;
+ struct work_struct tpd_led_work;
+
+ struct asus_rfkill wlan;
+ struct asus_rfkill bluetooth;
+ struct asus_rfkill wimax;
+ struct asus_rfkill wwan3g;
+
+ struct hotplug_slot *hotplug_slot;
+ struct mutex hotplug_lock;
+ struct mutex wmi_lock;
+ struct workqueue_struct *hotplug_workqueue;
+ struct work_struct hotplug_work;
+
+ struct asus_wmi_debug debug;
+
+ struct asus_wmi_driver *driver;
+};
+
+static int asus_wmi_input_init(struct asus_wmi *asus)
+{
+ int err;
+
+ asus->inputdev = input_allocate_device();
+ if (!asus->inputdev)
+ return -ENOMEM;
+
+ asus->inputdev->name = asus->driver->input_phys;
+ asus->inputdev->phys = asus->driver->input_name;
+ asus->inputdev->id.bustype = BUS_HOST;
+ asus->inputdev->dev.parent = &asus->platform_device->dev;
+
+ err = sparse_keymap_setup(asus->inputdev, asus->driver->keymap, NULL);
+ if (err)
+ goto err_free_dev;
+
+ err = input_register_device(asus->inputdev);
+ if (err)
+ goto err_free_keymap;
+
+ return 0;
+
+err_free_keymap:
+ sparse_keymap_free(asus->inputdev);
+err_free_dev:
+ input_free_device(asus->inputdev);
+ return err;
+}
+
+static void asus_wmi_input_exit(struct asus_wmi *asus)
+{
+ if (asus->inputdev) {
+ sparse_keymap_free(asus->inputdev);
+ input_unregister_device(asus->inputdev);
+ }
+
+ asus->inputdev = NULL;
+}
+
+static int asus_wmi_evaluate_method(u32 method_id, u32 arg0, u32 arg1,
+ u32 *retval)
+{
+ struct bios_args args = {
+ .arg0 = arg0,
+ .arg1 = arg1,
+ };
+ struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ acpi_status status;
+ union acpi_object *obj;
+ u32 tmp;
+
+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, 1, method_id,
+ &input, &output);
+
+ if (ACPI_FAILURE(status))
+ goto exit;
+
+ obj = (union acpi_object *)output.pointer;
+ if (obj && obj->type == ACPI_TYPE_INTEGER)
+ tmp = (u32) obj->integer.value;
+ else
+ tmp = 0;
+
+ if (retval)
+ *retval = tmp;
+
+ kfree(obj);
+
+exit:
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ if (tmp == ASUS_WMI_UNSUPPORTED_METHOD)
+ return -ENODEV;
+
+ return 0;
+}
+
+static int asus_wmi_get_devstate(struct asus_wmi *asus, u32 dev_id, u32 *retval)
+{
+ return asus_wmi_evaluate_method(asus->dsts_id, dev_id, 0, retval);
+}
+
+static int asus_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
+ u32 *retval)
+{
+ return asus_wmi_evaluate_method(ASUS_WMI_METHODID_DEVS, dev_id,
+ ctrl_param, retval);
+}
+
+/* Helper for special devices with magic return codes */
+static int asus_wmi_get_devstate_bits(struct asus_wmi *asus,
+ u32 dev_id, u32 mask)
+{
+ u32 retval = 0;
+ int err;
+
+ err = asus_wmi_get_devstate(asus, dev_id, &retval);
+
+ if (err < 0)
+ return err;
+
+ if (!(retval & ASUS_WMI_DSTS_PRESENCE_BIT))
+ return -ENODEV;
+
+ if (mask == ASUS_WMI_DSTS_STATUS_BIT) {
+ if (retval & ASUS_WMI_DSTS_UNKNOWN_BIT)
+ return -ENODEV;
+ }
+
+ return retval & mask;
+}
+
+static int asus_wmi_get_devstate_simple(struct asus_wmi *asus, u32 dev_id)
+{
+ return asus_wmi_get_devstate_bits(asus, dev_id,
+ ASUS_WMI_DSTS_STATUS_BIT);
+}
+
+/*
+ * LEDs
+ */
+/*
+ * These functions actually update the LED's, and are called from a
+ * workqueue. By doing this as separate work rather than when the LED
+ * subsystem asks, we avoid messing with the Asus ACPI stuff during a
+ * potentially bad time, such as a timer interrupt.
+ */
+static void tpd_led_update(struct work_struct *work)
+{
+ int ctrl_param;
+ struct asus_wmi *asus;
+
+ asus = container_of(work, struct asus_wmi, tpd_led_work);
+
+ ctrl_param = asus->tpd_led_wk;
+ asus_wmi_set_devstate(ASUS_WMI_DEVID_TOUCHPAD_LED, ctrl_param, NULL);
+}
+
+static void tpd_led_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct asus_wmi *asus;
+
+ asus = container_of(led_cdev, struct asus_wmi, tpd_led);
+
+ asus->tpd_led_wk = !!value;
+ queue_work(asus->led_workqueue, &asus->tpd_led_work);
+}
+
+static int read_tpd_led_state(struct asus_wmi *asus)
+{
+ return asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_TOUCHPAD_LED);
+}
+
+static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
+{
+ struct asus_wmi *asus;
+
+ asus = container_of(led_cdev, struct asus_wmi, tpd_led);
+
+ return read_tpd_led_state(asus);
+}
+
+static int asus_wmi_led_init(struct asus_wmi *asus)
+{
+ int rv;
+
+ if (read_tpd_led_state(asus) < 0)
+ return 0;
+
+ asus->led_workqueue = create_singlethread_workqueue("led_workqueue");
+ if (!asus->led_workqueue)
+ return -ENOMEM;
+ INIT_WORK(&asus->tpd_led_work, tpd_led_update);
+
+ asus->tpd_led.name = "asus::touchpad";
+ asus->tpd_led.brightness_set = tpd_led_set;
+ asus->tpd_led.brightness_get = tpd_led_get;
+ asus->tpd_led.max_brightness = 1;
+
+ rv = led_classdev_register(&asus->platform_device->dev, &asus->tpd_led);
+ if (rv) {
+ destroy_workqueue(asus->led_workqueue);
+ return rv;
+ }
+
+ return 0;
+}
+
+static void asus_wmi_led_exit(struct asus_wmi *asus)
+{
+ if (asus->tpd_led.dev)
+ led_classdev_unregister(&asus->tpd_led);
+ if (asus->led_workqueue)
+ destroy_workqueue(asus->led_workqueue);
+}
+
+/*
+ * PCI hotplug (for wlan rfkill)
+ */
+static bool asus_wlan_rfkill_blocked(struct asus_wmi *asus)
+{
+ int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
+
+ if (result < 0)
+ return false;
+ return !result;
+}
+
+static void asus_rfkill_hotplug(struct asus_wmi *asus)
+{
+ struct pci_dev *dev;
+ struct pci_bus *bus;
+ bool blocked;
+ bool absent;
+ u32 l;
+
+ mutex_lock(&asus->wmi_lock);
+ blocked = asus_wlan_rfkill_blocked(asus);
+ mutex_unlock(&asus->wmi_lock);
+
+ mutex_lock(&asus->hotplug_lock);
+
+ if (asus->wlan.rfkill)
+ rfkill_set_sw_state(asus->wlan.rfkill, blocked);
+
+ if (asus->hotplug_slot) {
+ bus = pci_find_bus(0, 1);
+ if (!bus) {
+ pr_warning("Unable to find PCI bus 1?\n");
+ goto out_unlock;
+ }
+
+ if (pci_bus_read_config_dword(bus, 0, PCI_VENDOR_ID, &l)) {
+ pr_err("Unable to read PCI config space?\n");
+ goto out_unlock;
+ }
+ absent = (l == 0xffffffff);
+
+ if (blocked != absent) {
+ pr_warning("BIOS says wireless lan is %s, "
+ "but the pci device is %s\n",
+ blocked ? "blocked" : "unblocked",
+ absent ? "absent" : "present");
+ pr_warning("skipped wireless hotplug as probably "
+ "inappropriate for this model\n");
+ goto out_unlock;
+ }
+
+ if (!blocked) {
+ dev = pci_get_slot(bus, 0);
+ if (dev) {
+ /* Device already present */
+ pci_dev_put(dev);
+ goto out_unlock;
+ }
+ dev = pci_scan_single_device(bus, 0);
+ if (dev) {
+ pci_bus_assign_resources(bus);
+ if (pci_bus_add_device(dev))
+ pr_err("Unable to hotplug wifi\n");
+ }
+ } else {
+ dev = pci_get_slot(bus, 0);
+ if (dev) {
+ pci_remove_bus_device(dev);
+ pci_dev_put(dev);
+ }
+ }
+ }
+
+out_unlock:
+ mutex_unlock(&asus->hotplug_lock);
+}
+
+static void asus_rfkill_notify(acpi_handle handle, u32 event, void *data)
+{
+ struct asus_wmi *asus = data;
+
+ if (event != ACPI_NOTIFY_BUS_CHECK)
+ return;
+
+ /*
+ * We can't call directly asus_rfkill_hotplug because most
+ * of the time WMBC is still being executed and not reetrant.
+ * There is currently no way to tell ACPICA that we want this
+ * method to be serialized, we schedule a asus_rfkill_hotplug
+ * call later, in a safer context.
+ */
+ queue_work(asus->hotplug_workqueue, &asus->hotplug_work);
+}
+
+static int asus_register_rfkill_notifier(struct asus_wmi *asus, char *node)
+{
+ acpi_status status;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, node, &handle);
+
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_install_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ asus_rfkill_notify, asus);
+ if (ACPI_FAILURE(status))
+ pr_warning("Failed to register notify on %s\n", node);
+ } else
+ return -ENODEV;
+
+ return 0;
+}
+
+static void asus_unregister_rfkill_notifier(struct asus_wmi *asus, char *node)
+{
+ acpi_status status = AE_OK;
+ acpi_handle handle;
+
+ status = acpi_get_handle(NULL, node, &handle);
+
+ if (ACPI_SUCCESS(status)) {
+ status = acpi_remove_notify_handler(handle,
+ ACPI_SYSTEM_NOTIFY,
+ asus_rfkill_notify);
+ if (ACPI_FAILURE(status))
+ pr_err("Error removing rfkill notify handler %s\n",
+ node);
+ }
+}
+
+static int asus_get_adapter_status(struct hotplug_slot *hotplug_slot,
+ u8 *value)
+{
+ struct asus_wmi *asus = hotplug_slot->private;
+ int result = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
+
+ if (result < 0)
+ return result;
+
+ *value = !!result;
+ return 0;
+}
+
+static void asus_cleanup_pci_hotplug(struct hotplug_slot *hotplug_slot)
+{
+ kfree(hotplug_slot->info);
+ kfree(hotplug_slot);
+}
+
+static struct hotplug_slot_ops asus_hotplug_slot_ops = {
+ .owner = THIS_MODULE,
+ .get_adapter_status = asus_get_adapter_status,
+ .get_power_status = asus_get_adapter_status,
+};
+
+static void asus_hotplug_work(struct work_struct *work)
+{
+ struct asus_wmi *asus;
+
+ asus = container_of(work, struct asus_wmi, hotplug_work);
+ asus_rfkill_hotplug(asus);
+}
+
+static int asus_setup_pci_hotplug(struct asus_wmi *asus)
+{
+ int ret = -ENOMEM;
+ struct pci_bus *bus = pci_find_bus(0, 1);
+
+ if (!bus) {
+ pr_err("Unable to find wifi PCI bus\n");
+ return -ENODEV;
+ }
+
+ asus->hotplug_workqueue =
+ create_singlethread_workqueue("hotplug_workqueue");
+ if (!asus->hotplug_workqueue)
+ goto error_workqueue;
+
+ INIT_WORK(&asus->hotplug_work, asus_hotplug_work);
+
+ asus->hotplug_slot = kzalloc(sizeof(struct hotplug_slot), GFP_KERNEL);
+ if (!asus->hotplug_slot)
+ goto error_slot;
+
+ asus->hotplug_slot->info = kzalloc(sizeof(struct hotplug_slot_info),
+ GFP_KERNEL);
+ if (!asus->hotplug_slot->info)
+ goto error_info;
+
+ asus->hotplug_slot->private = asus;
+ asus->hotplug_slot->release = &asus_cleanup_pci_hotplug;
+ asus->hotplug_slot->ops = &asus_hotplug_slot_ops;
+ asus_get_adapter_status(asus->hotplug_slot,
+ &asus->hotplug_slot->info->adapter_status);
+
+ ret = pci_hp_register(asus->hotplug_slot, bus, 0, "asus-wifi");
+ if (ret) {
+ pr_err("Unable to register hotplug slot - %d\n", ret);
+ goto error_register;
+ }
+
+ return 0;
+
+error_register:
+ kfree(asus->hotplug_slot->info);
+error_info:
+ kfree(asus->hotplug_slot);
+ asus->hotplug_slot = NULL;
+error_slot:
+ destroy_workqueue(asus->hotplug_workqueue);
+error_workqueue:
+ return ret;
+}
+
+/*
+ * Rfkill devices
+ */
+static int asus_rfkill_set(void *data, bool blocked)
+{
+ struct asus_rfkill *priv = data;
+ u32 ctrl_param = !blocked;
+
+ return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL);
+}
+
+static void asus_rfkill_query(struct rfkill *rfkill, void *data)
+{
+ struct asus_rfkill *priv = data;
+ int result;
+
+ result = asus_wmi_get_devstate_simple(priv->asus, priv->dev_id);
+
+ if (result < 0)
+ return;
+
+ rfkill_set_sw_state(priv->rfkill, !result);
+}
+
+static int asus_rfkill_wlan_set(void *data, bool blocked)
+{
+ struct asus_rfkill *priv = data;
+ struct asus_wmi *asus = priv->asus;
+ int ret;
+
+ /*
+ * This handler is enabled only if hotplug is enabled.
+ * In this case, the asus_wmi_set_devstate() will
+ * trigger a wmi notification and we need to wait
+ * this call to finish before being able to call
+ * any wmi method
+ */
+ mutex_lock(&asus->wmi_lock);
+ ret = asus_rfkill_set(data, blocked);
+ mutex_unlock(&asus->wmi_lock);
+ return ret;
+}
+
+static const struct rfkill_ops asus_rfkill_wlan_ops = {
+ .set_block = asus_rfkill_wlan_set,
+ .query = asus_rfkill_query,
+};
+
+static const struct rfkill_ops asus_rfkill_ops = {
+ .set_block = asus_rfkill_set,
+ .query = asus_rfkill_query,
+};
+
+static int asus_new_rfkill(struct asus_wmi *asus,
+ struct asus_rfkill *arfkill,
+ const char *name, enum rfkill_type type, int dev_id)
+{
+ int result = asus_wmi_get_devstate_simple(asus, dev_id);
+ struct rfkill **rfkill = &arfkill->rfkill;
+
+ if (result < 0)
+ return result;
+
+ arfkill->dev_id = dev_id;
+ arfkill->asus = asus;
+
+ if (dev_id == ASUS_WMI_DEVID_WLAN && asus->driver->hotplug_wireless)
+ *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
+ &asus_rfkill_wlan_ops, arfkill);
+ else
+ *rfkill = rfkill_alloc(name, &asus->platform_device->dev, type,
+ &asus_rfkill_ops, arfkill);
+
+ if (!*rfkill)
+ return -EINVAL;
+
+ rfkill_init_sw_state(*rfkill, !result);
+ result = rfkill_register(*rfkill);
+ if (result) {
+ rfkill_destroy(*rfkill);
+ *rfkill = NULL;
+ return result;
+ }
+ return 0;
+}
+
+static void asus_wmi_rfkill_exit(struct asus_wmi *asus)
+{
+ asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
+ asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
+ asus_unregister_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
+ if (asus->wlan.rfkill) {
+ rfkill_unregister(asus->wlan.rfkill);
+ rfkill_destroy(asus->wlan.rfkill);
+ asus->wlan.rfkill = NULL;
+ }
+ /*
+ * Refresh pci hotplug in case the rfkill state was changed after
+ * asus_unregister_rfkill_notifier()
+ */
+ asus_rfkill_hotplug(asus);
+ if (asus->hotplug_slot)
+ pci_hp_deregister(asus->hotplug_slot);
+ if (asus->hotplug_workqueue)
+ destroy_workqueue(asus->hotplug_workqueue);
+
+ if (asus->bluetooth.rfkill) {
+ rfkill_unregister(asus->bluetooth.rfkill);
+ rfkill_destroy(asus->bluetooth.rfkill);
+ asus->bluetooth.rfkill = NULL;
+ }
+ if (asus->wimax.rfkill) {
+ rfkill_unregister(asus->wimax.rfkill);
+ rfkill_destroy(asus->wimax.rfkill);
+ asus->wimax.rfkill = NULL;
+ }
+ if (asus->wwan3g.rfkill) {
+ rfkill_unregister(asus->wwan3g.rfkill);
+ rfkill_destroy(asus->wwan3g.rfkill);
+ asus->wwan3g.rfkill = NULL;
+ }
+}
+
+static int asus_wmi_rfkill_init(struct asus_wmi *asus)
+{
+ int result = 0;
+
+ mutex_init(&asus->hotplug_lock);
+ mutex_init(&asus->wmi_lock);
+
+ result = asus_new_rfkill(asus, &asus->wlan, "asus-wlan",
+ RFKILL_TYPE_WLAN, ASUS_WMI_DEVID_WLAN);
+
+ if (result && result != -ENODEV)
+ goto exit;
+
+ result = asus_new_rfkill(asus, &asus->bluetooth,
+ "asus-bluetooth", RFKILL_TYPE_BLUETOOTH,
+ ASUS_WMI_DEVID_BLUETOOTH);
+
+ if (result && result != -ENODEV)
+ goto exit;
+
+ result = asus_new_rfkill(asus, &asus->wimax, "asus-wimax",
+ RFKILL_TYPE_WIMAX, ASUS_WMI_DEVID_WIMAX);
+
+ if (result && result != -ENODEV)
+ goto exit;
+
+ result = asus_new_rfkill(asus, &asus->wwan3g, "asus-wwan3g",
+ RFKILL_TYPE_WWAN, ASUS_WMI_DEVID_WWAN3G);
+
+ if (result && result != -ENODEV)
+ goto exit;
+
+ if (!asus->driver->hotplug_wireless)
+ goto exit;
+
+ result = asus_setup_pci_hotplug(asus);
+ /*
+ * If we get -EBUSY then something else is handling the PCI hotplug -
+ * don't fail in this case
+ */
+ if (result == -EBUSY)
+ result = 0;
+
+ asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P5");
+ asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P6");
+ asus_register_rfkill_notifier(asus, "\\_SB.PCI0.P0P7");
+ /*
+ * Refresh pci hotplug in case the rfkill state was changed during
+ * setup.
+ */
+ asus_rfkill_hotplug(asus);
+
+exit:
+ if (result && result != -ENODEV)
+ asus_wmi_rfkill_exit(asus);
+
+ if (result == -ENODEV)
+ result = 0;
+
+ return result;
+}
+
+/*
+ * Hwmon device
+ */
+static ssize_t asus_hwmon_pwm1(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct asus_wmi *asus = dev_get_drvdata(dev);
+ u32 value;
+ int err;
+
+ err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_FAN_CTRL, &value);
+
+ if (err < 0)
+ return err;
+
+ value |= 0xFF;
+
+ if (value == 1) /* Low Speed */
+ value = 85;
+ else if (value == 2)
+ value = 170;
+ else if (value == 3)
+ value = 255;
+ else if (value != 0) {
+ pr_err("Unknown fan speed %#x", value);
+ value = -1;
+ }
+
+ return sprintf(buf, "%d\n", value);
+}
+
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO, asus_hwmon_pwm1, NULL, 0);
+
+static ssize_t
+show_name(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "asus\n");
+}
+static SENSOR_DEVICE_ATTR(name, S_IRUGO, show_name, NULL, 0);
+
+static struct attribute *hwmon_attributes[] = {
+ &sensor_dev_attr_pwm1.dev_attr.attr,
+ &sensor_dev_attr_name.dev_attr.attr,
+ NULL
+};
+
+static mode_t asus_hwmon_sysfs_is_visible(struct kobject *kobj,
+ struct attribute *attr, int idx)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct platform_device *pdev = to_platform_device(dev->parent);
+ struct asus_wmi *asus = platform_get_drvdata(pdev);
+ bool ok = true;
+ int dev_id = -1;
+ u32 value = ASUS_WMI_UNSUPPORTED_METHOD;
+
+ if (attr == &sensor_dev_attr_pwm1.dev_attr.attr)
+ dev_id = ASUS_WMI_DEVID_FAN_CTRL;
+
+ if (dev_id != -1) {
+ int err = asus_wmi_get_devstate(asus, dev_id, &value);
+
+ if (err < 0)
+ return err;
+ }
+
+ if (dev_id == ASUS_WMI_DEVID_FAN_CTRL) {
+ /*
+ * We need to find a better way, probably using sfun,
+ * bits or spec ...
+ * Currently we disable it if:
+ * - ASUS_WMI_UNSUPPORTED_METHOD is returned
+ * - reverved bits are non-zero
+ * - sfun and presence bit are not set
+ */
+ if (value != ASUS_WMI_UNSUPPORTED_METHOD || value & 0xFFF80000
+ || (!asus->sfun && !(value & ASUS_WMI_DSTS_PRESENCE_BIT)))
+ ok = false;
+ }
+
+ return ok ? attr->mode : 0;
+}
+
+static struct attribute_group hwmon_attribute_group = {
+ .is_visible = asus_hwmon_sysfs_is_visible,
+ .attrs = hwmon_attributes
+};
+
+static void asus_wmi_hwmon_exit(struct asus_wmi *asus)
+{
+ struct device *hwmon;
+
+ hwmon = asus->hwmon_device;
+ if (!hwmon)
+ return;
+ sysfs_remove_group(&hwmon->kobj, &hwmon_attribute_group);
+ hwmon_device_unregister(hwmon);
+ asus->hwmon_device = NULL;
+}
+
+static int asus_wmi_hwmon_init(struct asus_wmi *asus)
+{
+ struct device *hwmon;
+ int result;
+
+ hwmon = hwmon_device_register(&asus->platform_device->dev);
+ if (IS_ERR(hwmon)) {
+ pr_err("Could not register asus hwmon device\n");
+ return PTR_ERR(hwmon);
+ }
+ asus->hwmon_device = hwmon;
+ result = sysfs_create_group(&hwmon->kobj, &hwmon_attribute_group);
+ if (result)
+ asus_wmi_hwmon_exit(asus);
+ return result;
+}
+
+/*
+ * Backlight
+ */
+static int read_backlight_power(struct asus_wmi *asus)
+{
+ int ret = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_BACKLIGHT);
+
+ if (ret < 0)
+ return ret;
+
+ return ret ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN;
+}
+
+static int read_brightness_max(struct asus_wmi *asus)
+{
+ u32 retval;
+ int err;
+
+ err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
+
+ if (err < 0)
+ return err;
+
+ retval = retval & ASUS_WMI_DSTS_MAX_BRIGTH_MASK;
+ retval >>= 8;
+
+ if (!retval)
+ return -ENODEV;
+
+ return retval;
+}
+
+static int read_brightness(struct backlight_device *bd)
+{
+ struct asus_wmi *asus = bl_get_data(bd);
+ u32 retval;
+ int err;
+
+ err = asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_BRIGHTNESS, &retval);
+
+ if (err < 0)
+ return err;
+
+ return retval & ASUS_WMI_DSTS_BRIGHTNESS_MASK;
+}
+
+static int update_bl_status(struct backlight_device *bd)
+{
+ struct asus_wmi *asus = bl_get_data(bd);
+ u32 ctrl_param;
+ int power, err;
+
+ ctrl_param = bd->props.brightness;
+
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BRIGHTNESS,
+ ctrl_param, NULL);
+
+ if (err < 0)
+ return err;
+
+ power = read_backlight_power(asus);
+ if (power != -ENODEV && bd->props.power != power) {
+ ctrl_param = !!(bd->props.power == FB_BLANK_UNBLANK);
+ err = asus_wmi_set_devstate(ASUS_WMI_DEVID_BACKLIGHT,
+ ctrl_param, NULL);
+ }
+ return err;
+}
+
+static const struct backlight_ops asus_wmi_bl_ops = {
+ .get_brightness = read_brightness,
+ .update_status = update_bl_status,
+};
+
+static int asus_wmi_backlight_notify(struct asus_wmi *asus, int code)
+{
+ struct backlight_device *bd = asus->backlight_device;
+ int old = bd->props.brightness;
+ int new = old;
+
+ if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+ new = code - NOTIFY_BRNUP_MIN + 1;
+ else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
+ new = code - NOTIFY_BRNDOWN_MIN;
+
+ bd->props.brightness = new;
+ backlight_update_status(bd);
+ backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
+
+ return old;
+}
+
+static int asus_wmi_backlight_init(struct asus_wmi *asus)
+{
+ struct backlight_device *bd;
+ struct backlight_properties props;
+ int max;
+ int power;
+
+ max = read_brightness_max(asus);
+
+ if (max == -ENODEV)
+ max = 0;
+ else if (max < 0)
+ return max;
+
+ power = read_backlight_power(asus);
+
+ if (power == -ENODEV)
+ power = FB_BLANK_UNBLANK;
+ else if (power < 0)
+ return power;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = max;
+ bd = backlight_device_register(asus->driver->name,
+ &asus->platform_device->dev, asus,
+ &asus_wmi_bl_ops, &props);
+ if (IS_ERR(bd)) {
+ pr_err("Could not register backlight device\n");
+ return PTR_ERR(bd);
+ }
+
+ asus->backlight_device = bd;
+
+ bd->props.brightness = read_brightness(bd);
+ bd->props.power = power;
+ backlight_update_status(bd);
+
+ return 0;
+}
+
+static void asus_wmi_backlight_exit(struct asus_wmi *asus)
+{
+ if (asus->backlight_device)
+ backlight_device_unregister(asus->backlight_device);
+
+ asus->backlight_device = NULL;
+}
+
+static void asus_wmi_notify(u32 value, void *context)
+{
+ struct asus_wmi *asus = context;
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+ int code;
+ int orig_code;
+
+ status = wmi_get_event_data(value, &response);
+ if (status != AE_OK) {
+ pr_err("bad event status 0x%x\n", status);
+ return;
+ }
+
+ obj = (union acpi_object *)response.pointer;
+
+ if (!obj || obj->type != ACPI_TYPE_INTEGER)
+ goto exit;
+
+ code = obj->integer.value;
+ orig_code = code;
+
+ if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
+ code = NOTIFY_BRNUP_MIN;
+ else if (code >= NOTIFY_BRNDOWN_MIN &&
+ code <= NOTIFY_BRNDOWN_MAX)
+ code = NOTIFY_BRNDOWN_MIN;
+
+ if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
+ if (!acpi_video_backlight_support())
+ asus_wmi_backlight_notify(asus, orig_code);
+ } else if (!sparse_keymap_report_event(asus->inputdev, code, 1, true))
+ pr_info("Unknown key %x pressed\n", code);
+
+exit:
+ kfree(obj);
+}
+
+/*
+ * Sys helpers
+ */
+static int parse_arg(const char *buf, unsigned long count, int *val)
+{
+ if (!count)
+ return 0;
+ if (sscanf(buf, "%i", val) != 1)
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t store_sys_wmi(struct asus_wmi *asus, int devid,
+ const char *buf, size_t count)
+{
+ u32 retval;
+ int rv, err, value;
+
+ value = asus_wmi_get_devstate_simple(asus, devid);
+ if (value == -ENODEV) /* Check device presence */
+ return value;
+
+ rv = parse_arg(buf, count, &value);
+ err = asus_wmi_set_devstate(devid, value, &retval);
+
+ if (err < 0)
+ return err;
+
+ return rv;
+}
+
+static ssize_t show_sys_wmi(struct asus_wmi *asus, int devid, char *buf)
+{
+ int value = asus_wmi_get_devstate_simple(asus, devid);
+
+ if (value < 0)
+ return value;
+
+ return sprintf(buf, "%d\n", value);
+}
+
+#define ASUS_WMI_CREATE_DEVICE_ATTR(_name, _mode, _cm) \
+ static ssize_t show_##_name(struct device *dev, \
+ struct device_attribute *attr, \
+ char *buf) \
+ { \
+ struct asus_wmi *asus = dev_get_drvdata(dev); \
+ \
+ return show_sys_wmi(asus, _cm, buf); \
+ } \
+ static ssize_t store_##_name(struct device *dev, \
+ struct device_attribute *attr, \
+ const char *buf, size_t count) \
+ { \
+ struct asus_wmi *asus = dev_get_drvdata(dev); \
+ \
+ return store_sys_wmi(asus, _cm, buf, count); \
+ } \
+ static struct device_attribute dev_attr_##_name = { \
+ .attr = { \
+ .name = __stringify(_name), \
+ .mode = _mode }, \
+ .show = show_##_name, \
+ .store = store_##_name, \
+ }
+
+ASUS_WMI_CREATE_DEVICE_ATTR(touchpad, 0644, ASUS_WMI_DEVID_TOUCHPAD);
+ASUS_WMI_CREATE_DEVICE_ATTR(camera, 0644, ASUS_WMI_DEVID_CAMERA);
+ASUS_WMI_CREATE_DEVICE_ATTR(cardr, 0644, ASUS_WMI_DEVID_CARDREADER);
+
+static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int value;
+
+ if (!count || sscanf(buf, "%i", &value) != 1)
+ return -EINVAL;
+ if (value < 0 || value > 2)
+ return -EINVAL;
+
+ return asus_wmi_evaluate_method(ASUS_WMI_METHODID_CFVS, value, 0, NULL);
+}
+
+static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
+
+static struct attribute *platform_attributes[] = {
+ &dev_attr_cpufv.attr,
+ &dev_attr_camera.attr,
+ &dev_attr_cardr.attr,
+ &dev_attr_touchpad.attr,
+ NULL
+};
+
+static mode_t asus_sysfs_is_visible(struct kobject *kobj,
+ struct attribute *attr, int idx)
+{
+ struct device *dev = container_of(kobj, struct device, kobj);
+ struct platform_device *pdev = to_platform_device(dev);
+ struct asus_wmi *asus = platform_get_drvdata(pdev);
+ bool ok = true;
+ int devid = -1;
+
+ if (attr == &dev_attr_camera.attr)
+ devid = ASUS_WMI_DEVID_CAMERA;
+ else if (attr == &dev_attr_cardr.attr)
+ devid = ASUS_WMI_DEVID_CARDREADER;
+ else if (attr == &dev_attr_touchpad.attr)
+ devid = ASUS_WMI_DEVID_TOUCHPAD;
+
+ if (devid != -1)
+ ok = !(asus_wmi_get_devstate_simple(asus, devid) < 0);
+
+ return ok ? attr->mode : 0;
+}
+
+static struct attribute_group platform_attribute_group = {
+ .is_visible = asus_sysfs_is_visible,
+ .attrs = platform_attributes
+};
+
+static void asus_wmi_sysfs_exit(struct platform_device *device)
+{
+ sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
+}
+
+static int asus_wmi_sysfs_init(struct platform_device *device)
+{
+ return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
+}
+
+/*
+ * Platform device
+ */
+static int __init asus_wmi_platform_init(struct asus_wmi *asus)
+{
+ int rv;
+
+ /* INIT enable hotkeys on some models */
+ if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_INIT, 0, 0, &rv))
+ pr_info("Initialization: %#x", rv);
+
+ /* We don't know yet what to do with this version... */
+ if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SPEC, 0, 0x9, &rv)) {
+ pr_info("BIOS WMI version: %d.%d", rv >> 8, rv & 0xFF);
+ asus->spec = rv;
+ }
+
+ /*
+ * The SFUN method probably allows the original driver to get the list
+ * of features supported by a given model. For now, 0x0100 or 0x0800
+ * bit signifies that the laptop is equipped with a Wi-Fi MiniPCI card.
+ * The significance of others is yet to be found.
+ */
+ if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_SFUN, 0, 0, &rv)) {
+ pr_info("SFUN value: %#x", rv);
+ asus->sfun = rv;
+ }
+
+ /*
+ * Eee PC and Notebooks seems to have different method_id for DSTS,
+ * but it may also be related to the BIOS's SPEC.
+ * Note, on most Eeepc, there is no way to check if a method exist
+ * or note, while on notebooks, they returns 0xFFFFFFFE on failure,
+ * but once again, SPEC may probably be used for that kind of things.
+ */
+ if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS, 0, 0, NULL))
+ asus->dsts_id = ASUS_WMI_METHODID_DSTS;
+ else if (!asus_wmi_evaluate_method(ASUS_WMI_METHODID_DSTS2, 0, 0, NULL))
+ asus->dsts_id = ASUS_WMI_METHODID_DSTS2;
+
+ if (!asus->dsts_id) {
+ pr_err("Can't find DSTS");
+ return -ENODEV;
+ }
+
+ return asus_wmi_sysfs_init(asus->platform_device);
+}
+
+static void asus_wmi_platform_exit(struct asus_wmi *asus)
+{
+ asus_wmi_sysfs_exit(asus->platform_device);
+}
+
+/*
+ * debugfs
+ */
+struct asus_wmi_debugfs_node {
+ struct asus_wmi *asus;
+ char *name;
+ int (*show) (struct seq_file *m, void *data);
+};
+
+static int show_dsts(struct seq_file *m, void *data)
+{
+ struct asus_wmi *asus = m->private;
+ int err;
+ u32 retval = -1;
+
+ err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval);
+
+ if (err < 0)
+ return err;
+
+ seq_printf(m, "DSTS(%#x) = %#x\n", asus->debug.dev_id, retval);
+
+ return 0;
+}
+
+static int show_devs(struct seq_file *m, void *data)
+{
+ struct asus_wmi *asus = m->private;
+ int err;
+ u32 retval = -1;
+
+ err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param,
+ &retval);
+
+ if (err < 0)
+ return err;
+
+ seq_printf(m, "DEVS(%#x, %#x) = %#x\n", asus->debug.dev_id,
+ asus->debug.ctrl_param, retval);
+
+ return 0;
+}
+
+static int show_call(struct seq_file *m, void *data)
+{
+ struct asus_wmi *asus = m->private;
+ struct bios_args args = {
+ .arg0 = asus->debug.dev_id,
+ .arg1 = asus->debug.ctrl_param,
+ };
+ struct acpi_buffer input = { (acpi_size) sizeof(args), &args };
+ struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+
+ status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID,
+ 1, asus->debug.method_id,
+ &input, &output);
+
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ obj = (union acpi_object *)output.pointer;
+ if (obj && obj->type == ACPI_TYPE_INTEGER)
+ seq_printf(m, "%#x(%#x, %#x) = %#x\n", asus->debug.method_id,
+ asus->debug.dev_id, asus->debug.ctrl_param,
+ (u32) obj->integer.value);
+ else
+ seq_printf(m, "%#x(%#x, %#x) = t:%d\n", asus->debug.method_id,
+ asus->debug.dev_id, asus->debug.ctrl_param,
+ obj ? obj->type : -1);
+
+ kfree(obj);
+
+ return 0;
+}
+
+static struct asus_wmi_debugfs_node asus_wmi_debug_files[] = {
+ {NULL, "devs", show_devs},
+ {NULL, "dsts", show_dsts},
+ {NULL, "call", show_call},
+};
+
+static int asus_wmi_debugfs_open(struct inode *inode, struct file *file)
+{
+ struct asus_wmi_debugfs_node *node = inode->i_private;
+
+ return single_open(file, node->show, node->asus);
+}
+
+static const struct file_operations asus_wmi_debugfs_io_ops = {
+ .owner = THIS_MODULE,
+ .open = asus_wmi_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static void asus_wmi_debugfs_exit(struct asus_wmi *asus)
+{
+ debugfs_remove_recursive(asus->debug.root);
+}
+
+static int asus_wmi_debugfs_init(struct asus_wmi *asus)
+{
+ struct dentry *dent;
+ int i;
+
+ asus->debug.root = debugfs_create_dir(asus->driver->name, NULL);
+ if (!asus->debug.root) {
+ pr_err("failed to create debugfs directory");
+ goto error_debugfs;
+ }
+
+ dent = debugfs_create_x32("method_id", S_IRUGO | S_IWUSR,
+ asus->debug.root, &asus->debug.method_id);
+ if (!dent)
+ goto error_debugfs;
+
+ dent = debugfs_create_x32("dev_id", S_IRUGO | S_IWUSR,
+ asus->debug.root, &asus->debug.dev_id);
+ if (!dent)
+ goto error_debugfs;
+
+ dent = debugfs_create_x32("ctrl_param", S_IRUGO | S_IWUSR,
+ asus->debug.root, &asus->debug.ctrl_param);
+ if (!dent)
+ goto error_debugfs;
+
+ for (i = 0; i < ARRAY_SIZE(asus_wmi_debug_files); i++) {
+ struct asus_wmi_debugfs_node *node = &asus_wmi_debug_files[i];
+
+ node->asus = asus;
+ dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
+ asus->debug.root, node,
+ &asus_wmi_debugfs_io_ops);
+ if (!dent) {
+ pr_err("failed to create debug file: %s\n", node->name);
+ goto error_debugfs;
+ }
+ }
+
+ return 0;
+
+error_debugfs:
+ asus_wmi_debugfs_exit(asus);
+ return -ENOMEM;
+}
+
+/*
+ * WMI Driver
+ */
+static int asus_wmi_add(struct platform_device *pdev)
+{
+ struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
+ struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
+ struct asus_wmi *asus;
+ acpi_status status;
+ int err;
+
+ asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL);
+ if (!asus)
+ return -ENOMEM;
+
+ asus->driver = wdrv;
+ asus->platform_device = pdev;
+ wdrv->platform_device = pdev;
+ platform_set_drvdata(asus->platform_device, asus);
+
+ if (wdrv->quirks)
+ wdrv->quirks(asus->driver);
+
+ err = asus_wmi_platform_init(asus);
+ if (err)
+ goto fail_platform;
+
+ err = asus_wmi_input_init(asus);
+ if (err)
+ goto fail_input;
+
+ err = asus_wmi_hwmon_init(asus);
+ if (err)
+ goto fail_hwmon;
+
+ err = asus_wmi_led_init(asus);
+ if (err)
+ goto fail_leds;
+
+ err = asus_wmi_rfkill_init(asus);
+ if (err)
+ goto fail_rfkill;
+
+ if (!acpi_video_backlight_support()) {
+ err = asus_wmi_backlight_init(asus);
+ if (err && err != -ENODEV)
+ goto fail_backlight;
+ } else
+ pr_info("Backlight controlled by ACPI video driver\n");
+
+ status = wmi_install_notify_handler(asus->driver->event_guid,
+ asus_wmi_notify, asus);
+ if (ACPI_FAILURE(status)) {
+ pr_err("Unable to register notify handler - %d\n", status);
+ err = -ENODEV;
+ goto fail_wmi_handler;
+ }
+
+ err = asus_wmi_debugfs_init(asus);
+ if (err)
+ goto fail_debugfs;
+
+ return 0;
+
+fail_debugfs:
+ wmi_remove_notify_handler(asus->driver->event_guid);
+fail_wmi_handler:
+ asus_wmi_backlight_exit(asus);
+fail_backlight:
+ asus_wmi_rfkill_exit(asus);
+fail_rfkill:
+ asus_wmi_led_exit(asus);
+fail_leds:
+ asus_wmi_hwmon_exit(asus);
+fail_hwmon:
+ asus_wmi_input_exit(asus);
+fail_input:
+ asus_wmi_platform_exit(asus);
+fail_platform:
+ kfree(asus);
+ return err;
+}
+
+static int asus_wmi_remove(struct platform_device *device)
+{
+ struct asus_wmi *asus;
+
+ asus = platform_get_drvdata(device);
+ wmi_remove_notify_handler(asus->driver->event_guid);
+ asus_wmi_backlight_exit(asus);
+ asus_wmi_input_exit(asus);
+ asus_wmi_hwmon_exit(asus);
+ asus_wmi_led_exit(asus);
+ asus_wmi_rfkill_exit(asus);
+ asus_wmi_debugfs_exit(asus);
+ asus_wmi_platform_exit(asus);
+
+ kfree(asus);
+ return 0;
+}
+
+/*
+ * Platform driver - hibernate/resume callbacks
+ */
+static int asus_hotk_thaw(struct device *device)
+{
+ struct asus_wmi *asus = dev_get_drvdata(device);
+
+ if (asus->wlan.rfkill) {
+ bool wlan;
+
+ /*
+ * Work around bios bug - acpi _PTS turns off the wireless led
+ * during suspend. Normally it restores it on resume, but
+ * we should kick it ourselves in case hibernation is aborted.
+ */
+ wlan = asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WLAN);
+ asus_wmi_set_devstate(ASUS_WMI_DEVID_WLAN, wlan, NULL);
+ }
+
+ return 0;
+}
+
+static int asus_hotk_restore(struct device *device)
+{
+ struct asus_wmi *asus = dev_get_drvdata(device);
+ int bl;
+
+ /* Refresh both wlan rfkill state and pci hotplug */
+ if (asus->wlan.rfkill)
+ asus_rfkill_hotplug(asus);
+
+ if (asus->bluetooth.rfkill) {
+ bl = !asus_wmi_get_devstate_simple(asus,
+ ASUS_WMI_DEVID_BLUETOOTH);
+ rfkill_set_sw_state(asus->bluetooth.rfkill, bl);
+ }
+ if (asus->wimax.rfkill) {
+ bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WIMAX);
+ rfkill_set_sw_state(asus->wimax.rfkill, bl);
+ }
+ if (asus->wwan3g.rfkill) {
+ bl = !asus_wmi_get_devstate_simple(asus, ASUS_WMI_DEVID_WWAN3G);
+ rfkill_set_sw_state(asus->wwan3g.rfkill, bl);
+ }
+
+ return 0;
+}
+
+static const struct dev_pm_ops asus_pm_ops = {
+ .thaw = asus_hotk_thaw,
+ .restore = asus_hotk_restore,
+};
+
+static int asus_wmi_probe(struct platform_device *pdev)
+{
+ struct platform_driver *pdrv = to_platform_driver(pdev->dev.driver);
+ struct asus_wmi_driver *wdrv = to_asus_wmi_driver(pdrv);
+ int ret;
+
+ if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
+ pr_warning("Management GUID not found\n");
+ return -ENODEV;
+ }
+
+ if (wdrv->event_guid && !wmi_has_guid(wdrv->event_guid)) {
+ pr_warning("Event GUID not found\n");
+ return -ENODEV;
+ }
+
+ if (wdrv->probe) {
+ ret = wdrv->probe(pdev);
+ if (ret)
+ return ret;
+ }
+
+ return asus_wmi_add(pdev);
+}
+
+static bool used;
+
+int asus_wmi_register_driver(struct asus_wmi_driver *driver)
+{
+ struct platform_driver *platform_driver;
+ struct platform_device *platform_device;
+
+ if (used)
+ return -EBUSY;
+
+ platform_driver = &driver->platform_driver;
+ platform_driver->remove = asus_wmi_remove;
+ platform_driver->driver.owner = driver->owner;
+ platform_driver->driver.name = driver->name;
+ platform_driver->driver.pm = &asus_pm_ops;
+
+ platform_device = platform_create_bundle(platform_driver,
+ asus_wmi_probe,
+ NULL, 0, NULL, 0);
+ if (IS_ERR(platform_device))
+ return PTR_ERR(platform_device);
+
+ used = true;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(asus_wmi_register_driver);
+
+void asus_wmi_unregister_driver(struct asus_wmi_driver *driver)
+{
+ platform_device_unregister(driver->platform_device);
+ platform_driver_unregister(&driver->platform_driver);
+ used = false;
+}
+EXPORT_SYMBOL_GPL(asus_wmi_unregister_driver);
+
+static int __init asus_wmi_init(void)
+{
+ if (!wmi_has_guid(ASUS_WMI_MGMT_GUID)) {
+ pr_info("Asus Management GUID not found");
+ return -ENODEV;
+ }
+
+ pr_info("ASUS WMI generic driver loaded");
+ return 0;
+}
+
+static void __exit asus_wmi_exit(void)
+{
+ pr_info("ASUS WMI generic driver unloaded");
+}
+
+module_init(asus_wmi_init);
+module_exit(asus_wmi_exit);
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h
new file mode 100644
index 00000000000..c044522c876
--- /dev/null
+++ b/drivers/platform/x86/asus-wmi.h
@@ -0,0 +1,58 @@
+/*
+ * Asus PC WMI hotkey driver
+ *
+ * Copyright(C) 2010 Intel Corporation.
+ * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com>
+ *
+ * Portions based on wistron_btns.c:
+ * Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
+ * Copyright (C) 2005 Bernhard Rosenkraenzer <bero@arklinux.org>
+ * Copyright (C) 2005 Dmitry Torokhov <dtor@mail.ru>
+ *
+ * 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 _ASUS_WMI_H_
+#define _ASUS_WMI_H_
+
+#include <linux/platform_device.h>
+
+struct module;
+struct key_entry;
+struct asus_wmi;
+
+struct asus_wmi_driver {
+ bool hotplug_wireless;
+
+ const char *name;
+ struct module *owner;
+
+ const char *event_guid;
+
+ const struct key_entry *keymap;
+ const char *input_name;
+ const char *input_phys;
+
+ int (*probe) (struct platform_device *device);
+ void (*quirks) (struct asus_wmi_driver *driver);
+
+ struct platform_driver platform_driver;
+ struct platform_device *platform_device;
+};
+
+int asus_wmi_register_driver(struct asus_wmi_driver *driver);
+void asus_wmi_unregister_driver(struct asus_wmi_driver *driver);
+
+#endif /* !_ASUS_WMI_H_ */
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
index eb95878fa58..c16a27641ce 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -201,7 +201,7 @@ static bool extra_features;
* into 0x4F and read a few bytes from the output, like so:
* u8 writeData = 0x33;
* ec_transaction(0x4F, &writeData, 1, buffer, 32, 0);
- * That address is labled "fan1 table information" in the service manual.
+ * That address is labelled "fan1 table information" in the service manual.
* It should be clear which value in 'buffer' changes). This seems to be
* related to fan speed. It isn't a proper 'realtime' fan speed value
* though, because physically stopping or speeding up the fan doesn't
@@ -275,7 +275,7 @@ static int set_backlight_level(int level)
ec_write(BACKLIGHT_LEVEL_ADDR, level);
- return 1;
+ return 0;
}
static int get_backlight_level(void)
@@ -763,7 +763,7 @@ static int dmi_check_cb(const struct dmi_system_id *id)
printk(KERN_INFO DRIVER_NAME": Identified laptop model '%s'\n",
id->ident);
extra_features = false;
- return 0;
+ return 1;
}
static int dmi_check_cb_extra(const struct dmi_system_id *id)
@@ -772,7 +772,7 @@ static int dmi_check_cb_extra(const struct dmi_system_id *id)
"enabling extra features\n",
id->ident);
extra_features = true;
- return 0;
+ return 1;
}
static struct dmi_system_id __initdata compal_dmi_table[] = {
diff --git a/drivers/platform/x86/dell-wmi-aio.c b/drivers/platform/x86/dell-wmi-aio.c
new file mode 100644
index 00000000000..0ed84573ae1
--- /dev/null
+++ b/drivers/platform/x86/dell-wmi-aio.c
@@ -0,0 +1,171 @@
+/*
+ * WMI hotkeys support for Dell All-In-One series
+ *
+ * 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
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
+#include <acpi/acpi_drivers.h>
+#include <linux/acpi.h>
+#include <linux/string.h>
+
+MODULE_DESCRIPTION("WMI hotkeys driver for Dell All-In-One series");
+MODULE_LICENSE("GPL");
+
+#define EVENT_GUID1 "284A0E6B-380E-472A-921F-E52786257FB4"
+#define EVENT_GUID2 "02314822-307C-4F66-BF0E-48AEAEB26CC8"
+
+static const char *dell_wmi_aio_guids[] = {
+ EVENT_GUID1,
+ EVENT_GUID2,
+ NULL
+};
+
+MODULE_ALIAS("wmi:"EVENT_GUID1);
+MODULE_ALIAS("wmi:"EVENT_GUID2);
+
+static const struct key_entry dell_wmi_aio_keymap[] = {
+ { KE_KEY, 0xc0, { KEY_VOLUMEUP } },
+ { KE_KEY, 0xc1, { KEY_VOLUMEDOWN } },
+ { KE_END, 0 }
+};
+
+static struct input_dev *dell_wmi_aio_input_dev;
+
+static void dell_wmi_aio_notify(u32 value, void *context)
+{
+ struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
+ union acpi_object *obj;
+ acpi_status status;
+
+ status = wmi_get_event_data(value, &response);
+ if (status != AE_OK) {
+ pr_info("bad event status 0x%x\n", status);
+ return;
+ }
+
+ obj = (union acpi_object *)response.pointer;
+ if (obj) {
+ unsigned int scancode;
+
+ switch (obj->type) {
+ case ACPI_TYPE_INTEGER:
+ /* Most All-In-One correctly return integer scancode */
+ scancode = obj->integer.value;
+ sparse_keymap_report_event(dell_wmi_aio_input_dev,
+ scancode, 1, true);
+ break;
+ case ACPI_TYPE_BUFFER:
+ /* Broken machines return the scancode in a buffer */
+ if (obj->buffer.pointer && obj->buffer.length > 0) {
+ scancode = obj->buffer.pointer[0];
+ sparse_keymap_report_event(
+ dell_wmi_aio_input_dev,
+ scancode, 1, true);
+ }
+ break;
+ }
+ }
+ kfree(obj);
+}
+
+static int __init dell_wmi_aio_input_setup(void)
+{
+ int err;
+
+ dell_wmi_aio_input_dev = input_allocate_device();
+
+ if (!dell_wmi_aio_input_dev)
+ return -ENOMEM;
+
+ dell_wmi_aio_input_dev->name = "Dell AIO WMI hotkeys";
+ dell_wmi_aio_input_dev->phys = "wmi/input0";
+ dell_wmi_aio_input_dev->id.bustype = BUS_HOST;
+
+ err = sparse_keymap_setup(dell_wmi_aio_input_dev,
+ dell_wmi_aio_keymap, NULL);
+ if (err) {
+ pr_err("Unable to setup input device keymap\n");
+ goto err_free_dev;
+ }
+ err = input_register_device(dell_wmi_aio_input_dev);
+ if (err) {
+ pr_info("Unable to register input device\n");
+ goto err_free_keymap;
+ }
+ return 0;
+
+err_free_keymap:
+ sparse_keymap_free(dell_wmi_aio_input_dev);
+err_free_dev:
+ input_free_device(dell_wmi_aio_input_dev);
+ return err;
+}
+
+static const char *dell_wmi_aio_find(void)
+{
+ int i;
+
+ for (i = 0; dell_wmi_aio_guids[i] != NULL; i++)
+ if (wmi_has_guid(dell_wmi_aio_guids[i]))
+ return dell_wmi_aio_guids[i];
+
+ return NULL;
+}
+
+static int __init dell_wmi_aio_init(void)
+{
+ int err;
+ const char *guid;
+
+ guid = dell_wmi_aio_find();
+ if (!guid) {
+ pr_warning("No known WMI GUID found\n");
+ return -ENXIO;
+ }
+
+ err = dell_wmi_aio_input_setup();
+ if (err)
+ return err;
+
+ err = wmi_install_notify_handler(guid, dell_wmi_aio_notify, NULL);
+ if (err) {
+ pr_err("Unable to register notify handler - %d\n", err);
+ sparse_keymap_free(dell_wmi_aio_input_dev);
+ input_unregister_device(dell_wmi_aio_input_dev);
+ return err;
+ }
+
+ return 0;
+}
+
+static void __exit dell_wmi_aio_exit(void)
+{
+ const char *guid;
+
+ guid = dell_wmi_aio_find();
+ wmi_remove_notify_handler(guid);
+ sparse_keymap_free(dell_wmi_aio_input_dev);
+ input_unregister_device(dell_wmi_aio_input_dev);
+}
+
+module_init(dell_wmi_aio_init);
+module_exit(dell_wmi_aio_exit);
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c
index 6605beac0d0..5f2dd386152 100644
--- a/drivers/platform/x86/eeepc-laptop.c
+++ b/drivers/platform/x86/eeepc-laptop.c
@@ -1322,7 +1322,7 @@ static void cmsg_quirk(struct eeepc_laptop *eeepc, int cm, const char *name)
{
int dummy;
- /* Some BIOSes do not report cm although it is avaliable.
+ /* Some BIOSes do not report cm although it is available.
Check if cm_getv[cm] works and, if yes, assume cm should be set. */
if (!(eeepc->cm_supported & (1 << cm))
&& !read_acpi_int(eeepc->handle, cm_getv[cm], &dummy)) {
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c
index 4d38f98aa97..0ddc434fb93 100644
--- a/drivers/platform/x86/eeepc-wmi.c
+++ b/drivers/platform/x86/eeepc-wmi.c
@@ -2,7 +2,7 @@
* Eee PC WMI hotkey driver
*
* Copyright(C) 2010 Intel Corporation.
- * Copyright(C) 2010 Corentin Chary <corentin.chary@gmail.com>
+ * Copyright(C) 2010-2011 Corentin Chary <corentin.chary@gmail.com>
*
* Portions based on wistron_btns.c:
* Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
@@ -29,841 +29,57 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/slab.h>
#include <linux/input.h>
#include <linux/input/sparse-keymap.h>
-#include <linux/fb.h>
-#include <linux/backlight.h>
-#include <linux/leds.h>
-#include <linux/rfkill.h>
-#include <linux/debugfs.h>
-#include <linux/seq_file.h>
-#include <linux/platform_device.h>
+#include <linux/dmi.h>
#include <acpi/acpi_bus.h>
-#include <acpi/acpi_drivers.h>
+
+#include "asus-wmi.h"
#define EEEPC_WMI_FILE "eeepc-wmi"
-MODULE_AUTHOR("Yong Wang <yong.y.wang@intel.com>");
+MODULE_AUTHOR("Corentin Chary <corentincj@iksaif.net>");
MODULE_DESCRIPTION("Eee PC WMI Hotkey Driver");
MODULE_LICENSE("GPL");
#define EEEPC_ACPI_HID "ASUS010" /* old _HID used in eeepc-laptop */
#define EEEPC_WMI_EVENT_GUID "ABBC0F72-8EA1-11D1-00A0-C90629100000"
-#define EEEPC_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66"
MODULE_ALIAS("wmi:"EEEPC_WMI_EVENT_GUID);
-MODULE_ALIAS("wmi:"EEEPC_WMI_MGMT_GUID);
-
-#define NOTIFY_BRNUP_MIN 0x11
-#define NOTIFY_BRNUP_MAX 0x1f
-#define NOTIFY_BRNDOWN_MIN 0x20
-#define NOTIFY_BRNDOWN_MAX 0x2e
-#define EEEPC_WMI_METHODID_DEVS 0x53564544
-#define EEEPC_WMI_METHODID_DSTS 0x53544344
-#define EEEPC_WMI_METHODID_CFVS 0x53564643
+static bool hotplug_wireless;
-#define EEEPC_WMI_DEVID_BACKLIGHT 0x00050012
-#define EEEPC_WMI_DEVID_TPDLED 0x00100011
-#define EEEPC_WMI_DEVID_WLAN 0x00010011
-#define EEEPC_WMI_DEVID_BLUETOOTH 0x00010013
-#define EEEPC_WMI_DEVID_WWAN3G 0x00010019
+module_param(hotplug_wireless, bool, 0444);
+MODULE_PARM_DESC(hotplug_wireless,
+ "Enable hotplug for wireless device. "
+ "If your laptop needs that, please report to "
+ "acpi4asus-user@lists.sourceforge.net.");
static const struct key_entry eeepc_wmi_keymap[] = {
/* Sleep already handled via generic ACPI code */
- { KE_KEY, 0x5d, { KEY_WLAN } },
- { KE_KEY, 0x32, { KEY_MUTE } },
- { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
{ KE_KEY, 0x30, { KEY_VOLUMEUP } },
- { KE_IGNORE, NOTIFY_BRNDOWN_MIN, { KEY_BRIGHTNESSDOWN } },
- { KE_IGNORE, NOTIFY_BRNUP_MIN, { KEY_BRIGHTNESSUP } },
+ { KE_KEY, 0x31, { KEY_VOLUMEDOWN } },
+ { KE_KEY, 0x32, { KEY_MUTE } },
+ { KE_KEY, 0x5c, { KEY_F15 } }, /* Power Gear key */
+ { KE_KEY, 0x5d, { KEY_WLAN } },
+ { KE_KEY, 0x6b, { KEY_TOUCHPAD_TOGGLE } }, /* Toggle Touchpad */
+ { KE_KEY, 0x82, { KEY_CAMERA } },
+ { KE_KEY, 0x83, { KEY_CAMERA_ZOOMIN } },
+ { KE_KEY, 0x88, { KEY_WLAN } },
{ KE_KEY, 0xcc, { KEY_SWITCHVIDEOMODE } },
- { KE_KEY, 0x6b, { KEY_F13 } }, /* Disable Touchpad */
- { KE_KEY, 0xe1, { KEY_F14 } },
- { KE_KEY, 0xe9, { KEY_DISPLAY_OFF } },
- { KE_KEY, 0xe0, { KEY_PROG1 } },
- { KE_KEY, 0x5c, { KEY_F15 } },
+ { KE_KEY, 0xe0, { KEY_PROG1 } }, /* Task Manager */
+ { KE_KEY, 0xe1, { KEY_F14 } }, /* Change Resolution */
+ { KE_KEY, 0xe9, { KEY_BRIGHTNESS_ZERO } },
+ { KE_KEY, 0xeb, { KEY_CAMERA_ZOOMOUT } },
+ { KE_KEY, 0xec, { KEY_CAMERA_UP } },
+ { KE_KEY, 0xed, { KEY_CAMERA_DOWN } },
+ { KE_KEY, 0xee, { KEY_CAMERA_LEFT } },
+ { KE_KEY, 0xef, { KEY_CAMERA_RIGHT } },
{ KE_END, 0},
};
-struct bios_args {
- u32 dev_id;
- u32 ctrl_param;
-};
-
-/*
- * eeepc-wmi/ - debugfs root directory
- * dev_id - current dev_id
- * ctrl_param - current ctrl_param
- * devs - call DEVS(dev_id, ctrl_param) and print result
- * dsts - call DSTS(dev_id) and print result
- */
-struct eeepc_wmi_debug {
- struct dentry *root;
- u32 dev_id;
- u32 ctrl_param;
-};
-
-struct eeepc_wmi {
- struct input_dev *inputdev;
- struct backlight_device *backlight_device;
- struct platform_device *platform_device;
-
- struct led_classdev tpd_led;
- int tpd_led_wk;
- struct workqueue_struct *led_workqueue;
- struct work_struct tpd_led_work;
-
- struct rfkill *wlan_rfkill;
- struct rfkill *bluetooth_rfkill;
- struct rfkill *wwan3g_rfkill;
-
- struct eeepc_wmi_debug debug;
-};
-
-/* Only used in eeepc_wmi_init() and eeepc_wmi_exit() */
-static struct platform_device *platform_device;
-
-static int eeepc_wmi_input_init(struct eeepc_wmi *eeepc)
-{
- int err;
-
- eeepc->inputdev = input_allocate_device();
- if (!eeepc->inputdev)
- return -ENOMEM;
-
- eeepc->inputdev->name = "Eee PC WMI hotkeys";
- eeepc->inputdev->phys = EEEPC_WMI_FILE "/input0";
- eeepc->inputdev->id.bustype = BUS_HOST;
- eeepc->inputdev->dev.parent = &eeepc->platform_device->dev;
-
- err = sparse_keymap_setup(eeepc->inputdev, eeepc_wmi_keymap, NULL);
- if (err)
- goto err_free_dev;
-
- err = input_register_device(eeepc->inputdev);
- if (err)
- goto err_free_keymap;
-
- return 0;
-
-err_free_keymap:
- sparse_keymap_free(eeepc->inputdev);
-err_free_dev:
- input_free_device(eeepc->inputdev);
- return err;
-}
-
-static void eeepc_wmi_input_exit(struct eeepc_wmi *eeepc)
-{
- if (eeepc->inputdev) {
- sparse_keymap_free(eeepc->inputdev);
- input_unregister_device(eeepc->inputdev);
- }
-
- eeepc->inputdev = NULL;
-}
-
-static acpi_status eeepc_wmi_get_devstate(u32 dev_id, u32 *retval)
-{
- struct acpi_buffer input = { (acpi_size)sizeof(u32), &dev_id };
- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- acpi_status status;
- u32 tmp;
-
- status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
- 1, EEEPC_WMI_METHODID_DSTS, &input, &output);
-
- if (ACPI_FAILURE(status))
- return status;
-
- obj = (union acpi_object *)output.pointer;
- if (obj && obj->type == ACPI_TYPE_INTEGER)
- tmp = (u32)obj->integer.value;
- else
- tmp = 0;
-
- if (retval)
- *retval = tmp;
-
- kfree(obj);
-
- return status;
-
-}
-
-static acpi_status eeepc_wmi_set_devstate(u32 dev_id, u32 ctrl_param,
- u32 *retval)
-{
- struct bios_args args = {
- .dev_id = dev_id,
- .ctrl_param = ctrl_param,
- };
- struct acpi_buffer input = { (acpi_size)sizeof(args), &args };
- acpi_status status;
-
- if (!retval) {
- status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
- EEEPC_WMI_METHODID_DEVS,
- &input, NULL);
- } else {
- struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- u32 tmp;
-
- status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID, 1,
- EEEPC_WMI_METHODID_DEVS,
- &input, &output);
-
- if (ACPI_FAILURE(status))
- return status;
-
- obj = (union acpi_object *)output.pointer;
- if (obj && obj->type == ACPI_TYPE_INTEGER)
- tmp = (u32)obj->integer.value;
- else
- tmp = 0;
-
- *retval = tmp;
-
- kfree(obj);
- }
-
- return status;
-}
-
-/*
- * LEDs
- */
-/*
- * These functions actually update the LED's, and are called from a
- * workqueue. By doing this as separate work rather than when the LED
- * subsystem asks, we avoid messing with the Eeepc ACPI stuff during a
- * potentially bad time, such as a timer interrupt.
- */
-static void tpd_led_update(struct work_struct *work)
-{
- int ctrl_param;
- struct eeepc_wmi *eeepc;
-
- eeepc = container_of(work, struct eeepc_wmi, tpd_led_work);
-
- ctrl_param = eeepc->tpd_led_wk;
- eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_TPDLED, ctrl_param, NULL);
-}
-
-static void tpd_led_set(struct led_classdev *led_cdev,
- enum led_brightness value)
-{
- struct eeepc_wmi *eeepc;
-
- eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
-
- eeepc->tpd_led_wk = !!value;
- queue_work(eeepc->led_workqueue, &eeepc->tpd_led_work);
-}
-
-static int read_tpd_state(struct eeepc_wmi *eeepc)
-{
- u32 retval;
- acpi_status status;
-
- status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_TPDLED, &retval);
-
- if (ACPI_FAILURE(status))
- return -1;
- else if (!retval || retval == 0x00060000)
- /*
- * if touchpad led is present, DSTS will set some bits,
- * usually 0x00020000.
- * 0x00060000 means that the device is not supported
- */
- return -ENODEV;
- else
- /* Status is stored in the first bit */
- return retval & 0x1;
-}
-
-static enum led_brightness tpd_led_get(struct led_classdev *led_cdev)
-{
- struct eeepc_wmi *eeepc;
-
- eeepc = container_of(led_cdev, struct eeepc_wmi, tpd_led);
-
- return read_tpd_state(eeepc);
-}
-
-static int eeepc_wmi_led_init(struct eeepc_wmi *eeepc)
-{
- int rv;
-
- if (read_tpd_state(eeepc) < 0)
- return 0;
-
- eeepc->led_workqueue = create_singlethread_workqueue("led_workqueue");
- if (!eeepc->led_workqueue)
- return -ENOMEM;
- INIT_WORK(&eeepc->tpd_led_work, tpd_led_update);
-
- eeepc->tpd_led.name = "eeepc::touchpad";
- eeepc->tpd_led.brightness_set = tpd_led_set;
- eeepc->tpd_led.brightness_get = tpd_led_get;
- eeepc->tpd_led.max_brightness = 1;
-
- rv = led_classdev_register(&eeepc->platform_device->dev,
- &eeepc->tpd_led);
- if (rv) {
- destroy_workqueue(eeepc->led_workqueue);
- return rv;
- }
-
- return 0;
-}
-
-static void eeepc_wmi_led_exit(struct eeepc_wmi *eeepc)
-{
- if (eeepc->tpd_led.dev)
- led_classdev_unregister(&eeepc->tpd_led);
- if (eeepc->led_workqueue)
- destroy_workqueue(eeepc->led_workqueue);
-}
-
-/*
- * Rfkill devices
- */
-static int eeepc_rfkill_set(void *data, bool blocked)
-{
- int dev_id = (unsigned long)data;
- u32 ctrl_param = !blocked;
-
- return eeepc_wmi_set_devstate(dev_id, ctrl_param, NULL);
-}
-
-static void eeepc_rfkill_query(struct rfkill *rfkill, void *data)
-{
- int dev_id = (unsigned long)data;
- u32 retval;
- acpi_status status;
-
- status = eeepc_wmi_get_devstate(dev_id, &retval);
-
- if (ACPI_FAILURE(status))
- return ;
-
- rfkill_set_sw_state(rfkill, !(retval & 0x1));
-}
-
-static const struct rfkill_ops eeepc_rfkill_ops = {
- .set_block = eeepc_rfkill_set,
- .query = eeepc_rfkill_query,
-};
-
-static int eeepc_new_rfkill(struct eeepc_wmi *eeepc,
- struct rfkill **rfkill,
- const char *name,
- enum rfkill_type type, int dev_id)
-{
- int result;
- u32 retval;
- acpi_status status;
-
- status = eeepc_wmi_get_devstate(dev_id, &retval);
-
- if (ACPI_FAILURE(status))
- return -1;
-
- /* If the device is present, DSTS will always set some bits
- * 0x00070000 - 1110000000000000000 - device supported
- * 0x00060000 - 1100000000000000000 - not supported
- * 0x00020000 - 0100000000000000000 - device supported
- * 0x00010000 - 0010000000000000000 - not supported / special mode ?
- */
- if (!retval || retval == 0x00060000)
- return -ENODEV;
-
- *rfkill = rfkill_alloc(name, &eeepc->platform_device->dev, type,
- &eeepc_rfkill_ops, (void *)(long)dev_id);
-
- if (!*rfkill)
- return -EINVAL;
-
- rfkill_init_sw_state(*rfkill, !(retval & 0x1));
- result = rfkill_register(*rfkill);
- if (result) {
- rfkill_destroy(*rfkill);
- *rfkill = NULL;
- return result;
- }
- return 0;
-}
-
-static void eeepc_wmi_rfkill_exit(struct eeepc_wmi *eeepc)
-{
- if (eeepc->wlan_rfkill) {
- rfkill_unregister(eeepc->wlan_rfkill);
- rfkill_destroy(eeepc->wlan_rfkill);
- eeepc->wlan_rfkill = NULL;
- }
- if (eeepc->bluetooth_rfkill) {
- rfkill_unregister(eeepc->bluetooth_rfkill);
- rfkill_destroy(eeepc->bluetooth_rfkill);
- eeepc->bluetooth_rfkill = NULL;
- }
- if (eeepc->wwan3g_rfkill) {
- rfkill_unregister(eeepc->wwan3g_rfkill);
- rfkill_destroy(eeepc->wwan3g_rfkill);
- eeepc->wwan3g_rfkill = NULL;
- }
-}
-
-static int eeepc_wmi_rfkill_init(struct eeepc_wmi *eeepc)
-{
- int result = 0;
-
- result = eeepc_new_rfkill(eeepc, &eeepc->wlan_rfkill,
- "eeepc-wlan", RFKILL_TYPE_WLAN,
- EEEPC_WMI_DEVID_WLAN);
-
- if (result && result != -ENODEV)
- goto exit;
-
- result = eeepc_new_rfkill(eeepc, &eeepc->bluetooth_rfkill,
- "eeepc-bluetooth", RFKILL_TYPE_BLUETOOTH,
- EEEPC_WMI_DEVID_BLUETOOTH);
-
- if (result && result != -ENODEV)
- goto exit;
-
- result = eeepc_new_rfkill(eeepc, &eeepc->wwan3g_rfkill,
- "eeepc-wwan3g", RFKILL_TYPE_WWAN,
- EEEPC_WMI_DEVID_WWAN3G);
-
- if (result && result != -ENODEV)
- goto exit;
-
-exit:
- if (result && result != -ENODEV)
- eeepc_wmi_rfkill_exit(eeepc);
-
- if (result == -ENODEV)
- result = 0;
-
- return result;
-}
-
-/*
- * Backlight
- */
-static int read_brightness(struct backlight_device *bd)
-{
- u32 retval;
- acpi_status status;
-
- status = eeepc_wmi_get_devstate(EEEPC_WMI_DEVID_BACKLIGHT, &retval);
-
- if (ACPI_FAILURE(status))
- return -1;
- else
- return retval & 0xFF;
-}
-
-static int update_bl_status(struct backlight_device *bd)
-{
-
- u32 ctrl_param;
- acpi_status status;
-
- ctrl_param = bd->props.brightness;
-
- status = eeepc_wmi_set_devstate(EEEPC_WMI_DEVID_BACKLIGHT,
- ctrl_param, NULL);
-
- if (ACPI_FAILURE(status))
- return -1;
- else
- return 0;
-}
-
-static const struct backlight_ops eeepc_wmi_bl_ops = {
- .get_brightness = read_brightness,
- .update_status = update_bl_status,
-};
-
-static int eeepc_wmi_backlight_notify(struct eeepc_wmi *eeepc, int code)
-{
- struct backlight_device *bd = eeepc->backlight_device;
- int old = bd->props.brightness;
- int new = old;
-
- if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
- new = code - NOTIFY_BRNUP_MIN + 1;
- else if (code >= NOTIFY_BRNDOWN_MIN && code <= NOTIFY_BRNDOWN_MAX)
- new = code - NOTIFY_BRNDOWN_MIN;
-
- bd->props.brightness = new;
- backlight_update_status(bd);
- backlight_force_update(bd, BACKLIGHT_UPDATE_HOTKEY);
-
- return old;
-}
-
-static int eeepc_wmi_backlight_init(struct eeepc_wmi *eeepc)
-{
- struct backlight_device *bd;
- struct backlight_properties props;
-
- memset(&props, 0, sizeof(struct backlight_properties));
- props.max_brightness = 15;
- bd = backlight_device_register(EEEPC_WMI_FILE,
- &eeepc->platform_device->dev, eeepc,
- &eeepc_wmi_bl_ops, &props);
- if (IS_ERR(bd)) {
- pr_err("Could not register backlight device\n");
- return PTR_ERR(bd);
- }
-
- eeepc->backlight_device = bd;
-
- bd->props.brightness = read_brightness(bd);
- bd->props.power = FB_BLANK_UNBLANK;
- backlight_update_status(bd);
-
- return 0;
-}
-
-static void eeepc_wmi_backlight_exit(struct eeepc_wmi *eeepc)
-{
- if (eeepc->backlight_device)
- backlight_device_unregister(eeepc->backlight_device);
-
- eeepc->backlight_device = NULL;
-}
-
-static void eeepc_wmi_notify(u32 value, void *context)
-{
- struct eeepc_wmi *eeepc = context;
- struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL };
- union acpi_object *obj;
- acpi_status status;
- int code;
- int orig_code;
-
- status = wmi_get_event_data(value, &response);
- if (status != AE_OK) {
- pr_err("bad event status 0x%x\n", status);
- return;
- }
-
- obj = (union acpi_object *)response.pointer;
-
- if (obj && obj->type == ACPI_TYPE_INTEGER) {
- code = obj->integer.value;
- orig_code = code;
-
- if (code >= NOTIFY_BRNUP_MIN && code <= NOTIFY_BRNUP_MAX)
- code = NOTIFY_BRNUP_MIN;
- else if (code >= NOTIFY_BRNDOWN_MIN &&
- code <= NOTIFY_BRNDOWN_MAX)
- code = NOTIFY_BRNDOWN_MIN;
-
- if (code == NOTIFY_BRNUP_MIN || code == NOTIFY_BRNDOWN_MIN) {
- if (!acpi_video_backlight_support())
- eeepc_wmi_backlight_notify(eeepc, orig_code);
- }
-
- if (!sparse_keymap_report_event(eeepc->inputdev,
- code, 1, true))
- pr_info("Unknown key %x pressed\n", code);
- }
-
- kfree(obj);
-}
-
-static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- int value;
- struct acpi_buffer input = { (acpi_size)sizeof(value), &value };
- acpi_status status;
-
- if (!count || sscanf(buf, "%i", &value) != 1)
- return -EINVAL;
- if (value < 0 || value > 2)
- return -EINVAL;
-
- status = wmi_evaluate_method(EEEPC_WMI_MGMT_GUID,
- 1, EEEPC_WMI_METHODID_CFVS, &input, NULL);
-
- if (ACPI_FAILURE(status))
- return -EIO;
- else
- return count;
-}
-
-static DEVICE_ATTR(cpufv, S_IRUGO | S_IWUSR, NULL, store_cpufv);
-
-static struct attribute *platform_attributes[] = {
- &dev_attr_cpufv.attr,
- NULL
-};
-
-static struct attribute_group platform_attribute_group = {
- .attrs = platform_attributes
-};
-
-static void eeepc_wmi_sysfs_exit(struct platform_device *device)
-{
- sysfs_remove_group(&device->dev.kobj, &platform_attribute_group);
-}
-
-static int eeepc_wmi_sysfs_init(struct platform_device *device)
-{
- return sysfs_create_group(&device->dev.kobj, &platform_attribute_group);
-}
-
-/*
- * Platform device
- */
-static int __init eeepc_wmi_platform_init(struct eeepc_wmi *eeepc)
-{
- int err;
-
- eeepc->platform_device = platform_device_alloc(EEEPC_WMI_FILE, -1);
- if (!eeepc->platform_device)
- return -ENOMEM;
- platform_set_drvdata(eeepc->platform_device, eeepc);
-
- err = platform_device_add(eeepc->platform_device);
- if (err)
- goto fail_platform_device;
-
- err = eeepc_wmi_sysfs_init(eeepc->platform_device);
- if (err)
- goto fail_sysfs;
- return 0;
-
-fail_sysfs:
- platform_device_del(eeepc->platform_device);
-fail_platform_device:
- platform_device_put(eeepc->platform_device);
- return err;
-}
-
-static void eeepc_wmi_platform_exit(struct eeepc_wmi *eeepc)
-{
- eeepc_wmi_sysfs_exit(eeepc->platform_device);
- platform_device_unregister(eeepc->platform_device);
-}
-
-/*
- * debugfs
- */
-struct eeepc_wmi_debugfs_node {
- struct eeepc_wmi *eeepc;
- char *name;
- int (*show)(struct seq_file *m, void *data);
-};
-
-static int show_dsts(struct seq_file *m, void *data)
-{
- struct eeepc_wmi *eeepc = m->private;
- acpi_status status;
- u32 retval = -1;
-
- status = eeepc_wmi_get_devstate(eeepc->debug.dev_id, &retval);
-
- if (ACPI_FAILURE(status))
- return -EIO;
-
- seq_printf(m, "DSTS(%x) = %x\n", eeepc->debug.dev_id, retval);
-
- return 0;
-}
-
-static int show_devs(struct seq_file *m, void *data)
-{
- struct eeepc_wmi *eeepc = m->private;
- acpi_status status;
- u32 retval = -1;
-
- status = eeepc_wmi_set_devstate(eeepc->debug.dev_id,
- eeepc->debug.ctrl_param, &retval);
- if (ACPI_FAILURE(status))
- return -EIO;
-
- seq_printf(m, "DEVS(%x, %x) = %x\n", eeepc->debug.dev_id,
- eeepc->debug.ctrl_param, retval);
-
- return 0;
-}
-
-static struct eeepc_wmi_debugfs_node eeepc_wmi_debug_files[] = {
- { NULL, "devs", show_devs },
- { NULL, "dsts", show_dsts },
-};
-
-static int eeepc_wmi_debugfs_open(struct inode *inode, struct file *file)
-{
- struct eeepc_wmi_debugfs_node *node = inode->i_private;
-
- return single_open(file, node->show, node->eeepc);
-}
-
-static const struct file_operations eeepc_wmi_debugfs_io_ops = {
- .owner = THIS_MODULE,
- .open = eeepc_wmi_debugfs_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static void eeepc_wmi_debugfs_exit(struct eeepc_wmi *eeepc)
-{
- debugfs_remove_recursive(eeepc->debug.root);
-}
-
-static int eeepc_wmi_debugfs_init(struct eeepc_wmi *eeepc)
-{
- struct dentry *dent;
- int i;
-
- eeepc->debug.root = debugfs_create_dir(EEEPC_WMI_FILE, NULL);
- if (!eeepc->debug.root) {
- pr_err("failed to create debugfs directory");
- goto error_debugfs;
- }
-
- dent = debugfs_create_x32("dev_id", S_IRUGO|S_IWUSR,
- eeepc->debug.root, &eeepc->debug.dev_id);
- if (!dent)
- goto error_debugfs;
-
- dent = debugfs_create_x32("ctrl_param", S_IRUGO|S_IWUSR,
- eeepc->debug.root, &eeepc->debug.ctrl_param);
- if (!dent)
- goto error_debugfs;
-
- for (i = 0; i < ARRAY_SIZE(eeepc_wmi_debug_files); i++) {
- struct eeepc_wmi_debugfs_node *node = &eeepc_wmi_debug_files[i];
-
- node->eeepc = eeepc;
- dent = debugfs_create_file(node->name, S_IFREG | S_IRUGO,
- eeepc->debug.root, node,
- &eeepc_wmi_debugfs_io_ops);
- if (!dent) {
- pr_err("failed to create debug file: %s\n", node->name);
- goto error_debugfs;
- }
- }
-
- return 0;
-
-error_debugfs:
- eeepc_wmi_debugfs_exit(eeepc);
- return -ENOMEM;
-}
-
-/*
- * WMI Driver
- */
-static struct platform_device * __init eeepc_wmi_add(void)
-{
- struct eeepc_wmi *eeepc;
- acpi_status status;
- int err;
-
- eeepc = kzalloc(sizeof(struct eeepc_wmi), GFP_KERNEL);
- if (!eeepc)
- return ERR_PTR(-ENOMEM);
-
- /*
- * Register the platform device first. It is used as a parent for the
- * sub-devices below.
- */
- err = eeepc_wmi_platform_init(eeepc);
- if (err)
- goto fail_platform;
-
- err = eeepc_wmi_input_init(eeepc);
- if (err)
- goto fail_input;
-
- err = eeepc_wmi_led_init(eeepc);
- if (err)
- goto fail_leds;
-
- err = eeepc_wmi_rfkill_init(eeepc);
- if (err)
- goto fail_rfkill;
-
- if (!acpi_video_backlight_support()) {
- err = eeepc_wmi_backlight_init(eeepc);
- if (err)
- goto fail_backlight;
- } else
- pr_info("Backlight controlled by ACPI video driver\n");
-
- status = wmi_install_notify_handler(EEEPC_WMI_EVENT_GUID,
- eeepc_wmi_notify, eeepc);
- if (ACPI_FAILURE(status)) {
- pr_err("Unable to register notify handler - %d\n",
- status);
- err = -ENODEV;
- goto fail_wmi_handler;
- }
-
- err = eeepc_wmi_debugfs_init(eeepc);
- if (err)
- goto fail_debugfs;
-
- return eeepc->platform_device;
-
-fail_debugfs:
- wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
-fail_wmi_handler:
- eeepc_wmi_backlight_exit(eeepc);
-fail_backlight:
- eeepc_wmi_rfkill_exit(eeepc);
-fail_rfkill:
- eeepc_wmi_led_exit(eeepc);
-fail_leds:
- eeepc_wmi_input_exit(eeepc);
-fail_input:
- eeepc_wmi_platform_exit(eeepc);
-fail_platform:
- kfree(eeepc);
- return ERR_PTR(err);
-}
-
-static int eeepc_wmi_remove(struct platform_device *device)
-{
- struct eeepc_wmi *eeepc;
-
- eeepc = platform_get_drvdata(device);
- wmi_remove_notify_handler(EEEPC_WMI_EVENT_GUID);
- eeepc_wmi_backlight_exit(eeepc);
- eeepc_wmi_input_exit(eeepc);
- eeepc_wmi_led_exit(eeepc);
- eeepc_wmi_rfkill_exit(eeepc);
- eeepc_wmi_debugfs_exit(eeepc);
- eeepc_wmi_platform_exit(eeepc);
-
- kfree(eeepc);
- return 0;
-}
-
-static struct platform_driver platform_driver = {
- .driver = {
- .name = EEEPC_WMI_FILE,
- .owner = THIS_MODULE,
- },
-};
-
-static acpi_status __init eeepc_wmi_parse_device(acpi_handle handle, u32 level,
+static acpi_status eeepc_wmi_parse_device(acpi_handle handle, u32 level,
void *context, void **retval)
{
pr_warning("Found legacy ATKD device (%s)", EEEPC_ACPI_HID);
@@ -871,7 +87,7 @@ static acpi_status __init eeepc_wmi_parse_device(acpi_handle handle, u32 level,
return AE_CTRL_TERMINATE;
}
-static int __init eeepc_wmi_check_atkd(void)
+static int eeepc_wmi_check_atkd(void)
{
acpi_status status;
bool found = false;
@@ -884,16 +100,8 @@ static int __init eeepc_wmi_check_atkd(void)
return -1;
}
-static int __init eeepc_wmi_init(void)
+static int eeepc_wmi_probe(struct platform_device *pdev)
{
- int err;
-
- if (!wmi_has_guid(EEEPC_WMI_EVENT_GUID) ||
- !wmi_has_guid(EEEPC_WMI_MGMT_GUID)) {
- pr_warning("No known WMI GUID found\n");
- return -ENODEV;
- }
-
if (eeepc_wmi_check_atkd()) {
pr_warning("WMI device present, but legacy ATKD device is also "
"present and enabled.");
@@ -901,33 +109,59 @@ static int __init eeepc_wmi_init(void)
"acpi_osi=\"!Windows 2009\"");
pr_warning("Can't load eeepc-wmi, use default acpi_osi "
"(preferred) or eeepc-laptop");
- return -ENODEV;
+ return -EBUSY;
}
+ return 0;
+}
- platform_device = eeepc_wmi_add();
- if (IS_ERR(platform_device)) {
- err = PTR_ERR(platform_device);
- goto fail_eeepc_wmi;
- }
+static void eeepc_dmi_check(struct asus_wmi_driver *driver)
+{
+ const char *model;
+
+ model = dmi_get_system_info(DMI_PRODUCT_NAME);
+ if (!model)
+ return;
- err = platform_driver_register(&platform_driver);
- if (err) {
- pr_warning("Unable to register platform driver\n");
- goto fail_platform_driver;
+ /*
+ * Whitelist for wlan hotplug
+ *
+ * Asus 1000H needs the current hotplug code to handle
+ * Fn+F2 correctly. We may add other Asus here later, but
+ * it seems that most of the laptops supported by asus-wmi
+ * don't need to be on this list
+ */
+ if (strcmp(model, "1000H") == 0) {
+ driver->hotplug_wireless = true;
+ pr_info("wlan hotplug enabled\n");
}
+}
+
+static void eeepc_wmi_quirks(struct asus_wmi_driver *driver)
+{
+ driver->hotplug_wireless = hotplug_wireless;
+ eeepc_dmi_check(driver);
+}
+
+static struct asus_wmi_driver asus_wmi_driver = {
+ .name = EEEPC_WMI_FILE,
+ .owner = THIS_MODULE,
+ .event_guid = EEEPC_WMI_EVENT_GUID,
+ .keymap = eeepc_wmi_keymap,
+ .input_name = "Eee PC WMI hotkeys",
+ .input_phys = EEEPC_WMI_FILE "/input0",
+ .probe = eeepc_wmi_probe,
+ .quirks = eeepc_wmi_quirks,
+};
- return 0;
-fail_platform_driver:
- eeepc_wmi_remove(platform_device);
-fail_eeepc_wmi:
- return err;
+static int __init eeepc_wmi_init(void)
+{
+ return asus_wmi_register_driver(&asus_wmi_driver);
}
static void __exit eeepc_wmi_exit(void)
{
- eeepc_wmi_remove(platform_device);
- platform_driver_unregister(&platform_driver);
+ asus_wmi_unregister_driver(&asus_wmi_driver);
}
module_init(eeepc_wmi_init);
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c
index 9e05af9c41c..1bc4a7539ba 100644
--- a/drivers/platform/x86/hp-wmi.c
+++ b/drivers/platform/x86/hp-wmi.c
@@ -2,6 +2,7 @@
* HP WMI hotkeys
*
* Copyright (C) 2008 Red Hat <mjg@redhat.com>
+ * Copyright (C) 2010, 2011 Anssi Hannula <anssi.hannula@iki.fi>
*
* Portions based on wistron_btns.c:
* Copyright (C) 2005 Miloslav Trmac <mitr@volny.cz>
@@ -51,6 +52,7 @@ MODULE_ALIAS("wmi:5FB7F034-2C63-45e9-BE91-3D44E2C707E4");
#define HPWMI_HARDWARE_QUERY 0x4
#define HPWMI_WIRELESS_QUERY 0x5
#define HPWMI_HOTKEY_QUERY 0xc
+#define HPWMI_WIRELESS2_QUERY 0x1b
#define PREFIX "HP WMI: "
#define UNIMP "Unimplemented "
@@ -86,7 +88,46 @@ struct bios_args {
struct bios_return {
u32 sigpass;
u32 return_code;
- u32 value;
+};
+
+enum hp_return_value {
+ HPWMI_RET_WRONG_SIGNATURE = 0x02,
+ HPWMI_RET_UNKNOWN_COMMAND = 0x03,
+ HPWMI_RET_UNKNOWN_CMDTYPE = 0x04,
+ HPWMI_RET_INVALID_PARAMETERS = 0x05,
+};
+
+enum hp_wireless2_bits {
+ HPWMI_POWER_STATE = 0x01,
+ HPWMI_POWER_SOFT = 0x02,
+ HPWMI_POWER_BIOS = 0x04,
+ HPWMI_POWER_HARD = 0x08,
+};
+
+#define IS_HWBLOCKED(x) ((x & (HPWMI_POWER_BIOS | HPWMI_POWER_HARD)) \
+ != (HPWMI_POWER_BIOS | HPWMI_POWER_HARD))
+#define IS_SWBLOCKED(x) !(x & HPWMI_POWER_SOFT)
+
+struct bios_rfkill2_device_state {
+ u8 radio_type;
+ u8 bus_type;
+ u16 vendor_id;
+ u16 product_id;
+ u16 subsys_vendor_id;
+ u16 subsys_product_id;
+ u8 rfkill_id;
+ u8 power;
+ u8 unknown[4];
+};
+
+/* 7 devices fit into the 128 byte buffer */
+#define HPWMI_MAX_RFKILL2_DEVICES 7
+
+struct bios_rfkill2_state {
+ u8 unknown[7];
+ u8 count;
+ u8 pad[8];
+ struct bios_rfkill2_device_state device[HPWMI_MAX_RFKILL2_DEVICES];
};
static const struct key_entry hp_wmi_keymap[] = {
@@ -108,6 +149,15 @@ static struct rfkill *wifi_rfkill;
static struct rfkill *bluetooth_rfkill;
static struct rfkill *wwan_rfkill;
+struct rfkill2_device {
+ u8 id;
+ int num;
+ struct rfkill *rfkill;
+};
+
+static int rfkill2_count;
+static struct rfkill2_device rfkill2[HPWMI_MAX_RFKILL2_DEVICES];
+
static const struct dev_pm_ops hp_wmi_pm_ops = {
.resume = hp_wmi_resume_handler,
.restore = hp_wmi_resume_handler,
@@ -129,7 +179,8 @@ static struct platform_driver hp_wmi_driver = {
* query: The commandtype -> What should be queried
* write: The command -> 0 read, 1 write, 3 ODM specific
* buffer: Buffer used as input and/or output
- * buffersize: Size of buffer
+ * insize: Size of input buffer
+ * outsize: Size of output buffer
*
* returns zero on success
* an HP WMI query specific error code (which is positive)
@@ -140,25 +191,29 @@ static struct platform_driver hp_wmi_driver = {
* size. E.g. Battery info query (0x7) is defined to have 1 byte input
* and 128 byte output. The caller would do:
* buffer = kzalloc(128, GFP_KERNEL);
- * ret = hp_wmi_perform_query(0x7, 0, buffer, 128)
+ * ret = hp_wmi_perform_query(0x7, 0, buffer, 1, 128)
*/
-static int hp_wmi_perform_query(int query, int write, u32 *buffer,
- int buffersize)
+static int hp_wmi_perform_query(int query, int write, void *buffer,
+ int insize, int outsize)
{
- struct bios_return bios_return;
- acpi_status status;
+ struct bios_return *bios_return;
+ int actual_outsize;
union acpi_object *obj;
struct bios_args args = {
.signature = 0x55434553,
.command = write ? 0x2 : 0x1,
.commandtype = query,
- .datasize = buffersize,
- .data = *buffer,
+ .datasize = insize,
+ .data = 0,
};
struct acpi_buffer input = { sizeof(struct bios_args), &args };
struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL };
- status = wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output);
+ if (WARN_ON(insize > sizeof(args.data)))
+ return -EINVAL;
+ memcpy(&args.data, buffer, insize);
+
+ wmi_evaluate_method(HPWMI_BIOS_GUID, 0, 0x3, &input, &output);
obj = output.pointer;
@@ -169,10 +224,26 @@ static int hp_wmi_perform_query(int query, int write, u32 *buffer,
return -EINVAL;
}
- bios_return = *((struct bios_return *)obj->buffer.pointer);
+ bios_return = (struct bios_return *)obj->buffer.pointer;
- memcpy(buffer, &bios_return.value, sizeof(bios_return.value));
+ if (bios_return->return_code) {
+ if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE)
+ printk(KERN_WARNING PREFIX "query 0x%x returned "
+ "error 0x%x\n",
+ query, bios_return->return_code);
+ kfree(obj);
+ return bios_return->return_code;
+ }
+
+ if (!outsize) {
+ /* ignore output data */
+ kfree(obj);
+ return 0;
+ }
+ actual_outsize = min(outsize, (int)(obj->buffer.length - sizeof(*bios_return)));
+ memcpy(buffer, obj->buffer.pointer + sizeof(*bios_return), actual_outsize);
+ memset(buffer + actual_outsize, 0, outsize - actual_outsize);
kfree(obj);
return 0;
}
@@ -181,7 +252,7 @@ static int hp_wmi_display_state(void)
{
int state = 0;
int ret = hp_wmi_perform_query(HPWMI_DISPLAY_QUERY, 0, &state,
- sizeof(state));
+ sizeof(state), sizeof(state));
if (ret)
return -EINVAL;
return state;
@@ -191,7 +262,7 @@ static int hp_wmi_hddtemp_state(void)
{
int state = 0;
int ret = hp_wmi_perform_query(HPWMI_HDDTEMP_QUERY, 0, &state,
- sizeof(state));
+ sizeof(state), sizeof(state));
if (ret)
return -EINVAL;
return state;
@@ -201,7 +272,7 @@ static int hp_wmi_als_state(void)
{
int state = 0;
int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 0, &state,
- sizeof(state));
+ sizeof(state), sizeof(state));
if (ret)
return -EINVAL;
return state;
@@ -211,7 +282,7 @@ static int hp_wmi_dock_state(void)
{
int state = 0;
int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state,
- sizeof(state));
+ sizeof(state), sizeof(state));
if (ret)
return -EINVAL;
@@ -223,7 +294,7 @@ static int hp_wmi_tablet_state(void)
{
int state = 0;
int ret = hp_wmi_perform_query(HPWMI_HARDWARE_QUERY, 0, &state,
- sizeof(state));
+ sizeof(state), sizeof(state));
if (ret)
return ret;
@@ -237,7 +308,7 @@ static int hp_wmi_set_block(void *data, bool blocked)
int ret;
ret = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 1,
- &query, sizeof(query));
+ &query, sizeof(query), 0);
if (ret)
return -EINVAL;
return 0;
@@ -252,7 +323,8 @@ static bool hp_wmi_get_sw_state(enum hp_wmi_radio r)
int wireless = 0;
int mask;
hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0,
- &wireless, sizeof(wireless));
+ &wireless, sizeof(wireless),
+ sizeof(wireless));
/* TBD: Pass error */
mask = 0x200 << (r * 8);
@@ -268,7 +340,8 @@ static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
int wireless = 0;
int mask;
hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0,
- &wireless, sizeof(wireless));
+ &wireless, sizeof(wireless),
+ sizeof(wireless));
/* TBD: Pass error */
mask = 0x800 << (r * 8);
@@ -279,6 +352,51 @@ static bool hp_wmi_get_hw_state(enum hp_wmi_radio r)
return true;
}
+static int hp_wmi_rfkill2_set_block(void *data, bool blocked)
+{
+ int rfkill_id = (int)(long)data;
+ char buffer[4] = { 0x01, 0x00, rfkill_id, !blocked };
+
+ if (hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 1,
+ buffer, sizeof(buffer), 0))
+ return -EINVAL;
+ return 0;
+}
+
+static const struct rfkill_ops hp_wmi_rfkill2_ops = {
+ .set_block = hp_wmi_rfkill2_set_block,
+};
+
+static int hp_wmi_rfkill2_refresh(void)
+{
+ int err, i;
+ struct bios_rfkill2_state state;
+
+ err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 0, &state,
+ 0, sizeof(state));
+ if (err)
+ return err;
+
+ for (i = 0; i < rfkill2_count; i++) {
+ int num = rfkill2[i].num;
+ struct bios_rfkill2_device_state *devstate;
+ devstate = &state.device[num];
+
+ if (num >= state.count ||
+ devstate->rfkill_id != rfkill2[i].id) {
+ printk(KERN_WARNING PREFIX "power configuration of "
+ "the wireless devices unexpectedly changed\n");
+ continue;
+ }
+
+ rfkill_set_states(rfkill2[i].rfkill,
+ IS_SWBLOCKED(devstate->power),
+ IS_HWBLOCKED(devstate->power));
+ }
+
+ return 0;
+}
+
static ssize_t show_display(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -329,7 +447,7 @@ static ssize_t set_als(struct device *dev, struct device_attribute *attr,
{
u32 tmp = simple_strtoul(buf, NULL, 10);
int ret = hp_wmi_perform_query(HPWMI_ALS_QUERY, 1, &tmp,
- sizeof(tmp));
+ sizeof(tmp), sizeof(tmp));
if (ret)
return -EINVAL;
@@ -402,6 +520,7 @@ static void hp_wmi_notify(u32 value, void *context)
case HPWMI_BEZEL_BUTTON:
ret = hp_wmi_perform_query(HPWMI_HOTKEY_QUERY, 0,
&key_code,
+ sizeof(key_code),
sizeof(key_code));
if (ret)
break;
@@ -412,6 +531,11 @@ static void hp_wmi_notify(u32 value, void *context)
key_code);
break;
case HPWMI_WIRELESS:
+ if (rfkill2_count) {
+ hp_wmi_rfkill2_refresh();
+ break;
+ }
+
if (wifi_rfkill)
rfkill_set_states(wifi_rfkill,
hp_wmi_get_sw_state(HPWMI_WIFI),
@@ -502,32 +626,16 @@ static void cleanup_sysfs(struct platform_device *device)
device_remove_file(&device->dev, &dev_attr_tablet);
}
-static int __devinit hp_wmi_bios_setup(struct platform_device *device)
+static int __devinit hp_wmi_rfkill_setup(struct platform_device *device)
{
int err;
int wireless = 0;
err = hp_wmi_perform_query(HPWMI_WIRELESS_QUERY, 0, &wireless,
- sizeof(wireless));
+ sizeof(wireless), sizeof(wireless));
if (err)
return err;
- err = device_create_file(&device->dev, &dev_attr_display);
- if (err)
- goto add_sysfs_error;
- err = device_create_file(&device->dev, &dev_attr_hddtemp);
- if (err)
- goto add_sysfs_error;
- err = device_create_file(&device->dev, &dev_attr_als);
- if (err)
- goto add_sysfs_error;
- err = device_create_file(&device->dev, &dev_attr_dock);
- if (err)
- goto add_sysfs_error;
- err = device_create_file(&device->dev, &dev_attr_tablet);
- if (err)
- goto add_sysfs_error;
-
if (wireless & 0x1) {
wifi_rfkill = rfkill_alloc("hp-wifi", &device->dev,
RFKILL_TYPE_WLAN,
@@ -573,14 +681,131 @@ static int __devinit hp_wmi_bios_setup(struct platform_device *device)
return 0;
register_wwan_err:
rfkill_destroy(wwan_rfkill);
+ wwan_rfkill = NULL;
if (bluetooth_rfkill)
rfkill_unregister(bluetooth_rfkill);
register_bluetooth_error:
rfkill_destroy(bluetooth_rfkill);
+ bluetooth_rfkill = NULL;
if (wifi_rfkill)
rfkill_unregister(wifi_rfkill);
register_wifi_error:
rfkill_destroy(wifi_rfkill);
+ wifi_rfkill = NULL;
+ return err;
+}
+
+static int __devinit hp_wmi_rfkill2_setup(struct platform_device *device)
+{
+ int err, i;
+ struct bios_rfkill2_state state;
+ err = hp_wmi_perform_query(HPWMI_WIRELESS2_QUERY, 0, &state,
+ 0, sizeof(state));
+ if (err)
+ return err;
+
+ if (state.count > HPWMI_MAX_RFKILL2_DEVICES) {
+ printk(KERN_WARNING PREFIX "unable to parse 0x1b query output\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < state.count; i++) {
+ struct rfkill *rfkill;
+ enum rfkill_type type;
+ char *name;
+ switch (state.device[i].radio_type) {
+ case HPWMI_WIFI:
+ type = RFKILL_TYPE_WLAN;
+ name = "hp-wifi";
+ break;
+ case HPWMI_BLUETOOTH:
+ type = RFKILL_TYPE_BLUETOOTH;
+ name = "hp-bluetooth";
+ break;
+ case HPWMI_WWAN:
+ type = RFKILL_TYPE_WWAN;
+ name = "hp-wwan";
+ break;
+ default:
+ printk(KERN_WARNING PREFIX "unknown device type 0x%x\n",
+ state.device[i].radio_type);
+ continue;
+ }
+
+ if (!state.device[i].vendor_id) {
+ printk(KERN_WARNING PREFIX "zero device %d while %d "
+ "reported\n", i, state.count);
+ continue;
+ }
+
+ rfkill = rfkill_alloc(name, &device->dev, type,
+ &hp_wmi_rfkill2_ops, (void *)(long)i);
+ if (!rfkill) {
+ err = -ENOMEM;
+ goto fail;
+ }
+
+ rfkill2[rfkill2_count].id = state.device[i].rfkill_id;
+ rfkill2[rfkill2_count].num = i;
+ rfkill2[rfkill2_count].rfkill = rfkill;
+
+ rfkill_init_sw_state(rfkill,
+ IS_SWBLOCKED(state.device[i].power));
+ rfkill_set_hw_state(rfkill,
+ IS_HWBLOCKED(state.device[i].power));
+
+ if (!(state.device[i].power & HPWMI_POWER_BIOS))
+ printk(KERN_INFO PREFIX "device %s blocked by BIOS\n",
+ name);
+
+ err = rfkill_register(rfkill);
+ if (err) {
+ rfkill_destroy(rfkill);
+ goto fail;
+ }
+
+ rfkill2_count++;
+ }
+
+ return 0;
+fail:
+ for (; rfkill2_count > 0; rfkill2_count--) {
+ rfkill_unregister(rfkill2[rfkill2_count - 1].rfkill);
+ rfkill_destroy(rfkill2[rfkill2_count - 1].rfkill);
+ }
+ return err;
+}
+
+static int __devinit hp_wmi_bios_setup(struct platform_device *device)
+{
+ int err;
+
+ /* clear detected rfkill devices */
+ wifi_rfkill = NULL;
+ bluetooth_rfkill = NULL;
+ wwan_rfkill = NULL;
+ rfkill2_count = 0;
+
+ if (hp_wmi_rfkill_setup(device))
+ hp_wmi_rfkill2_setup(device);
+
+ err = device_create_file(&device->dev, &dev_attr_display);
+ if (err)
+ goto add_sysfs_error;
+ err = device_create_file(&device->dev, &dev_attr_hddtemp);
+ if (err)
+ goto add_sysfs_error;
+ err = device_create_file(&device->dev, &dev_attr_als);
+ if (err)
+ goto add_sysfs_error;
+ err = device_create_file(&device->dev, &dev_attr_dock);
+ if (err)
+ goto add_sysfs_error;
+ err = device_create_file(&device->dev, &dev_attr_tablet);
+ if (err)
+ goto add_sysfs_error;
+ return 0;
+
add_sysfs_error:
cleanup_sysfs(device);
return err;
@@ -588,8 +813,14 @@ add_sysfs_error:
static int __exit hp_wmi_bios_remove(struct platform_device *device)
{
+ int i;
cleanup_sysfs(device);
+ for (i = 0; i < rfkill2_count; i++) {
+ rfkill_unregister(rfkill2[i].rfkill);
+ rfkill_destroy(rfkill2[i].rfkill);
+ }
+
if (wifi_rfkill) {
rfkill_unregister(wifi_rfkill);
rfkill_destroy(wifi_rfkill);
@@ -622,6 +853,9 @@ static int hp_wmi_resume_handler(struct device *device)
input_sync(hp_wmi_input_dev);
}
+ if (rfkill2_count)
+ hp_wmi_rfkill2_refresh();
+
if (wifi_rfkill)
rfkill_set_states(wifi_rfkill,
hp_wmi_get_sw_state(HPWMI_WIFI),
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index 114d95247cd..21b101899ba 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -459,6 +459,8 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event)
if (test_bit(vpc_bit, &vpc1)) {
if (vpc_bit == 9)
ideapad_sync_rfk_state(adevice);
+ else if (vpc_bit == 4)
+ read_ec_data(handle, 0x12, &vpc2);
else
ideapad_input_report(priv, vpc_bit);
}
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 1294a39373b..85c8ad43c0c 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -1111,7 +1111,7 @@ static int ips_monitor(void *data)
last_msecs = jiffies_to_msecs(jiffies);
expire = jiffies + msecs_to_jiffies(IPS_SAMPLE_PERIOD);
- __set_current_state(TASK_UNINTERRUPTIBLE);
+ __set_current_state(TASK_INTERRUPTIBLE);
mod_timer(&timer, expire);
schedule();
diff --git a/drivers/platform/x86/intel_mid_powerbtn.c b/drivers/platform/x86/intel_mid_powerbtn.c
new file mode 100644
index 00000000000..213e79ba68d
--- /dev/null
+++ b/drivers/platform/x86/intel_mid_powerbtn.c
@@ -0,0 +1,148 @@
+/*
+ * Power button driver for Medfield.
+ *
+ * Copyright (C) 2010 Intel 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; 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <asm/intel_scu_ipc.h>
+
+#define DRIVER_NAME "msic_power_btn"
+
+#define MSIC_IRQ_STAT 0x02
+ #define MSIC_IRQ_PB (1 << 0)
+#define MSIC_PB_CONFIG 0x3e
+#define MSIC_PB_STATUS 0x3f
+ #define MSIC_PB_LEVEL (1 << 3) /* 1 - release, 0 - press */
+
+struct mfld_pb_priv {
+ struct input_dev *input;
+ unsigned int irq;
+};
+
+static irqreturn_t mfld_pb_isr(int irq, void *dev_id)
+{
+ struct mfld_pb_priv *priv = dev_id;
+ int ret;
+ u8 pbstat;
+
+ ret = intel_scu_ipc_ioread8(MSIC_PB_STATUS, &pbstat);
+ if (ret < 0)
+ return IRQ_HANDLED;
+
+ input_event(priv->input, EV_KEY, KEY_POWER, !(pbstat & MSIC_PB_LEVEL));
+ input_sync(priv->input);
+
+ return IRQ_HANDLED;
+}
+
+static int __devinit mfld_pb_probe(struct platform_device *pdev)
+{
+ struct mfld_pb_priv *priv;
+ struct input_dev *input;
+ int irq;
+ int error;
+
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return -EINVAL;
+
+ priv = kzalloc(sizeof(struct mfld_pb_priv), GFP_KERNEL);
+ input = input_allocate_device();
+ if (!priv || !input) {
+ error = -ENOMEM;
+ goto err_free_mem;
+ }
+
+ priv->input = input;
+ priv->irq = irq;
+
+ input->name = pdev->name;
+ input->phys = "power-button/input0";
+ input->id.bustype = BUS_HOST;
+ input->dev.parent = &pdev->dev;
+
+ input_set_capability(input, EV_KEY, KEY_POWER);
+
+ error = request_threaded_irq(priv->irq, NULL, mfld_pb_isr,
+ 0, DRIVER_NAME, priv);
+ if (error) {
+ dev_err(&pdev->dev,
+ "unable to request irq %d for mfld power button\n",
+ irq);
+ goto err_free_mem;
+ }
+
+ error = input_register_device(input);
+ if (error) {
+ dev_err(&pdev->dev,
+ "unable to register input dev, error %d\n", error);
+ goto err_free_irq;
+ }
+
+ platform_set_drvdata(pdev, priv);
+ return 0;
+
+err_free_irq:
+ free_irq(priv->irq, priv);
+err_free_mem:
+ input_free_device(input);
+ kfree(priv);
+ return error;
+}
+
+static int __devexit mfld_pb_remove(struct platform_device *pdev)
+{
+ struct mfld_pb_priv *priv = platform_get_drvdata(pdev);
+
+ free_irq(priv->irq, priv);
+ input_unregister_device(priv->input);
+ kfree(priv);
+
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static struct platform_driver mfld_pb_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = mfld_pb_probe,
+ .remove = __devexit_p(mfld_pb_remove),
+};
+
+static int __init mfld_pb_init(void)
+{
+ return platform_driver_register(&mfld_pb_driver);
+}
+module_init(mfld_pb_init);
+
+static void __exit mfld_pb_exit(void)
+{
+ platform_driver_unregister(&mfld_pb_driver);
+}
+module_exit(mfld_pb_exit);
+
+MODULE_AUTHOR("Hong Liu <hong.liu@intel.com>");
+MODULE_DESCRIPTION("Intel Medfield Power Button Driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
new file mode 100644
index 00000000000..6c12db50316
--- /dev/null
+++ b/drivers/platform/x86/intel_mid_thermal.c
@@ -0,0 +1,576 @@
+/*
+ * intel_mid_thermal.c - Intel MID platform thermal driver
+ *
+ * Copyright (C) 2011 Intel 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; 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.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ * Author: Durgadoss R <durgadoss.r@intel.com>
+ */
+
+#define pr_fmt(fmt) "intel_mid_thermal: " fmt
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/param.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/pm.h>
+#include <linux/thermal.h>
+
+#include <asm/intel_scu_ipc.h>
+
+/* Number of thermal sensors */
+#define MSIC_THERMAL_SENSORS 4
+
+/* ADC1 - thermal registers */
+#define MSIC_THERM_ADC1CNTL1 0x1C0
+#define MSIC_ADC_ENBL 0x10
+#define MSIC_ADC_START 0x08
+
+#define MSIC_THERM_ADC1CNTL3 0x1C2
+#define MSIC_ADCTHERM_ENBL 0x04
+#define MSIC_ADCRRDATA_ENBL 0x05
+#define MSIC_CHANL_MASK_VAL 0x0F
+
+#define MSIC_STOPBIT_MASK 16
+#define MSIC_ADCTHERM_MASK 4
+#define ADC_CHANLS_MAX 15 /* Number of ADC channels */
+#define ADC_LOOP_MAX (ADC_CHANLS_MAX - MSIC_THERMAL_SENSORS)
+
+/* ADC channel code values */
+#define SKIN_SENSOR0_CODE 0x08
+#define SKIN_SENSOR1_CODE 0x09
+#define SYS_SENSOR_CODE 0x0A
+#define MSIC_DIE_SENSOR_CODE 0x03
+
+#define SKIN_THERM_SENSOR0 0
+#define SKIN_THERM_SENSOR1 1
+#define SYS_THERM_SENSOR2 2
+#define MSIC_DIE_THERM_SENSOR3 3
+
+/* ADC code range */
+#define ADC_MAX 977
+#define ADC_MIN 162
+#define ADC_VAL0C 887
+#define ADC_VAL20C 720
+#define ADC_VAL40C 508
+#define ADC_VAL60C 315
+
+/* ADC base addresses */
+#define ADC_CHNL_START_ADDR 0x1C5 /* increments by 1 */
+#define ADC_DATA_START_ADDR 0x1D4 /* increments by 2 */
+
+/* MSIC die attributes */
+#define MSIC_DIE_ADC_MIN 488
+#define MSIC_DIE_ADC_MAX 1004
+
+/* This holds the address of the first free ADC channel,
+ * among the 15 channels
+ */
+static int channel_index;
+
+struct platform_info {
+ struct platform_device *pdev;
+ struct thermal_zone_device *tzd[MSIC_THERMAL_SENSORS];
+};
+
+struct thermal_device_info {
+ unsigned int chnl_addr;
+ int direct;
+ /* This holds the current temperature in millidegree celsius */
+ long curr_temp;
+};
+
+/**
+ * to_msic_die_temp - converts adc_val to msic_die temperature
+ * @adc_val: ADC value to be converted
+ *
+ * Can sleep
+ */
+static int to_msic_die_temp(uint16_t adc_val)
+{
+ return (368 * (adc_val) / 1000) - 220;
+}
+
+/**
+ * is_valid_adc - checks whether the adc code is within the defined range
+ * @min: minimum value for the sensor
+ * @max: maximum value for the sensor
+ *
+ * Can sleep
+ */
+static int is_valid_adc(uint16_t adc_val, uint16_t min, uint16_t max)
+{
+ return (adc_val >= min) && (adc_val <= max);
+}
+
+/**
+ * adc_to_temp - converts the ADC code to temperature in C
+ * @direct: true if ths channel is direct index
+ * @adc_val: the adc_val that needs to be converted
+ * @tp: temperature return value
+ *
+ * Linear approximation is used to covert the skin adc value into temperature.
+ * This technique is used to avoid very long look-up table to get
+ * the appropriate temp value from ADC value.
+ * The adc code vs sensor temp curve is split into five parts
+ * to achieve very close approximate temp value with less than
+ * 0.5C error
+ */
+static int adc_to_temp(int direct, uint16_t adc_val, unsigned long *tp)
+{
+ int temp;
+
+ /* Direct conversion for die temperature */
+ if (direct) {
+ if (is_valid_adc(adc_val, MSIC_DIE_ADC_MIN, MSIC_DIE_ADC_MAX)) {
+ *tp = to_msic_die_temp(adc_val) * 1000;
+ return 0;
+ }
+ return -ERANGE;
+ }
+
+ if (!is_valid_adc(adc_val, ADC_MIN, ADC_MAX))
+ return -ERANGE;
+
+ /* Linear approximation for skin temperature */
+ if (adc_val > ADC_VAL0C)
+ temp = 177 - (adc_val/5);
+ else if ((adc_val <= ADC_VAL0C) && (adc_val > ADC_VAL20C))
+ temp = 111 - (adc_val/8);
+ else if ((adc_val <= ADC_VAL20C) && (adc_val > ADC_VAL40C))
+ temp = 92 - (adc_val/10);
+ else if ((adc_val <= ADC_VAL40C) && (adc_val > ADC_VAL60C))
+ temp = 91 - (adc_val/10);
+ else
+ temp = 112 - (adc_val/6);
+
+ /* Convert temperature in celsius to milli degree celsius */
+ *tp = temp * 1000;
+ return 0;
+}
+
+/**
+ * mid_read_temp - read sensors for temperature
+ * @temp: holds the current temperature for the sensor after reading
+ *
+ * reads the adc_code from the channel and converts it to real
+ * temperature. The converted value is stored in temp.
+ *
+ * Can sleep
+ */
+static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp)
+{
+ struct thermal_device_info *td_info = tzd->devdata;
+ uint16_t adc_val, addr;
+ uint8_t data = 0;
+ int ret;
+ unsigned long curr_temp;
+
+
+ addr = td_info->chnl_addr;
+
+ /* Enable the msic for conversion before reading */
+ ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
+ if (ret)
+ return ret;
+
+ /* Re-toggle the RRDATARD bit (temporary workaround) */
+ ret = intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
+ if (ret)
+ return ret;
+
+ /* Read the higher bits of data */
+ ret = intel_scu_ipc_ioread8(addr, &data);
+ if (ret)
+ return ret;
+
+ /* Shift bits to accomodate the lower two data bits */
+ adc_val = (data << 2);
+ addr++;
+
+ ret = intel_scu_ipc_ioread8(addr, &data);/* Read lower bits */
+ if (ret)
+ return ret;
+
+ /* Adding lower two bits to the higher bits */
+ data &= 03;
+ adc_val += data;
+
+ /* Convert ADC value to temperature */
+ ret = adc_to_temp(td_info->direct, adc_val, &curr_temp);
+ if (ret == 0)
+ *temp = td_info->curr_temp = curr_temp;
+ return ret;
+}
+
+/**
+ * configure_adc - enables/disables the ADC for conversion
+ * @val: zero: disables the ADC non-zero:enables the ADC
+ *
+ * Enable/Disable the ADC depending on the argument
+ *
+ * Can sleep
+ */
+static int configure_adc(int val)
+{
+ int ret;
+ uint8_t data;
+
+ ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
+ if (ret)
+ return ret;
+
+ if (val) {
+ /* Enable and start the ADC */
+ data |= (MSIC_ADC_ENBL | MSIC_ADC_START);
+ } else {
+ /* Just stop the ADC */
+ data &= (~MSIC_ADC_START);
+ }
+
+ return intel_scu_ipc_iowrite8(MSIC_THERM_ADC1CNTL1, data);
+}
+
+/**
+ * set_up_therm_channel - enable thermal channel for conversion
+ * @base_addr: index of free msic ADC channel
+ *
+ * Enable all the three channels for conversion
+ *
+ * Can sleep
+ */
+static int set_up_therm_channel(u16 base_addr)
+{
+ int ret;
+
+ /* Enable all the sensor channels */
+ ret = intel_scu_ipc_iowrite8(base_addr, SKIN_SENSOR0_CODE);
+ if (ret)
+ return ret;
+
+ ret = intel_scu_ipc_iowrite8(base_addr + 1, SKIN_SENSOR1_CODE);
+ if (ret)
+ return ret;
+
+ ret = intel_scu_ipc_iowrite8(base_addr + 2, SYS_SENSOR_CODE);
+ if (ret)
+ return ret;
+
+ /* Since this is the last channel, set the stop bit
+ to 1 by ORing the DIE_SENSOR_CODE with 0x10 */
+ ret = intel_scu_ipc_iowrite8(base_addr + 3,
+ (MSIC_DIE_SENSOR_CODE | 0x10));
+ if (ret)
+ return ret;
+
+ /* Enable ADC and start it */
+ return configure_adc(1);
+}
+
+/**
+ * reset_stopbit - sets the stop bit to 0 on the given channel
+ * @addr: address of the channel
+ *
+ * Can sleep
+ */
+static int reset_stopbit(uint16_t addr)
+{
+ int ret;
+ uint8_t data;
+ ret = intel_scu_ipc_ioread8(addr, &data);
+ if (ret)
+ return ret;
+ /* Set the stop bit to zero */
+ return intel_scu_ipc_iowrite8(addr, (data & 0xEF));
+}
+
+/**
+ * find_free_channel - finds an empty channel for conversion
+ *
+ * If the ADC is not enabled then start using 0th channel
+ * itself. Otherwise find an empty channel by looking for a
+ * channel in which the stopbit is set to 1. returns the index
+ * of the first free channel if succeeds or an error code.
+ *
+ * Context: can sleep
+ *
+ * FIXME: Ultimately the channel allocator will move into the intel_scu_ipc
+ * code.
+ */
+static int find_free_channel(void)
+{
+ int ret;
+ int i;
+ uint8_t data;
+
+ /* check whether ADC is enabled */
+ ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL1, &data);
+ if (ret)
+ return ret;
+
+ if ((data & MSIC_ADC_ENBL) == 0)
+ return 0;
+
+ /* ADC is already enabled; Looking for an empty channel */
+ for (i = 0; i < ADC_CHANLS_MAX; i++) {
+ ret = intel_scu_ipc_ioread8(ADC_CHNL_START_ADDR + i, &data);
+ if (ret)
+ return ret;
+
+ if (data & MSIC_STOPBIT_MASK) {
+ ret = i;
+ break;
+ }
+ }
+ return (ret > ADC_LOOP_MAX) ? (-EINVAL) : ret;
+}
+
+/**
+ * mid_initialize_adc - initializing the ADC
+ * @dev: our device structure
+ *
+ * Initialize the ADC for reading thermistor values. Can sleep.
+ */
+static int mid_initialize_adc(struct device *dev)
+{
+ u8 data;
+ u16 base_addr;
+ int ret;
+
+ /*
+ * Ensure that adctherm is disabled before we
+ * initialize the ADC
+ */
+ ret = intel_scu_ipc_ioread8(MSIC_THERM_ADC1CNTL3, &data);
+ if (ret)
+ return ret;
+
+ if (data & MSIC_ADCTHERM_MASK)
+ dev_warn(dev, "ADCTHERM already set");
+
+ /* Index of the first channel in which the stop bit is set */
+ channel_index = find_free_channel();
+ if (channel_index < 0) {
+ dev_err(dev, "No free ADC channels");
+ return channel_index;
+ }
+
+ base_addr = ADC_CHNL_START_ADDR + channel_index;
+
+ if (!(channel_index == 0 || channel_index == ADC_LOOP_MAX)) {
+ /* Reset stop bit for channels other than 0 and 12 */
+ ret = reset_stopbit(base_addr);
+ if (ret)
+ return ret;
+
+ /* Index of the first free channel */
+ base_addr++;
+ channel_index++;
+ }
+
+ ret = set_up_therm_channel(base_addr);
+ if (ret) {
+ dev_err(dev, "unable to enable ADC");
+ return ret;
+ }
+ dev_dbg(dev, "ADC initialization successful");
+ return ret;
+}
+
+/**
+ * initialize_sensor - sets default temp and timer ranges
+ * @index: index of the sensor
+ *
+ * Context: can sleep
+ */
+static struct thermal_device_info *initialize_sensor(int index)
+{
+ struct thermal_device_info *td_info =
+ kzalloc(sizeof(struct thermal_device_info), GFP_KERNEL);
+
+ if (!td_info)
+ return NULL;
+
+ /* Set the base addr of the channel for this sensor */
+ td_info->chnl_addr = ADC_DATA_START_ADDR + 2 * (channel_index + index);
+ /* Sensor 3 is direct conversion */
+ if (index == 3)
+ td_info->direct = 1;
+ return td_info;
+}
+
+/**
+ * mid_thermal_resume - resume routine
+ * @pdev: platform device structure
+ *
+ * mid thermal resume: re-initializes the adc. Can sleep.
+ */
+static int mid_thermal_resume(struct platform_device *pdev)
+{
+ return mid_initialize_adc(&pdev->dev);
+}
+
+/**
+ * mid_thermal_suspend - suspend routine
+ * @pdev: platform device structure
+ *
+ * mid thermal suspend implements the suspend functionality
+ * by stopping the ADC. Can sleep.
+ */
+static int mid_thermal_suspend(struct platform_device *pdev, pm_message_t mesg)
+{
+ /*
+ * This just stops the ADC and does not disable it.
+ * temporary workaround until we have a generic ADC driver.
+ * If 0 is passed, it disables the ADC.
+ */
+ return configure_adc(0);
+}
+
+/**
+ * read_curr_temp - reads the current temperature and stores in temp
+ * @temp: holds the current temperature value after reading
+ *
+ * Can sleep
+ */
+static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp)
+{
+ WARN_ON(tzd == NULL);
+ return mid_read_temp(tzd, temp);
+}
+
+/* Can't be const */
+static struct thermal_zone_device_ops tzd_ops = {
+ .get_temp = read_curr_temp,
+};
+
+
+/**
+ * mid_thermal_probe - mfld thermal initialize
+ * @pdev: platform device structure
+ *
+ * mid thermal probe initializes the hardware and registers
+ * all the sensors with the generic thermal framework. Can sleep.
+ */
+static int mid_thermal_probe(struct platform_device *pdev)
+{
+ static char *name[MSIC_THERMAL_SENSORS] = {
+ "skin0", "skin1", "sys", "msicdie"
+ };
+
+ int ret;
+ int i;
+ struct platform_info *pinfo;
+
+ pinfo = kzalloc(sizeof(struct platform_info), GFP_KERNEL);
+ if (!pinfo)
+ return -ENOMEM;
+
+ /* Initializing the hardware */
+ ret = mid_initialize_adc(&pdev->dev);
+ if (ret) {
+ dev_err(&pdev->dev, "ADC init failed");
+ kfree(pinfo);
+ return ret;
+ }
+
+ /* Register each sensor with the generic thermal framework*/
+ for (i = 0; i < MSIC_THERMAL_SENSORS; i++) {
+ pinfo->tzd[i] = thermal_zone_device_register(name[i],
+ 0, initialize_sensor(i),
+ &tzd_ops, 0, 0, 0, 0);
+ if (IS_ERR(pinfo->tzd[i]))
+ goto reg_fail;
+ }
+
+ pinfo->pdev = pdev;
+ platform_set_drvdata(pdev, pinfo);
+ return 0;
+
+reg_fail:
+ ret = PTR_ERR(pinfo->tzd[i]);
+ while (--i >= 0)
+ thermal_zone_device_unregister(pinfo->tzd[i]);
+ configure_adc(0);
+ kfree(pinfo);
+ return ret;
+}
+
+/**
+ * mid_thermal_remove - mfld thermal finalize
+ * @dev: platform device structure
+ *
+ * MLFD thermal remove unregisters all the sensors from the generic
+ * thermal framework. Can sleep.
+ */
+static int mid_thermal_remove(struct platform_device *pdev)
+{
+ int i;
+ struct platform_info *pinfo = platform_get_drvdata(pdev);
+
+ for (i = 0; i < MSIC_THERMAL_SENSORS; i++)
+ thermal_zone_device_unregister(pinfo->tzd[i]);
+
+ platform_set_drvdata(pdev, NULL);
+
+ /* Stop the ADC */
+ return configure_adc(0);
+}
+
+/*********************************************************************
+ * Driver initialisation and finalization
+ *********************************************************************/
+
+#define DRIVER_NAME "msic_sensor"
+
+static const struct platform_device_id therm_id_table[] = {
+ { DRIVER_NAME, 1 },
+ { }
+};
+
+static struct platform_driver mid_thermal_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = mid_thermal_probe,
+ .suspend = mid_thermal_suspend,
+ .resume = mid_thermal_resume,
+ .remove = __devexit_p(mid_thermal_remove),
+ .id_table = therm_id_table,
+};
+
+static int __init mid_thermal_module_init(void)
+{
+ return platform_driver_register(&mid_thermal_driver);
+}
+
+static void __exit mid_thermal_module_exit(void)
+{
+ platform_driver_unregister(&mid_thermal_driver);
+}
+
+module_init(mid_thermal_module_init);
+module_exit(mid_thermal_module_exit);
+
+MODULE_AUTHOR("Durgadoss R <durgadoss.r@intel.com>");
+MODULE_DESCRIPTION("Intel Medfield Platform Thermal Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/intel_pmic_gpio.c b/drivers/platform/x86/intel_pmic_gpio.c
index 61433d49286..d653104b59c 100644
--- a/drivers/platform/x86/intel_pmic_gpio.c
+++ b/drivers/platform/x86/intel_pmic_gpio.c
@@ -257,9 +257,11 @@ static int __devinit platform_pmic_gpio_probe(struct platform_device *pdev)
}
for (i = 0; i < 8; i++) {
- set_irq_chip_and_handler_name(i + pg->irq_base, &pmic_irqchip,
- handle_simple_irq, "demux");
- set_irq_chip_data(i + pg->irq_base, pg);
+ irq_set_chip_and_handler_name(i + pg->irq_base,
+ &pmic_irqchip,
+ handle_simple_irq,
+ "demux");
+ irq_set_chip_data(i + pg->irq_base, pg);
}
return 0;
err:
diff --git a/drivers/platform/x86/intel_rar_register.c b/drivers/platform/x86/intel_rar_register.c
index 2b11a33325e..bde47e9080c 100644
--- a/drivers/platform/x86/intel_rar_register.c
+++ b/drivers/platform/x86/intel_rar_register.c
@@ -485,7 +485,7 @@ EXPORT_SYMBOL(rar_lock);
*
* The register_rar function is to used by other device drivers
* to ensure that this driver is ready. As we cannot be sure of
- * the compile/execute order of drivers in ther kernel, it is
+ * the compile/execute order of drivers in the kernel, it is
* best to give this driver a callback function to call when
* it is ready to give out addresses. The callback function
* would have those steps that continue the initialization of
diff --git a/drivers/platform/x86/intel_scu_ipc.c b/drivers/platform/x86/intel_scu_ipc.c
index a91d510a798..940accbe28d 100644
--- a/drivers/platform/x86/intel_scu_ipc.c
+++ b/drivers/platform/x86/intel_scu_ipc.c
@@ -9,7 +9,7 @@
* as published by the Free Software Foundation; version 2
* of the License.
*
- * SCU runing in ARC processor communicates with other entity running in IA
+ * SCU running in ARC processor communicates with other entity running in IA
* core through IPC mechanism which in turn messaging between IA core ad SCU.
* SCU has two IPC mechanism IPC-1 and IPC-2. IPC-1 is used between IA32 and
* SCU where IPC-2 is used between P-Unit and SCU. This driver delas with
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
index 142d3857931..23fb2afda00 100644
--- a/drivers/platform/x86/msi-laptop.c
+++ b/drivers/platform/x86/msi-laptop.c
@@ -51,6 +51,8 @@
* laptop as MSI S270. YMMV.
*/
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
@@ -60,6 +62,8 @@
#include <linux/platform_device.h>
#include <linux/rfkill.h>
#include <linux/i8042.h>
+#include <linux/input.h>
+#include <linux/input/sparse-keymap.h>
#define MSI_DRIVER_VERSION "0.5"
@@ -78,6 +82,9 @@
#define MSI_STANDARD_EC_SCM_LOAD_ADDRESS 0x2d
#define MSI_STANDARD_EC_SCM_LOAD_MASK (1 << 0)
+#define MSI_STANDARD_EC_TOUCHPAD_ADDRESS 0xe4
+#define MSI_STANDARD_EC_TOUCHPAD_MASK (1 << 4)
+
static int msi_laptop_resume(struct platform_device *device);
#define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f
@@ -90,6 +97,14 @@ static int auto_brightness;
module_param(auto_brightness, int, 0);
MODULE_PARM_DESC(auto_brightness, "Enable automatic brightness control (0: disabled; 1: enabled; 2: don't touch)");
+static const struct key_entry msi_laptop_keymap[] = {
+ {KE_KEY, KEY_TOUCHPAD_ON, {KEY_TOUCHPAD_ON} }, /* Touch Pad On */
+ {KE_KEY, KEY_TOUCHPAD_OFF, {KEY_TOUCHPAD_OFF} },/* Touch Pad On */
+ {KE_END, 0}
+};
+
+static struct input_dev *msi_laptop_input_dev;
+
static bool old_ec_model;
static int wlan_s, bluetooth_s, threeg_s;
static int threeg_exists;
@@ -432,8 +447,7 @@ static struct platform_device *msipf_device;
static int dmi_check_cb(const struct dmi_system_id *id)
{
- printk(KERN_INFO "msi-laptop: Identified laptop model '%s'.\n",
- id->ident);
+ pr_info("Identified laptop model '%s'.\n", id->ident);
return 1;
}
@@ -605,6 +619,21 @@ static void msi_update_rfkill(struct work_struct *ignored)
}
static DECLARE_DELAYED_WORK(msi_rfkill_work, msi_update_rfkill);
+static void msi_send_touchpad_key(struct work_struct *ignored)
+{
+ u8 rdata;
+ int result;
+
+ result = ec_read(MSI_STANDARD_EC_TOUCHPAD_ADDRESS, &rdata);
+ if (result < 0)
+ return;
+
+ sparse_keymap_report_event(msi_laptop_input_dev,
+ (rdata & MSI_STANDARD_EC_TOUCHPAD_MASK) ?
+ KEY_TOUCHPAD_ON : KEY_TOUCHPAD_OFF, 1, true);
+}
+static DECLARE_DELAYED_WORK(msi_touchpad_work, msi_send_touchpad_key);
+
static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
struct serio *port)
{
@@ -613,12 +642,17 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
if (str & 0x20)
return false;
- /* 0x54 wwan, 0x62 bluetooth, 0x76 wlan*/
+ /* 0x54 wwan, 0x62 bluetooth, 0x76 wlan, 0xE4 touchpad toggle*/
if (unlikely(data == 0xe0)) {
extended = true;
return false;
} else if (unlikely(extended)) {
+ extended = false;
switch (data) {
+ case 0xE4:
+ schedule_delayed_work(&msi_touchpad_work,
+ round_jiffies_relative(0.5 * HZ));
+ break;
case 0x54:
case 0x62:
case 0x76:
@@ -626,7 +660,6 @@ static bool msi_laptop_i8042_filter(unsigned char data, unsigned char str,
round_jiffies_relative(0.5 * HZ));
break;
}
- extended = false;
}
return false;
@@ -731,6 +764,42 @@ static int msi_laptop_resume(struct platform_device *device)
return 0;
}
+static int __init msi_laptop_input_setup(void)
+{
+ int err;
+
+ msi_laptop_input_dev = input_allocate_device();
+ if (!msi_laptop_input_dev)
+ return -ENOMEM;
+
+ msi_laptop_input_dev->name = "MSI Laptop hotkeys";
+ msi_laptop_input_dev->phys = "msi-laptop/input0";
+ msi_laptop_input_dev->id.bustype = BUS_HOST;
+
+ err = sparse_keymap_setup(msi_laptop_input_dev,
+ msi_laptop_keymap, NULL);
+ if (err)
+ goto err_free_dev;
+
+ err = input_register_device(msi_laptop_input_dev);
+ if (err)
+ goto err_free_keymap;
+
+ return 0;
+
+err_free_keymap:
+ sparse_keymap_free(msi_laptop_input_dev);
+err_free_dev:
+ input_free_device(msi_laptop_input_dev);
+ return err;
+}
+
+static void msi_laptop_input_destroy(void)
+{
+ sparse_keymap_free(msi_laptop_input_dev);
+ input_unregister_device(msi_laptop_input_dev);
+}
+
static int load_scm_model_init(struct platform_device *sdev)
{
u8 data;
@@ -759,16 +828,23 @@ static int load_scm_model_init(struct platform_device *sdev)
if (result < 0)
goto fail_rfkill;
+ /* setup input device */
+ result = msi_laptop_input_setup();
+ if (result)
+ goto fail_input;
+
result = i8042_install_filter(msi_laptop_i8042_filter);
if (result) {
- printk(KERN_ERR
- "msi-laptop: Unable to install key filter\n");
+ pr_err("Unable to install key filter\n");
goto fail_filter;
}
return 0;
fail_filter:
+ msi_laptop_input_destroy();
+
+fail_input:
rfkill_cleanup();
fail_rfkill:
@@ -799,7 +875,7 @@ static int __init msi_init(void)
/* Register backlight stuff */
if (acpi_video_backlight_support()) {
- printk(KERN_INFO "MSI: Brightness ignored, must be controlled "
+ pr_info("Brightness ignored, must be controlled "
"by ACPI video driver\n");
} else {
struct backlight_properties props;
@@ -854,7 +930,7 @@ static int __init msi_init(void)
if (auto_brightness != 2)
set_auto_brightness(auto_brightness);
- printk(KERN_INFO "msi-laptop: driver "MSI_DRIVER_VERSION" successfully loaded.\n");
+ pr_info("driver "MSI_DRIVER_VERSION" successfully loaded.\n");
return 0;
@@ -886,6 +962,7 @@ static void __exit msi_cleanup(void)
{
if (load_scm_model) {
i8042_remove_filter(msi_laptop_i8042_filter);
+ msi_laptop_input_destroy();
cancel_delayed_work_sync(&msi_rfkill_work);
rfkill_cleanup();
}
@@ -901,7 +978,7 @@ static void __exit msi_cleanup(void)
if (auto_brightness != 2)
set_auto_brightness(1);
- printk(KERN_INFO "msi-laptop: driver unloaded.\n");
+ pr_info("driver unloaded.\n");
}
module_init(msi_init);
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
new file mode 100644
index 00000000000..de434c6dc2d
--- /dev/null
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -0,0 +1,832 @@
+/*
+ * Samsung Laptop driver
+ *
+ * Copyright (C) 2009,2011 Greg Kroah-Hartman (gregkh@suse.de)
+ * Copyright (C) 2009,2011 Novell 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.
+ *
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/pci.h>
+#include <linux/backlight.h>
+#include <linux/fb.h>
+#include <linux/dmi.h>
+#include <linux/platform_device.h>
+#include <linux/rfkill.h>
+
+/*
+ * This driver is needed because a number of Samsung laptops do not hook
+ * their control settings through ACPI. So we have to poke around in the
+ * BIOS to do things like brightness values, and "special" key controls.
+ */
+
+/*
+ * We have 0 - 8 as valid brightness levels. The specs say that level 0 should
+ * be reserved by the BIOS (which really doesn't make much sense), we tell
+ * userspace that the value is 0 - 7 and then just tell the hardware 1 - 8
+ */
+#define MAX_BRIGHT 0x07
+
+
+#define SABI_IFACE_MAIN 0x00
+#define SABI_IFACE_SUB 0x02
+#define SABI_IFACE_COMPLETE 0x04
+#define SABI_IFACE_DATA 0x05
+
+/* Structure to get data back to the calling function */
+struct sabi_retval {
+ u8 retval[20];
+};
+
+struct sabi_header_offsets {
+ u8 port;
+ u8 re_mem;
+ u8 iface_func;
+ u8 en_mem;
+ u8 data_offset;
+ u8 data_segment;
+};
+
+struct sabi_commands {
+ /*
+ * Brightness is 0 - 8, as described above.
+ * Value 0 is for the BIOS to use
+ */
+ u8 get_brightness;
+ u8 set_brightness;
+
+ /*
+ * first byte:
+ * 0x00 - wireless is off
+ * 0x01 - wireless is on
+ * second byte:
+ * 0x02 - 3G is off
+ * 0x03 - 3G is on
+ * TODO, verify 3G is correct, that doesn't seem right...
+ */
+ u8 get_wireless_button;
+ u8 set_wireless_button;
+
+ /* 0 is off, 1 is on */
+ u8 get_backlight;
+ u8 set_backlight;
+
+ /*
+ * 0x80 or 0x00 - no action
+ * 0x81 - recovery key pressed
+ */
+ u8 get_recovery_mode;
+ u8 set_recovery_mode;
+
+ /*
+ * on seclinux: 0 is low, 1 is high,
+ * on swsmi: 0 is normal, 1 is silent, 2 is turbo
+ */
+ u8 get_performance_level;
+ u8 set_performance_level;
+
+ /*
+ * Tell the BIOS that Linux is running on this machine.
+ * 81 is on, 80 is off
+ */
+ u8 set_linux;
+};
+
+struct sabi_performance_level {
+ const char *name;
+ u8 value;
+};
+
+struct sabi_config {
+ const char *test_string;
+ u16 main_function;
+ const struct sabi_header_offsets header_offsets;
+ const struct sabi_commands commands;
+ const struct sabi_performance_level performance_levels[4];
+ u8 min_brightness;
+ u8 max_brightness;
+};
+
+static const struct sabi_config sabi_configs[] = {
+ {
+ .test_string = "SECLINUX",
+
+ .main_function = 0x4c49,
+
+ .header_offsets = {
+ .port = 0x00,
+ .re_mem = 0x02,
+ .iface_func = 0x03,
+ .en_mem = 0x04,
+ .data_offset = 0x05,
+ .data_segment = 0x07,
+ },
+
+ .commands = {
+ .get_brightness = 0x00,
+ .set_brightness = 0x01,
+
+ .get_wireless_button = 0x02,
+ .set_wireless_button = 0x03,
+
+ .get_backlight = 0x04,
+ .set_backlight = 0x05,
+
+ .get_recovery_mode = 0x06,
+ .set_recovery_mode = 0x07,
+
+ .get_performance_level = 0x08,
+ .set_performance_level = 0x09,
+
+ .set_linux = 0x0a,
+ },
+
+ .performance_levels = {
+ {
+ .name = "silent",
+ .value = 0,
+ },
+ {
+ .name = "normal",
+ .value = 1,
+ },
+ { },
+ },
+ .min_brightness = 1,
+ .max_brightness = 8,
+ },
+ {
+ .test_string = "SwSmi@",
+
+ .main_function = 0x5843,
+
+ .header_offsets = {
+ .port = 0x00,
+ .re_mem = 0x04,
+ .iface_func = 0x02,
+ .en_mem = 0x03,
+ .data_offset = 0x05,
+ .data_segment = 0x07,
+ },
+
+ .commands = {
+ .get_brightness = 0x10,
+ .set_brightness = 0x11,
+
+ .get_wireless_button = 0x12,
+ .set_wireless_button = 0x13,
+
+ .get_backlight = 0x2d,
+ .set_backlight = 0x2e,
+
+ .get_recovery_mode = 0xff,
+ .set_recovery_mode = 0xff,
+
+ .get_performance_level = 0x31,
+ .set_performance_level = 0x32,
+
+ .set_linux = 0xff,
+ },
+
+ .performance_levels = {
+ {
+ .name = "normal",
+ .value = 0,
+ },
+ {
+ .name = "silent",
+ .value = 1,
+ },
+ {
+ .name = "overclock",
+ .value = 2,
+ },
+ { },
+ },
+ .min_brightness = 0,
+ .max_brightness = 8,
+ },
+ { },
+};
+
+static const struct sabi_config *sabi_config;
+
+static void __iomem *sabi;
+static void __iomem *sabi_iface;
+static void __iomem *f0000_segment;
+static struct backlight_device *backlight_device;
+static struct mutex sabi_mutex;
+static struct platform_device *sdev;
+static struct rfkill *rfk;
+
+static int force;
+module_param(force, bool, 0);
+MODULE_PARM_DESC(force,
+ "Disable the DMI check and forces the driver to be loaded");
+
+static int debug;
+module_param(debug, bool, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
+static int sabi_get_command(u8 command, struct sabi_retval *sretval)
+{
+ int retval = 0;
+ u16 port = readw(sabi + sabi_config->header_offsets.port);
+ u8 complete, iface_data;
+
+ mutex_lock(&sabi_mutex);
+
+ /* enable memory to be able to write to it */
+ outb(readb(sabi + sabi_config->header_offsets.en_mem), port);
+
+ /* write out the command */
+ writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN);
+ writew(command, sabi_iface + SABI_IFACE_SUB);
+ writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
+ outb(readb(sabi + sabi_config->header_offsets.iface_func), port);
+
+ /* write protect memory to make it safe */
+ outb(readb(sabi + sabi_config->header_offsets.re_mem), port);
+
+ /* see if the command actually succeeded */
+ complete = readb(sabi_iface + SABI_IFACE_COMPLETE);
+ iface_data = readb(sabi_iface + SABI_IFACE_DATA);
+ if (complete != 0xaa || iface_data == 0xff) {
+ pr_warn("SABI get command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n",
+ command, complete, iface_data);
+ retval = -EINVAL;
+ goto exit;
+ }
+ /*
+ * Save off the data into a structure so the caller use it.
+ * Right now we only want the first 4 bytes,
+ * There are commands that need more, but not for the ones we
+ * currently care about.
+ */
+ sretval->retval[0] = readb(sabi_iface + SABI_IFACE_DATA);
+ sretval->retval[1] = readb(sabi_iface + SABI_IFACE_DATA + 1);
+ sretval->retval[2] = readb(sabi_iface + SABI_IFACE_DATA + 2);
+ sretval->retval[3] = readb(sabi_iface + SABI_IFACE_DATA + 3);
+
+exit:
+ mutex_unlock(&sabi_mutex);
+ return retval;
+
+}
+
+static int sabi_set_command(u8 command, u8 data)
+{
+ int retval = 0;
+ u16 port = readw(sabi + sabi_config->header_offsets.port);
+ u8 complete, iface_data;
+
+ mutex_lock(&sabi_mutex);
+
+ /* enable memory to be able to write to it */
+ outb(readb(sabi + sabi_config->header_offsets.en_mem), port);
+
+ /* write out the command */
+ writew(sabi_config->main_function, sabi_iface + SABI_IFACE_MAIN);
+ writew(command, sabi_iface + SABI_IFACE_SUB);
+ writeb(0, sabi_iface + SABI_IFACE_COMPLETE);
+ writeb(data, sabi_iface + SABI_IFACE_DATA);
+ outb(readb(sabi + sabi_config->header_offsets.iface_func), port);
+
+ /* write protect memory to make it safe */
+ outb(readb(sabi + sabi_config->header_offsets.re_mem), port);
+
+ /* see if the command actually succeeded */
+ complete = readb(sabi_iface + SABI_IFACE_COMPLETE);
+ iface_data = readb(sabi_iface + SABI_IFACE_DATA);
+ if (complete != 0xaa || iface_data == 0xff) {
+ pr_warn("SABI set command 0x%02x failed with completion flag 0x%02x and data 0x%02x\n",
+ command, complete, iface_data);
+ retval = -EINVAL;
+ }
+
+ mutex_unlock(&sabi_mutex);
+ return retval;
+}
+
+static void test_backlight(void)
+{
+ struct sabi_retval sretval;
+
+ sabi_get_command(sabi_config->commands.get_backlight, &sretval);
+ printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
+
+ sabi_set_command(sabi_config->commands.set_backlight, 0);
+ printk(KERN_DEBUG "backlight should be off\n");
+
+ sabi_get_command(sabi_config->commands.get_backlight, &sretval);
+ printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
+
+ msleep(1000);
+
+ sabi_set_command(sabi_config->commands.set_backlight, 1);
+ printk(KERN_DEBUG "backlight should be on\n");
+
+ sabi_get_command(sabi_config->commands.get_backlight, &sretval);
+ printk(KERN_DEBUG "backlight = 0x%02x\n", sretval.retval[0]);
+}
+
+static void test_wireless(void)
+{
+ struct sabi_retval sretval;
+
+ sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
+ printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
+
+ sabi_set_command(sabi_config->commands.set_wireless_button, 0);
+ printk(KERN_DEBUG "wireless led should be off\n");
+
+ sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
+ printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
+
+ msleep(1000);
+
+ sabi_set_command(sabi_config->commands.set_wireless_button, 1);
+ printk(KERN_DEBUG "wireless led should be on\n");
+
+ sabi_get_command(sabi_config->commands.get_wireless_button, &sretval);
+ printk(KERN_DEBUG "wireless led = 0x%02x\n", sretval.retval[0]);
+}
+
+static u8 read_brightness(void)
+{
+ struct sabi_retval sretval;
+ int user_brightness = 0;
+ int retval;
+
+ retval = sabi_get_command(sabi_config->commands.get_brightness,
+ &sretval);
+ if (!retval) {
+ user_brightness = sretval.retval[0];
+ if (user_brightness != 0)
+ user_brightness -= sabi_config->min_brightness;
+ }
+ return user_brightness;
+}
+
+static void set_brightness(u8 user_brightness)
+{
+ u8 user_level = user_brightness - sabi_config->min_brightness;
+
+ sabi_set_command(sabi_config->commands.set_brightness, user_level);
+}
+
+static int get_brightness(struct backlight_device *bd)
+{
+ return (int)read_brightness();
+}
+
+static int update_status(struct backlight_device *bd)
+{
+ set_brightness(bd->props.brightness);
+
+ if (bd->props.power == FB_BLANK_UNBLANK)
+ sabi_set_command(sabi_config->commands.set_backlight, 1);
+ else
+ sabi_set_command(sabi_config->commands.set_backlight, 0);
+ return 0;
+}
+
+static const struct backlight_ops backlight_ops = {
+ .get_brightness = get_brightness,
+ .update_status = update_status,
+};
+
+static int rfkill_set(void *data, bool blocked)
+{
+ /* Do something with blocked...*/
+ /*
+ * blocked == false is on
+ * blocked == true is off
+ */
+ if (blocked)
+ sabi_set_command(sabi_config->commands.set_wireless_button, 0);
+ else
+ sabi_set_command(sabi_config->commands.set_wireless_button, 1);
+
+ return 0;
+}
+
+static struct rfkill_ops rfkill_ops = {
+ .set_block = rfkill_set,
+};
+
+static int init_wireless(struct platform_device *sdev)
+{
+ int retval;
+
+ rfk = rfkill_alloc("samsung-wifi", &sdev->dev, RFKILL_TYPE_WLAN,
+ &rfkill_ops, NULL);
+ if (!rfk)
+ return -ENOMEM;
+
+ retval = rfkill_register(rfk);
+ if (retval) {
+ rfkill_destroy(rfk);
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static void destroy_wireless(void)
+{
+ rfkill_unregister(rfk);
+ rfkill_destroy(rfk);
+}
+
+static ssize_t get_performance_level(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct sabi_retval sretval;
+ int retval;
+ int i;
+
+ /* Read the state */
+ retval = sabi_get_command(sabi_config->commands.get_performance_level,
+ &sretval);
+ if (retval)
+ return retval;
+
+ /* The logic is backwards, yeah, lots of fun... */
+ for (i = 0; sabi_config->performance_levels[i].name; ++i) {
+ if (sretval.retval[0] == sabi_config->performance_levels[i].value)
+ return sprintf(buf, "%s\n", sabi_config->performance_levels[i].name);
+ }
+ return sprintf(buf, "%s\n", "unknown");
+}
+
+static ssize_t set_performance_level(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ if (count >= 1) {
+ int i;
+ for (i = 0; sabi_config->performance_levels[i].name; ++i) {
+ const struct sabi_performance_level *level =
+ &sabi_config->performance_levels[i];
+ if (!strncasecmp(level->name, buf, strlen(level->name))) {
+ sabi_set_command(sabi_config->commands.set_performance_level,
+ level->value);
+ break;
+ }
+ }
+ if (!sabi_config->performance_levels[i].name)
+ return -EINVAL;
+ }
+ return count;
+}
+static DEVICE_ATTR(performance_level, S_IWUSR | S_IRUGO,
+ get_performance_level, set_performance_level);
+
+
+static int __init dmi_check_cb(const struct dmi_system_id *id)
+{
+ pr_info("found laptop model '%s'\n",
+ id->ident);
+ return 1;
+}
+
+static struct dmi_system_id __initdata samsung_dmi_table[] = {
+ {
+ .ident = "N128",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N128"),
+ DMI_MATCH(DMI_BOARD_NAME, "N128"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "N130",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N130"),
+ DMI_MATCH(DMI_BOARD_NAME, "N130"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "X125",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X125"),
+ DMI_MATCH(DMI_BOARD_NAME, "X125"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "X120/X170",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X120/X170"),
+ DMI_MATCH(DMI_BOARD_NAME, "X120/X170"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "NC10",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "NC10"),
+ DMI_MATCH(DMI_BOARD_NAME, "NC10"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "NP-Q45",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "SQ45S70S"),
+ DMI_MATCH(DMI_BOARD_NAME, "SQ45S70S"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "X360",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "X360"),
+ DMI_MATCH(DMI_BOARD_NAME, "X360"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "R518",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "R518"),
+ DMI_MATCH(DMI_BOARD_NAME, "R518"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "R519/R719",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "R519/R719"),
+ DMI_MATCH(DMI_BOARD_NAME, "R519/R719"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "N150/N210/N220",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N150/N210/N220"),
+ DMI_MATCH(DMI_BOARD_NAME, "N150/N210/N220"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "N150P/N210P/N220P",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N150P/N210P/N220P"),
+ DMI_MATCH(DMI_BOARD_NAME, "N150P/N210P/N220P"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "R530/R730",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "R530/R730"),
+ DMI_MATCH(DMI_BOARD_NAME, "R530/R730"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "NF110/NF210/NF310",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "NF110/NF210/NF310"),
+ DMI_MATCH(DMI_BOARD_NAME, "NF110/NF210/NF310"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "N145P/N250P/N260P",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "N145P/N250P/N260P"),
+ DMI_MATCH(DMI_BOARD_NAME, "N145P/N250P/N260P"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "R70/R71",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR,
+ "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "R70/R71"),
+ DMI_MATCH(DMI_BOARD_NAME, "R70/R71"),
+ },
+ .callback = dmi_check_cb,
+ },
+ {
+ .ident = "P460",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "P460"),
+ DMI_MATCH(DMI_BOARD_NAME, "P460"),
+ },
+ .callback = dmi_check_cb,
+ },
+ { },
+};
+MODULE_DEVICE_TABLE(dmi, samsung_dmi_table);
+
+static int find_signature(void __iomem *memcheck, const char *testStr)
+{
+ int i = 0;
+ int loca;
+
+ for (loca = 0; loca < 0xffff; loca++) {
+ char temp = readb(memcheck + loca);
+
+ if (temp == testStr[i]) {
+ if (i == strlen(testStr)-1)
+ break;
+ ++i;
+ } else {
+ i = 0;
+ }
+ }
+ return loca;
+}
+
+static int __init samsung_init(void)
+{
+ struct backlight_properties props;
+ struct sabi_retval sretval;
+ unsigned int ifaceP;
+ int i;
+ int loca;
+ int retval;
+
+ mutex_init(&sabi_mutex);
+
+ if (!force && !dmi_check_system(samsung_dmi_table))
+ return -ENODEV;
+
+ f0000_segment = ioremap_nocache(0xf0000, 0xffff);
+ if (!f0000_segment) {
+ pr_err("Can't map the segment at 0xf0000\n");
+ return -EINVAL;
+ }
+
+ /* Try to find one of the signatures in memory to find the header */
+ for (i = 0; sabi_configs[i].test_string != 0; ++i) {
+ sabi_config = &sabi_configs[i];
+ loca = find_signature(f0000_segment, sabi_config->test_string);
+ if (loca != 0xffff)
+ break;
+ }
+
+ if (loca == 0xffff) {
+ pr_err("This computer does not support SABI\n");
+ goto error_no_signature;
+ }
+
+ /* point to the SMI port Number */
+ loca += 1;
+ sabi = (f0000_segment + loca);
+
+ if (debug) {
+ printk(KERN_DEBUG "This computer supports SABI==%x\n",
+ loca + 0xf0000 - 6);
+ printk(KERN_DEBUG "SABI header:\n");
+ printk(KERN_DEBUG " SMI Port Number = 0x%04x\n",
+ readw(sabi + sabi_config->header_offsets.port));
+ printk(KERN_DEBUG " SMI Interface Function = 0x%02x\n",
+ readb(sabi + sabi_config->header_offsets.iface_func));
+ printk(KERN_DEBUG " SMI enable memory buffer = 0x%02x\n",
+ readb(sabi + sabi_config->header_offsets.en_mem));
+ printk(KERN_DEBUG " SMI restore memory buffer = 0x%02x\n",
+ readb(sabi + sabi_config->header_offsets.re_mem));
+ printk(KERN_DEBUG " SABI data offset = 0x%04x\n",
+ readw(sabi + sabi_config->header_offsets.data_offset));
+ printk(KERN_DEBUG " SABI data segment = 0x%04x\n",
+ readw(sabi + sabi_config->header_offsets.data_segment));
+ }
+
+ /* Get a pointer to the SABI Interface */
+ ifaceP = (readw(sabi + sabi_config->header_offsets.data_segment) & 0x0ffff) << 4;
+ ifaceP += readw(sabi + sabi_config->header_offsets.data_offset) & 0x0ffff;
+ sabi_iface = ioremap_nocache(ifaceP, 16);
+ if (!sabi_iface) {
+ pr_err("Can't remap %x\n", ifaceP);
+ goto exit;
+ }
+ if (debug) {
+ printk(KERN_DEBUG "ifaceP = 0x%08x\n", ifaceP);
+ printk(KERN_DEBUG "sabi_iface = %p\n", sabi_iface);
+
+ test_backlight();
+ test_wireless();
+
+ retval = sabi_get_command(sabi_config->commands.get_brightness,
+ &sretval);
+ printk(KERN_DEBUG "brightness = 0x%02x\n", sretval.retval[0]);
+ }
+
+ /* Turn on "Linux" mode in the BIOS */
+ if (sabi_config->commands.set_linux != 0xff) {
+ retval = sabi_set_command(sabi_config->commands.set_linux,
+ 0x81);
+ if (retval) {
+ pr_warn("Linux mode was not set!\n");
+ goto error_no_platform;
+ }
+ }
+
+ /* knock up a platform device to hang stuff off of */
+ sdev = platform_device_register_simple("samsung", -1, NULL, 0);
+ if (IS_ERR(sdev))
+ goto error_no_platform;
+
+ /* create a backlight device to talk to this one */
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = sabi_config->max_brightness;
+ backlight_device = backlight_device_register("samsung", &sdev->dev,
+ NULL, &backlight_ops,
+ &props);
+ if (IS_ERR(backlight_device))
+ goto error_no_backlight;
+
+ backlight_device->props.brightness = read_brightness();
+ backlight_device->props.power = FB_BLANK_UNBLANK;
+ backlight_update_status(backlight_device);
+
+ retval = init_wireless(sdev);
+ if (retval)
+ goto error_no_rfk;
+
+ retval = device_create_file(&sdev->dev, &dev_attr_performance_level);
+ if (retval)
+ goto error_file_create;
+
+exit:
+ return 0;
+
+error_file_create:
+ destroy_wireless();
+
+error_no_rfk:
+ backlight_device_unregister(backlight_device);
+
+error_no_backlight:
+ platform_device_unregister(sdev);
+
+error_no_platform:
+ iounmap(sabi_iface);
+
+error_no_signature:
+ iounmap(f0000_segment);
+ return -EINVAL;
+}
+
+static void __exit samsung_exit(void)
+{
+ /* Turn off "Linux" mode in the BIOS */
+ if (sabi_config->commands.set_linux != 0xff)
+ sabi_set_command(sabi_config->commands.set_linux, 0x80);
+
+ device_remove_file(&sdev->dev, &dev_attr_performance_level);
+ backlight_device_unregister(backlight_device);
+ destroy_wireless();
+ iounmap(sabi_iface);
+ iounmap(f0000_segment);
+ platform_device_unregister(sdev);
+}
+
+module_init(samsung_init);
+module_exit(samsung_exit);
+
+MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
+MODULE_DESCRIPTION("Samsung Backlight driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c
index 13d8d63bcca..e642f5f2950 100644
--- a/drivers/platform/x86/sony-laptop.c
+++ b/drivers/platform/x86/sony-laptop.c
@@ -71,8 +71,9 @@
#endif
#define DRV_PFX "sony-laptop: "
-#define dprintk(msg...) do { \
- if (debug) printk(KERN_WARNING DRV_PFX msg); \
+#define dprintk(msg...) do { \
+ if (debug) \
+ pr_warn(DRV_PFX msg); \
} while (0)
#define SONY_LAPTOP_DRIVER_VERSION "0.6"
@@ -124,6 +125,19 @@ MODULE_PARM_DESC(minor,
"default is -1 (automatic)");
#endif
+static int kbd_backlight; /* = 1 */
+module_param(kbd_backlight, int, 0444);
+MODULE_PARM_DESC(kbd_backlight,
+ "set this to 0 to disable keyboard backlight, "
+ "1 to enable it (default: 0)");
+
+static int kbd_backlight_timeout; /* = 0 */
+module_param(kbd_backlight_timeout, int, 0444);
+MODULE_PARM_DESC(kbd_backlight_timeout,
+ "set this to 0 to set the default 10 seconds timeout, "
+ "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout "
+ "(default: 0)");
+
enum sony_nc_rfkill {
SONY_WIFI,
SONY_BLUETOOTH,
@@ -402,7 +416,7 @@ static int sony_laptop_setup_input(struct acpi_device *acpi_device)
error = kfifo_alloc(&sony_laptop_input.fifo,
SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
if (error) {
- printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
+ pr_err(DRV_PFX "kfifo_alloc failed\n");
goto err_dec_users;
}
@@ -591,7 +605,7 @@ struct sony_nc_value {
int value; /* current setting */
int valid; /* Has ever been set */
int debug; /* active only in debug mode ? */
- struct device_attribute devattr; /* sysfs atribute */
+ struct device_attribute devattr; /* sysfs attribute */
};
#define SNC_HANDLE_NAMES(_name, _values...) \
@@ -686,7 +700,7 @@ static int acpi_callgetfunc(acpi_handle handle, char *name, int *result)
return 0;
}
- printk(KERN_WARNING DRV_PFX "acpi_callreadfunc failed\n");
+ pr_warn(DRV_PFX "acpi_callreadfunc failed\n");
return -1;
}
@@ -712,7 +726,7 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
if (status == AE_OK) {
if (result != NULL) {
if (out_obj.type != ACPI_TYPE_INTEGER) {
- printk(KERN_WARNING DRV_PFX "acpi_evaluate_object bad "
+ pr_warn(DRV_PFX "acpi_evaluate_object bad "
"return type\n");
return -1;
}
@@ -721,34 +735,103 @@ static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
return 0;
}
- printk(KERN_WARNING DRV_PFX "acpi_evaluate_object failed\n");
+ pr_warn(DRV_PFX "acpi_evaluate_object failed\n");
return -1;
}
-static int sony_find_snc_handle(int handle)
+struct sony_nc_handles {
+ u16 cap[0x10];
+ struct device_attribute devattr;
+};
+
+static struct sony_nc_handles *handles;
+
+static ssize_t sony_nc_handles_show(struct device *dev,
+ struct device_attribute *attr, char *buffer)
+{
+ ssize_t len = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
+ len += snprintf(buffer + len, PAGE_SIZE - len, "0x%.4x ",
+ handles->cap[i]);
+ }
+ len += snprintf(buffer + len, PAGE_SIZE - len, "\n");
+
+ return len;
+}
+
+static int sony_nc_handles_setup(struct platform_device *pd)
{
int i;
int result;
- for (i = 0x20; i < 0x30; i++) {
- acpi_callsetfunc(sony_nc_acpi_handle, "SN00", i, &result);
- if (result == handle)
- return i-0x20;
+ handles = kzalloc(sizeof(*handles), GFP_KERNEL);
+ if (!handles)
+ return -ENOMEM;
+
+ sysfs_attr_init(&handles->devattr.attr);
+ handles->devattr.attr.name = "handles";
+ handles->devattr.attr.mode = S_IRUGO;
+ handles->devattr.show = sony_nc_handles_show;
+
+ for (i = 0; i < ARRAY_SIZE(handles->cap); i++) {
+ if (!acpi_callsetfunc(sony_nc_acpi_handle,
+ "SN00", i + 0x20, &result)) {
+ dprintk("caching handle 0x%.4x (offset: 0x%.2x)\n",
+ result, i);
+ handles->cap[i] = result;
+ }
+ }
+
+ /* allow reading capabilities via sysfs */
+ if (device_create_file(&pd->dev, &handles->devattr)) {
+ kfree(handles);
+ handles = NULL;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int sony_nc_handles_cleanup(struct platform_device *pd)
+{
+ if (handles) {
+ device_remove_file(&pd->dev, &handles->devattr);
+ kfree(handles);
+ handles = NULL;
}
+ return 0;
+}
+static int sony_find_snc_handle(int handle)
+{
+ int i;
+ for (i = 0; i < 0x10; i++) {
+ if (handles->cap[i] == handle) {
+ dprintk("found handle 0x%.4x (offset: 0x%.2x)\n",
+ handle, i);
+ return i;
+ }
+ }
+ dprintk("handle 0x%.4x not found\n", handle);
return -1;
}
static int sony_call_snc_handle(int handle, int argument, int *result)
{
+ int ret = 0;
int offset = sony_find_snc_handle(handle);
if (offset < 0)
return -1;
- return acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
- result);
+ ret = acpi_callsetfunc(sony_nc_acpi_handle, "SN07", offset | argument,
+ result);
+ dprintk("called SN07 with 0x%.4x (result: 0x%.4x)\n", offset | argument,
+ *result);
+ return ret;
}
/*
@@ -857,11 +940,39 @@ static int sony_backlight_get_brightness(struct backlight_device *bd)
return value - 1;
}
-static struct backlight_device *sony_backlight_device;
+static int sony_nc_get_brightness_ng(struct backlight_device *bd)
+{
+ int result;
+ int *handle = (int *)bl_get_data(bd);
+
+ sony_call_snc_handle(*handle, 0x0200, &result);
+
+ return result & 0xff;
+}
+
+static int sony_nc_update_status_ng(struct backlight_device *bd)
+{
+ int value, result;
+ int *handle = (int *)bl_get_data(bd);
+
+ value = bd->props.brightness;
+ sony_call_snc_handle(*handle, 0x0100 | (value << 16), &result);
+
+ return sony_nc_get_brightness_ng(bd);
+}
+
static const struct backlight_ops sony_backlight_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
.update_status = sony_backlight_update_status,
.get_brightness = sony_backlight_get_brightness,
};
+static const struct backlight_ops sony_backlight_ng_ops = {
+ .options = BL_CORE_SUSPENDRESUME,
+ .update_status = sony_nc_update_status_ng,
+ .get_brightness = sony_nc_get_brightness_ng,
+};
+static int backlight_ng_handle;
+static struct backlight_device *sony_backlight_device;
/*
* New SNC-only Vaios event mapping to driver known keys
@@ -972,7 +1083,7 @@ static void sony_nc_notify(struct acpi_device *device, u32 event)
}
if (!key_event->data)
- printk(KERN_INFO DRV_PFX
+ pr_info(DRV_PFX
"Unknown event: 0x%x 0x%x\n",
key_handle,
ev);
@@ -996,7 +1107,7 @@ static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
struct acpi_device_info *info;
if (ACPI_SUCCESS(acpi_get_object_info(handle, &info))) {
- printk(KERN_WARNING DRV_PFX "method: name: %4.4s, args %X\n",
+ pr_warn(DRV_PFX "method: name: %4.4s, args %X\n",
(char *)&info->name, info->param_count);
kfree(info);
@@ -1037,7 +1148,7 @@ static int sony_nc_resume(struct acpi_device *device)
ret = acpi_callsetfunc(sony_nc_acpi_handle, *item->acpiset,
item->value, NULL);
if (ret < 0) {
- printk("%s: %d\n", __func__, ret);
+ pr_err(DRV_PFX "%s: %d\n", __func__, ret);
break;
}
}
@@ -1054,11 +1165,6 @@ static int sony_nc_resume(struct acpi_device *device)
sony_nc_function_setup(device);
}
- /* set the last requested brightness level */
- if (sony_backlight_device &&
- sony_backlight_update_status(sony_backlight_device) < 0)
- printk(KERN_WARNING DRV_PFX "unable to restore brightness level\n");
-
/* re-read rfkill state */
sony_nc_rfkill_update();
@@ -1206,12 +1312,12 @@ static void sony_nc_rfkill_setup(struct acpi_device *device)
device_enum = (union acpi_object *) buffer.pointer;
if (!device_enum) {
- pr_err("Invalid SN06 return object\n");
+ pr_err(DRV_PFX "No SN06 return object.");
goto out_no_enum;
}
if (device_enum->type != ACPI_TYPE_BUFFER) {
- pr_err("Invalid SN06 return object type 0x%.2x\n",
- device_enum->type);
+ pr_err(DRV_PFX "Invalid SN06 return object 0x%.2x\n",
+ device_enum->type);
goto out_no_enum;
}
@@ -1245,6 +1351,209 @@ out_no_enum:
return;
}
+/* Keyboard backlight feature */
+#define KBDBL_HANDLER 0x137
+#define KBDBL_PRESENT 0xB00
+#define SET_MODE 0xC00
+#define SET_TIMEOUT 0xE00
+
+struct kbd_backlight {
+ int mode;
+ int timeout;
+ struct device_attribute mode_attr;
+ struct device_attribute timeout_attr;
+};
+
+static struct kbd_backlight *kbdbl_handle;
+
+static ssize_t __sony_nc_kbd_backlight_mode_set(u8 value)
+{
+ int result;
+
+ if (value > 1)
+ return -EINVAL;
+
+ if (sony_call_snc_handle(KBDBL_HANDLER,
+ (value << 0x10) | SET_MODE, &result))
+ return -EIO;
+
+ kbdbl_handle->mode = value;
+
+ return 0;
+}
+
+static ssize_t sony_nc_kbd_backlight_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buffer, size_t count)
+{
+ int ret = 0;
+ unsigned long value;
+
+ if (count > 31)
+ return -EINVAL;
+
+ if (strict_strtoul(buffer, 10, &value))
+ return -EINVAL;
+
+ ret = __sony_nc_kbd_backlight_mode_set(value);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t sony_nc_kbd_backlight_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buffer)
+{
+ ssize_t count = 0;
+ count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->mode);
+ return count;
+}
+
+static int __sony_nc_kbd_backlight_timeout_set(u8 value)
+{
+ int result;
+
+ if (value > 3)
+ return -EINVAL;
+
+ if (sony_call_snc_handle(KBDBL_HANDLER,
+ (value << 0x10) | SET_TIMEOUT, &result))
+ return -EIO;
+
+ kbdbl_handle->timeout = value;
+
+ return 0;
+}
+
+static ssize_t sony_nc_kbd_backlight_timeout_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buffer, size_t count)
+{
+ int ret = 0;
+ unsigned long value;
+
+ if (count > 31)
+ return -EINVAL;
+
+ if (strict_strtoul(buffer, 10, &value))
+ return -EINVAL;
+
+ ret = __sony_nc_kbd_backlight_timeout_set(value);
+ if (ret < 0)
+ return ret;
+
+ return count;
+}
+
+static ssize_t sony_nc_kbd_backlight_timeout_show(struct device *dev,
+ struct device_attribute *attr, char *buffer)
+{
+ ssize_t count = 0;
+ count = snprintf(buffer, PAGE_SIZE, "%d\n", kbdbl_handle->timeout);
+ return count;
+}
+
+static int sony_nc_kbd_backlight_setup(struct platform_device *pd)
+{
+ int result;
+
+ if (sony_call_snc_handle(0x137, KBDBL_PRESENT, &result))
+ return 0;
+ if (!(result & 0x02))
+ return 0;
+
+ kbdbl_handle = kzalloc(sizeof(*kbdbl_handle), GFP_KERNEL);
+ if (!kbdbl_handle)
+ return -ENOMEM;
+
+ sysfs_attr_init(&kbdbl_handle->mode_attr.attr);
+ kbdbl_handle->mode_attr.attr.name = "kbd_backlight";
+ kbdbl_handle->mode_attr.attr.mode = S_IRUGO | S_IWUSR;
+ kbdbl_handle->mode_attr.show = sony_nc_kbd_backlight_mode_show;
+ kbdbl_handle->mode_attr.store = sony_nc_kbd_backlight_mode_store;
+
+ sysfs_attr_init(&kbdbl_handle->timeout_attr.attr);
+ kbdbl_handle->timeout_attr.attr.name = "kbd_backlight_timeout";
+ kbdbl_handle->timeout_attr.attr.mode = S_IRUGO | S_IWUSR;
+ kbdbl_handle->timeout_attr.show = sony_nc_kbd_backlight_timeout_show;
+ kbdbl_handle->timeout_attr.store = sony_nc_kbd_backlight_timeout_store;
+
+ if (device_create_file(&pd->dev, &kbdbl_handle->mode_attr))
+ goto outkzalloc;
+
+ if (device_create_file(&pd->dev, &kbdbl_handle->timeout_attr))
+ goto outmode;
+
+ __sony_nc_kbd_backlight_mode_set(kbd_backlight);
+ __sony_nc_kbd_backlight_timeout_set(kbd_backlight_timeout);
+
+ return 0;
+
+outmode:
+ device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
+outkzalloc:
+ kfree(kbdbl_handle);
+ kbdbl_handle = NULL;
+ return -1;
+}
+
+static int sony_nc_kbd_backlight_cleanup(struct platform_device *pd)
+{
+ if (kbdbl_handle) {
+ device_remove_file(&pd->dev, &kbdbl_handle->mode_attr);
+ device_remove_file(&pd->dev, &kbdbl_handle->timeout_attr);
+ kfree(kbdbl_handle);
+ }
+ return 0;
+}
+
+static void sony_nc_backlight_setup(void)
+{
+ acpi_handle unused;
+ int max_brightness = 0;
+ const struct backlight_ops *ops = NULL;
+ struct backlight_properties props;
+
+ if (sony_find_snc_handle(0x12f) != -1) {
+ backlight_ng_handle = 0x12f;
+ ops = &sony_backlight_ng_ops;
+ max_brightness = 0xff;
+
+ } else if (sony_find_snc_handle(0x137) != -1) {
+ backlight_ng_handle = 0x137;
+ ops = &sony_backlight_ng_ops;
+ max_brightness = 0xff;
+
+ } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
+ &unused))) {
+ ops = &sony_backlight_ops;
+ max_brightness = SONY_MAX_BRIGHTNESS - 1;
+
+ } else
+ return;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.type = BACKLIGHT_PLATFORM;
+ props.max_brightness = max_brightness;
+ sony_backlight_device = backlight_device_register("sony", NULL,
+ &backlight_ng_handle,
+ ops, &props);
+
+ if (IS_ERR(sony_backlight_device)) {
+ pr_warning(DRV_PFX "unable to register backlight device\n");
+ sony_backlight_device = NULL;
+ } else
+ sony_backlight_device->props.brightness =
+ ops->get_brightness(sony_backlight_device);
+}
+
+static void sony_nc_backlight_cleanup(void)
+{
+ if (sony_backlight_device)
+ backlight_device_unregister(sony_backlight_device);
+}
+
static int sony_nc_add(struct acpi_device *device)
{
acpi_status status;
@@ -1252,8 +1561,8 @@ static int sony_nc_add(struct acpi_device *device)
acpi_handle handle;
struct sony_nc_value *item;
- printk(KERN_INFO DRV_PFX "%s v%s.\n",
- SONY_NC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
+ pr_info(DRV_PFX "%s v%s.\n", SONY_NC_DRIVER_NAME,
+ SONY_LAPTOP_DRIVER_VERSION);
sony_nc_acpi_device = device;
strcpy(acpi_device_class(device), "sony/hotkey");
@@ -1269,13 +1578,18 @@ static int sony_nc_add(struct acpi_device *device)
goto outwalk;
}
+ result = sony_pf_add();
+ if (result)
+ goto outpresent;
+
if (debug) {
- status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_nc_acpi_handle,
- 1, sony_walk_callback, NULL, NULL, NULL);
+ status = acpi_walk_namespace(ACPI_TYPE_METHOD,
+ sony_nc_acpi_handle, 1, sony_walk_callback,
+ NULL, NULL, NULL);
if (ACPI_FAILURE(status)) {
- printk(KERN_WARNING DRV_PFX "unable to walk acpi resources\n");
+ pr_warn(DRV_PFX "unable to walk acpi resources\n");
result = -ENODEV;
- goto outwalk;
+ goto outpresent;
}
}
@@ -1288,6 +1602,12 @@ static int sony_nc_add(struct acpi_device *device)
if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "SN00",
&handle))) {
dprintk("Doing SNC setup\n");
+ result = sony_nc_handles_setup(sony_pf_device);
+ if (result)
+ goto outpresent;
+ result = sony_nc_kbd_backlight_setup(sony_pf_device);
+ if (result)
+ goto outsnc;
sony_nc_function_setup(device);
sony_nc_rfkill_setup(device);
}
@@ -1295,40 +1615,17 @@ static int sony_nc_add(struct acpi_device *device)
/* setup input devices and helper fifo */
result = sony_laptop_setup_input(device);
if (result) {
- printk(KERN_ERR DRV_PFX
- "Unable to create input devices.\n");
- goto outwalk;
+ pr_err(DRV_PFX "Unable to create input devices.\n");
+ goto outkbdbacklight;
}
if (acpi_video_backlight_support()) {
- printk(KERN_INFO DRV_PFX "brightness ignored, must be "
+ pr_info(DRV_PFX "brightness ignored, must be "
"controlled by ACPI video driver\n");
- } else if (ACPI_SUCCESS(acpi_get_handle(sony_nc_acpi_handle, "GBRT",
- &handle))) {
- struct backlight_properties props;
- memset(&props, 0, sizeof(struct backlight_properties));
- props.type = BACKLIGHT_PLATFORM;
- props.max_brightness = SONY_MAX_BRIGHTNESS - 1;
- sony_backlight_device = backlight_device_register("sony", NULL,
- NULL,
- &sony_backlight_ops,
- &props);
-
- if (IS_ERR(sony_backlight_device)) {
- printk(KERN_WARNING DRV_PFX "unable to register backlight device\n");
- sony_backlight_device = NULL;
- } else {
- sony_backlight_device->props.brightness =
- sony_backlight_get_brightness
- (sony_backlight_device);
- }
-
+ } else {
+ sony_nc_backlight_setup();
}
- result = sony_pf_add();
- if (result)
- goto outbacklight;
-
/* create sony_pf sysfs attributes related to the SNC device */
for (item = sony_nc_values; item->name; ++item) {
@@ -1374,14 +1671,19 @@ static int sony_nc_add(struct acpi_device *device)
for (item = sony_nc_values; item->name; ++item) {
device_remove_file(&sony_pf_device->dev, &item->devattr);
}
- sony_pf_remove();
-
- outbacklight:
- if (sony_backlight_device)
- backlight_device_unregister(sony_backlight_device);
+ sony_nc_backlight_cleanup();
sony_laptop_remove_input();
+ outkbdbacklight:
+ sony_nc_kbd_backlight_cleanup(sony_pf_device);
+
+ outsnc:
+ sony_nc_handles_cleanup(sony_pf_device);
+
+ outpresent:
+ sony_pf_remove();
+
outwalk:
sony_nc_rfkill_cleanup();
return result;
@@ -1391,8 +1693,7 @@ static int sony_nc_remove(struct acpi_device *device, int type)
{
struct sony_nc_value *item;
- if (sony_backlight_device)
- backlight_device_unregister(sony_backlight_device);
+ sony_nc_backlight_cleanup();
sony_nc_acpi_device = NULL;
@@ -1400,6 +1701,8 @@ static int sony_nc_remove(struct acpi_device *device, int type)
device_remove_file(&sony_pf_device->dev, &item->devattr);
}
+ sony_nc_kbd_backlight_cleanup(sony_pf_device);
+ sony_nc_handles_cleanup(sony_pf_device);
sony_pf_remove();
sony_laptop_remove_input();
sony_nc_rfkill_cleanup();
@@ -1438,7 +1741,6 @@ static struct acpi_driver sony_nc_driver = {
#define SONYPI_DEVICE_TYPE1 0x00000001
#define SONYPI_DEVICE_TYPE2 0x00000002
#define SONYPI_DEVICE_TYPE3 0x00000004
-#define SONYPI_DEVICE_TYPE4 0x00000008
#define SONYPI_TYPE1_OFFSET 0x04
#define SONYPI_TYPE2_OFFSET 0x12
@@ -1584,8 +1886,8 @@ static struct sonypi_event sonypi_blueev[] = {
/* The set of possible wireless events */
static struct sonypi_event sonypi_wlessev[] = {
- { 0x59, SONYPI_EVENT_WIRELESS_ON },
- { 0x5a, SONYPI_EVENT_WIRELESS_OFF },
+ { 0x59, SONYPI_EVENT_IGNORE },
+ { 0x5a, SONYPI_EVENT_IGNORE },
{ 0, 0 }
};
@@ -1842,7 +2144,7 @@ out:
if (pcidev)
pci_dev_put(pcidev);
- printk(KERN_INFO DRV_PFX "detected Type%d model\n",
+ pr_info(DRV_PFX "detected Type%d model\n",
dev->model == SONYPI_DEVICE_TYPE1 ? 1 :
dev->model == SONYPI_DEVICE_TYPE2 ? 2 : 3);
}
@@ -1890,7 +2192,7 @@ static int __sony_pic_camera_ready(void)
static int __sony_pic_camera_off(void)
{
if (!camera) {
- printk(KERN_WARNING DRV_PFX "camera control not enabled\n");
+ pr_warn(DRV_PFX "camera control not enabled\n");
return -ENODEV;
}
@@ -1910,7 +2212,7 @@ static int __sony_pic_camera_on(void)
int i, j, x;
if (!camera) {
- printk(KERN_WARNING DRV_PFX "camera control not enabled\n");
+ pr_warn(DRV_PFX "camera control not enabled\n");
return -ENODEV;
}
@@ -1933,7 +2235,7 @@ static int __sony_pic_camera_on(void)
}
if (j == 0) {
- printk(KERN_WARNING DRV_PFX "failed to power on camera\n");
+ pr_warn(DRV_PFX "failed to power on camera\n");
return -ENODEV;
}
@@ -1989,7 +2291,7 @@ int sony_pic_camera_command(int command, u8 value)
ITERATIONS_SHORT);
break;
default:
- printk(KERN_ERR DRV_PFX "sony_pic_camera_command invalid: %d\n",
+ pr_err(DRV_PFX "sony_pic_camera_command invalid: %d\n",
command);
break;
}
@@ -2396,7 +2698,7 @@ static int sonypi_compat_init(void)
error =
kfifo_alloc(&sonypi_compat.fifo, SONY_LAPTOP_BUF_SIZE, GFP_KERNEL);
if (error) {
- printk(KERN_ERR DRV_PFX "kfifo_alloc failed\n");
+ pr_err(DRV_PFX "kfifo_alloc failed\n");
return error;
}
@@ -2406,11 +2708,11 @@ static int sonypi_compat_init(void)
sonypi_misc_device.minor = minor;
error = misc_register(&sonypi_misc_device);
if (error) {
- printk(KERN_ERR DRV_PFX "misc_register failed\n");
+ pr_err(DRV_PFX "misc_register failed\n");
goto err_free_kfifo;
}
if (minor == -1)
- printk(KERN_INFO DRV_PFX "device allocated minor is %d\n",
+ pr_info(DRV_PFX "device allocated minor is %d\n",
sonypi_misc_device.minor);
return 0;
@@ -2470,8 +2772,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
}
for (i = 0; i < p->interrupt_count; i++) {
if (!p->interrupts[i]) {
- printk(KERN_WARNING DRV_PFX
- "Invalid IRQ %d\n",
+ pr_warn(DRV_PFX "Invalid IRQ %d\n",
p->interrupts[i]);
continue;
}
@@ -2510,7 +2811,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)
ioport->io2.address_length);
}
else {
- printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
+ pr_err(DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");
return AE_ERROR;
}
return AE_OK;
@@ -2538,7 +2839,7 @@ static int sony_pic_possible_resources(struct acpi_device *device)
dprintk("Evaluating _STA\n");
result = acpi_bus_get_status(device);
if (result) {
- printk(KERN_WARNING DRV_PFX "Unable to read status\n");
+ pr_warn(DRV_PFX "Unable to read status\n");
goto end;
}
@@ -2554,8 +2855,7 @@ static int sony_pic_possible_resources(struct acpi_device *device)
status = acpi_walk_resources(device->handle, METHOD_NAME__PRS,
sony_pic_read_possible_resource, &spic_dev);
if (ACPI_FAILURE(status)) {
- printk(KERN_WARNING DRV_PFX
- "Failure evaluating %s\n",
+ pr_warn(DRV_PFX "Failure evaluating %s\n",
METHOD_NAME__PRS);
result = -ENODEV;
}
@@ -2669,7 +2969,7 @@ static int sony_pic_enable(struct acpi_device *device,
/* check for total failure */
if (ACPI_FAILURE(status)) {
- printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n");
+ pr_err(DRV_PFX "Error evaluating _SRS\n");
result = -ENODEV;
goto end;
}
@@ -2725,6 +3025,9 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)
if (ev == dev->event_types[i].events[j].data) {
device_event =
dev->event_types[i].events[j].event;
+ /* some events may require ignoring */
+ if (!device_event)
+ return IRQ_HANDLED;
goto found;
}
}
@@ -2744,7 +3047,6 @@ found:
sony_laptop_report_input_event(device_event);
acpi_bus_generate_proc_event(dev->acpi_dev, 1, device_event);
sonypi_compat_report_event(device_event);
-
return IRQ_HANDLED;
}
@@ -2759,7 +3061,7 @@ static int sony_pic_remove(struct acpi_device *device, int type)
struct sony_pic_irq *irq, *tmp_irq;
if (sony_pic_disable(device)) {
- printk(KERN_ERR DRV_PFX "Couldn't disable device.\n");
+ pr_err(DRV_PFX "Couldn't disable device.\n");
return -ENXIO;
}
@@ -2799,8 +3101,8 @@ static int sony_pic_add(struct acpi_device *device)
struct sony_pic_ioport *io, *tmp_io;
struct sony_pic_irq *irq, *tmp_irq;
- printk(KERN_INFO DRV_PFX "%s v%s.\n",
- SONY_PIC_DRIVER_NAME, SONY_LAPTOP_DRIVER_VERSION);
+ pr_info(DRV_PFX "%s v%s.\n", SONY_PIC_DRIVER_NAME,
+ SONY_LAPTOP_DRIVER_VERSION);
spic_dev.acpi_dev = device;
strcpy(acpi_device_class(device), "sony/hotkey");
@@ -2810,16 +3112,14 @@ static int sony_pic_add(struct acpi_device *device)
/* read _PRS resources */
result = sony_pic_possible_resources(device);
if (result) {
- printk(KERN_ERR DRV_PFX
- "Unable to read possible resources.\n");
+ pr_err(DRV_PFX "Unable to read possible resources.\n");
goto err_free_resources;
}
/* setup input devices and helper fifo */
result = sony_laptop_setup_input(device);
if (result) {
- printk(KERN_ERR DRV_PFX
- "Unable to create input devices.\n");
+ pr_err(DRV_PFX "Unable to create input devices.\n");
goto err_free_resources;
}
@@ -2829,7 +3129,7 @@ static int sony_pic_add(struct acpi_device *device)
/* request io port */
list_for_each_entry_reverse(io, &spic_dev.ioports, list) {
if (request_region(io->io1.minimum, io->io1.address_length,
- "Sony Programable I/O Device")) {
+ "Sony Programmable I/O Device")) {
dprintk("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n",
io->io1.minimum, io->io1.maximum,
io->io1.address_length);
@@ -2837,7 +3137,7 @@ static int sony_pic_add(struct acpi_device *device)
if (io->io2.minimum) {
if (request_region(io->io2.minimum,
io->io2.address_length,
- "Sony Programable I/O Device")) {
+ "Sony Programmable I/O Device")) {
dprintk("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n",
io->io2.minimum, io->io2.maximum,
io->io2.address_length);
@@ -2860,7 +3160,7 @@ static int sony_pic_add(struct acpi_device *device)
}
}
if (!spic_dev.cur_ioport) {
- printk(KERN_ERR DRV_PFX "Failed to request_region.\n");
+ pr_err(DRV_PFX "Failed to request_region.\n");
result = -ENODEV;
goto err_remove_compat;
}
@@ -2880,7 +3180,7 @@ static int sony_pic_add(struct acpi_device *device)
}
}
if (!spic_dev.cur_irq) {
- printk(KERN_ERR DRV_PFX "Failed to request_irq.\n");
+ pr_err(DRV_PFX "Failed to request_irq.\n");
result = -ENODEV;
goto err_release_region;
}
@@ -2888,7 +3188,7 @@ static int sony_pic_add(struct acpi_device *device)
/* set resource status _SRS */
result = sony_pic_enable(device, spic_dev.cur_ioport, spic_dev.cur_irq);
if (result) {
- printk(KERN_ERR DRV_PFX "Couldn't enable device.\n");
+ pr_err(DRV_PFX "Couldn't enable device.\n");
goto err_free_irq;
}
@@ -2997,8 +3297,7 @@ static int __init sony_laptop_init(void)
if (!no_spic && dmi_check_system(sonypi_dmi_table)) {
result = acpi_bus_register_driver(&sony_pic_driver);
if (result) {
- printk(KERN_ERR DRV_PFX
- "Unable to register SPIC driver.");
+ pr_err(DRV_PFX "Unable to register SPIC driver.");
goto out;
}
spic_drv_registered = 1;
@@ -3006,7 +3305,7 @@ static int __init sony_laptop_init(void)
result = acpi_bus_register_driver(&sony_nc_driver);
if (result) {
- printk(KERN_ERR DRV_PFX "Unable to register SNC driver.");
+ pr_err(DRV_PFX "Unable to register SNC driver.");
goto out_unregister_pic;
}
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 947bdcaa0ce..a08561f5349 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -2407,7 +2407,7 @@ static void hotkey_compare_and_issue_event(struct tp_nvram_state *oldn,
* This code is supposed to duplicate the IBM firmware behaviour:
* - Pressing MUTE issues mute hotkey message, even when already mute
* - Pressing Volume up/down issues volume up/down hotkey messages,
- * even when already at maximum or minumum volume
+ * even when already at maximum or minimum volume
* - The act of unmuting issues volume up/down notification,
* depending which key was used to unmute
*
@@ -2990,7 +2990,7 @@ static void tpacpi_send_radiosw_update(void)
* rfkill input events, or we will race the rfkill core input
* handler.
*
- * tpacpi_inputdev_send_mutex works as a syncronization point
+ * tpacpi_inputdev_send_mutex works as a synchronization point
* for the above.
*
* We optimize to avoid numerous calls to hotkey_get_wlsw.
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c
new file mode 100644
index 00000000000..c1372ed9d2e
--- /dev/null
+++ b/drivers/platform/x86/xo15-ebook.c
@@ -0,0 +1,180 @@
+/*
+ * OLPC XO-1.5 ebook switch driver
+ * (based on generic ACPI button driver)
+ *
+ * Copyright (C) 2009 Paul Fox <pgf@laptop.org>
+ * Copyright (C) 2010 One Laptop per Child
+ *
+ * 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/init.h>
+#include <linux/types.h>
+#include <linux/input.h>
+#include <acpi/acpi_bus.h>
+#include <acpi/acpi_drivers.h>
+
+#define MODULE_NAME "xo15-ebook"
+#define PREFIX MODULE_NAME ": "
+
+#define XO15_EBOOK_CLASS MODULE_NAME
+#define XO15_EBOOK_TYPE_UNKNOWN 0x00
+#define XO15_EBOOK_NOTIFY_STATUS 0x80
+
+#define XO15_EBOOK_SUBCLASS "ebook"
+#define XO15_EBOOK_HID "XO15EBK"
+#define XO15_EBOOK_DEVICE_NAME "EBook Switch"
+
+ACPI_MODULE_NAME(MODULE_NAME);
+
+MODULE_DESCRIPTION("OLPC XO-1.5 ebook switch driver");
+MODULE_LICENSE("GPL");
+
+static const struct acpi_device_id ebook_device_ids[] = {
+ { XO15_EBOOK_HID, 0 },
+ { "", 0 },
+};
+MODULE_DEVICE_TABLE(acpi, ebook_device_ids);
+
+struct ebook_switch {
+ struct input_dev *input;
+ char phys[32]; /* for input device */
+};
+
+static int ebook_send_state(struct acpi_device *device)
+{
+ struct ebook_switch *button = acpi_driver_data(device);
+ unsigned long long state;
+ acpi_status status;
+
+ status = acpi_evaluate_integer(device->handle, "EBK", NULL, &state);
+ if (ACPI_FAILURE(status))
+ return -EIO;
+
+ /* input layer checks if event is redundant */
+ input_report_switch(button->input, SW_TABLET_MODE, !state);
+ input_sync(button->input);
+ return 0;
+}
+
+static void ebook_switch_notify(struct acpi_device *device, u32 event)
+{
+ switch (event) {
+ case ACPI_FIXED_HARDWARE_EVENT:
+ case XO15_EBOOK_NOTIFY_STATUS:
+ ebook_send_state(device);
+ break;
+ default:
+ ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+ "Unsupported event [0x%x]\n", event));
+ break;
+ }
+}
+
+static int ebook_switch_resume(struct acpi_device *device)
+{
+ return ebook_send_state(device);
+}
+
+static int ebook_switch_add(struct acpi_device *device)
+{
+ struct ebook_switch *button;
+ struct input_dev *input;
+ const char *hid = acpi_device_hid(device);
+ char *name, *class;
+ int error;
+
+ button = kzalloc(sizeof(struct ebook_switch), GFP_KERNEL);
+ if (!button)
+ return -ENOMEM;
+
+ device->driver_data = button;
+
+ button->input = input = input_allocate_device();
+ if (!input) {
+ error = -ENOMEM;
+ goto err_free_button;
+ }
+
+ name = acpi_device_name(device);
+ class = acpi_device_class(device);
+
+ if (strcmp(hid, XO15_EBOOK_HID)) {
+ printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid);
+ error = -ENODEV;
+ goto err_free_input;
+ }
+
+ strcpy(name, XO15_EBOOK_DEVICE_NAME);
+ sprintf(class, "%s/%s", XO15_EBOOK_CLASS, XO15_EBOOK_SUBCLASS);
+
+ snprintf(button->phys, sizeof(button->phys), "%s/button/input0", hid);
+
+ input->name = name;
+ input->phys = button->phys;
+ input->id.bustype = BUS_HOST;
+ input->dev.parent = &device->dev;
+
+ input->evbit[0] = BIT_MASK(EV_SW);
+ set_bit(SW_TABLET_MODE, input->swbit);
+
+ error = input_register_device(input);
+ if (error)
+ goto err_free_input;
+
+ ebook_send_state(device);
+
+ if (device->wakeup.flags.valid) {
+ /* Button's GPE is run-wake GPE */
+ acpi_enable_gpe(device->wakeup.gpe_device,
+ device->wakeup.gpe_number);
+ device_set_wakeup_enable(&device->dev, true);
+ }
+
+ return 0;
+
+ err_free_input:
+ input_free_device(input);
+ err_free_button:
+ kfree(button);
+ return error;
+}
+
+static int ebook_switch_remove(struct acpi_device *device, int type)
+{
+ struct ebook_switch *button = acpi_driver_data(device);
+
+ input_unregister_device(button->input);
+ kfree(button);
+ return 0;
+}
+
+static struct acpi_driver xo15_ebook_driver = {
+ .name = MODULE_NAME,
+ .class = XO15_EBOOK_CLASS,
+ .ids = ebook_device_ids,
+ .ops = {
+ .add = ebook_switch_add,
+ .resume = ebook_switch_resume,
+ .remove = ebook_switch_remove,
+ .notify = ebook_switch_notify,
+ },
+};
+
+static int __init xo15_ebook_init(void)
+{
+ return acpi_bus_register_driver(&xo15_ebook_driver);
+}
+
+static void __exit xo15_ebook_exit(void)
+{
+ acpi_bus_unregister_driver(&xo15_ebook_driver);
+}
+
+module_init(xo15_ebook_init);
+module_exit(xo15_ebook_exit);
diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c
index 2a9ab89f83b..e5ced3a4c1e 100644
--- a/drivers/power/z2_battery.c
+++ b/drivers/power/z2_battery.c
@@ -215,8 +215,8 @@ static int __devinit z2_batt_probe(struct i2c_client *client,
if (ret)
goto err2;
- set_irq_type(gpio_to_irq(info->charge_gpio),
- IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(gpio_to_irq(info->charge_gpio),
+ IRQ_TYPE_EDGE_BOTH);
ret = request_irq(gpio_to_irq(info->charge_gpio),
z2_charge_switch_irq, IRQF_DISABLED,
"AC Detect", charger);
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index de75f67f4cc..b9f29e0d429 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -126,7 +126,7 @@ config REGULATOR_MAX8998
and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages.
config REGULATOR_TWL4030
- bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
+ bool "TI TWL4030/TWL5030/TWL6030/TPS659x0 PMIC"
depends on TWL4030_CORE
help
This driver supports the voltage regulators provided by
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 2dec589a890..b1d77946e9c 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -206,29 +206,6 @@ static int ab3100_enable_regulator(struct regulator_dev *reg)
return err;
}
- /* Per-regulator power on delay from spec */
- switch (abreg->regreg) {
- case AB3100_LDO_A: /* Fallthrough */
- case AB3100_LDO_C: /* Fallthrough */
- case AB3100_LDO_D: /* Fallthrough */
- case AB3100_LDO_E: /* Fallthrough */
- case AB3100_LDO_H: /* Fallthrough */
- case AB3100_LDO_K:
- udelay(200);
- break;
- case AB3100_LDO_F:
- udelay(600);
- break;
- case AB3100_LDO_G:
- udelay(400);
- break;
- case AB3100_BUCK:
- mdelay(1);
- break;
- default:
- break;
- }
-
return 0;
}
@@ -450,11 +427,37 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
return abreg->plfdata->external_voltage;
}
+static int ab3100_enable_time_regulator(struct regulator_dev *reg)
+{
+ struct ab3100_regulator *abreg = reg->reg_data;
+
+ /* Per-regulator power on delay from spec */
+ switch (abreg->regreg) {
+ case AB3100_LDO_A: /* Fallthrough */
+ case AB3100_LDO_C: /* Fallthrough */
+ case AB3100_LDO_D: /* Fallthrough */
+ case AB3100_LDO_E: /* Fallthrough */
+ case AB3100_LDO_H: /* Fallthrough */
+ case AB3100_LDO_K:
+ return 200;
+ case AB3100_LDO_F:
+ return 600;
+ case AB3100_LDO_G:
+ return 400;
+ case AB3100_BUCK:
+ return 1000;
+ default:
+ break;
+ }
+ return 0;
+}
+
static struct regulator_ops regulator_ops_fixed = {
.enable = ab3100_enable_regulator,
.disable = ab3100_disable_regulator,
.is_enabled = ab3100_is_enabled_regulator,
.get_voltage = ab3100_get_voltage_regulator,
+ .enable_time = ab3100_enable_time_regulator,
};
static struct regulator_ops regulator_ops_variable = {
@@ -464,6 +467,7 @@ static struct regulator_ops regulator_ops_variable = {
.get_voltage = ab3100_get_voltage_regulator,
.set_voltage = ab3100_set_voltage_regulator,
.list_voltage = ab3100_list_voltage_regulator,
+ .enable_time = ab3100_enable_time_regulator,
};
static struct regulator_ops regulator_ops_variable_sleepable = {
@@ -474,6 +478,7 @@ static struct regulator_ops regulator_ops_variable_sleepable = {
.set_voltage = ab3100_set_voltage_regulator,
.set_suspend_voltage = ab3100_set_suspend_voltage_regulator,
.list_voltage = ab3100_list_voltage_regulator,
+ .enable_time = ab3100_enable_time_regulator,
};
/*
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index d9a052c53ae..02f3c2333c8 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -9,7 +9,7 @@
* AB8500 peripheral regulators
*
* AB8500 supports the following regulators:
- * VAUX1/2/3, VINTCORE, VTVOUT, VAUDIO, VAMIC1/2, VDMIC, VANA
+ * VAUX1/2/3, VINTCORE, VTVOUT, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -38,6 +38,7 @@
* @voltage_mask: mask to control regulator voltage
* @voltages: supported voltage table
* @voltages_len: number of supported voltages for the regulator
+ * @delay: startup/set voltage delay in us
*/
struct ab8500_regulator_info {
struct device *dev;
@@ -55,6 +56,7 @@ struct ab8500_regulator_info {
u8 voltage_mask;
int const *voltages;
int voltages_len;
+ unsigned int delay;
};
/* voltage tables for the vauxn/vintcore supplies */
@@ -290,6 +292,29 @@ static int ab8500_regulator_set_voltage(struct regulator_dev *rdev,
return ret;
}
+static int ab8500_regulator_enable_time(struct regulator_dev *rdev)
+{
+ struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+
+ return info->delay;
+}
+
+static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
+ unsigned int old_sel,
+ unsigned int new_sel)
+{
+ struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
+ int ret;
+
+ /* If the regulator isn't on, it won't take time here */
+ ret = ab8500_regulator_is_enabled(rdev);
+ if (ret < 0)
+ return ret;
+ if (!ret)
+ return 0;
+ return info->delay;
+}
+
static struct regulator_ops ab8500_regulator_ops = {
.enable = ab8500_regulator_enable,
.disable = ab8500_regulator_disable,
@@ -297,6 +322,8 @@ static struct regulator_ops ab8500_regulator_ops = {
.get_voltage = ab8500_regulator_get_voltage,
.set_voltage = ab8500_regulator_set_voltage,
.list_voltage = ab8500_list_voltage,
+ .enable_time = ab8500_regulator_enable_time,
+ .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
};
static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
@@ -317,6 +344,8 @@ static struct regulator_ops ab8500_regulator_fixed_ops = {
.is_enabled = ab8500_regulator_is_enabled,
.get_voltage = ab8500_fixed_get_voltage,
.list_voltage = ab8500_list_voltage,
+ .enable_time = ab8500_regulator_enable_time,
+ .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
};
static struct ab8500_regulator_info
@@ -426,12 +455,28 @@ static struct ab8500_regulator_info
.owner = THIS_MODULE,
.n_voltages = 1,
},
+ .delay = 10000,
.fixed_uV = 2000000,
.update_bank = 0x03,
.update_reg = 0x80,
.update_mask = 0x82,
.update_val_enable = 0x02,
},
+ [AB8500_LDO_USB] = {
+ .desc = {
+ .name = "LDO-USB",
+ .ops = &ab8500_regulator_fixed_ops,
+ .type = REGULATOR_VOLTAGE,
+ .id = AB8500_LDO_USB,
+ .owner = THIS_MODULE,
+ .n_voltages = 1,
+ },
+ .fixed_uV = 3300000,
+ .update_bank = 0x03,
+ .update_reg = 0x82,
+ .update_mask = 0x03,
+ .update_val_enable = 0x01,
+ },
[AB8500_LDO_AUDIO] = {
.desc = {
.name = "LDO-AUDIO",
@@ -511,6 +556,186 @@ static struct ab8500_regulator_info
};
+struct ab8500_reg_init {
+ u8 bank;
+ u8 addr;
+ u8 mask;
+};
+
+#define REG_INIT(_id, _bank, _addr, _mask) \
+ [_id] = { \
+ .bank = _bank, \
+ .addr = _addr, \
+ .mask = _mask, \
+ }
+
+static struct ab8500_reg_init ab8500_reg_init[] = {
+ /*
+ * 0x30, VanaRequestCtrl
+ * 0x0C, VpllRequestCtrl
+ * 0xc0, VextSupply1RequestCtrl
+ */
+ REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
+ /*
+ * 0x03, VextSupply2RequestCtrl
+ * 0x0c, VextSupply3RequestCtrl
+ * 0x30, Vaux1RequestCtrl
+ * 0xc0, Vaux2RequestCtrl
+ */
+ REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
+ /*
+ * 0x03, Vaux3RequestCtrl
+ * 0x04, SwHPReq
+ */
+ REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
+ /*
+ * 0x08, VanaSysClkReq1HPValid
+ * 0x20, Vaux1SysClkReq1HPValid
+ * 0x40, Vaux2SysClkReq1HPValid
+ * 0x80, Vaux3SysClkReq1HPValid
+ */
+ REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
+ /*
+ * 0x10, VextSupply1SysClkReq1HPValid
+ * 0x20, VextSupply2SysClkReq1HPValid
+ * 0x40, VextSupply3SysClkReq1HPValid
+ */
+ REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
+ /*
+ * 0x08, VanaHwHPReq1Valid
+ * 0x20, Vaux1HwHPReq1Valid
+ * 0x40, Vaux2HwHPReq1Valid
+ * 0x80, Vaux3HwHPReq1Valid
+ */
+ REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
+ /*
+ * 0x01, VextSupply1HwHPReq1Valid
+ * 0x02, VextSupply2HwHPReq1Valid
+ * 0x04, VextSupply3HwHPReq1Valid
+ */
+ REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
+ /*
+ * 0x08, VanaHwHPReq2Valid
+ * 0x20, Vaux1HwHPReq2Valid
+ * 0x40, Vaux2HwHPReq2Valid
+ * 0x80, Vaux3HwHPReq2Valid
+ */
+ REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
+ /*
+ * 0x01, VextSupply1HwHPReq2Valid
+ * 0x02, VextSupply2HwHPReq2Valid
+ * 0x04, VextSupply3HwHPReq2Valid
+ */
+ REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
+ /*
+ * 0x20, VanaSwHPReqValid
+ * 0x80, Vaux1SwHPReqValid
+ */
+ REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
+ /*
+ * 0x01, Vaux2SwHPReqValid
+ * 0x02, Vaux3SwHPReqValid
+ * 0x04, VextSupply1SwHPReqValid
+ * 0x08, VextSupply2SwHPReqValid
+ * 0x10, VextSupply3SwHPReqValid
+ */
+ REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
+ /*
+ * 0x02, SysClkReq2Valid1
+ * ...
+ * 0x80, SysClkReq8Valid1
+ */
+ REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
+ /*
+ * 0x02, SysClkReq2Valid2
+ * ...
+ * 0x80, SysClkReq8Valid2
+ */
+ REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
+ /*
+ * 0x02, VTVoutEna
+ * 0x04, Vintcore12Ena
+ * 0x38, Vintcore12Sel
+ * 0x40, Vintcore12LP
+ * 0x80, VTVoutLP
+ */
+ REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
+ /*
+ * 0x02, VaudioEna
+ * 0x04, VdmicEna
+ * 0x08, Vamic1Ena
+ * 0x10, Vamic2Ena
+ */
+ REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
+ /*
+ * 0x01, Vamic1_dzout
+ * 0x02, Vamic2_dzout
+ */
+ REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
+ /*
+ * 0x0c, VanaRegu
+ * 0x03, VpllRegu
+ */
+ REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
+ /*
+ * 0x01, VrefDDREna
+ * 0x02, VrefDDRSleepMode
+ */
+ REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
+ /*
+ * 0x03, VextSupply1Regu
+ * 0x0c, VextSupply2Regu
+ * 0x30, VextSupply3Regu
+ * 0x40, ExtSupply2Bypass
+ * 0x80, ExtSupply3Bypass
+ */
+ REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
+ /*
+ * 0x03, Vaux1Regu
+ * 0x0c, Vaux2Regu
+ */
+ REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
+ /*
+ * 0x03, Vaux3Regu
+ */
+ REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
+ /*
+ * 0x3f, Vsmps1Sel1
+ */
+ REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
+ /*
+ * 0x0f, Vaux1Sel
+ */
+ REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
+ /*
+ * 0x0f, Vaux2Sel
+ */
+ REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
+ /*
+ * 0x07, Vaux3Sel
+ */
+ REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
+ /*
+ * 0x01, VextSupply12LP
+ */
+ REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
+ /*
+ * 0x04, Vaux1Disch
+ * 0x08, Vaux2Disch
+ * 0x10, Vaux3Disch
+ * 0x20, Vintcore12Disch
+ * 0x40, VTVoutDisch
+ * 0x80, VaudioDisch
+ */
+ REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
+ /*
+ * 0x02, VanaDisch
+ * 0x04, VdmicPullDownEna
+ * 0x10, VdmicDisch
+ */
+ REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
+};
+
static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
{
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
@@ -529,10 +754,51 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
/* make sure the platform data has the correct size */
if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
- dev_err(&pdev->dev, "platform configuration error\n");
+ dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
return -EINVAL;
}
+ /* initialize registers */
+ for (i = 0; i < pdata->num_regulator_reg_init; i++) {
+ int id;
+ u8 value;
+
+ id = pdata->regulator_reg_init[i].id;
+ value = pdata->regulator_reg_init[i].value;
+
+ /* check for configuration errors */
+ if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
+ dev_err(&pdev->dev,
+ "Configuration error: id outside range.\n");
+ return -EINVAL;
+ }
+ if (value & ~ab8500_reg_init[id].mask) {
+ dev_err(&pdev->dev,
+ "Configuration error: value outside mask.\n");
+ return -EINVAL;
+ }
+
+ /* initialize register */
+ err = abx500_mask_and_set_register_interruptible(&pdev->dev,
+ ab8500_reg_init[id].bank,
+ ab8500_reg_init[id].addr,
+ ab8500_reg_init[id].mask,
+ value);
+ if (err < 0) {
+ dev_err(&pdev->dev,
+ "Failed to initialize 0x%02x, 0x%02x.\n",
+ ab8500_reg_init[id].bank,
+ ab8500_reg_init[id].addr);
+ return err;
+ }
+ dev_vdbg(&pdev->dev,
+ " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
+ ab8500_reg_init[id].bank,
+ ab8500_reg_init[id].addr,
+ ab8500_reg_init[id].mask,
+ value);
+ }
+
/* register all regulators */
for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
struct ab8500_regulator_info *info = NULL;
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 9fa20957847..3ffc6979d16 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -1629,6 +1629,7 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
int ret;
+ int delay = 0;
unsigned int selector;
trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
@@ -1662,6 +1663,22 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
}
}
+ /*
+ * If we can't obtain the old selector there is not enough
+ * info to call set_voltage_time_sel().
+ */
+ if (rdev->desc->ops->set_voltage_time_sel &&
+ rdev->desc->ops->get_voltage_sel) {
+ unsigned int old_selector = 0;
+
+ ret = rdev->desc->ops->get_voltage_sel(rdev);
+ if (ret < 0)
+ return ret;
+ old_selector = ret;
+ delay = rdev->desc->ops->set_voltage_time_sel(rdev,
+ old_selector, selector);
+ }
+
if (best_val != INT_MAX) {
ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
selector = best_val;
@@ -1672,6 +1689,14 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
ret = -EINVAL;
}
+ /* Insert any necessary delays */
+ if (delay >= 1000) {
+ mdelay(delay / 1000);
+ udelay(delay % 1000);
+ } else if (delay) {
+ udelay(delay);
+ }
+
if (ret == 0)
_notifier_call_chain(rdev, REGULATOR_EVENT_VOLTAGE_CHANGE,
NULL);
@@ -1740,6 +1765,51 @@ out:
EXPORT_SYMBOL_GPL(regulator_set_voltage);
/**
+ * regulator_set_voltage_time - get raise/fall time
+ * @regulator: regulator source
+ * @old_uV: starting voltage in microvolts
+ * @new_uV: target voltage in microvolts
+ *
+ * Provided with the starting and ending voltage, this function attempts to
+ * calculate the time in microseconds required to rise or fall to this new
+ * voltage.
+ */
+int regulator_set_voltage_time(struct regulator *regulator,
+ int old_uV, int new_uV)
+{
+ struct regulator_dev *rdev = regulator->rdev;
+ struct regulator_ops *ops = rdev->desc->ops;
+ int old_sel = -1;
+ int new_sel = -1;
+ int voltage;
+ int i;
+
+ /* Currently requires operations to do this */
+ if (!ops->list_voltage || !ops->set_voltage_time_sel
+ || !rdev->desc->n_voltages)
+ return -EINVAL;
+
+ for (i = 0; i < rdev->desc->n_voltages; i++) {
+ /* We only look for exact voltage matches here */
+ voltage = regulator_list_voltage(regulator, i);
+ if (voltage < 0)
+ return -EINVAL;
+ if (voltage == 0)
+ continue;
+ if (voltage == old_uV)
+ old_sel = i;
+ if (voltage == new_uV)
+ new_sel = i;
+ }
+
+ if (old_sel < 0 || new_sel < 0)
+ return -EINVAL;
+
+ return ops->set_voltage_time_sel(rdev, old_sel, new_sel);
+}
+EXPORT_SYMBOL_GPL(regulator_set_voltage_time);
+
+/**
* regulator_sync_voltage - re-apply last regulator output voltage
* @regulator: regulator source
*
@@ -2565,8 +2635,11 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
init_data->consumer_supplies[i].dev,
init_data->consumer_supplies[i].dev_name,
init_data->consumer_supplies[i].supply);
- if (ret < 0)
+ if (ret < 0) {
+ dev_err(dev, "Failed to set supply %s\n",
+ init_data->consumer_supplies[i].supply);
goto unset_supplies;
+ }
}
list_add(&rdev->list, &regulator_list);
@@ -2653,6 +2726,47 @@ out:
EXPORT_SYMBOL_GPL(regulator_suspend_prepare);
/**
+ * regulator_suspend_finish - resume regulators from system wide suspend
+ *
+ * Turn on regulators that might be turned off by regulator_suspend_prepare
+ * and that should be turned on according to the regulators properties.
+ */
+int regulator_suspend_finish(void)
+{
+ struct regulator_dev *rdev;
+ int ret = 0, error;
+
+ mutex_lock(&regulator_list_mutex);
+ list_for_each_entry(rdev, &regulator_list, list) {
+ struct regulator_ops *ops = rdev->desc->ops;
+
+ mutex_lock(&rdev->mutex);
+ if ((rdev->use_count > 0 || rdev->constraints->always_on) &&
+ ops->enable) {
+ error = ops->enable(rdev);
+ if (error)
+ ret = error;
+ } else {
+ if (!has_full_constraints)
+ goto unlock;
+ if (!ops->disable)
+ goto unlock;
+ if (ops->is_enabled && !ops->is_enabled(rdev))
+ goto unlock;
+
+ error = ops->disable(rdev);
+ if (error)
+ ret = error;
+ }
+unlock:
+ mutex_unlock(&rdev->mutex);
+ }
+ mutex_unlock(&regulator_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(regulator_suspend_finish);
+
+/**
* regulator_has_full_constraints - the system has fully specified constraints
*
* Calling this function will cause the regulator API to disable all
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c
index 01ef7e9903b..77e0cfb30b2 100644
--- a/drivers/regulator/max8997.c
+++ b/drivers/regulator/max8997.c
@@ -1185,6 +1185,7 @@ static const struct platform_device_id max8997_pmic_id[] = {
{ "max8997-pmic", 0},
{ },
};
+MODULE_DEVICE_TABLE(platform, max8997_pmic_id);
static struct platform_driver max8997_pmic_driver = {
.driver = {
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c
index 0ec49ca527a..43410266f99 100644
--- a/drivers/regulator/max8998.c
+++ b/drivers/regulator/max8998.c
@@ -887,6 +887,7 @@ static const struct platform_device_id max8998_pmic_id[] = {
{ "lp3974-pmic", TYPE_LP3974 },
{ }
};
+MODULE_DEVICE_TABLE(platform, max8998_pmic_id);
static struct platform_driver max8998_pmic_driver = {
.driver = {
diff --git a/drivers/regulator/tps6524x-regulator.c b/drivers/regulator/tps6524x-regulator.c
index 176a6be5a8c..9166aa0a9df 100644
--- a/drivers/regulator/tps6524x-regulator.c
+++ b/drivers/regulator/tps6524x-regulator.c
@@ -596,7 +596,7 @@ static struct regulator_ops regulator_ops = {
.get_current_limit = get_current_limit,
};
-static int __devexit pmic_remove(struct spi_device *spi)
+static int pmic_remove(struct spi_device *spi)
{
struct tps6524x *hw = spi_get_drvdata(spi);
int i;
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 06df898842c..e93453b1b97 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -565,9 +565,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
}
irq = platform_get_irq_byname(pdev, "UV");
- ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
- IRQF_TRIGGER_RISING, dcdc->name,
- dcdc);
+ ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
+ IRQF_TRIGGER_RISING, dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
@@ -575,9 +574,8 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
}
irq = platform_get_irq_byname(pdev, "HC");
- ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_oc_irq,
- IRQF_TRIGGER_RISING, dcdc->name,
- dcdc);
+ ret = request_threaded_irq(irq, NULL, wm831x_dcdc_oc_irq,
+ IRQF_TRIGGER_RISING, dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request HC IRQ %d: %d\n",
irq, ret);
@@ -589,7 +587,7 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
return 0;
err_uv:
- wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
+ free_irq(platform_get_irq_byname(pdev, "UV"), dcdc);
err_regulator:
regulator_unregister(dcdc->regulator);
err:
@@ -606,8 +604,8 @@ static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
- wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "HC"), dcdc);
- wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
+ free_irq(platform_get_irq_byname(pdev, "HC"), dcdc);
+ free_irq(platform_get_irq_byname(pdev, "UV"), dcdc);
regulator_unregister(dcdc->regulator);
if (dcdc->dvs_gpio)
gpio_free(dcdc->dvs_gpio);
@@ -756,9 +754,8 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
}
irq = platform_get_irq_byname(pdev, "UV");
- ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
- IRQF_TRIGGER_RISING, dcdc->name,
- dcdc);
+ ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
+ IRQF_TRIGGER_RISING, dcdc->name, dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
@@ -783,7 +780,7 @@ static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
platform_set_drvdata(pdev, NULL);
- wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
+ free_irq(platform_get_irq_byname(pdev, "UV"), dcdc);
regulator_unregister(dcdc->regulator);
kfree(dcdc);
@@ -885,9 +882,9 @@ static __devinit int wm831x_boostp_probe(struct platform_device *pdev)
}
irq = platform_get_irq_byname(pdev, "UV");
- ret = wm831x_request_irq(wm831x, irq, wm831x_dcdc_uv_irq,
- IRQF_TRIGGER_RISING, dcdc->name,
- dcdc);
+ ret = request_threaded_irq(irq, NULL, wm831x_dcdc_uv_irq,
+ IRQF_TRIGGER_RISING, dcdc->name,
+ dcdc);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
@@ -908,11 +905,10 @@ err:
static __devexit int wm831x_boostp_remove(struct platform_device *pdev)
{
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
- struct wm831x *wm831x = dcdc->wm831x;
platform_set_drvdata(pdev, NULL);
- wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), dcdc);
+ free_irq(platform_get_irq_byname(pdev, "UV"), dcdc);
regulator_unregister(dcdc->regulator);
kfree(dcdc);
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 6c446cd6ad5..01f27c7f423 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -198,9 +198,8 @@ static __devinit int wm831x_isink_probe(struct platform_device *pdev)
}
irq = platform_get_irq(pdev, 0);
- ret = wm831x_request_irq(wm831x, irq, wm831x_isink_irq,
- IRQF_TRIGGER_RISING, isink->name,
- isink);
+ ret = request_threaded_irq(irq, NULL, wm831x_isink_irq,
+ IRQF_TRIGGER_RISING, isink->name, isink);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request ISINK IRQ %d: %d\n",
irq, ret);
@@ -221,11 +220,10 @@ err:
static __devexit int wm831x_isink_remove(struct platform_device *pdev)
{
struct wm831x_isink *isink = platform_get_drvdata(pdev);
- struct wm831x *wm831x = isink->wm831x;
platform_set_drvdata(pdev, NULL);
- wm831x_free_irq(wm831x, platform_get_irq(pdev, 0), isink);
+ free_irq(platform_get_irq(pdev, 0), isink);
regulator_unregister(isink->regulator);
kfree(isink);
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index c94fc5b7cd5..2220cf8defb 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -354,9 +354,9 @@ static __devinit int wm831x_gp_ldo_probe(struct platform_device *pdev)
}
irq = platform_get_irq_byname(pdev, "UV");
- ret = wm831x_request_irq(wm831x, irq, wm831x_ldo_uv_irq,
- IRQF_TRIGGER_RISING, ldo->name,
- ldo);
+ ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq,
+ IRQF_TRIGGER_RISING, ldo->name,
+ ldo);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
@@ -377,11 +377,10 @@ err:
static __devexit int wm831x_gp_ldo_remove(struct platform_device *pdev)
{
struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
- struct wm831x *wm831x = ldo->wm831x;
platform_set_drvdata(pdev, NULL);
- wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo);
+ free_irq(platform_get_irq_byname(pdev, "UV"), ldo);
regulator_unregister(ldo->regulator);
kfree(ldo);
@@ -619,9 +618,8 @@ static __devinit int wm831x_aldo_probe(struct platform_device *pdev)
}
irq = platform_get_irq_byname(pdev, "UV");
- ret = wm831x_request_irq(wm831x, irq, wm831x_ldo_uv_irq,
- IRQF_TRIGGER_RISING, ldo->name,
- ldo);
+ ret = request_threaded_irq(irq, NULL, wm831x_ldo_uv_irq,
+ IRQF_TRIGGER_RISING, ldo->name, ldo);
if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret);
@@ -642,9 +640,8 @@ err:
static __devexit int wm831x_aldo_remove(struct platform_device *pdev)
{
struct wm831x_ldo *ldo = platform_get_drvdata(pdev);
- struct wm831x *wm831x = ldo->wm831x;
- wm831x_free_irq(wm831x, platform_get_irq_byname(pdev, "UV"), ldo);
+ free_irq(platform_get_irq_byname(pdev, "UV"), ldo);
regulator_unregister(ldo->regulator);
kfree(ldo);
diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c
index e55dc1ac83a..6ac55fd4841 100644
--- a/drivers/rtc/rtc-sh.c
+++ b/drivers/rtc/rtc-sh.c
@@ -782,11 +782,11 @@ static void sh_rtc_set_irq_wake(struct device *dev, int enabled)
struct platform_device *pdev = to_platform_device(dev);
struct sh_rtc *rtc = platform_get_drvdata(pdev);
- set_irq_wake(rtc->periodic_irq, enabled);
+ irq_set_irq_wake(rtc->periodic_irq, enabled);
if (rtc->carry_irq > 0) {
- set_irq_wake(rtc->carry_irq, enabled);
- set_irq_wake(rtc->alarm_irq, enabled);
+ irq_set_irq_wake(rtc->carry_irq, enabled);
+ irq_set_irq_wake(rtc->alarm_irq, enabled);
}
}
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c
index 5833afbf08d..c6ca115c71d 100644
--- a/drivers/sh/intc/core.c
+++ b/drivers/sh/intc/core.c
@@ -63,7 +63,7 @@ void intc_set_prio_level(unsigned int irq, unsigned int level)
static void intc_redirect_irq(unsigned int irq, struct irq_desc *desc)
{
- generic_handle_irq((unsigned int)get_irq_data(irq));
+ generic_handle_irq((unsigned int)irq_get_handler_data(irq));
}
static void __init intc_register_irq(struct intc_desc *desc,
@@ -116,9 +116,9 @@ static void __init intc_register_irq(struct intc_desc *desc,
irq_data = irq_get_irq_data(irq);
disable_irq_nosync(irq);
- set_irq_chip_and_handler_name(irq, &d->chip,
- handle_level_irq, "level");
- set_irq_chip_data(irq, (void *)data[primary]);
+ irq_set_chip_and_handler_name(irq, &d->chip, handle_level_irq,
+ "level");
+ irq_set_chip_data(irq, (void *)data[primary]);
/*
* set priority level
@@ -340,9 +340,9 @@ int __init register_intc_controller(struct intc_desc *desc)
vect2->enum_id = 0;
/* redirect this interrupts to the first one */
- set_irq_chip(irq2, &dummy_irq_chip);
- set_irq_chained_handler(irq2, intc_redirect_irq);
- set_irq_data(irq2, (void *)irq);
+ irq_set_chip(irq2, &dummy_irq_chip);
+ irq_set_chained_handler(irq2, intc_redirect_irq);
+ irq_set_handler_data(irq2, (void *)irq);
}
}
@@ -387,19 +387,16 @@ static int intc_suspend(void)
/* enable wakeup irqs belonging to this intc controller */
for_each_active_irq(irq) {
struct irq_data *data;
- struct irq_desc *desc;
struct irq_chip *chip;
data = irq_get_irq_data(irq);
chip = irq_data_get_irq_chip(data);
if (chip != &d->chip)
continue;
- desc = irq_to_desc(irq);
- if ((desc->status & IRQ_WAKEUP))
+ if (irqd_is_wakeup_set(data))
chip->irq_enable(data);
}
}
-
return 0;
}
@@ -412,7 +409,6 @@ static void intc_resume(void)
for_each_active_irq(irq) {
struct irq_data *data;
- struct irq_desc *desc;
struct irq_chip *chip;
data = irq_get_irq_data(irq);
@@ -423,8 +419,7 @@ static void intc_resume(void)
*/
if (chip != &d->chip)
continue;
- desc = irq_to_desc(irq);
- if (desc->status & IRQ_DISABLED)
+ if (irqd_irq_disabled(data))
chip->irq_disable(data);
else
chip->irq_enable(data);
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h
index df36a421e67..5b934851efa 100644
--- a/drivers/sh/intc/internals.h
+++ b/drivers/sh/intc/internals.h
@@ -86,7 +86,7 @@ enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */
static inline struct intc_desc_int *get_intc_desc(unsigned int irq)
{
- struct irq_chip *chip = get_irq_chip(irq);
+ struct irq_chip *chip = irq_get_chip(irq);
return container_of(chip, struct intc_desc_int, chip);
}
@@ -103,7 +103,7 @@ static inline void activate_irq(int irq)
set_irq_flags(irq, IRQF_VALID);
#else
/* same effect on other architectures */
- set_irq_noprobe(irq);
+ irq_set_noprobe(irq);
#endif
}
diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c
index 4e0ff718116..ce5f81d7cc6 100644
--- a/drivers/sh/intc/virq.c
+++ b/drivers/sh/intc/virq.c
@@ -110,7 +110,7 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc)
{
struct irq_data *data = irq_get_irq_data(irq);
struct irq_chip *chip = irq_data_get_irq_chip(data);
- struct intc_virq_list *entry, *vlist = irq_data_get_irq_data(data);
+ struct intc_virq_list *entry, *vlist = irq_data_get_irq_handler_data(data);
struct intc_desc_int *d = get_intc_desc(irq);
chip->irq_mask_ack(data);
@@ -118,7 +118,7 @@ static void intc_virq_handler(unsigned int irq, struct irq_desc *desc)
for_each_virq(entry, vlist) {
unsigned long addr, handle;
- handle = (unsigned long)get_irq_data(entry->irq);
+ handle = (unsigned long)irq_get_handler_data(entry->irq);
addr = INTC_REG(d, _INTC_ADDR_E(handle), 0);
if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0))
@@ -229,13 +229,13 @@ restart:
intc_irq_xlate_set(irq, entry->enum_id, d);
- set_irq_chip_and_handler_name(irq, get_irq_chip(entry->pirq),
+ irq_set_chip_and_handler_name(irq, irq_get_chip(entry->pirq),
handle_simple_irq, "virq");
- set_irq_chip_data(irq, get_irq_chip_data(entry->pirq));
+ irq_set_chip_data(irq, irq_get_chip_data(entry->pirq));
- set_irq_data(irq, (void *)entry->handle);
+ irq_set_handler_data(irq, (void *)entry->handle);
- set_irq_chained_handler(entry->pirq, intc_virq_handler);
+ irq_set_chained_handler(entry->pirq, intc_virq_handler);
add_virq_to_pirq(entry->pirq, irq);
radix_tree_tag_clear(&d->tree, entry->enum_id,
diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
index e3556ff43bb..ac5bbc8722e 100644
--- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
+++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c
@@ -341,7 +341,7 @@ int bcmsdh_register_oob_intr(void *dhdp)
if (error)
return -ENODEV;
- set_irq_wake(sdhcinfo->oob_irq, 1);
+ irq_set_irq_wake(sdhcinfo->oob_irq, 1);
sdhcinfo->oob_irq_registered = true;
}
@@ -352,7 +352,7 @@ void bcmsdh_unregister_oob_intr(void)
{
SDLX_MSG(("%s: Enter\n", __func__));
- set_irq_wake(sdhcinfo->oob_irq, 0);
+ irq_set_irq_wake(sdhcinfo->oob_irq, 0);
disable_irq(sdhcinfo->oob_irq); /* just in case.. */
free_irq(sdhcinfo->oob_irq, NULL);
sdhcinfo->oob_irq_registered = false;
diff --git a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
index ea9b733c392..21cdb0637be 100644
--- a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
+++ b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c
@@ -597,7 +597,7 @@ static int cy_as_hal_configure_interrupts(void *dev_p)
int result;
int irq_pin = AST_INT;
- set_irq_type(OMAP_GPIO_IRQ(irq_pin), IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(OMAP_GPIO_IRQ(irq_pin), IRQ_TYPE_LEVEL_LOW);
/*
* for shared IRQS must provide non NULL device ptr
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index c35f1a73bc8..52fdf60bdbe 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -178,7 +178,7 @@ static int __init xen_hvc_init(void)
if (xencons_irq < 0)
xencons_irq = 0; /* NO_IRQ */
else
- set_irq_noprobe(xencons_irq);
+ irq_set_noprobe(xencons_irq);
hp = hvc_alloc(HVC_COOKIE, xencons_irq, ops, 256);
if (IS_ERR(hp))
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index e1aee37270f..80484af781e 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1506,7 +1506,7 @@ config SERIAL_BCM63XX_CONSOLE
config SERIAL_GRLIB_GAISLER_APBUART
tristate "GRLIB APBUART serial support"
- depends on OF
+ depends on OF && SPARC
select SERIAL_CORE
---help---
Add support for the GRLIB APBUART serial port.
diff --git a/drivers/tty/serial/apbuart.c b/drivers/tty/serial/apbuart.c
index 1ab999b04ef..19a943693e4 100644
--- a/drivers/tty/serial/apbuart.c
+++ b/drivers/tty/serial/apbuart.c
@@ -555,10 +555,9 @@ static struct uart_driver grlib_apbuart_driver = {
static int __devinit apbuart_probe(struct platform_device *op)
{
- int i = -1;
+ int i;
struct uart_port *port = NULL;
- i = 0;
for (i = 0; i < grlib_apbuart_port_nr; i++) {
if (op->dev.of_node == grlib_apbuart_nodes[i])
break;
@@ -566,6 +565,7 @@ static int __devinit apbuart_probe(struct platform_device *op)
port = &grlib_apbuart_ports[i];
port->dev = &op->dev;
+ port->irq = op->archdata.irqs[0];
uart_add_one_port(&grlib_apbuart_driver, (struct uart_port *) port);
@@ -598,24 +598,12 @@ static struct platform_driver grlib_apbuart_of_driver = {
static int grlib_apbuart_configure(void)
{
- struct device_node *np, *rp;
- const u32 *prop;
- int freq_khz, line = 0;
-
- /* Get bus frequency */
- rp = of_find_node_by_path("/");
- if (!rp)
- return -ENODEV;
- rp = of_get_next_child(rp, NULL);
- if (!rp)
- return -ENODEV;
- prop = of_get_property(rp, "clock-frequency", NULL);
- if (!prop)
- return -ENODEV;
- freq_khz = *prop;
+ struct device_node *np;
+ int line = 0;
for_each_matching_node(np, apbuart_match) {
- const int *irqs, *ampopts;
+ const int *ampopts;
+ const u32 *freq_hz;
const struct amba_prom_registers *regs;
struct uart_port *port;
unsigned long addr;
@@ -623,11 +611,11 @@ static int grlib_apbuart_configure(void)
ampopts = of_get_property(np, "ampopts", NULL);
if (ampopts && (*ampopts == 0))
continue; /* Ignore if used by another OS instance */
-
- irqs = of_get_property(np, "interrupts", NULL);
regs = of_get_property(np, "reg", NULL);
+ /* Frequency of APB Bus is frequency of UART */
+ freq_hz = of_get_property(np, "freq", NULL);
- if (!irqs || !regs)
+ if (!regs || !freq_hz || (*freq_hz == 0))
continue;
grlib_apbuart_nodes[line] = np;
@@ -638,12 +626,12 @@ static int grlib_apbuart_configure(void)
port->mapbase = addr;
port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map));
- port->irq = *irqs;
+ port->irq = 0;
port->iotype = UPIO_MEM;
port->ops = &grlib_apbuart_ops;
port->flags = UPF_BOOT_AUTOCONF;
port->line = line;
- port->uartclk = freq_khz * 1000;
+ port->uartclk = *freq_hz;
port->fifosize = apbuart_scan_fifo_size((struct uart_port *) port, line);
line++;
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 2e7fc9cee9c..b906f11f7c1 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -1644,7 +1644,7 @@ static int __devinit msm_hs_probe(struct platform_device *pdev)
if (unlikely(uport->irq < 0))
return -ENXIO;
- if (unlikely(set_irq_wake(uport->irq, 1)))
+ if (unlikely(irq_set_irq_wake(uport->irq, 1)))
return -ENXIO;
if (pdata == NULL || pdata->rx_wakeup_irq < 0)
@@ -1658,7 +1658,7 @@ static int __devinit msm_hs_probe(struct platform_device *pdev)
if (unlikely(msm_uport->rx_wakeup.irq < 0))
return -ENXIO;
- if (unlikely(set_irq_wake(msm_uport->rx_wakeup.irq, 1)))
+ if (unlikely(irq_set_irq_wake(msm_uport->rx_wakeup.irq, 1)))
return -ENXIO;
}
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c
index b37f92cb71b..444b60aa15e 100644
--- a/drivers/usb/gadget/pxa25x_udc.c
+++ b/drivers/usb/gadget/pxa25x_udc.c
@@ -139,24 +139,6 @@ static const char ep0name [] = "ep0";
static void pxa25x_ep_fifo_flush (struct usb_ep *ep);
static void nuke (struct pxa25x_ep *, int status);
-/* one GPIO should be used to detect VBUS from the host */
-static int is_vbus_present(void)
-{
- struct pxa2xx_udc_mach_info *mach = the_controller->mach;
-
- if (gpio_is_valid(mach->gpio_vbus)) {
- int value = gpio_get_value(mach->gpio_vbus);
-
- if (mach->gpio_vbus_inverted)
- return !value;
- else
- return !!value;
- }
- if (mach->udc_is_connected)
- return mach->udc_is_connected();
- return 1;
-}
-
/* one GPIO should control a D+ pullup, so host sees this device (or not) */
static void pullup_off(void)
{
@@ -1055,7 +1037,7 @@ udc_seq_show(struct seq_file *m, void *_d)
"%s version: %s\nGadget driver: %s\nHost %s\n\n",
driver_name, DRIVER_VERSION SIZE_STR "(pio)",
dev->driver ? dev->driver->driver.name : "(none)",
- is_vbus_present() ? "full speed" : "disconnected");
+ dev->gadget.speed == USB_SPEED_FULL ? "full speed" : "disconnected");
/* registers for device and ep0 */
seq_printf(m,
@@ -1094,7 +1076,7 @@ udc_seq_show(struct seq_file *m, void *_d)
(tmp & UDCCFR_ACM) ? " acm" : "");
}
- if (!is_vbus_present() || !dev->driver)
+ if (dev->gadget.speed != USB_SPEED_FULL || !dev->driver)
goto done;
seq_printf(m, "ep0 IN %lu/%lu, OUT %lu/%lu\nirqs %lu\n\n",
@@ -1435,14 +1417,6 @@ lubbock_vbus_irq(int irq, void *_dev)
#endif
-static irqreturn_t udc_vbus_irq(int irq, void *_dev)
-{
- struct pxa25x_udc *dev = _dev;
-
- pxa25x_udc_vbus_session(&dev->gadget, is_vbus_present());
- return IRQ_HANDLED;
-}
-
/*-------------------------------------------------------------------------*/
@@ -1766,12 +1740,9 @@ pxa25x_udc_irq(int irq, void *_dev)
if (unlikely(udccr & UDCCR_SUSIR)) {
udc_ack_int_UDCCR(UDCCR_SUSIR);
handled = 1;
- DBG(DBG_VERBOSE, "USB suspend%s\n", is_vbus_present()
- ? "" : "+disconnect");
+ DBG(DBG_VERBOSE, "USB suspend\n");
- if (!is_vbus_present())
- stop_activity(dev, dev->driver);
- else if (dev->gadget.speed != USB_SPEED_UNKNOWN
+ if (dev->gadget.speed != USB_SPEED_UNKNOWN
&& dev->driver
&& dev->driver->suspend)
dev->driver->suspend(&dev->gadget);
@@ -1786,8 +1757,7 @@ pxa25x_udc_irq(int irq, void *_dev)
if (dev->gadget.speed != USB_SPEED_UNKNOWN
&& dev->driver
- && dev->driver->resume
- && is_vbus_present())
+ && dev->driver->resume)
dev->driver->resume(&dev->gadget);
}
@@ -2137,7 +2107,7 @@ static struct pxa25x_udc memory = {
static int __init pxa25x_udc_probe(struct platform_device *pdev)
{
struct pxa25x_udc *dev = &memory;
- int retval, vbus_irq, irq;
+ int retval, irq;
u32 chiprev;
/* insist on Intel/ARM/XScale */
@@ -2199,19 +2169,6 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
dev->transceiver = otg_get_transceiver();
- if (gpio_is_valid(dev->mach->gpio_vbus)) {
- if ((retval = gpio_request(dev->mach->gpio_vbus,
- "pxa25x_udc GPIO VBUS"))) {
- dev_dbg(&pdev->dev,
- "can't get vbus gpio %d, err: %d\n",
- dev->mach->gpio_vbus, retval);
- goto err_gpio_vbus;
- }
- gpio_direction_input(dev->mach->gpio_vbus);
- vbus_irq = gpio_to_irq(dev->mach->gpio_vbus);
- } else
- vbus_irq = 0;
-
if (gpio_is_valid(dev->mach->gpio_pullup)) {
if ((retval = gpio_request(dev->mach->gpio_pullup,
"pca25x_udc GPIO PULLUP"))) {
@@ -2237,7 +2194,7 @@ static int __init pxa25x_udc_probe(struct platform_device *pdev)
udc_disable(dev);
udc_reinit(dev);
- dev->vbus = !!is_vbus_present();
+ dev->vbus = 0;
/* irq setup after old hardware state is cleaned up */
retval = request_irq(irq, pxa25x_udc_irq,
@@ -2273,22 +2230,10 @@ lubbock_fail0:
}
} else
#endif
- if (vbus_irq) {
- retval = request_irq(vbus_irq, udc_vbus_irq,
- IRQF_DISABLED | IRQF_SAMPLE_RANDOM |
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- driver_name, dev);
- if (retval != 0) {
- pr_err("%s: can't get irq %i, err %d\n",
- driver_name, vbus_irq, retval);
- goto err_vbus_irq;
- }
- }
create_debug_files(dev);
return 0;
- err_vbus_irq:
#ifdef CONFIG_ARCH_LUBBOCK
free_irq(LUBBOCK_USB_DISC_IRQ, dev);
err_irq_lub:
@@ -2298,9 +2243,6 @@ lubbock_fail0:
if (gpio_is_valid(dev->mach->gpio_pullup))
gpio_free(dev->mach->gpio_pullup);
err_gpio_pullup:
- if (gpio_is_valid(dev->mach->gpio_vbus))
- gpio_free(dev->mach->gpio_vbus);
- err_gpio_vbus:
if (dev->transceiver) {
otg_put_transceiver(dev->transceiver);
dev->transceiver = NULL;
@@ -2337,10 +2279,6 @@ static int __exit pxa25x_udc_remove(struct platform_device *pdev)
free_irq(LUBBOCK_USB_IRQ, dev);
}
#endif
- if (gpio_is_valid(dev->mach->gpio_vbus)) {
- free_irq(gpio_to_irq(dev->mach->gpio_vbus), dev);
- gpio_free(dev->mach->gpio_vbus);
- }
if (gpio_is_valid(dev->mach->gpio_pullup))
gpio_free(dev->mach->gpio_pullup);
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 38193f4e980..44e4deb362e 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -3832,7 +3832,7 @@ static int oxu_drv_probe(struct platform_device *pdev)
return -EBUSY;
}
- ret = set_irq_type(irq, IRQF_TRIGGER_FALLING);
+ ret = irq_set_irq_type(irq, IRQF_TRIGGER_FALLING);
if (ret) {
dev_err(&pdev->dev, "error setting irq type\n");
ret = -EFAULT;
diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 2ba3b070ed0..c47aac4a1f9 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -943,7 +943,7 @@ static void tusb_musb_enable(struct musb *musb)
musb_writel(tbase, TUSB_INT_CTRL_CONF,
TUSB_INT_CTRL_CONF_INT_RELCYC(0));
- set_irq_type(musb->nIrq, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(musb->nIrq, IRQ_TYPE_LEVEL_LOW);
/* maybe force into the Default-A OTG state machine */
if (!(musb_readl(tbase, TUSB_DEV_OTG_STAT)
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index 825b665245b..a2e5b5100ab 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -627,7 +627,12 @@ static void overlay1fb_enable(struct pxafb_layer *ofb)
static void overlay1fb_disable(struct pxafb_layer *ofb)
{
- uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
+ uint32_t lccr5;
+
+ if (!(lcd_readl(ofb->fbi, OVL1C1) & OVLxC1_OEN))
+ return;
+
+ lccr5 = lcd_readl(ofb->fbi, LCCR5);
lcd_writel(ofb->fbi, OVL1C1, ofb->control[0] & ~OVLxC1_OEN);
@@ -685,7 +690,12 @@ static void overlay2fb_enable(struct pxafb_layer *ofb)
static void overlay2fb_disable(struct pxafb_layer *ofb)
{
- uint32_t lccr5 = lcd_readl(ofb->fbi, LCCR5);
+ uint32_t lccr5;
+
+ if (!(lcd_readl(ofb->fbi, OVL2C1) & OVLxC1_OEN))
+ return;
+
+ lccr5 = lcd_readl(ofb->fbi, LCCR5);
lcd_writel(ofb->fbi, OVL2C1, ofb->control[0] & ~OVLxC1_OEN);
@@ -720,12 +730,10 @@ static int overlayfb_open(struct fb_info *info, int user)
if (user == 0)
return -ENODEV;
- /* allow only one user at a time */
- if (atomic_inc_and_test(&ofb->usage))
- return -EBUSY;
+ if (ofb->usage++ == 0)
+ /* unblank the base framebuffer */
+ fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
- /* unblank the base framebuffer */
- fb_blank(&ofb->fbi->fb, FB_BLANK_UNBLANK);
return 0;
}
@@ -733,12 +741,15 @@ static int overlayfb_release(struct fb_info *info, int user)
{
struct pxafb_layer *ofb = (struct pxafb_layer*) info;
- atomic_dec(&ofb->usage);
- ofb->ops->disable(ofb);
+ if (ofb->usage == 1) {
+ ofb->ops->disable(ofb);
+ ofb->fb.var.height = -1;
+ ofb->fb.var.width = -1;
+ ofb->fb.var.xres = ofb->fb.var.xres_virtual = 0;
+ ofb->fb.var.yres = ofb->fb.var.yres_virtual = 0;
- free_pages_exact(ofb->video_mem, ofb->video_mem_size);
- ofb->video_mem = NULL;
- ofb->video_mem_size = 0;
+ ofb->usage--;
+ }
return 0;
}
@@ -750,7 +761,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
int xpos, ypos, pfor, bpp;
xpos = NONSTD_TO_XPOS(var->nonstd);
- ypos = NONSTD_TO_XPOS(var->nonstd);
+ ypos = NONSTD_TO_YPOS(var->nonstd);
pfor = NONSTD_TO_PFOR(var->nonstd);
bpp = pxafb_var_to_bpp(var);
@@ -794,7 +805,7 @@ static int overlayfb_check_var(struct fb_var_screeninfo *var,
return 0;
}
-static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
+static int overlayfb_check_video_memory(struct pxafb_layer *ofb)
{
struct fb_var_screeninfo *var = &ofb->fb.var;
int pfor = NONSTD_TO_PFOR(var->nonstd);
@@ -812,27 +823,11 @@ static int overlayfb_map_video_memory(struct pxafb_layer *ofb)
size = PAGE_ALIGN(ofb->fb.fix.line_length * var->yres_virtual);
- /* don't re-allocate if the original video memory is enough */
if (ofb->video_mem) {
if (ofb->video_mem_size >= size)
return 0;
-
- free_pages_exact(ofb->video_mem, ofb->video_mem_size);
}
-
- ofb->video_mem = alloc_pages_exact(size, GFP_KERNEL | __GFP_ZERO);
- if (ofb->video_mem == NULL)
- return -ENOMEM;
-
- ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
- ofb->video_mem_size = size;
-
- mutex_lock(&ofb->fb.mm_lock);
- ofb->fb.fix.smem_start = ofb->video_mem_phys;
- ofb->fb.fix.smem_len = ofb->fb.fix.line_length * var->yres_virtual;
- mutex_unlock(&ofb->fb.mm_lock);
- ofb->fb.screen_base = ofb->video_mem;
- return 0;
+ return -EINVAL;
}
static int overlayfb_set_par(struct fb_info *info)
@@ -841,13 +836,13 @@ static int overlayfb_set_par(struct fb_info *info)
struct fb_var_screeninfo *var = &info->var;
int xpos, ypos, pfor, bpp, ret;
- ret = overlayfb_map_video_memory(ofb);
+ ret = overlayfb_check_video_memory(ofb);
if (ret)
return ret;
bpp = pxafb_var_to_bpp(var);
xpos = NONSTD_TO_XPOS(var->nonstd);
- ypos = NONSTD_TO_XPOS(var->nonstd);
+ ypos = NONSTD_TO_YPOS(var->nonstd);
pfor = NONSTD_TO_PFOR(var->nonstd);
ofb->control[0] = OVLxC1_PPL(var->xres) | OVLxC1_LPO(var->yres) |
@@ -891,7 +886,7 @@ static void __devinit init_pxafb_overlay(struct pxafb_info *fbi,
ofb->id = id;
ofb->ops = &ofb_ops[id];
- atomic_set(&ofb->usage, 0);
+ ofb->usage = 0;
ofb->fbi = fbi;
init_completion(&ofb->branch_done);
}
@@ -904,29 +899,60 @@ static inline int pxafb_overlay_supported(void)
return 0;
}
-static int __devinit pxafb_overlay_init(struct pxafb_info *fbi)
+static int __devinit pxafb_overlay_map_video_memory(struct pxafb_info *pxafb,
+ struct pxafb_layer *ofb)
+{
+ /* We assume that user will use at most video_mem_size for overlay fb,
+ * anyway, it's useless to use 16bpp main plane and 24bpp overlay
+ */
+ ofb->video_mem = alloc_pages_exact(PAGE_ALIGN(pxafb->video_mem_size),
+ GFP_KERNEL | __GFP_ZERO);
+ if (ofb->video_mem == NULL)
+ return -ENOMEM;
+
+ ofb->video_mem_phys = virt_to_phys(ofb->video_mem);
+ ofb->video_mem_size = PAGE_ALIGN(pxafb->video_mem_size);
+
+ mutex_lock(&ofb->fb.mm_lock);
+ ofb->fb.fix.smem_start = ofb->video_mem_phys;
+ ofb->fb.fix.smem_len = pxafb->video_mem_size;
+ mutex_unlock(&ofb->fb.mm_lock);
+
+ ofb->fb.screen_base = ofb->video_mem;
+
+ return 0;
+}
+
+static void __devinit pxafb_overlay_init(struct pxafb_info *fbi)
{
int i, ret;
if (!pxafb_overlay_supported())
- return 0;
+ return;
for (i = 0; i < 2; i++) {
- init_pxafb_overlay(fbi, &fbi->overlay[i], i);
- ret = register_framebuffer(&fbi->overlay[i].fb);
+ struct pxafb_layer *ofb = &fbi->overlay[i];
+ init_pxafb_overlay(fbi, ofb, i);
+ ret = register_framebuffer(&ofb->fb);
if (ret) {
dev_err(fbi->dev, "failed to register overlay %d\n", i);
- return ret;
+ continue;
}
+ ret = pxafb_overlay_map_video_memory(fbi, ofb);
+ if (ret) {
+ dev_err(fbi->dev,
+ "failed to map video memory for overlay %d\n",
+ i);
+ unregister_framebuffer(&ofb->fb);
+ continue;
+ }
+ ofb->registered = 1;
}
/* mask all IU/BS/EOF/SOF interrupts */
lcd_writel(fbi, LCCR5, ~0);
- /* place overlay(s) on top of base */
- fbi->lccr0 |= LCCR0_OUC;
pr_info("PXA Overlay driver loaded successfully!\n");
- return 0;
}
static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
@@ -936,8 +962,15 @@ static void __devexit pxafb_overlay_exit(struct pxafb_info *fbi)
if (!pxafb_overlay_supported())
return;
- for (i = 0; i < 2; i++)
- unregister_framebuffer(&fbi->overlay[i].fb);
+ for (i = 0; i < 2; i++) {
+ struct pxafb_layer *ofb = &fbi->overlay[i];
+ if (ofb->registered) {
+ if (ofb->video_mem)
+ free_pages_exact(ofb->video_mem,
+ ofb->video_mem_size);
+ unregister_framebuffer(&ofb->fb);
+ }
+ }
}
#else
static inline void pxafb_overlay_init(struct pxafb_info *fbi) {}
@@ -1368,7 +1401,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var,
(lcd_readl(fbi, LCCR3) != fbi->reg_lccr3) ||
(lcd_readl(fbi, LCCR4) != fbi->reg_lccr4) ||
(lcd_readl(fbi, FDADR0) != fbi->fdadr[0]) ||
- (lcd_readl(fbi, FDADR1) != fbi->fdadr[1]))
+ ((fbi->lccr0 & LCCR0_SDS) &&
+ (lcd_readl(fbi, FDADR1) != fbi->fdadr[1])))
pxafb_schedule_work(fbi, C_REENABLE);
return 0;
@@ -1420,7 +1454,8 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
lcd_writel(fbi, LCCR0, fbi->reg_lccr0 & ~LCCR0_ENB);
lcd_writel(fbi, FDADR0, fbi->fdadr[0]);
- lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
+ if (fbi->lccr0 & LCCR0_SDS)
+ lcd_writel(fbi, FDADR1, fbi->fdadr[1]);
lcd_writel(fbi, LCCR0, fbi->reg_lccr0 | LCCR0_ENB);
}
@@ -1613,7 +1648,8 @@ pxafb_freq_transition(struct notifier_block *nb, unsigned long val, void *data)
switch (val) {
case CPUFREQ_PRECHANGE:
- set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
+ if (!fbi->overlay[0].usage && !fbi->overlay[1].usage)
+ set_ctrlr_state(fbi, C_DISABLE_CLKCHANGE);
break;
case CPUFREQ_POSTCHANGE:
@@ -1806,6 +1842,12 @@ static struct pxafb_info * __devinit pxafb_init_fbinfo(struct device *dev)
pxafb_decode_mach_info(fbi, inf);
+#ifdef CONFIG_FB_PXA_OVERLAY
+ /* place overlay(s) on top of base */
+ if (pxafb_overlay_supported())
+ fbi->lccr0 |= LCCR0_OUC;
+#endif
+
init_waitqueue_head(&fbi->ctrlr_wait);
INIT_WORK(&fbi->task, pxafb_task);
mutex_init(&fbi->ctrlr_lock);
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index 2353521c5c8..26ba9fa3f73 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -92,7 +92,8 @@ struct pxafb_layer_ops {
struct pxafb_layer {
struct fb_info fb;
int id;
- atomic_t usage;
+ int registered;
+ uint32_t usage;
uint32_t control[2];
struct pxafb_layer_ops *ops;
diff --git a/drivers/vlynq/vlynq.c b/drivers/vlynq/vlynq.c
index f885c868a04..aa250cebecd 100644
--- a/drivers/vlynq/vlynq.c
+++ b/drivers/vlynq/vlynq.c
@@ -135,40 +135,40 @@ static void vlynq_reset(struct vlynq_device *dev)
msleep(5);
}
-static void vlynq_irq_unmask(unsigned int irq)
+static void vlynq_irq_unmask(struct irq_data *d)
{
- u32 val;
- struct vlynq_device *dev = get_irq_chip_data(irq);
+ struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
int virq;
+ u32 val;
BUG_ON(!dev);
- virq = irq - dev->irq_start;
+ virq = d->irq - dev->irq_start;
val = readl(&dev->remote->int_device[virq >> 2]);
val |= (VINT_ENABLE | virq) << VINT_OFFSET(virq);
writel(val, &dev->remote->int_device[virq >> 2]);
}
-static void vlynq_irq_mask(unsigned int irq)
+static void vlynq_irq_mask(struct irq_data *d)
{
- u32 val;
- struct vlynq_device *dev = get_irq_chip_data(irq);
+ struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
int virq;
+ u32 val;
BUG_ON(!dev);
- virq = irq - dev->irq_start;
+ virq = d->irq - dev->irq_start;
val = readl(&dev->remote->int_device[virq >> 2]);
val &= ~(VINT_ENABLE << VINT_OFFSET(virq));
writel(val, &dev->remote->int_device[virq >> 2]);
}
-static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
+static int vlynq_irq_type(struct irq_data *d, unsigned int flow_type)
{
- u32 val;
- struct vlynq_device *dev = get_irq_chip_data(irq);
+ struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
int virq;
+ u32 val;
BUG_ON(!dev);
- virq = irq - dev->irq_start;
+ virq = d->irq - dev->irq_start;
val = readl(&dev->remote->int_device[virq >> 2]);
switch (flow_type & IRQ_TYPE_SENSE_MASK) {
case IRQ_TYPE_EDGE_RISING:
@@ -192,10 +192,9 @@ static int vlynq_irq_type(unsigned int irq, unsigned int flow_type)
return 0;
}
-static void vlynq_local_ack(unsigned int irq)
+static void vlynq_local_ack(struct irq_data *d)
{
- struct vlynq_device *dev = get_irq_chip_data(irq);
-
+ struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
u32 status = readl(&dev->local->status);
pr_debug("%s: local status: 0x%08x\n",
@@ -203,10 +202,9 @@ static void vlynq_local_ack(unsigned int irq)
writel(status, &dev->local->status);
}
-static void vlynq_remote_ack(unsigned int irq)
+static void vlynq_remote_ack(struct irq_data *d)
{
- struct vlynq_device *dev = get_irq_chip_data(irq);
-
+ struct vlynq_device *dev = irq_data_get_irq_chip_data(d);
u32 status = readl(&dev->remote->status);
pr_debug("%s: remote status: 0x%08x\n",
@@ -238,23 +236,23 @@ static irqreturn_t vlynq_irq(int irq, void *dev_id)
static struct irq_chip vlynq_irq_chip = {
.name = "vlynq",
- .unmask = vlynq_irq_unmask,
- .mask = vlynq_irq_mask,
- .set_type = vlynq_irq_type,
+ .irq_unmask = vlynq_irq_unmask,
+ .irq_mask = vlynq_irq_mask,
+ .irq_set_type = vlynq_irq_type,
};
static struct irq_chip vlynq_local_chip = {
.name = "vlynq local error",
- .unmask = vlynq_irq_unmask,
- .mask = vlynq_irq_mask,
- .ack = vlynq_local_ack,
+ .irq_unmask = vlynq_irq_unmask,
+ .irq_mask = vlynq_irq_mask,
+ .irq_ack = vlynq_local_ack,
};
static struct irq_chip vlynq_remote_chip = {
.name = "vlynq local error",
- .unmask = vlynq_irq_unmask,
- .mask = vlynq_irq_mask,
- .ack = vlynq_remote_ack,
+ .irq_unmask = vlynq_irq_unmask,
+ .irq_mask = vlynq_irq_mask,
+ .irq_ack = vlynq_remote_ack,
};
static int vlynq_setup_irq(struct vlynq_device *dev)
@@ -291,17 +289,17 @@ static int vlynq_setup_irq(struct vlynq_device *dev)
for (i = dev->irq_start; i <= dev->irq_end; i++) {
virq = i - dev->irq_start;
if (virq == dev->local_irq) {
- set_irq_chip_and_handler(i, &vlynq_local_chip,
+ irq_set_chip_and_handler(i, &vlynq_local_chip,
handle_level_irq);
- set_irq_chip_data(i, dev);
+ irq_set_chip_data(i, dev);
} else if (virq == dev->remote_irq) {
- set_irq_chip_and_handler(i, &vlynq_remote_chip,
+ irq_set_chip_and_handler(i, &vlynq_remote_chip,
handle_level_irq);
- set_irq_chip_data(i, dev);
+ irq_set_chip_data(i, dev);
} else {
- set_irq_chip_and_handler(i, &vlynq_irq_chip,
+ irq_set_chip_and_handler(i, &vlynq_irq_chip,
handle_simple_irq);
- set_irq_chip_data(i, dev);
+ irq_set_chip_data(i, dev);
writel(0, &dev->remote->int_device[virq >> 2]);
}
}
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c
index 95921b77cf8..2f4fa02744a 100644
--- a/drivers/w1/masters/ds1wm.c
+++ b/drivers/w1/masters/ds1wm.c
@@ -368,9 +368,9 @@ static int ds1wm_probe(struct platform_device *pdev)
ds1wm_data->active_high = plat->active_high;
if (res->flags & IORESOURCE_IRQ_HIGHEDGE)
- set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING);
if (res->flags & IORESOURCE_IRQ_LOWEDGE)
- set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
+ irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_FALLING);
ret = request_irq(ds1wm_data->irq, ds1wm_isr, IRQF_DISABLED,
"ds1wm", ds1wm_data);
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c
index 596ba604e78..51b5551b4e3 100644
--- a/drivers/watchdog/davinci_wdt.c
+++ b/drivers/watchdog/davinci_wdt.c
@@ -202,7 +202,6 @@ static struct miscdevice davinci_wdt_miscdev = {
static int __devinit davinci_wdt_probe(struct platform_device *pdev)
{
int ret = 0, size;
- struct resource *res;
struct device *dev = &pdev->dev;
wdt_clk = clk_get(dev, NULL);
@@ -216,31 +215,31 @@ static int __devinit davinci_wdt_probe(struct platform_device *pdev)
dev_info(dev, "heartbeat %d sec\n", heartbeat);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
+ wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (wdt_mem == NULL) {
dev_err(dev, "failed to get memory region resource\n");
return -ENOENT;
}
- size = resource_size(res);
- wdt_mem = request_mem_region(res->start, size, pdev->name);
-
- if (wdt_mem == NULL) {
+ size = resource_size(wdt_mem);
+ if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
dev_err(dev, "failed to get memory region\n");
return -ENOENT;
}
- wdt_base = ioremap(res->start, size);
+ wdt_base = ioremap(wdt_mem->start, size);
if (!wdt_base) {
dev_err(dev, "failed to map memory region\n");
+ release_mem_region(wdt_mem->start, size);
+ wdt_mem = NULL;
return -ENOMEM;
}
ret = misc_register(&davinci_wdt_miscdev);
if (ret < 0) {
dev_err(dev, "cannot register misc device\n");
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, size);
+ wdt_mem = NULL;
} else {
set_bit(WDT_DEVICE_INITED, &wdt_status);
}
@@ -253,8 +252,7 @@ static int __devexit davinci_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&davinci_wdt_miscdev);
if (wdt_mem) {
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, resource_size(wdt_mem));
wdt_mem = NULL;
}
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c
index 7a82ce5a633..73ba2fd8e59 100644
--- a/drivers/watchdog/max63xx_wdt.c
+++ b/drivers/watchdog/max63xx_wdt.c
@@ -270,7 +270,6 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
{
int ret = 0;
int size;
- struct resource *res;
struct device *dev = &pdev->dev;
struct max63xx_timeout *table;
@@ -294,21 +293,19 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
max63xx_pdev = pdev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
+ wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (wdt_mem == NULL) {
dev_err(dev, "failed to get memory region resource\n");
return -ENOENT;
}
- size = resource_size(res);
- wdt_mem = request_mem_region(res->start, size, pdev->name);
-
- if (wdt_mem == NULL) {
+ size = resource_size(wdt_mem);
+ if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
dev_err(dev, "failed to get memory region\n");
return -ENOENT;
}
- wdt_base = ioremap(res->start, size);
+ wdt_base = ioremap(wdt_mem->start, size);
if (!wdt_base) {
dev_err(dev, "failed to map memory region\n");
ret = -ENOMEM;
@@ -326,8 +323,8 @@ static int __devinit max63xx_wdt_probe(struct platform_device *pdev)
out_unmap:
iounmap(wdt_base);
out_request:
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, size);
+ wdt_mem = NULL;
return ret;
}
@@ -336,8 +333,7 @@ static int __devexit max63xx_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&max63xx_wdt_miscdev);
if (wdt_mem) {
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, resource_size(wdt_mem));
wdt_mem = NULL;
}
diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c
index 267377a5a83..afa78a54711 100644
--- a/drivers/watchdog/nv_tco.c
+++ b/drivers/watchdog/nv_tco.c
@@ -302,7 +302,7 @@ MODULE_DEVICE_TABLE(pci, tco_pci_tbl);
* Init & exit routines
*/
-static unsigned char __init nv_tco_getdevice(void)
+static unsigned char __devinit nv_tco_getdevice(void)
{
struct pci_dev *dev = NULL;
u32 val;
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index c7cf4cbf8ab..61493322556 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -254,7 +254,6 @@ static struct miscdevice pnx4008_wdt_miscdev = {
static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
{
int ret = 0, size;
- struct resource *res;
if (heartbeat < 1 || heartbeat > MAX_HEARTBEAT)
heartbeat = DEFAULT_HEARTBEAT;
@@ -262,42 +261,42 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
printk(KERN_INFO MODULE_NAME
"PNX4008 Watchdog Timer: heartbeat %d sec\n", heartbeat);
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
+ wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (wdt_mem == NULL) {
printk(KERN_INFO MODULE_NAME
"failed to get memory region resouce\n");
return -ENOENT;
}
- size = resource_size(res);
- wdt_mem = request_mem_region(res->start, size, pdev->name);
+ size = resource_size(wdt_mem);
- if (wdt_mem == NULL) {
+ if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
printk(KERN_INFO MODULE_NAME "failed to get memory region\n");
return -ENOENT;
}
- wdt_base = (void __iomem *)IO_ADDRESS(res->start);
+ wdt_base = (void __iomem *)IO_ADDRESS(wdt_mem->start);
wdt_clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(wdt_clk)) {
ret = PTR_ERR(wdt_clk);
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, size);
+ wdt_mem = NULL;
goto out;
}
ret = clk_enable(wdt_clk);
if (ret) {
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, size);
+ wdt_mem = NULL;
+ clk_put(wdt_clk);
goto out;
}
ret = misc_register(&pnx4008_wdt_miscdev);
if (ret < 0) {
printk(KERN_ERR MODULE_NAME "cannot register misc device\n");
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, size);
+ wdt_mem = NULL;
clk_disable(wdt_clk);
clk_put(wdt_clk);
} else {
@@ -320,8 +319,7 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev)
clk_put(wdt_clk);
if (wdt_mem) {
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, resource_size(wdt_mem));
wdt_mem = NULL;
}
return 0;
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 25b39bf3592..f7f5aa00df6 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -402,7 +402,6 @@ static inline void s3c2410wdt_cpufreq_deregister(void)
static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
{
- struct resource *res;
struct device *dev;
unsigned int wtcon;
int started = 0;
@@ -416,20 +415,19 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
/* get the memory region for the watchdog timer */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
+ wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (wdt_mem == NULL) {
dev_err(dev, "no memory resource specified\n");
return -ENOENT;
}
- size = resource_size(res);
- wdt_mem = request_mem_region(res->start, size, pdev->name);
- if (wdt_mem == NULL) {
+ size = resource_size(wdt_mem);
+ if (!request_mem_region(wdt_mem->start, size, pdev->name)) {
dev_err(dev, "failed to get memory region\n");
return -EBUSY;
}
- wdt_base = ioremap(res->start, size);
+ wdt_base = ioremap(wdt_mem->start, size);
if (wdt_base == NULL) {
dev_err(dev, "failed to ioremap() region\n");
ret = -EINVAL;
@@ -524,8 +522,8 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
iounmap(wdt_base);
err_req:
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, size);
+ wdt_mem = NULL;
return ret;
}
@@ -545,8 +543,7 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev)
iounmap(wdt_base);
- release_resource(wdt_mem);
- kfree(wdt_mem);
+ release_mem_region(wdt_mem->start, resource_size(wdt_mem));
wdt_mem = NULL;
return 0;
}
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c
index 100b114e3c3..bf16ffb4d21 100644
--- a/drivers/watchdog/softdog.c
+++ b/drivers/watchdog/softdog.c
@@ -48,6 +48,7 @@
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/uaccess.h>
+#include <linux/kernel.h>
#define PFX "SoftDog: "
@@ -75,6 +76,11 @@ MODULE_PARM_DESC(soft_noboot,
"Softdog action, set to 1 to ignore reboots, 0 to reboot "
"(default depends on ONLY_TESTING)");
+static int soft_panic;
+module_param(soft_panic, int, 0);
+MODULE_PARM_DESC(soft_panic,
+ "Softdog action, set to 1 to panic, 0 to reboot (default=0)");
+
/*
* Our timer
*/
@@ -98,7 +104,10 @@ static void watchdog_fire(unsigned long data)
if (soft_noboot)
printk(KERN_CRIT PFX "Triggered - Reboot ignored.\n");
- else {
+ else if (soft_panic) {
+ printk(KERN_CRIT PFX "Initiating panic.\n");
+ panic("Software Watchdog Timer expired.");
+ } else {
printk(KERN_CRIT PFX "Initiating system reboot.\n");
emergency_restart();
printk(KERN_CRIT PFX "Reboot didn't ?????\n");
@@ -267,7 +276,8 @@ static struct notifier_block softdog_notifier = {
};
static char banner[] __initdata = KERN_INFO "Software Watchdog Timer: 0.07 "
- "initialized. soft_noboot=%d soft_margin=%d sec (nowayout= %d)\n";
+ "initialized. soft_noboot=%d soft_margin=%d sec soft_panic=%d "
+ "(nowayout= %d)\n";
static int __init watchdog_init(void)
{
@@ -298,7 +308,7 @@ static int __init watchdog_init(void)
return ret;
}
- printk(banner, soft_noboot, soft_margin, nowayout);
+ printk(banner, soft_noboot, soft_margin, soft_panic, nowayout);
return 0;
}
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
index 1bc493848ed..87e0527669d 100644
--- a/drivers/watchdog/sp5100_tco.c
+++ b/drivers/watchdog/sp5100_tco.c
@@ -42,6 +42,7 @@
#define PFX TCO_MODULE_NAME ": "
/* internal variables */
+static u32 tcobase_phys;
static void __iomem *tcobase;
static unsigned int pm_iobase;
static DEFINE_SPINLOCK(tco_lock); /* Guards the hardware */
@@ -305,10 +306,18 @@ static unsigned char __devinit sp5100_tco_setupdevice(void)
/* Low three bits of BASE0 are reserved. */
val = val << 8 | (inb(SP5100_IO_PM_DATA_REG) & 0xf8);
+ if (!request_mem_region_exclusive(val, SP5100_WDT_MEM_MAP_SIZE,
+ "SP5100 TCO")) {
+ printk(KERN_ERR PFX "mmio address 0x%04x already in use\n",
+ val);
+ goto unreg_region;
+ }
+ tcobase_phys = val;
+
tcobase = ioremap(val, SP5100_WDT_MEM_MAP_SIZE);
if (tcobase == 0) {
printk(KERN_ERR PFX "failed to get tcobase address\n");
- goto unreg_region;
+ goto unreg_mem_region;
}
/* Enable watchdog decode bit */
@@ -346,7 +355,8 @@ static unsigned char __devinit sp5100_tco_setupdevice(void)
/* Done */
return 1;
- iounmap(tcobase);
+unreg_mem_region:
+ release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
unreg_region:
release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
exit:
@@ -401,6 +411,7 @@ static int __devinit sp5100_tco_init(struct platform_device *dev)
exit:
iounmap(tcobase);
+ release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
return ret;
}
@@ -414,6 +425,7 @@ static void __devexit sp5100_tco_cleanup(void)
/* Deregister */
misc_deregister(&sp5100_tco_miscdev);
iounmap(tcobase);
+ release_mem_region(tcobase_phys, SP5100_WDT_MEM_MAP_SIZE);
release_region(pm_iobase, SP5100_PM_IOPORTS_SIZE);
}
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 02b5a9c05cf..036343ba204 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -122,7 +122,7 @@ static struct irq_chip xen_pirq_chip;
/* Get info for IRQ */
static struct irq_info *info_for_irq(unsigned irq)
{
- return get_irq_data(irq);
+ return irq_get_handler_data(irq);
}
/* Constructors for packed IRQ information. */
@@ -403,7 +403,7 @@ static void xen_irq_init(unsigned irq)
info->type = IRQT_UNBOUND;
- set_irq_data(irq, info);
+ irq_set_handler_data(irq, info);
list_add_tail(&info->list, &xen_irq_list_head);
}
@@ -458,11 +458,11 @@ static int __must_check xen_allocate_irq_gsi(unsigned gsi)
static void xen_free_irq(unsigned irq)
{
- struct irq_info *info = get_irq_data(irq);
+ struct irq_info *info = irq_get_handler_data(irq);
list_del(&info->list);
- set_irq_data(irq, NULL);
+ irq_set_handler_data(irq, NULL);
kfree(info);
@@ -585,7 +585,7 @@ static void ack_pirq(struct irq_data *data)
{
int evtchn = evtchn_from_irq(data->irq);
- move_native_irq(data->irq);
+ irq_move_irq(data);
if (VALID_EVTCHN(evtchn)) {
mask_evtchn(evtchn);
@@ -639,8 +639,8 @@ int xen_bind_pirq_gsi_to_irq(unsigned gsi,
if (irq < 0)
goto out;
- set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
- handle_level_irq, name);
+ irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq,
+ name);
irq_op.irq = irq;
irq_op.vector = 0;
@@ -690,8 +690,8 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
if (irq == -1)
goto out;
- set_irq_chip_and_handler_name(irq, &xen_pirq_chip,
- handle_level_irq, name);
+ irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_level_irq,
+ name);
xen_irq_info_pirq_init(irq, 0, pirq, 0, vector, 0);
ret = irq_set_msi_desc(irq, msidesc);
@@ -772,7 +772,7 @@ int bind_evtchn_to_irq(unsigned int evtchn)
if (irq == -1)
goto out;
- set_irq_chip_and_handler_name(irq, &xen_dynamic_chip,
+ irq_set_chip_and_handler_name(irq, &xen_dynamic_chip,
handle_fasteoi_irq, "event");
xen_irq_info_evtchn_init(irq, evtchn);
@@ -799,7 +799,7 @@ static int bind_ipi_to_irq(unsigned int ipi, unsigned int cpu)
if (irq < 0)
goto out;
- set_irq_chip_and_handler_name(irq, &xen_percpu_chip,
+ irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
handle_percpu_irq, "ipi");
bind_ipi.vcpu = cpu;
@@ -848,7 +848,7 @@ int bind_virq_to_irq(unsigned int virq, unsigned int cpu)
if (irq == -1)
goto out;
- set_irq_chip_and_handler_name(irq, &xen_percpu_chip,
+ irq_set_chip_and_handler_name(irq, &xen_percpu_chip,
handle_percpu_irq, "virq");
bind_virq.virq = virq;
@@ -1339,7 +1339,7 @@ static void ack_dynirq(struct irq_data *data)
{
int evtchn = evtchn_from_irq(data->irq);
- move_masked_irq(data->irq);
+ irq_move_masked_irq(data);
if (VALID_EVTCHN(evtchn))
unmask_evtchn(evtchn);
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 017ce600fbc..b0f9e8fb005 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -273,7 +273,7 @@ static int __unmap_grant_pages(struct grant_map *map, int offset, int pages)
map->vma->vm_start + map->notify.addr;
err = copy_to_user(tmp, &err, 1);
if (err)
- return err;
+ return -EFAULT;
map->notify.flags &= ~UNMAP_NOTIFY_CLEAR_BYTE;
} else if (pgno >= offset && pgno < offset + pages) {
uint8_t *tmp = kmap(map->pages[pgno]);
@@ -662,7 +662,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
if (map->flags) {
if ((vma->vm_flags & VM_WRITE) &&
(map->flags & GNTMAP_readonly))
- return -EINVAL;
+ goto out_unlock_put;
} else {
map->flags = GNTMAP_host_map;
if (!(vma->vm_flags & VM_WRITE))
@@ -700,6 +700,8 @@ unlock_out:
spin_unlock(&priv->lock);
return err;
+out_unlock_put:
+ spin_unlock(&priv->lock);
out_put_map:
if (use_ptemod)
map->vma = NULL;
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index ccc991c542d..57c3bb2884c 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -136,9 +136,8 @@ struct btrfs_inode {
* items we think we'll end up using, and reserved_extents is the number
* of extent items we've reserved metadata for.
*/
- spinlock_t accounting_lock;
atomic_t outstanding_extents;
- int reserved_extents;
+ atomic_t reserved_extents;
/*
* ordered_data_close is set by truncate when a file that used
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 4d2110eafe2..41d1d7c70e2 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -340,6 +340,8 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
WARN_ON(start & ((u64)PAGE_CACHE_SIZE - 1));
cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS);
+ if (!cb)
+ return -ENOMEM;
atomic_set(&cb->pending_bios, 0);
cb->errors = 0;
cb->inode = inode;
@@ -354,6 +356,10 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev;
bio = compressed_bio_alloc(bdev, first_byte, GFP_NOFS);
+ if(!bio) {
+ kfree(cb);
+ return -ENOMEM;
+ }
bio->bi_private = cb;
bio->bi_end_io = end_compressed_bio_write;
atomic_inc(&cb->pending_bios);
@@ -657,8 +663,9 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
atomic_inc(&cb->pending_bios);
if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
- btrfs_lookup_bio_sums(root, inode, comp_bio,
- sums);
+ ret = btrfs_lookup_bio_sums(root, inode,
+ comp_bio, sums);
+ BUG_ON(ret);
}
sums += (comp_bio->bi_size + root->sectorsize - 1) /
root->sectorsize;
@@ -683,8 +690,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
ret = btrfs_bio_wq_end_io(root->fs_info, comp_bio, 0);
BUG_ON(ret);
- if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
- btrfs_lookup_bio_sums(root, inode, comp_bio, sums);
+ if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM)) {
+ ret = btrfs_lookup_bio_sums(root, inode, comp_bio, sums);
+ BUG_ON(ret);
+ }
ret = btrfs_map_bio(root, READ, comp_bio, mirror_num, 0);
BUG_ON(ret);
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index b5baff0dccf..84d7ca1fe0b 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -147,10 +147,11 @@ noinline void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
struct extent_buffer *btrfs_root_node(struct btrfs_root *root)
{
struct extent_buffer *eb;
- spin_lock(&root->node_lock);
- eb = root->node;
+
+ rcu_read_lock();
+ eb = rcu_dereference(root->node);
extent_buffer_get(eb);
- spin_unlock(&root->node_lock);
+ rcu_read_unlock();
return eb;
}
@@ -165,14 +166,8 @@ struct extent_buffer *btrfs_lock_root_node(struct btrfs_root *root)
while (1) {
eb = btrfs_root_node(root);
btrfs_tree_lock(eb);
-
- spin_lock(&root->node_lock);
- if (eb == root->node) {
- spin_unlock(&root->node_lock);
+ if (eb == root->node)
break;
- }
- spin_unlock(&root->node_lock);
-
btrfs_tree_unlock(eb);
free_extent_buffer(eb);
}
@@ -458,10 +453,8 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
else
parent_start = 0;
- spin_lock(&root->node_lock);
- root->node = cow;
extent_buffer_get(cow);
- spin_unlock(&root->node_lock);
+ rcu_assign_pointer(root->node, cow);
btrfs_free_tree_block(trans, root, buf, parent_start,
last_ref);
@@ -542,6 +535,9 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
ret = __btrfs_cow_block(trans, root, buf, parent,
parent_slot, cow_ret, search_start, 0);
+
+ trace_btrfs_cow_block(root, buf, *cow_ret);
+
return ret;
}
@@ -686,6 +682,8 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,
if (!cur) {
cur = read_tree_block(root, blocknr,
blocksize, gen);
+ if (!cur)
+ return -EIO;
} else if (!uptodate) {
btrfs_read_buffer(cur, gen);
}
@@ -732,122 +730,6 @@ static inline unsigned int leaf_data_end(struct btrfs_root *root,
return btrfs_item_offset_nr(leaf, nr - 1);
}
-/*
- * extra debugging checks to make sure all the items in a key are
- * well formed and in the proper order
- */
-static int check_node(struct btrfs_root *root, struct btrfs_path *path,
- int level)
-{
- struct extent_buffer *parent = NULL;
- struct extent_buffer *node = path->nodes[level];
- struct btrfs_disk_key parent_key;
- struct btrfs_disk_key node_key;
- int parent_slot;
- int slot;
- struct btrfs_key cpukey;
- u32 nritems = btrfs_header_nritems(node);
-
- if (path->nodes[level + 1])
- parent = path->nodes[level + 1];
-
- slot = path->slots[level];
- BUG_ON(nritems == 0);
- if (parent) {
- parent_slot = path->slots[level + 1];
- btrfs_node_key(parent, &parent_key, parent_slot);
- btrfs_node_key(node, &node_key, 0);
- BUG_ON(memcmp(&parent_key, &node_key,
- sizeof(struct btrfs_disk_key)));
- BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
- btrfs_header_bytenr(node));
- }
- BUG_ON(nritems > BTRFS_NODEPTRS_PER_BLOCK(root));
- if (slot != 0) {
- btrfs_node_key_to_cpu(node, &cpukey, slot - 1);
- btrfs_node_key(node, &node_key, slot);
- BUG_ON(comp_keys(&node_key, &cpukey) <= 0);
- }
- if (slot < nritems - 1) {
- btrfs_node_key_to_cpu(node, &cpukey, slot + 1);
- btrfs_node_key(node, &node_key, slot);
- BUG_ON(comp_keys(&node_key, &cpukey) >= 0);
- }
- return 0;
-}
-
-/*
- * extra checking to make sure all the items in a leaf are
- * well formed and in the proper order
- */
-static int check_leaf(struct btrfs_root *root, struct btrfs_path *path,
- int level)
-{
- struct extent_buffer *leaf = path->nodes[level];
- struct extent_buffer *parent = NULL;
- int parent_slot;
- struct btrfs_key cpukey;
- struct btrfs_disk_key parent_key;
- struct btrfs_disk_key leaf_key;
- int slot = path->slots[0];
-
- u32 nritems = btrfs_header_nritems(leaf);
-
- if (path->nodes[level + 1])
- parent = path->nodes[level + 1];
-
- if (nritems == 0)
- return 0;
-
- if (parent) {
- parent_slot = path->slots[level + 1];
- btrfs_node_key(parent, &parent_key, parent_slot);
- btrfs_item_key(leaf, &leaf_key, 0);
-
- BUG_ON(memcmp(&parent_key, &leaf_key,
- sizeof(struct btrfs_disk_key)));
- BUG_ON(btrfs_node_blockptr(parent, parent_slot) !=
- btrfs_header_bytenr(leaf));
- }
- if (slot != 0 && slot < nritems - 1) {
- btrfs_item_key(leaf, &leaf_key, slot);
- btrfs_item_key_to_cpu(leaf, &cpukey, slot - 1);
- if (comp_keys(&leaf_key, &cpukey) <= 0) {
- btrfs_print_leaf(root, leaf);
- printk(KERN_CRIT "slot %d offset bad key\n", slot);
- BUG_ON(1);
- }
- if (btrfs_item_offset_nr(leaf, slot - 1) !=
- btrfs_item_end_nr(leaf, slot)) {
- btrfs_print_leaf(root, leaf);
- printk(KERN_CRIT "slot %d offset bad\n", slot);
- BUG_ON(1);
- }
- }
- if (slot < nritems - 1) {
- btrfs_item_key(leaf, &leaf_key, slot);
- btrfs_item_key_to_cpu(leaf, &cpukey, slot + 1);
- BUG_ON(comp_keys(&leaf_key, &cpukey) >= 0);
- if (btrfs_item_offset_nr(leaf, slot) !=
- btrfs_item_end_nr(leaf, slot + 1)) {
- btrfs_print_leaf(root, leaf);
- printk(KERN_CRIT "slot %d offset bad\n", slot);
- BUG_ON(1);
- }
- }
- BUG_ON(btrfs_item_offset_nr(leaf, 0) +
- btrfs_item_size_nr(leaf, 0) != BTRFS_LEAF_DATA_SIZE(root));
- return 0;
-}
-
-static noinline int check_block(struct btrfs_root *root,
- struct btrfs_path *path, int level)
-{
- return 0;
- if (level == 0)
- return check_leaf(root, path, level);
- return check_node(root, path, level);
-}
/*
* search for key in the extent_buffer. The items start at offset p,
@@ -1046,9 +928,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
goto enospc;
}
- spin_lock(&root->node_lock);
- root->node = child;
- spin_unlock(&root->node_lock);
+ rcu_assign_pointer(root->node, child);
add_root_to_dirty_list(root);
btrfs_tree_unlock(child);
@@ -1188,7 +1068,6 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
}
}
/* double check we haven't messed things up */
- check_block(root, path, level);
if (orig_ptr !=
btrfs_node_blockptr(path->nodes[level], path->slots[level]))
BUG();
@@ -1798,12 +1677,6 @@ cow_done:
if (!cow)
btrfs_unlock_up_safe(p, level + 1);
- ret = check_block(root, p, level);
- if (ret) {
- ret = -1;
- goto done;
- }
-
ret = bin_search(b, key, level, &slot);
if (level != 0) {
@@ -2130,10 +2003,8 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans,
btrfs_mark_buffer_dirty(c);
- spin_lock(&root->node_lock);
old = root->node;
- root->node = c;
- spin_unlock(&root->node_lock);
+ rcu_assign_pointer(root->node, c);
/* the super has an extra ref to root->node */
free_extent_buffer(old);
@@ -3840,7 +3711,8 @@ int btrfs_insert_item(struct btrfs_trans_handle *trans, struct btrfs_root
unsigned long ptr;
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
ret = btrfs_insert_empty_item(trans, root, path, cpu_key, data_size);
if (!ret) {
leaf = path->nodes[0];
@@ -4217,6 +4089,7 @@ find_next_key:
}
btrfs_set_path_blocking(path);
cur = read_node_slot(root, cur, slot);
+ BUG_ON(!cur);
btrfs_tree_lock(cur);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 7f78cc78fdd..d47ce830785 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -28,6 +28,7 @@
#include <linux/wait.h>
#include <linux/slab.h>
#include <linux/kobject.h>
+#include <trace/events/btrfs.h>
#include <asm/kmap_types.h>
#include "extent_io.h"
#include "extent_map.h"
@@ -40,6 +41,7 @@ extern struct kmem_cache *btrfs_trans_handle_cachep;
extern struct kmem_cache *btrfs_transaction_cachep;
extern struct kmem_cache *btrfs_bit_radix_cachep;
extern struct kmem_cache *btrfs_path_cachep;
+extern struct kmem_cache *btrfs_free_space_cachep;
struct btrfs_ordered_sum;
#define BTRFS_MAGIC "_BHRfS_M"
@@ -782,9 +784,6 @@ struct btrfs_free_cluster {
/* first extent starting offset */
u64 window_start;
- /* if this cluster simply points at a bitmap in the block group */
- bool points_to_bitmap;
-
struct btrfs_block_group_cache *block_group;
/*
* when a cluster is allocated from a block group, we put the
@@ -1283,6 +1282,7 @@ struct btrfs_root {
#define BTRFS_INODE_NODUMP (1 << 8)
#define BTRFS_INODE_NOATIME (1 << 9)
#define BTRFS_INODE_DIRSYNC (1 << 10)
+#define BTRFS_INODE_COMPRESS (1 << 11)
/* some macros to generate set/get funcs for the struct fields. This
* assumes there is a lefoo_to_cpu for every type, so lets make a simple
@@ -2157,6 +2157,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_prepare_extent_commit(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
@@ -2227,10 +2229,12 @@ u64 btrfs_account_ro_block_groups_free_space(struct btrfs_space_info *sinfo);
int btrfs_error_unpin_extent_range(struct btrfs_root *root,
u64 start, u64 end);
int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr,
- u64 num_bytes);
+ u64 num_bytes, u64 *actual_bytes);
int btrfs_force_chunk_alloc(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 type);
+int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range);
+int btrfs_init_space_info(struct btrfs_fs_info *fs_info);
/* ctree.c */
int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
int level, int *slot);
@@ -2392,6 +2396,9 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans,
struct btrfs_path *path, u64 dir,
const char *name, u16 name_len,
int mod);
+int verify_dir_item(struct btrfs_root *root,
+ struct extent_buffer *leaf,
+ struct btrfs_dir_item *dir_item);
/* orphan.c */
int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans,
@@ -2528,7 +2535,7 @@ int btrfs_update_inode(struct btrfs_trans_handle *trans,
struct inode *inode);
int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode);
int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode);
-void btrfs_orphan_cleanup(struct btrfs_root *root);
+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);
@@ -2536,7 +2543,7 @@ 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 size);
+int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size);
int btrfs_invalidate_inodes(struct btrfs_root *root);
void btrfs_add_delayed_iput(struct inode *inode);
void btrfs_run_delayed_iputs(struct btrfs_root *root);
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index e807b143b85..bce28f65389 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -483,6 +483,8 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans,
INIT_LIST_HEAD(&head_ref->cluster);
mutex_init(&head_ref->mutex);
+ trace_btrfs_delayed_ref_head(ref, head_ref, action);
+
existing = tree_insert(&delayed_refs->root, &ref->rb_node);
if (existing) {
@@ -537,6 +539,8 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans,
}
full_ref->level = level;
+ trace_btrfs_delayed_tree_ref(ref, full_ref, action);
+
existing = tree_insert(&delayed_refs->root, &ref->rb_node);
if (existing) {
@@ -591,6 +595,8 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans,
full_ref->objectid = owner;
full_ref->offset = offset;
+ trace_btrfs_delayed_data_ref(ref, full_ref, action);
+
existing = tree_insert(&delayed_refs->root, &ref->rb_node);
if (existing) {
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index f0cad5ae5be..c62f02f6ae6 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -151,7 +151,7 @@ int btrfs_insert_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
ret = PTR_ERR(dir_item);
if (ret == -EEXIST)
goto second_insert;
- goto out;
+ goto out_free;
}
leaf = path->nodes[0];
@@ -170,7 +170,7 @@ second_insert:
/* FIXME, use some real flag for selecting the extra index */
if (root == root->fs_info->tree_root) {
ret = 0;
- goto out;
+ goto out_free;
}
btrfs_release_path(root, path);
@@ -180,7 +180,7 @@ second_insert:
name, name_len);
if (IS_ERR(dir_item)) {
ret2 = PTR_ERR(dir_item);
- goto out;
+ goto out_free;
}
leaf = path->nodes[0];
btrfs_cpu_key_to_disk(&disk_key, location);
@@ -192,7 +192,9 @@ second_insert:
name_ptr = (unsigned long)(dir_item + 1);
write_extent_buffer(leaf, name, name_ptr, name_len);
btrfs_mark_buffer_dirty(leaf);
-out:
+
+out_free:
+
btrfs_free_path(path);
if (ret)
return ret;
@@ -377,6 +379,9 @@ struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root,
leaf = path->nodes[0];
dir_item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_dir_item);
+ if (verify_dir_item(root, leaf, dir_item))
+ return NULL;
+
total_len = btrfs_item_size_nr(leaf, path->slots[0]);
while (cur < total_len) {
this_len = sizeof(*dir_item) +
@@ -429,3 +434,35 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
}
return ret;
}
+
+int verify_dir_item(struct btrfs_root *root,
+ struct extent_buffer *leaf,
+ struct btrfs_dir_item *dir_item)
+{
+ u16 namelen = BTRFS_NAME_LEN;
+ u8 type = btrfs_dir_type(leaf, dir_item);
+
+ if (type >= BTRFS_FT_MAX) {
+ printk(KERN_CRIT "btrfs: invalid dir item type: %d\n",
+ (int)type);
+ return 1;
+ }
+
+ if (type == BTRFS_FT_XATTR)
+ namelen = XATTR_NAME_MAX;
+
+ if (btrfs_dir_name_len(leaf, dir_item) > namelen) {
+ printk(KERN_CRIT "btrfS: invalid dir item name len: %u\n",
+ (unsigned)btrfs_dir_data_len(leaf, dir_item));
+ return 1;
+ }
+
+ /* BTRFS_MAX_XATTR_SIZE is the same for all dir items */
+ if (btrfs_dir_data_len(leaf, dir_item) > BTRFS_MAX_XATTR_SIZE(root)) {
+ printk(KERN_CRIT "btrfs: invalid dir item data len: %u\n",
+ (unsigned)btrfs_dir_data_len(leaf, dir_item));
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 830d261d0e6..d7a7315bd03 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -29,6 +29,7 @@
#include <linux/crc32c.h>
#include <linux/slab.h>
#include <linux/migrate.h>
+#include <asm/unaligned.h>
#include "compat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -198,7 +199,7 @@ u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len)
void btrfs_csum_final(u32 crc, char *result)
{
- *(__le32 *)result = ~cpu_to_le32(crc);
+ put_unaligned_le32(~crc, result);
}
/*
@@ -323,6 +324,7 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
int num_copies = 0;
int mirror_num = 0;
+ 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,
@@ -331,6 +333,14 @@ static int btree_read_extent_buffer_pages(struct btrfs_root *root,
!verify_parent_transid(io_tree, eb, parent_transid))
return ret;
+ /*
+ * This buffer's crc is fine, but its contents are corrupted, so
+ * there is no reason to read the other copies, they won't be
+ * any less wrong.
+ */
+ if (test_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags))
+ return ret;
+
num_copies = btrfs_num_copies(&root->fs_info->mapping_tree,
eb->start, eb->len);
if (num_copies == 1)
@@ -419,6 +429,73 @@ static int check_tree_block_fsid(struct btrfs_root *root,
return ret;
}
+#define CORRUPT(reason, eb, root, slot) \
+ printk(KERN_CRIT "btrfs: corrupt leaf, %s: block=%llu," \
+ "root=%llu, slot=%d\n", reason, \
+ (unsigned long long)btrfs_header_bytenr(eb), \
+ (unsigned long long)root->objectid, slot)
+
+static noinline int check_leaf(struct btrfs_root *root,
+ struct extent_buffer *leaf)
+{
+ struct btrfs_key key;
+ struct btrfs_key leaf_key;
+ u32 nritems = btrfs_header_nritems(leaf);
+ int slot;
+
+ if (nritems == 0)
+ return 0;
+
+ /* Check the 0 item */
+ if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
+ BTRFS_LEAF_DATA_SIZE(root)) {
+ CORRUPT("invalid item offset size pair", leaf, root, 0);
+ return -EIO;
+ }
+
+ /*
+ * Check to make sure each items keys are in the correct order and their
+ * offsets make sense. We only have to loop through nritems-1 because
+ * we check the current slot against the next slot, which verifies the
+ * next slot's offset+size makes sense and that the current's slot
+ * offset is correct.
+ */
+ for (slot = 0; slot < nritems - 1; slot++) {
+ btrfs_item_key_to_cpu(leaf, &leaf_key, slot);
+ btrfs_item_key_to_cpu(leaf, &key, slot + 1);
+
+ /* Make sure the keys are in the right order */
+ if (btrfs_comp_cpu_keys(&leaf_key, &key) >= 0) {
+ CORRUPT("bad key order", leaf, root, slot);
+ return -EIO;
+ }
+
+ /*
+ * Make sure the offset and ends are right, remember that the
+ * item data starts at the end of the leaf and grows towards the
+ * front.
+ */
+ if (btrfs_item_offset_nr(leaf, slot) !=
+ btrfs_item_end_nr(leaf, slot + 1)) {
+ CORRUPT("slot offset bad", leaf, root, slot);
+ return -EIO;
+ }
+
+ /*
+ * Check to make sure that we don't point outside of the leaf,
+ * just incase all the items are consistent to eachother, but
+ * all point outside of the leaf.
+ */
+ if (btrfs_item_end_nr(leaf, slot) >
+ BTRFS_LEAF_DATA_SIZE(root)) {
+ CORRUPT("slot end outside of leaf", leaf, root, slot);
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_DEBUG_LOCK_ALLOC
void btrfs_set_buffer_lockdep_class(struct extent_buffer *eb, int level)
{
@@ -485,8 +562,20 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
btrfs_set_buffer_lockdep_class(eb, found_level);
ret = csum_tree_block(root, eb, 1);
- if (ret)
+ if (ret) {
ret = -EIO;
+ goto err;
+ }
+
+ /*
+ * If this is a leaf block and it is corrupt, set the corrupt bit so
+ * that we don't try and read the other copies of this block, just
+ * return -EIO.
+ */
+ if (found_level == 0 && check_leaf(root, eb)) {
+ set_bit(EXTENT_BUFFER_CORRUPT, &eb->bflags);
+ ret = -EIO;
+ }
end = min_t(u64, eb->len, PAGE_CACHE_SIZE);
end = eb->start + end - 1;
@@ -1159,7 +1248,10 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root,
root, fs_info, location->objectid);
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path) {
+ kfree(root);
+ return ERR_PTR(-ENOMEM);
+ }
ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0);
if (ret == 0) {
l = path->nodes[0];
@@ -1553,6 +1645,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
goto fail_bdi;
}
+ fs_info->btree_inode->i_mapping->flags &= ~__GFP_FS;
+
INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC);
INIT_LIST_HEAD(&fs_info->trans_list);
INIT_LIST_HEAD(&fs_info->dead_roots);
@@ -1683,6 +1777,12 @@ struct btrfs_root *open_ctree(struct super_block *sb,
btrfs_check_super_valid(fs_info, sb->s_flags & MS_RDONLY);
+ /*
+ * In the long term, we'll store the compression type in the super
+ * block, and it'll be used for per file compression control.
+ */
+ fs_info->compress_type = BTRFS_COMPRESS_ZLIB;
+
ret = btrfs_parse_options(tree_root, options);
if (ret) {
err = ret;
@@ -1888,6 +1988,12 @@ struct btrfs_root *open_ctree(struct super_block *sb,
fs_info->metadata_alloc_profile = (u64)-1;
fs_info->system_alloc_profile = fs_info->metadata_alloc_profile;
+ ret = btrfs_init_space_info(fs_info);
+ if (ret) {
+ printk(KERN_ERR "Failed to initial space info: %d\n", ret);
+ goto fail_block_groups;
+ }
+
ret = btrfs_read_block_groups(extent_root);
if (ret) {
printk(KERN_ERR "Failed to read block groups: %d\n", ret);
@@ -1979,9 +2085,14 @@ struct btrfs_root *open_ctree(struct super_block *sb,
if (!(sb->s_flags & MS_RDONLY)) {
down_read(&fs_info->cleanup_work_sem);
- btrfs_orphan_cleanup(fs_info->fs_root);
- btrfs_orphan_cleanup(fs_info->tree_root);
+ err = btrfs_orphan_cleanup(fs_info->fs_root);
+ if (!err)
+ err = btrfs_orphan_cleanup(fs_info->tree_root);
up_read(&fs_info->cleanup_work_sem);
+ if (err) {
+ close_ctree(tree_root);
+ return ERR_PTR(err);
+ }
}
return tree_root;
@@ -2356,8 +2467,12 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info)
root_objectid = gang[ret - 1]->root_key.objectid + 1;
for (i = 0; i < ret; i++) {
+ int err;
+
root_objectid = gang[i]->root_key.objectid;
- btrfs_orphan_cleanup(gang[i]);
+ err = btrfs_orphan_cleanup(gang[i]);
+ if (err)
+ return err;
}
root_objectid++;
}
@@ -2868,7 +2983,10 @@ static int btrfs_destroy_pinned_extent(struct btrfs_root *root,
break;
/* opt_discard */
- ret = btrfs_error_discard_extent(root, start, end + 1 - start);
+ if (btrfs_test_opt(root, DISCARD))
+ ret = btrfs_error_discard_extent(root, start,
+ end + 1 - start,
+ NULL);
clear_extent_dirty(unpin, start, end, GFP_NOFS);
btrfs_error_unpin_extent_range(root, start, end);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 7b3089b5c2d..f619c3cb13b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -36,8 +36,6 @@
static int update_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
u64 bytenr, u64 num_bytes, int alloc);
-static int update_reserved_bytes(struct btrfs_block_group_cache *cache,
- u64 num_bytes, int reserve, int sinfo);
static int __btrfs_free_extent(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
u64 bytenr, u64 num_bytes, u64 parent,
@@ -442,7 +440,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
* allocate blocks for the tree root we can't do the fast caching since
* we likely hold important locks.
*/
- if (!trans->transaction->in_commit &&
+ if (trans && (!trans->transaction->in_commit) &&
(root && root != root->fs_info->tree_root)) {
spin_lock(&cache->lock);
if (cache->cached != BTRFS_CACHE_NO) {
@@ -471,7 +469,7 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
if (load_cache_only)
return 0;
- caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_KERNEL);
+ caching_ctl = kzalloc(sizeof(*caching_ctl), GFP_NOFS);
BUG_ON(!caching_ctl);
INIT_LIST_HEAD(&caching_ctl->list);
@@ -1740,39 +1738,45 @@ static int remove_extent_backref(struct btrfs_trans_handle *trans,
return ret;
}
-static void btrfs_issue_discard(struct block_device *bdev,
+static int btrfs_issue_discard(struct block_device *bdev,
u64 start, u64 len)
{
- blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL, 0);
+ return blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_NOFS, 0);
}
static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,
- u64 num_bytes)
+ u64 num_bytes, u64 *actual_bytes)
{
int ret;
- u64 map_length = num_bytes;
+ u64 discarded_bytes = 0;
struct btrfs_multi_bio *multi = NULL;
- if (!btrfs_test_opt(root, DISCARD))
- return 0;
/* Tell the block device(s) that the sectors can be discarded */
- ret = btrfs_map_block(&root->fs_info->mapping_tree, READ,
- bytenr, &map_length, &multi, 0);
+ ret = btrfs_map_block(&root->fs_info->mapping_tree, REQ_DISCARD,
+ bytenr, &num_bytes, &multi, 0);
if (!ret) {
struct btrfs_bio_stripe *stripe = multi->stripes;
int i;
- if (map_length > num_bytes)
- map_length = num_bytes;
for (i = 0; i < multi->num_stripes; i++, stripe++) {
- btrfs_issue_discard(stripe->dev->bdev,
- stripe->physical,
- map_length);
+ ret = btrfs_issue_discard(stripe->dev->bdev,
+ stripe->physical,
+ stripe->length);
+ if (!ret)
+ discarded_bytes += stripe->length;
+ else if (ret != -EOPNOTSUPP)
+ break;
}
kfree(multi);
}
+ if (discarded_bytes && ret == -EOPNOTSUPP)
+ ret = 0;
+
+ if (actual_bytes)
+ *actual_bytes = discarded_bytes;
+
return ret;
}
@@ -3996,6 +4000,7 @@ 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;
int nr_extents;
+ int reserved_extents;
int ret;
if (btrfs_transaction_in_commit(root->fs_info))
@@ -4003,25 +4008,24 @@ int btrfs_delalloc_reserve_metadata(struct inode *inode, u64 num_bytes)
num_bytes = ALIGN(num_bytes, root->sectorsize);
- spin_lock(&BTRFS_I(inode)->accounting_lock);
nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents) + 1;
- if (nr_extents > BTRFS_I(inode)->reserved_extents) {
- nr_extents -= BTRFS_I(inode)->reserved_extents;
+ reserved_extents = atomic_read(&BTRFS_I(inode)->reserved_extents);
+
+ if (nr_extents > reserved_extents) {
+ nr_extents -= reserved_extents;
to_reserve = calc_trans_metadata_size(root, nr_extents);
} else {
nr_extents = 0;
to_reserve = 0;
}
- spin_unlock(&BTRFS_I(inode)->accounting_lock);
+
to_reserve += calc_csum_metadata_size(inode, num_bytes);
ret = reserve_metadata_bytes(NULL, root, block_rsv, to_reserve, 1);
if (ret)
return ret;
- spin_lock(&BTRFS_I(inode)->accounting_lock);
- BTRFS_I(inode)->reserved_extents += nr_extents;
+ atomic_add(nr_extents, &BTRFS_I(inode)->reserved_extents);
atomic_inc(&BTRFS_I(inode)->outstanding_extents);
- spin_unlock(&BTRFS_I(inode)->accounting_lock);
block_rsv_add_bytes(block_rsv, to_reserve, 1);
@@ -4036,20 +4040,30 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)
struct btrfs_root *root = BTRFS_I(inode)->root;
u64 to_free;
int nr_extents;
+ int reserved_extents;
num_bytes = ALIGN(num_bytes, root->sectorsize);
atomic_dec(&BTRFS_I(inode)->outstanding_extents);
WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents) < 0);
- spin_lock(&BTRFS_I(inode)->accounting_lock);
- nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents);
- if (nr_extents < BTRFS_I(inode)->reserved_extents) {
- nr_extents = BTRFS_I(inode)->reserved_extents - nr_extents;
- BTRFS_I(inode)->reserved_extents -= nr_extents;
- } else {
- nr_extents = 0;
- }
- spin_unlock(&BTRFS_I(inode)->accounting_lock);
+ reserved_extents = atomic_read(&BTRFS_I(inode)->reserved_extents);
+ do {
+ int old, new;
+
+ nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents);
+ if (nr_extents >= reserved_extents) {
+ nr_extents = 0;
+ break;
+ }
+ old = reserved_extents;
+ nr_extents = reserved_extents - nr_extents;
+ new = reserved_extents - nr_extents;
+ old = atomic_cmpxchg(&BTRFS_I(inode)->reserved_extents,
+ reserved_extents, new);
+ if (likely(old == reserved_extents))
+ break;
+ reserved_extents = old;
+ } while (1);
to_free = calc_csum_metadata_size(inode, num_bytes);
if (nr_extents > 0)
@@ -4223,8 +4237,8 @@ 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.
*/
-static int update_reserved_bytes(struct btrfs_block_group_cache *cache,
- u64 num_bytes, int reserve, int sinfo)
+int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
+ u64 num_bytes, int reserve, int sinfo)
{
int ret = 0;
if (sinfo) {
@@ -4363,7 +4377,9 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans,
if (ret)
break;
- ret = btrfs_discard_extent(root, start, end + 1 - start);
+ if (btrfs_test_opt(root, DISCARD))
+ ret = btrfs_discard_extent(root, start,
+ end + 1 - start, NULL);
clear_extent_dirty(unpin, start, end, GFP_NOFS);
unpin_extent_range(root, start, end);
@@ -4704,10 +4720,10 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
WARN_ON(test_bit(EXTENT_BUFFER_DIRTY, &buf->bflags));
btrfs_add_free_space(cache, buf->start, buf->len);
- ret = update_reserved_bytes(cache, buf->len, 0, 0);
+ ret = btrfs_update_reserved_bytes(cache, buf->len, 0, 0);
if (ret == -EAGAIN) {
/* block group became read-only */
- update_reserved_bytes(cache, buf->len, 0, 1);
+ btrfs_update_reserved_bytes(cache, buf->len, 0, 1);
goto out;
}
@@ -4744,6 +4760,11 @@ pin:
}
}
out:
+ /*
+ * Deleting the buffer, clear the corrupt flag since it doesn't matter
+ * anymore.
+ */
+ clear_bit(EXTENT_BUFFER_CORRUPT, &buf->bflags);
btrfs_put_block_group(cache);
}
@@ -5191,7 +5212,7 @@ checks:
search_start - offset);
BUG_ON(offset > search_start);
- ret = update_reserved_bytes(block_group, num_bytes, 1,
+ ret = btrfs_update_reserved_bytes(block_group, num_bytes, 1,
(data & BTRFS_BLOCK_GROUP_DATA));
if (ret == -EAGAIN) {
btrfs_add_free_space(block_group, offset, num_bytes);
@@ -5397,6 +5418,8 @@ again:
dump_space_info(sinfo, num_bytes, 1);
}
+ trace_btrfs_reserved_extent_alloc(root, ins->objectid, ins->offset);
+
return ret;
}
@@ -5412,12 +5435,15 @@ int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len)
return -ENOSPC;
}
- ret = btrfs_discard_extent(root, start, len);
+ if (btrfs_test_opt(root, DISCARD))
+ ret = btrfs_discard_extent(root, start, len, NULL);
btrfs_add_free_space(cache, start, len);
- update_reserved_bytes(cache, len, 0, 1);
+ btrfs_update_reserved_bytes(cache, len, 0, 1);
btrfs_put_block_group(cache);
+ trace_btrfs_reserved_extent_free(root, start, len);
+
return ret;
}
@@ -5444,7 +5470,8 @@ static int alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
size = sizeof(*extent_item) + btrfs_extent_inline_ref_size(type);
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
path->leave_spinning = 1;
ret = btrfs_insert_empty_item(trans, fs_info->extent_root, path,
@@ -5614,7 +5641,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
put_caching_control(caching_ctl);
}
- ret = update_reserved_bytes(block_group, ins->offset, 1, 1);
+ ret = btrfs_update_reserved_bytes(block_group, ins->offset, 1, 1);
BUG_ON(ret);
btrfs_put_block_group(block_group);
ret = alloc_reserved_file_extent(trans, root, 0, root_objectid,
@@ -6047,6 +6074,8 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
if (reada && level == 1)
reada_walk_down(trans, root, wc, path);
next = read_tree_block(root, bytenr, blocksize, generation);
+ if (!next)
+ return -EIO;
btrfs_tree_lock(next);
btrfs_set_lock_blocking(next);
}
@@ -6438,10 +6467,14 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
BUG_ON(root->root_key.objectid != BTRFS_TREE_RELOC_OBJECTID);
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
wc = kzalloc(sizeof(*wc), GFP_NOFS);
- BUG_ON(!wc);
+ if (!wc) {
+ btrfs_free_path(path);
+ return -ENOMEM;
+ }
btrfs_assert_tree_locked(parent);
parent_level = btrfs_header_level(parent);
@@ -6899,7 +6932,11 @@ static noinline int get_new_locations(struct inode *reloc_inode,
}
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path) {
+ if (exts != *extents)
+ kfree(exts);
+ return -ENOMEM;
+ }
cur_pos = extent_key->objectid - offset;
last_byte = extent_key->objectid + extent_key->offset;
@@ -6941,6 +6978,10 @@ static noinline int get_new_locations(struct inode *reloc_inode,
struct disk_extent *old = exts;
max *= 2;
exts = kzalloc(sizeof(*exts) * max, GFP_NOFS);
+ if (!exts) {
+ ret = -ENOMEM;
+ goto out;
+ }
memcpy(exts, old, sizeof(*exts) * nr);
if (old != *extents)
kfree(old);
@@ -7423,7 +7464,8 @@ static noinline int replace_extents_in_leaf(struct btrfs_trans_handle *trans,
int ret;
new_extent = kmalloc(sizeof(*new_extent), GFP_NOFS);
- BUG_ON(!new_extent);
+ if (!new_extent)
+ return -ENOMEM;
ref = btrfs_lookup_leaf_ref(root, leaf->start);
BUG_ON(!ref);
@@ -7609,7 +7651,8 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root)
reloc_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
BUG_ON(!reloc_root);
- btrfs_orphan_cleanup(reloc_root);
+ ret = btrfs_orphan_cleanup(reloc_root);
+ BUG_ON(ret);
return 0;
}
@@ -7627,7 +7670,8 @@ static noinline int init_reloc_tree(struct btrfs_trans_handle *trans,
return 0;
root_item = kmalloc(sizeof(*root_item), GFP_NOFS);
- BUG_ON(!root_item);
+ if (!root_item)
+ return -ENOMEM;
ret = btrfs_copy_root(trans, root, root->commit_root,
&eb, BTRFS_TREE_RELOC_OBJECTID);
@@ -7653,7 +7697,7 @@ static noinline int init_reloc_tree(struct btrfs_trans_handle *trans,
reloc_root = btrfs_read_fs_root_no_radix(root->fs_info->tree_root,
&root_key);
- BUG_ON(!reloc_root);
+ BUG_ON(IS_ERR(reloc_root));
reloc_root->last_trans = trans->transid;
reloc_root->commit_root = NULL;
reloc_root->ref_tree = &root->fs_info->reloc_ref_tree;
@@ -7906,6 +7950,10 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root,
eb = read_tree_block(found_root, block_start,
block_size, 0);
+ if (!eb) {
+ ret = -EIO;
+ goto out;
+ }
btrfs_tree_lock(eb);
BUG_ON(level != btrfs_header_level(eb));
@@ -8621,6 +8669,12 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
BUG_ON(!block_group);
BUG_ON(!block_group->ro);
+ /*
+ * Free the reserved super bytes from this block group before
+ * remove it.
+ */
+ free_excluded_extents(root, block_group);
+
memcpy(&key, &block_group->key, sizeof(key));
if (block_group->flags & (BTRFS_BLOCK_GROUP_DUP |
BTRFS_BLOCK_GROUP_RAID1 |
@@ -8724,13 +8778,84 @@ out:
return ret;
}
+int btrfs_init_space_info(struct btrfs_fs_info *fs_info)
+{
+ struct btrfs_space_info *space_info;
+ int ret;
+
+ ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM, 0, 0,
+ &space_info);
+ if (ret)
+ return ret;
+
+ ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA, 0, 0,
+ &space_info);
+ if (ret)
+ return ret;
+
+ ret = update_space_info(fs_info, BTRFS_BLOCK_GROUP_DATA, 0, 0,
+ &space_info);
+ if (ret)
+ return ret;
+
+ return ret;
+}
+
int btrfs_error_unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
{
return unpin_extent_range(root, start, end);
}
int btrfs_error_discard_extent(struct btrfs_root *root, u64 bytenr,
- u64 num_bytes)
+ u64 num_bytes, u64 *actual_bytes)
+{
+ return btrfs_discard_extent(root, bytenr, num_bytes, actual_bytes);
+}
+
+int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
{
- return btrfs_discard_extent(root, bytenr, num_bytes);
+ struct btrfs_fs_info *fs_info = root->fs_info;
+ struct btrfs_block_group_cache *cache = NULL;
+ u64 group_trimmed;
+ u64 start;
+ u64 end;
+ u64 trimmed = 0;
+ int ret = 0;
+
+ cache = btrfs_lookup_block_group(fs_info, range->start);
+
+ while (cache) {
+ if (cache->key.objectid >= (range->start + range->len)) {
+ btrfs_put_block_group(cache);
+ break;
+ }
+
+ start = max(range->start, cache->key.objectid);
+ end = min(range->start + range->len,
+ cache->key.objectid + cache->key.offset);
+
+ if (end - start >= range->minlen) {
+ if (!block_group_cache_done(cache)) {
+ ret = cache_block_group(cache, NULL, root, 0);
+ if (!ret)
+ wait_block_group_cache_done(cache);
+ }
+ ret = btrfs_trim_block_group(cache,
+ &group_trimmed,
+ start,
+ end,
+ range->minlen);
+
+ trimmed += group_trimmed;
+ if (ret) {
+ btrfs_put_block_group(cache);
+ break;
+ }
+ }
+
+ cache = next_block_group(fs_info->tree_root, cache);
+ }
+
+ range->len = trimmed;
+ return ret;
}
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index b5b92824a27..20ddb28602a 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -2192,6 +2192,8 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
else
write_flags = WRITE;
+ trace___extent_writepage(page, inode, wbc);
+
WARN_ON(!PageLocked(page));
pg_offset = i_size & (PAGE_CACHE_SIZE - 1);
if (page->index > end_index ||
@@ -3690,6 +3692,7 @@ int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
"wanted %lu %lu\n", (unsigned long long)eb->start,
eb->len, start, min_len);
WARN_ON(1);
+ return -EINVAL;
}
p = extent_buffer_page(eb, i);
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 9318dfefd59..f62c5442835 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -31,6 +31,7 @@
#define EXTENT_BUFFER_UPTODATE 0
#define EXTENT_BUFFER_BLOCKING 1
#define EXTENT_BUFFER_DIRTY 2
+#define EXTENT_BUFFER_CORRUPT 3
/* these are flags for extent_clear_unlock_delalloc */
#define EXTENT_CLEAR_UNLOCK_PAGE 0x1
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 4f19a3e1bf3..a6a9d4e8b49 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -48,7 +48,8 @@ int btrfs_insert_file_extent(struct btrfs_trans_handle *trans,
struct extent_buffer *leaf;
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
file_key.objectid = objectid;
file_key.offset = pos;
btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);
@@ -169,6 +170,8 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
path = btrfs_alloc_path();
+ if (!path)
+ return -ENOMEM;
if (bio->bi_size > PAGE_CACHE_SIZE * 8)
path->reada = 2;
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index f447b783bb8..656bc0a892b 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -45,14 +45,14 @@
* and be replaced with calls into generic code.
*/
static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
- int write_bytes,
+ size_t write_bytes,
struct page **prepared_pages,
struct iov_iter *i)
{
size_t copied = 0;
+ size_t total_copied = 0;
int pg = 0;
int offset = pos & (PAGE_CACHE_SIZE - 1);
- int total_copied = 0;
while (write_bytes > 0) {
size_t count = min_t(size_t,
@@ -88,9 +88,8 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages,
total_copied += copied;
/* Return to btrfs_file_aio_write to fault page */
- if (unlikely(copied == 0)) {
+ if (unlikely(copied == 0))
break;
- }
if (unlikely(copied < PAGE_CACHE_SIZE - offset)) {
offset += copied;
@@ -109,8 +108,6 @@ static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages)
{
size_t i;
for (i = 0; i < num_pages; i++) {
- if (!pages[i])
- break;
/* page checked is some magic around finding pages that
* have been modified without going through btrfs_set_page_dirty
* clear it here
@@ -130,13 +127,12 @@ static noinline void btrfs_drop_pages(struct page **pages, size_t num_pages)
* this also makes the decision about creating an inline extent vs
* doing real data extents, marking pages dirty and delalloc as required.
*/
-static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct file *file,
- struct page **pages,
- size_t num_pages,
- loff_t pos,
- size_t write_bytes)
+static noinline int dirty_and_release_pages(struct btrfs_root *root,
+ struct file *file,
+ struct page **pages,
+ size_t num_pages,
+ loff_t pos,
+ size_t write_bytes)
{
int err = 0;
int i;
@@ -154,7 +150,8 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
end_of_last_block = start_pos + num_bytes - 1;
err = btrfs_set_extent_delalloc(inode, start_pos, end_of_last_block,
NULL);
- BUG_ON(err);
+ if (err)
+ return err;
for (i = 0; i < num_pages; i++) {
struct page *p = pages[i];
@@ -162,13 +159,14 @@ static noinline int dirty_and_release_pages(struct btrfs_trans_handle *trans,
ClearPageChecked(p);
set_page_dirty(p);
}
- if (end_pos > isize) {
+
+ /*
+ * we've only changed i_size in ram, and we haven't updated
+ * the disk i_size. There is no need to log the inode
+ * at this time.
+ */
+ if (end_pos > isize)
i_size_write(inode, end_pos);
- /* we've only changed i_size in ram, and we haven't updated
- * the disk i_size. There is no need to log the inode
- * at this time.
- */
- }
return 0;
}
@@ -610,6 +608,8 @@ again:
key.offset = split;
ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
+ if (ret < 0)
+ goto out;
if (ret > 0 && path->slots[0] > 0)
path->slots[0]--;
@@ -819,12 +819,11 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
last_pos = ((u64)index + num_pages) << PAGE_CACHE_SHIFT;
if (start_pos > inode->i_size) {
- err = btrfs_cont_expand(inode, start_pos);
+ err = btrfs_cont_expand(inode, i_size_read(inode), start_pos);
if (err)
return err;
}
- memset(pages, 0, num_pages * sizeof(struct page *));
again:
for (i = 0; i < num_pages; i++) {
pages[i] = grab_cache_page(inode->i_mapping, index + i);
@@ -896,156 +895,71 @@ fail:
}
-static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
- const struct iovec *iov,
- unsigned long nr_segs, loff_t pos)
+static noinline ssize_t __btrfs_buffered_write(struct file *file,
+ struct iov_iter *i,
+ loff_t pos)
{
- struct file *file = iocb->ki_filp;
struct inode *inode = fdentry(file)->d_inode;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct page **pages = NULL;
- struct iov_iter i;
- loff_t *ppos = &iocb->ki_pos;
- loff_t start_pos;
- ssize_t num_written = 0;
- ssize_t err = 0;
- size_t count;
- size_t ocount;
- int ret = 0;
- int nrptrs;
unsigned long first_index;
unsigned long last_index;
- int will_write;
- int buffered = 0;
- int copied = 0;
- int dirty_pages = 0;
-
- will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) ||
- (file->f_flags & O_DIRECT));
-
- start_pos = pos;
-
- vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
-
- mutex_lock(&inode->i_mutex);
-
- err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
- if (err)
- goto out;
- count = ocount;
-
- current->backing_dev_info = inode->i_mapping->backing_dev_info;
- err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
- if (err)
- goto out;
-
- if (count == 0)
- goto out;
-
- err = file_remove_suid(file);
- if (err)
- goto out;
-
- /*
- * If BTRFS flips readonly due to some impossible error
- * (fs_info->fs_state now has BTRFS_SUPER_FLAG_ERROR),
- * although we have opened a file as writable, we have
- * to stop this write operation to ensure FS consistency.
- */
- if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
- err = -EROFS;
- goto out;
- }
-
- file_update_time(file);
- BTRFS_I(inode)->sequence++;
-
- if (unlikely(file->f_flags & O_DIRECT)) {
- num_written = generic_file_direct_write(iocb, iov, &nr_segs,
- pos, ppos, count,
- ocount);
- /*
- * the generic O_DIRECT will update in-memory i_size after the
- * DIOs are done. But our endio handlers that update the on
- * disk i_size never update past the in memory i_size. So we
- * need one more update here to catch any additions to the
- * file
- */
- if (inode->i_size != BTRFS_I(inode)->disk_i_size) {
- btrfs_ordered_update_i_size(inode, inode->i_size, NULL);
- mark_inode_dirty(inode);
- }
-
- if (num_written < 0) {
- ret = num_written;
- num_written = 0;
- goto out;
- } else if (num_written == count) {
- /* pick up pos changes done by the generic code */
- pos = *ppos;
- goto out;
- }
- /*
- * We are going to do buffered for the rest of the range, so we
- * need to make sure to invalidate the buffered pages when we're
- * done.
- */
- buffered = 1;
- pos += num_written;
- }
+ size_t num_written = 0;
+ int nrptrs;
+ int ret;
- iov_iter_init(&i, iov, nr_segs, count, num_written);
- nrptrs = min((iov_iter_count(&i) + PAGE_CACHE_SIZE - 1) /
+ nrptrs = min((iov_iter_count(i) + PAGE_CACHE_SIZE - 1) /
PAGE_CACHE_SIZE, PAGE_CACHE_SIZE /
(sizeof(struct page *)));
pages = kmalloc(nrptrs * sizeof(struct page *), GFP_KERNEL);
- if (!pages) {
- ret = -ENOMEM;
- goto out;
- }
-
- /* generic_write_checks can change our pos */
- start_pos = pos;
+ if (!pages)
+ return -ENOMEM;
first_index = pos >> PAGE_CACHE_SHIFT;
- last_index = (pos + iov_iter_count(&i)) >> PAGE_CACHE_SHIFT;
+ last_index = (pos + iov_iter_count(i)) >> PAGE_CACHE_SHIFT;
- while (iov_iter_count(&i) > 0) {
+ while (iov_iter_count(i) > 0) {
size_t offset = pos & (PAGE_CACHE_SIZE - 1);
- size_t write_bytes = min(iov_iter_count(&i),
+ size_t write_bytes = min(iov_iter_count(i),
nrptrs * (size_t)PAGE_CACHE_SIZE -
offset);
size_t num_pages = (write_bytes + offset +
PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
+ size_t dirty_pages;
+ size_t copied;
WARN_ON(num_pages > nrptrs);
- memset(pages, 0, sizeof(struct page *) * nrptrs);
/*
* Fault pages before locking them in prepare_pages
* to avoid recursive lock
*/
- if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) {
+ if (unlikely(iov_iter_fault_in_readable(i, write_bytes))) {
ret = -EFAULT;
- goto out;
+ break;
}
ret = btrfs_delalloc_reserve_space(inode,
num_pages << PAGE_CACHE_SHIFT);
if (ret)
- goto out;
+ break;
+ /*
+ * This is going to setup the pages array with the number of
+ * pages we want, so we don't really need to worry about the
+ * contents of pages from loop to loop
+ */
ret = prepare_pages(root, file, pages, num_pages,
pos, first_index, last_index,
write_bytes);
if (ret) {
btrfs_delalloc_release_space(inode,
num_pages << PAGE_CACHE_SHIFT);
- goto out;
+ break;
}
copied = btrfs_copy_from_user(pos, num_pages,
- write_bytes, pages, &i);
+ write_bytes, pages, i);
/*
* if we have trouble faulting in the pages, fall
@@ -1061,6 +975,13 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
PAGE_CACHE_SIZE - 1) >>
PAGE_CACHE_SHIFT;
+ /*
+ * If we had a short copy we need to release the excess delaloc
+ * bytes we reserved. We need to increment outstanding_extents
+ * because btrfs_delalloc_release_space will decrement it, but
+ * we still have an outstanding extent for the chunk we actually
+ * managed to copy.
+ */
if (num_pages > dirty_pages) {
if (copied > 0)
atomic_inc(
@@ -1071,39 +992,157 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
}
if (copied > 0) {
- dirty_and_release_pages(NULL, root, file, pages,
- dirty_pages, pos, copied);
+ ret = dirty_and_release_pages(root, file, pages,
+ dirty_pages, pos,
+ copied);
+ if (ret) {
+ btrfs_delalloc_release_space(inode,
+ dirty_pages << PAGE_CACHE_SHIFT);
+ btrfs_drop_pages(pages, num_pages);
+ break;
+ }
}
btrfs_drop_pages(pages, num_pages);
- if (copied > 0) {
- if (will_write) {
- filemap_fdatawrite_range(inode->i_mapping, pos,
- pos + copied - 1);
- } else {
- balance_dirty_pages_ratelimited_nr(
- inode->i_mapping,
- dirty_pages);
- if (dirty_pages <
- (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
- btrfs_btree_balance_dirty(root, 1);
- btrfs_throttle(root);
- }
- }
+ cond_resched();
+
+ balance_dirty_pages_ratelimited_nr(inode->i_mapping,
+ dirty_pages);
+ if (dirty_pages < (root->leafsize >> PAGE_CACHE_SHIFT) + 1)
+ btrfs_btree_balance_dirty(root, 1);
+ btrfs_throttle(root);
pos += copied;
num_written += copied;
+ }
- cond_resched();
+ kfree(pages);
+
+ return num_written ? num_written : ret;
+}
+
+static ssize_t __btrfs_direct_write(struct kiocb *iocb,
+ const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos,
+ loff_t *ppos, size_t count, size_t ocount)
+{
+ struct file *file = iocb->ki_filp;
+ struct inode *inode = fdentry(file)->d_inode;
+ struct iov_iter i;
+ ssize_t written;
+ ssize_t written_buffered;
+ loff_t endbyte;
+ int err;
+
+ written = generic_file_direct_write(iocb, iov, &nr_segs, pos, ppos,
+ count, ocount);
+
+ /*
+ * the generic O_DIRECT will update in-memory i_size after the
+ * DIOs are done. But our endio handlers that update the on
+ * disk i_size never update past the in memory i_size. So we
+ * need one more update here to catch any additions to the
+ * file
+ */
+ if (inode->i_size != BTRFS_I(inode)->disk_i_size) {
+ btrfs_ordered_update_i_size(inode, inode->i_size, NULL);
+ mark_inode_dirty(inode);
}
+
+ if (written < 0 || written == count)
+ return written;
+
+ pos += written;
+ count -= written;
+ iov_iter_init(&i, iov, nr_segs, count, written);
+ written_buffered = __btrfs_buffered_write(file, &i, pos);
+ if (written_buffered < 0) {
+ err = written_buffered;
+ goto out;
+ }
+ endbyte = pos + written_buffered - 1;
+ err = filemap_write_and_wait_range(file->f_mapping, pos, endbyte);
+ if (err)
+ goto out;
+ written += written_buffered;
+ *ppos = pos + written_buffered;
+ invalidate_mapping_pages(file->f_mapping, pos >> PAGE_CACHE_SHIFT,
+ endbyte >> PAGE_CACHE_SHIFT);
out:
- mutex_unlock(&inode->i_mutex);
- if (ret)
- err = ret;
+ return written ? written : err;
+}
- kfree(pages);
- *ppos = pos;
+static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
+ const struct iovec *iov,
+ unsigned long nr_segs, loff_t pos)
+{
+ struct file *file = iocb->ki_filp;
+ struct inode *inode = fdentry(file)->d_inode;
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ loff_t *ppos = &iocb->ki_pos;
+ ssize_t num_written = 0;
+ ssize_t err = 0;
+ size_t count, ocount;
+
+ vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
+
+ mutex_lock(&inode->i_mutex);
+
+ err = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
+ if (err) {
+ mutex_unlock(&inode->i_mutex);
+ goto out;
+ }
+ count = ocount;
+
+ current->backing_dev_info = inode->i_mapping->backing_dev_info;
+ err = generic_write_checks(file, &pos, &count, S_ISBLK(inode->i_mode));
+ if (err) {
+ mutex_unlock(&inode->i_mutex);
+ goto out;
+ }
+
+ if (count == 0) {
+ mutex_unlock(&inode->i_mutex);
+ goto out;
+ }
+
+ err = file_remove_suid(file);
+ if (err) {
+ mutex_unlock(&inode->i_mutex);
+ goto out;
+ }
+
+ /*
+ * If BTRFS flips readonly due to some impossible error
+ * (fs_info->fs_state now has BTRFS_SUPER_FLAG_ERROR),
+ * although we have opened a file as writable, we have
+ * to stop this write operation to ensure FS consistency.
+ */
+ if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
+ mutex_unlock(&inode->i_mutex);
+ err = -EROFS;
+ goto out;
+ }
+
+ file_update_time(file);
+ BTRFS_I(inode)->sequence++;
+
+ if (unlikely(file->f_flags & O_DIRECT)) {
+ num_written = __btrfs_direct_write(iocb, iov, nr_segs,
+ pos, ppos, count, ocount);
+ } else {
+ struct iov_iter i;
+
+ iov_iter_init(&i, iov, nr_segs, count, num_written);
+
+ num_written = __btrfs_buffered_write(file, &i, pos);
+ if (num_written > 0)
+ *ppos = pos + num_written;
+ }
+
+ mutex_unlock(&inode->i_mutex);
/*
* we want to make sure fsync finds this change
@@ -1118,43 +1157,12 @@ out:
* one running right now.
*/
BTRFS_I(inode)->last_trans = root->fs_info->generation + 1;
-
- if (num_written > 0 && will_write) {
- struct btrfs_trans_handle *trans;
-
- err = btrfs_wait_ordered_range(inode, start_pos, num_written);
- if (err)
+ if (num_written > 0 || num_written == -EIOCBQUEUED) {
+ err = generic_write_sync(file, pos, num_written);
+ if (err < 0 && num_written > 0)
num_written = err;
-
- if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) {
- trans = btrfs_start_transaction(root, 0);
- if (IS_ERR(trans)) {
- num_written = PTR_ERR(trans);
- goto done;
- }
- mutex_lock(&inode->i_mutex);
- ret = btrfs_log_dentry_safe(trans, root,
- file->f_dentry);
- mutex_unlock(&inode->i_mutex);
- if (ret == 0) {
- ret = btrfs_sync_log(trans, root);
- if (ret == 0)
- btrfs_end_transaction(trans, root);
- else
- btrfs_commit_transaction(trans, root);
- } else if (ret != BTRFS_NO_LOG_SYNC) {
- btrfs_commit_transaction(trans, root);
- } else {
- btrfs_end_transaction(trans, root);
- }
- }
- if (file->f_flags & O_DIRECT && buffered) {
- invalidate_mapping_pages(inode->i_mapping,
- start_pos >> PAGE_CACHE_SHIFT,
- (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT);
- }
}
-done:
+out:
current->backing_dev_info = NULL;
return num_written ? num_written : err;
}
@@ -1197,6 +1205,7 @@ int btrfs_sync_file(struct file *file, int datasync)
int ret = 0;
struct btrfs_trans_handle *trans;
+ trace_btrfs_sync_file(file, datasync);
/* we wait first, since the writeback may change the inode */
root->log_batch++;
@@ -1324,7 +1333,8 @@ static long btrfs_fallocate(struct file *file, int mode,
goto out;
if (alloc_start > inode->i_size) {
- ret = btrfs_cont_expand(inode, alloc_start);
+ ret = btrfs_cont_expand(inode, i_size_read(inode),
+ alloc_start);
if (ret)
goto out;
}
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index a0390657451..0037427d8a9 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -393,7 +393,8 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
break;
need_loop = 1;
- e = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS);
+ e = kmem_cache_zalloc(btrfs_free_space_cachep,
+ GFP_NOFS);
if (!e) {
kunmap(page);
unlock_page(page);
@@ -405,7 +406,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
e->bytes = le64_to_cpu(entry->bytes);
if (!e->bytes) {
kunmap(page);
- kfree(e);
+ kmem_cache_free(btrfs_free_space_cachep, e);
unlock_page(page);
page_cache_release(page);
goto free_cache;
@@ -420,7 +421,8 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
e->bitmap = kzalloc(PAGE_CACHE_SIZE, GFP_NOFS);
if (!e->bitmap) {
kunmap(page);
- kfree(e);
+ kmem_cache_free(
+ btrfs_free_space_cachep, e);
unlock_page(page);
page_cache_release(page);
goto free_cache;
@@ -1187,7 +1189,7 @@ static void free_bitmap(struct btrfs_block_group_cache *block_group,
{
unlink_free_space(block_group, bitmap_info);
kfree(bitmap_info->bitmap);
- kfree(bitmap_info);
+ kmem_cache_free(btrfs_free_space_cachep, bitmap_info);
block_group->total_bitmaps--;
recalculate_thresholds(block_group);
}
@@ -1285,9 +1287,22 @@ static int insert_into_bitmap(struct btrfs_block_group_cache *block_group,
* If we are below the extents threshold then we can add this as an
* extent, and don't have to deal with the bitmap
*/
- if (block_group->free_extents < block_group->extents_thresh &&
- info->bytes > block_group->sectorsize * 4)
- return 0;
+ if (block_group->free_extents < block_group->extents_thresh) {
+ /*
+ * If this block group has some small extents we don't want to
+ * use up all of our free slots in the cache with them, we want
+ * to reserve them to larger extents, however if we have plent
+ * of cache left then go ahead an dadd them, no sense in adding
+ * the overhead of a bitmap if we don't have to.
+ */
+ if (info->bytes <= block_group->sectorsize * 4) {
+ if (block_group->free_extents * 2 <=
+ block_group->extents_thresh)
+ return 0;
+ } else {
+ return 0;
+ }
+ }
/*
* some block groups are so tiny they can't be enveloped by a bitmap, so
@@ -1342,8 +1357,8 @@ new_bitmap:
/* no pre-allocated info, allocate a new one */
if (!info) {
- info = kzalloc(sizeof(struct btrfs_free_space),
- GFP_NOFS);
+ info = kmem_cache_zalloc(btrfs_free_space_cachep,
+ GFP_NOFS);
if (!info) {
spin_lock(&block_group->tree_lock);
ret = -ENOMEM;
@@ -1365,7 +1380,7 @@ out:
if (info) {
if (info->bitmap)
kfree(info->bitmap);
- kfree(info);
+ kmem_cache_free(btrfs_free_space_cachep, info);
}
return ret;
@@ -1398,7 +1413,7 @@ bool try_merge_free_space(struct btrfs_block_group_cache *block_group,
else
__unlink_free_space(block_group, right_info);
info->bytes += right_info->bytes;
- kfree(right_info);
+ kmem_cache_free(btrfs_free_space_cachep, right_info);
merged = true;
}
@@ -1410,7 +1425,7 @@ bool try_merge_free_space(struct btrfs_block_group_cache *block_group,
__unlink_free_space(block_group, left_info);
info->offset = left_info->offset;
info->bytes += left_info->bytes;
- kfree(left_info);
+ kmem_cache_free(btrfs_free_space_cachep, left_info);
merged = true;
}
@@ -1423,7 +1438,7 @@ int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
struct btrfs_free_space *info;
int ret = 0;
- info = kzalloc(sizeof(struct btrfs_free_space), GFP_NOFS);
+ info = kmem_cache_zalloc(btrfs_free_space_cachep, GFP_NOFS);
if (!info)
return -ENOMEM;
@@ -1450,7 +1465,7 @@ int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
link:
ret = link_free_space(block_group, info);
if (ret)
- kfree(info);
+ kmem_cache_free(btrfs_free_space_cachep, info);
out:
spin_unlock(&block_group->tree_lock);
@@ -1520,7 +1535,7 @@ again:
kfree(info->bitmap);
block_group->total_bitmaps--;
}
- kfree(info);
+ kmem_cache_free(btrfs_free_space_cachep, info);
goto out_lock;
}
@@ -1556,7 +1571,7 @@ again:
/* the hole we're creating ends at the end
* of the info struct, just free the info
*/
- kfree(info);
+ kmem_cache_free(btrfs_free_space_cachep, info);
}
spin_unlock(&block_group->tree_lock);
@@ -1629,30 +1644,28 @@ __btrfs_return_cluster_to_free_space(
{
struct btrfs_free_space *entry;
struct rb_node *node;
- bool bitmap;
spin_lock(&cluster->lock);
if (cluster->block_group != block_group)
goto out;
- bitmap = cluster->points_to_bitmap;
cluster->block_group = NULL;
cluster->window_start = 0;
list_del_init(&cluster->block_group_list);
- cluster->points_to_bitmap = false;
-
- if (bitmap)
- goto out;
node = rb_first(&cluster->root);
while (node) {
+ bool bitmap;
+
entry = rb_entry(node, struct btrfs_free_space, offset_index);
node = rb_next(&entry->offset_index);
rb_erase(&entry->offset_index, &cluster->root);
- BUG_ON(entry->bitmap);
- try_merge_free_space(block_group, entry, false);
+
+ bitmap = (entry->bitmap != NULL);
+ if (!bitmap)
+ try_merge_free_space(block_group, entry, false);
tree_insert_offset(&block_group->free_space_offset,
- entry->offset, &entry->offset_index, 0);
+ entry->offset, &entry->offset_index, bitmap);
}
cluster->root = RB_ROOT;
@@ -1689,7 +1702,7 @@ void btrfs_remove_free_space_cache(struct btrfs_block_group_cache *block_group)
unlink_free_space(block_group, info);
if (info->bitmap)
kfree(info->bitmap);
- kfree(info);
+ kmem_cache_free(btrfs_free_space_cachep, info);
if (need_resched()) {
spin_unlock(&block_group->tree_lock);
cond_resched();
@@ -1722,7 +1735,7 @@ u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
entry->offset += bytes;
entry->bytes -= bytes;
if (!entry->bytes)
- kfree(entry);
+ kmem_cache_free(btrfs_free_space_cachep, entry);
else
link_free_space(block_group, entry);
}
@@ -1775,50 +1788,24 @@ int btrfs_return_cluster_to_free_space(
static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
struct btrfs_free_cluster *cluster,
+ struct btrfs_free_space *entry,
u64 bytes, u64 min_start)
{
- struct btrfs_free_space *entry;
int err;
u64 search_start = cluster->window_start;
u64 search_bytes = bytes;
u64 ret = 0;
- spin_lock(&block_group->tree_lock);
- spin_lock(&cluster->lock);
-
- if (!cluster->points_to_bitmap)
- goto out;
-
- if (cluster->block_group != block_group)
- goto out;
-
- /*
- * search_start is the beginning of the bitmap, but at some point it may
- * be a good idea to point to the actual start of the free area in the
- * bitmap, so do the offset_to_bitmap trick anyway, and set bitmap_only
- * to 1 to make sure we get the bitmap entry
- */
- entry = tree_search_offset(block_group,
- offset_to_bitmap(block_group, search_start),
- 1, 0);
- if (!entry || !entry->bitmap)
- goto out;
-
search_start = min_start;
search_bytes = bytes;
err = search_bitmap(block_group, entry, &search_start,
&search_bytes);
if (err)
- goto out;
+ return 0;
ret = search_start;
bitmap_clear_bits(block_group, entry, ret, bytes);
- if (entry->bytes == 0)
- free_bitmap(block_group, entry);
-out:
- spin_unlock(&cluster->lock);
- spin_unlock(&block_group->tree_lock);
return ret;
}
@@ -1836,10 +1823,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
struct rb_node *node;
u64 ret = 0;
- if (cluster->points_to_bitmap)
- return btrfs_alloc_from_bitmap(block_group, cluster, bytes,
- min_start);
-
spin_lock(&cluster->lock);
if (bytes > cluster->max_size)
goto out;
@@ -1852,9 +1835,9 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
goto out;
entry = rb_entry(node, struct btrfs_free_space, offset_index);
-
while(1) {
- if (entry->bytes < bytes || entry->offset < min_start) {
+ if (entry->bytes < bytes ||
+ (!entry->bitmap && entry->offset < min_start)) {
struct rb_node *node;
node = rb_next(&entry->offset_index);
@@ -1864,10 +1847,27 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
offset_index);
continue;
}
- ret = entry->offset;
- entry->offset += bytes;
- entry->bytes -= bytes;
+ if (entry->bitmap) {
+ ret = btrfs_alloc_from_bitmap(block_group,
+ cluster, entry, bytes,
+ min_start);
+ if (ret == 0) {
+ struct rb_node *node;
+ node = rb_next(&entry->offset_index);
+ if (!node)
+ break;
+ entry = rb_entry(node, struct btrfs_free_space,
+ offset_index);
+ continue;
+ }
+ } else {
+
+ ret = entry->offset;
+
+ entry->offset += bytes;
+ entry->bytes -= bytes;
+ }
if (entry->bytes == 0)
rb_erase(&entry->offset_index, &cluster->root);
@@ -1884,7 +1884,12 @@ out:
block_group->free_space -= bytes;
if (entry->bytes == 0) {
block_group->free_extents--;
- kfree(entry);
+ if (entry->bitmap) {
+ kfree(entry->bitmap);
+ block_group->total_bitmaps--;
+ recalculate_thresholds(block_group);
+ }
+ kmem_cache_free(btrfs_free_space_cachep, entry);
}
spin_unlock(&block_group->tree_lock);
@@ -1904,12 +1909,13 @@ static int btrfs_bitmap_cluster(struct btrfs_block_group_cache *block_group,
unsigned long found_bits;
unsigned long start = 0;
unsigned long total_found = 0;
+ int ret;
bool found = false;
i = offset_to_bit(entry->offset, block_group->sectorsize,
max_t(u64, offset, entry->offset));
- search_bits = bytes_to_bits(min_bytes, block_group->sectorsize);
- total_bits = bytes_to_bits(bytes, block_group->sectorsize);
+ search_bits = bytes_to_bits(bytes, block_group->sectorsize);
+ total_bits = bytes_to_bits(min_bytes, block_group->sectorsize);
again:
found_bits = 0;
@@ -1926,7 +1932,7 @@ again:
}
if (!found_bits)
- return -1;
+ return -ENOSPC;
if (!found) {
start = i;
@@ -1950,189 +1956,208 @@ again:
cluster->window_start = start * block_group->sectorsize +
entry->offset;
- cluster->points_to_bitmap = true;
+ rb_erase(&entry->offset_index, &block_group->free_space_offset);
+ ret = tree_insert_offset(&cluster->root, entry->offset,
+ &entry->offset_index, 1);
+ BUG_ON(ret);
return 0;
}
/*
- * here we try to find a cluster of blocks in a block group. The goal
- * is to find at least bytes free and up to empty_size + bytes free.
- * We might not find them all in one contiguous area.
- *
- * returns zero and sets up cluster if things worked out, otherwise
- * it returns -enospc
+ * This searches the block group for just extents to fill the cluster with.
*/
-int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct btrfs_block_group_cache *block_group,
- struct btrfs_free_cluster *cluster,
- u64 offset, u64 bytes, u64 empty_size)
+static int setup_cluster_no_bitmap(struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster,
+ u64 offset, u64 bytes, u64 min_bytes)
{
+ struct btrfs_free_space *first = NULL;
struct btrfs_free_space *entry = NULL;
+ struct btrfs_free_space *prev = NULL;
+ struct btrfs_free_space *last;
struct rb_node *node;
- struct btrfs_free_space *next;
- struct btrfs_free_space *last = NULL;
- u64 min_bytes;
u64 window_start;
u64 window_free;
- u64 max_extent = 0;
- bool found_bitmap = false;
- int ret;
+ u64 max_extent;
+ u64 max_gap = 128 * 1024;
- /* for metadata, allow allocates with more holes */
- if (btrfs_test_opt(root, SSD_SPREAD)) {
- min_bytes = bytes + empty_size;
- } else if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) {
- /*
- * we want to do larger allocations when we are
- * flushing out the delayed refs, it helps prevent
- * making more work as we go along.
- */
- if (trans->transaction->delayed_refs.flushing)
- min_bytes = max(bytes, (bytes + empty_size) >> 1);
- else
- min_bytes = max(bytes, (bytes + empty_size) >> 4);
- } else
- min_bytes = max(bytes, (bytes + empty_size) >> 2);
-
- spin_lock(&block_group->tree_lock);
- spin_lock(&cluster->lock);
-
- /* someone already found a cluster, hooray */
- if (cluster->block_group) {
- ret = 0;
- goto out;
- }
-again:
- entry = tree_search_offset(block_group, offset, found_bitmap, 1);
- if (!entry) {
- ret = -ENOSPC;
- goto out;
- }
+ entry = tree_search_offset(block_group, offset, 0, 1);
+ if (!entry)
+ return -ENOSPC;
/*
- * If found_bitmap is true, we exhausted our search for extent entries,
- * and we just want to search all of the bitmaps that we can find, and
- * ignore any extent entries we find.
+ * We don't want bitmaps, so just move along until we find a normal
+ * extent entry.
*/
- while (entry->bitmap || found_bitmap ||
- (!entry->bitmap && entry->bytes < min_bytes)) {
- struct rb_node *node = rb_next(&entry->offset_index);
-
- if (entry->bitmap && entry->bytes > bytes + empty_size) {
- ret = btrfs_bitmap_cluster(block_group, entry, cluster,
- offset, bytes + empty_size,
- min_bytes);
- if (!ret)
- goto got_it;
- }
-
- if (!node) {
- ret = -ENOSPC;
- goto out;
- }
+ while (entry->bitmap) {
+ node = rb_next(&entry->offset_index);
+ if (!node)
+ return -ENOSPC;
entry = rb_entry(node, struct btrfs_free_space, offset_index);
}
- /*
- * We already searched all the extent entries from the passed in offset
- * to the end and didn't find enough space for the cluster, and we also
- * didn't find any bitmaps that met our criteria, just go ahead and exit
- */
- if (found_bitmap) {
- ret = -ENOSPC;
- goto out;
- }
-
- cluster->points_to_bitmap = false;
window_start = entry->offset;
window_free = entry->bytes;
- last = entry;
max_extent = entry->bytes;
+ first = entry;
+ last = entry;
+ prev = entry;
- while (1) {
- /* out window is just right, lets fill it */
- if (window_free >= bytes + empty_size)
- break;
-
- node = rb_next(&last->offset_index);
- if (!node) {
- if (found_bitmap)
- goto again;
- ret = -ENOSPC;
- goto out;
- }
- next = rb_entry(node, struct btrfs_free_space, offset_index);
+ while (window_free <= min_bytes) {
+ node = rb_next(&entry->offset_index);
+ if (!node)
+ return -ENOSPC;
+ entry = rb_entry(node, struct btrfs_free_space, offset_index);
- /*
- * we found a bitmap, so if this search doesn't result in a
- * cluster, we know to go and search again for the bitmaps and
- * start looking for space there
- */
- if (next->bitmap) {
- if (!found_bitmap)
- offset = next->offset;
- found_bitmap = true;
- last = next;
+ if (entry->bitmap)
continue;
- }
-
/*
* we haven't filled the empty size and the window is
* very large. reset and try again
*/
- if (next->offset - (last->offset + last->bytes) > 128 * 1024 ||
- next->offset - window_start > (bytes + empty_size) * 2) {
- entry = next;
+ if (entry->offset - (prev->offset + prev->bytes) > max_gap ||
+ entry->offset - window_start > (min_bytes * 2)) {
+ first = entry;
window_start = entry->offset;
window_free = entry->bytes;
last = entry;
max_extent = entry->bytes;
} else {
- last = next;
- window_free += next->bytes;
+ last = entry;
+ window_free += entry->bytes;
if (entry->bytes > max_extent)
max_extent = entry->bytes;
}
+ prev = entry;
}
- cluster->window_start = entry->offset;
+ cluster->window_start = first->offset;
+
+ node = &first->offset_index;
/*
* now we've found our entries, pull them out of the free space
* cache and put them into the cluster rbtree
- *
- * The cluster includes an rbtree, but only uses the offset index
- * of each free space cache entry.
*/
- while (1) {
+ do {
+ int ret;
+
+ entry = rb_entry(node, struct btrfs_free_space, offset_index);
node = rb_next(&entry->offset_index);
- if (entry->bitmap && node) {
- entry = rb_entry(node, struct btrfs_free_space,
- offset_index);
+ if (entry->bitmap)
continue;
- } else if (entry->bitmap && !node) {
- break;
- }
rb_erase(&entry->offset_index, &block_group->free_space_offset);
ret = tree_insert_offset(&cluster->root, entry->offset,
&entry->offset_index, 0);
BUG_ON(ret);
+ } while (node && entry != last);
- if (!node || entry == last)
- break;
+ cluster->max_size = max_extent;
+
+ return 0;
+}
+
+/*
+ * This specifically looks for bitmaps that may work in the cluster, we assume
+ * that we have already failed to find extents that will work.
+ */
+static int setup_cluster_bitmap(struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster,
+ u64 offset, u64 bytes, u64 min_bytes)
+{
+ struct btrfs_free_space *entry;
+ struct rb_node *node;
+ int ret = -ENOSPC;
+
+ if (block_group->total_bitmaps == 0)
+ return -ENOSPC;
+ entry = tree_search_offset(block_group,
+ offset_to_bitmap(block_group, offset),
+ 0, 1);
+ if (!entry)
+ return -ENOSPC;
+
+ 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;
+}
+
+/*
+ * here we try to find a cluster of blocks in a block group. The goal
+ * is to find at least bytes free and up to empty_size + bytes free.
+ * We might not find them all in one contiguous area.
+ *
+ * returns zero and sets up cluster if things worked out, otherwise
+ * it returns -enospc
+ */
+int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct btrfs_block_group_cache *block_group,
+ struct btrfs_free_cluster *cluster,
+ u64 offset, u64 bytes, u64 empty_size)
+{
+ u64 min_bytes;
+ int ret;
+
+ /* for metadata, allow allocates with more holes */
+ if (btrfs_test_opt(root, SSD_SPREAD)) {
+ min_bytes = bytes + empty_size;
+ } else if (block_group->flags & BTRFS_BLOCK_GROUP_METADATA) {
+ /*
+ * we want to do larger allocations when we are
+ * flushing out the delayed refs, it helps prevent
+ * making more work as we go along.
+ */
+ if (trans->transaction->delayed_refs.flushing)
+ min_bytes = max(bytes, (bytes + empty_size) >> 1);
+ else
+ min_bytes = max(bytes, (bytes + empty_size) >> 4);
+ } else
+ min_bytes = max(bytes, (bytes + empty_size) >> 2);
+
+ spin_lock(&block_group->tree_lock);
+
+ /*
+ * If we know we don't have enough space to make a cluster don't even
+ * bother doing all the work to try and find one.
+ */
+ if (block_group->free_space < min_bytes) {
+ spin_unlock(&block_group->tree_lock);
+ return -ENOSPC;
}
- cluster->max_size = max_extent;
-got_it:
- ret = 0;
- atomic_inc(&block_group->count);
- list_add_tail(&cluster->block_group_list, &block_group->cluster_list);
- cluster->block_group = block_group;
+ spin_lock(&cluster->lock);
+
+ /* someone already found a cluster, hooray */
+ if (cluster->block_group) {
+ ret = 0;
+ goto out;
+ }
+
+ ret = setup_cluster_no_bitmap(block_group, cluster, offset, bytes,
+ min_bytes);
+ if (ret)
+ ret = setup_cluster_bitmap(block_group, cluster, offset,
+ bytes, min_bytes);
+
+ if (!ret) {
+ atomic_inc(&block_group->count);
+ list_add_tail(&cluster->block_group_list,
+ &block_group->cluster_list);
+ cluster->block_group = block_group;
+ }
out:
spin_unlock(&cluster->lock);
spin_unlock(&block_group->tree_lock);
@@ -2149,8 +2174,99 @@ void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster)
spin_lock_init(&cluster->refill_lock);
cluster->root = RB_ROOT;
cluster->max_size = 0;
- cluster->points_to_bitmap = false;
INIT_LIST_HEAD(&cluster->block_group_list);
cluster->block_group = NULL;
}
+int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
+ u64 *trimmed, u64 start, u64 end, u64 minlen)
+{
+ struct btrfs_free_space *entry = NULL;
+ struct btrfs_fs_info *fs_info = block_group->fs_info;
+ u64 bytes = 0;
+ u64 actually_trimmed;
+ int ret = 0;
+
+ *trimmed = 0;
+
+ while (start < end) {
+ spin_lock(&block_group->tree_lock);
+
+ if (block_group->free_space < minlen) {
+ spin_unlock(&block_group->tree_lock);
+ break;
+ }
+
+ entry = tree_search_offset(block_group, start, 0, 1);
+ if (!entry)
+ entry = tree_search_offset(block_group,
+ offset_to_bitmap(block_group,
+ start),
+ 1, 1);
+
+ if (!entry || entry->offset >= end) {
+ spin_unlock(&block_group->tree_lock);
+ break;
+ }
+
+ if (entry->bitmap) {
+ ret = search_bitmap(block_group, entry, &start, &bytes);
+ if (!ret) {
+ if (start >= end) {
+ spin_unlock(&block_group->tree_lock);
+ break;
+ }
+ bytes = min(bytes, end - start);
+ bitmap_clear_bits(block_group, entry,
+ start, bytes);
+ if (entry->bytes == 0)
+ free_bitmap(block_group, entry);
+ } else {
+ start = entry->offset + BITS_PER_BITMAP *
+ block_group->sectorsize;
+ spin_unlock(&block_group->tree_lock);
+ ret = 0;
+ continue;
+ }
+ } else {
+ start = entry->offset;
+ bytes = min(entry->bytes, end - start);
+ unlink_free_space(block_group, entry);
+ kfree(entry);
+ }
+
+ spin_unlock(&block_group->tree_lock);
+
+ if (bytes >= minlen) {
+ int update_ret;
+ update_ret = btrfs_update_reserved_bytes(block_group,
+ bytes, 1, 1);
+
+ ret = btrfs_error_discard_extent(fs_info->extent_root,
+ start,
+ bytes,
+ &actually_trimmed);
+
+ btrfs_add_free_space(block_group,
+ start, bytes);
+ if (!update_ret)
+ btrfs_update_reserved_bytes(block_group,
+ bytes, 0, 1);
+
+ if (ret)
+ break;
+ *trimmed += actually_trimmed;
+ }
+ start += bytes;
+ bytes = 0;
+
+ if (fatal_signal_pending(current)) {
+ ret = -ERESTARTSYS;
+ break;
+ }
+
+ cond_resched();
+ }
+
+ return ret;
+}
diff --git a/fs/btrfs/free-space-cache.h b/fs/btrfs/free-space-cache.h
index e49ca5c321b..65c3b935289 100644
--- a/fs/btrfs/free-space-cache.h
+++ b/fs/btrfs/free-space-cache.h
@@ -68,4 +68,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
int btrfs_return_cluster_to_free_space(
struct btrfs_block_group_cache *block_group,
struct btrfs_free_cluster *cluster);
+int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
+ u64 *trimmed, u64 start, u64 end, u64 minlen);
#endif
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index c56eb590917..c05a08f4c41 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -30,7 +30,8 @@ int btrfs_find_highest_inode(struct btrfs_root *root, u64 *objectid)
int slot;
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
search_key.objectid = BTRFS_LAST_FREE_OBJECTID;
search_key.type = -1;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 119520bdb9a..93c28a1d6bd 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -50,6 +50,7 @@
#include "tree-log.h"
#include "compression.h"
#include "locking.h"
+#include "free-space-cache.h"
struct btrfs_iget_args {
u64 ino;
@@ -70,6 +71,7 @@ static struct kmem_cache *btrfs_inode_cachep;
struct kmem_cache *btrfs_trans_handle_cachep;
struct kmem_cache *btrfs_transaction_cachep;
struct kmem_cache *btrfs_path_cachep;
+struct kmem_cache *btrfs_free_space_cachep;
#define S_SHIFT 12
static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = {
@@ -82,7 +84,8 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = {
[S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK,
};
-static void btrfs_truncate(struct inode *inode);
+static int btrfs_setsize(struct inode *inode, loff_t newsize);
+static int btrfs_truncate(struct inode *inode);
static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end);
static noinline int cow_file_range(struct inode *inode,
struct page *locked_page,
@@ -288,6 +291,7 @@ static noinline int add_async_extent(struct async_cow *cow,
struct async_extent *async_extent;
async_extent = kmalloc(sizeof(*async_extent), GFP_NOFS);
+ BUG_ON(!async_extent);
async_extent->start = start;
async_extent->ram_size = ram_size;
async_extent->compressed_size = compressed_size;
@@ -382,9 +386,11 @@ again:
*/
if (!(BTRFS_I(inode)->flags & BTRFS_INODE_NOCOMPRESS) &&
(btrfs_test_opt(root, COMPRESS) ||
- (BTRFS_I(inode)->force_compress))) {
+ (BTRFS_I(inode)->force_compress) ||
+ (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))) {
WARN_ON(pages);
pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
+ BUG_ON(!pages);
if (BTRFS_I(inode)->force_compress)
compress_type = BTRFS_I(inode)->force_compress;
@@ -1254,7 +1260,8 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
ret = run_delalloc_nocow(inode, locked_page, start, end,
page_started, 0, nr_written);
else if (!btrfs_test_opt(root, COMPRESS) &&
- !(BTRFS_I(inode)->force_compress))
+ !(BTRFS_I(inode)->force_compress) &&
+ !(BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))
ret = cow_file_range(inode, locked_page, start, end,
page_started, nr_written, 1);
else
@@ -1461,8 +1468,11 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
if (bio_flags & EXTENT_BIO_COMPRESSED) {
return btrfs_submit_compressed_read(inode, bio,
mirror_num, bio_flags);
- } else if (!skip_sum)
- btrfs_lookup_bio_sums(root, inode, bio, NULL);
+ } else if (!skip_sum) {
+ ret = btrfs_lookup_bio_sums(root, inode, bio, NULL);
+ if (ret)
+ return ret;
+ }
goto mapit;
} else if (!skip_sum) {
/* csum items have already been cloned */
@@ -1785,6 +1795,8 @@ out:
static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
struct extent_state *state, int uptodate)
{
+ trace_btrfs_writepage_end_io_hook(page, start, end, uptodate);
+
ClearPagePrivate2(page);
return btrfs_finish_ordered_io(page->mapping->host, start, end);
}
@@ -1895,10 +1907,10 @@ static int btrfs_io_failed_hook(struct bio *failed_bio,
else
rw = READ;
- BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio,
+ ret = BTRFS_I(inode)->io_tree.ops->submit_bio_hook(inode, rw, bio,
failrec->last_mirror,
failrec->bio_flags, 0);
- return 0;
+ return ret;
}
/*
@@ -2282,7 +2294,7 @@ int btrfs_orphan_del(struct btrfs_trans_handle *trans, struct inode *inode)
* this cleans up any orphans that may be left on the list from the last use
* of this root.
*/
-void btrfs_orphan_cleanup(struct btrfs_root *root)
+int btrfs_orphan_cleanup(struct btrfs_root *root)
{
struct btrfs_path *path;
struct extent_buffer *leaf;
@@ -2292,10 +2304,13 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
int ret = 0, nr_unlink = 0, nr_truncate = 0;
if (cmpxchg(&root->orphan_cleanup_state, 0, ORPHAN_CLEANUP_STARTED))
- return;
+ return 0;
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path) {
+ ret = -ENOMEM;
+ goto out;
+ }
path->reada = -1;
key.objectid = BTRFS_ORPHAN_OBJECTID;
@@ -2304,11 +2319,8 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
while (1) {
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
- if (ret < 0) {
- printk(KERN_ERR "Error searching slot for orphan: %d"
- "\n", ret);
- break;
- }
+ if (ret < 0)
+ goto out;
/*
* if ret == 0 means we found what we were searching for, which
@@ -2316,6 +2328,7 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
* find the key and see if we have stuff that matches
*/
if (ret > 0) {
+ ret = 0;
if (path->slots[0] == 0)
break;
path->slots[0]--;
@@ -2343,7 +2356,10 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
found_key.type = BTRFS_INODE_ITEM_KEY;
found_key.offset = 0;
inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL);
- BUG_ON(IS_ERR(inode));
+ if (IS_ERR(inode)) {
+ ret = PTR_ERR(inode);
+ goto out;
+ }
/*
* add this inode to the orphan list so btrfs_orphan_del does
@@ -2361,7 +2377,10 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
*/
if (is_bad_inode(inode)) {
trans = btrfs_start_transaction(root, 0);
- BUG_ON(IS_ERR(trans));
+ if (IS_ERR(trans)) {
+ ret = PTR_ERR(trans);
+ goto out;
+ }
btrfs_orphan_del(trans, inode);
btrfs_end_transaction(trans, root);
iput(inode);
@@ -2370,17 +2389,22 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
/* if we have links, this was a truncate, lets do that */
if (inode->i_nlink) {
+ if (!S_ISREG(inode->i_mode)) {
+ WARN_ON(1);
+ iput(inode);
+ continue;
+ }
nr_truncate++;
- btrfs_truncate(inode);
+ ret = btrfs_truncate(inode);
} else {
nr_unlink++;
}
/* this will do delete_inode and everything for us */
iput(inode);
+ if (ret)
+ goto out;
}
- btrfs_free_path(path);
-
root->orphan_cleanup_state = ORPHAN_CLEANUP_DONE;
if (root->orphan_block_rsv)
@@ -2389,14 +2413,20 @@ void btrfs_orphan_cleanup(struct btrfs_root *root)
if (root->orphan_block_rsv || root->orphan_item_inserted) {
trans = btrfs_join_transaction(root, 1);
- BUG_ON(IS_ERR(trans));
- btrfs_end_transaction(trans, root);
+ if (!IS_ERR(trans))
+ btrfs_end_transaction(trans, root);
}
if (nr_unlink)
printk(KERN_INFO "btrfs: unlinked %d orphans\n", nr_unlink);
if (nr_truncate)
printk(KERN_INFO "btrfs: truncated %d orphans\n", nr_truncate);
+
+out:
+ if (ret)
+ printk(KERN_CRIT "btrfs: could not do orphan cleanup %d\n", ret);
+ btrfs_free_path(path);
+ return ret;
}
/*
@@ -2507,6 +2537,8 @@ static void btrfs_read_locked_inode(struct inode *inode)
BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
+ if (location.objectid == BTRFS_FREE_SPACE_OBJECTID)
+ inode->i_mapping->flags &= ~__GFP_FS;
/*
* try to precache a NULL acl entry for files that don't have
@@ -2635,10 +2667,10 @@ failed:
* recovery code. It remove a link in a directory with a given name, and
* also drops the back refs in the inode to the directory
*/
-int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
- struct btrfs_root *root,
- struct inode *dir, struct inode *inode,
- const char *name, int name_len)
+static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct inode *dir, struct inode *inode,
+ const char *name, int name_len)
{
struct btrfs_path *path;
int ret = 0;
@@ -2710,12 +2742,25 @@ err:
btrfs_i_size_write(dir, dir->i_size - name_len * 2);
inode->i_ctime = dir->i_mtime = dir->i_ctime = CURRENT_TIME;
btrfs_update_inode(trans, root, dir);
- btrfs_drop_nlink(inode);
- ret = btrfs_update_inode(trans, root, inode);
out:
return ret;
}
+int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct inode *dir, struct inode *inode,
+ const char *name, int name_len)
+{
+ int ret;
+ ret = __btrfs_unlink_inode(trans, root, dir, inode, name, name_len);
+ if (!ret) {
+ btrfs_drop_nlink(inode);
+ ret = btrfs_update_inode(trans, root, inode);
+ }
+ return ret;
+}
+
+
/* helper to check if there is any shared block in the path */
static int check_path_shared(struct btrfs_root *root,
struct btrfs_path *path)
@@ -3537,7 +3582,13 @@ out:
return ret;
}
-int btrfs_cont_expand(struct inode *inode, loff_t size)
+/*
+ * This function puts in dummy file extents for the area we're creating a hole
+ * for. So if we are truncating this file to a larger size we need to insert
+ * these file extents so that btrfs_get_extent will return a EXTENT_MAP_HOLE for
+ * the range between oldsize and size
+ */
+int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
{
struct btrfs_trans_handle *trans;
struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -3545,7 +3596,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
struct extent_map *em = NULL;
struct extent_state *cached_state = NULL;
u64 mask = root->sectorsize - 1;
- u64 hole_start = (inode->i_size + mask) & ~mask;
+ u64 hole_start = (oldsize + mask) & ~mask;
u64 block_end = (size + mask) & ~mask;
u64 last_byte;
u64 cur_offset;
@@ -3590,13 +3641,15 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
err = btrfs_drop_extents(trans, inode, cur_offset,
cur_offset + hole_size,
&hint_byte, 1);
- BUG_ON(err);
+ if (err)
+ break;
err = btrfs_insert_file_extent(trans, root,
inode->i_ino, cur_offset, 0,
0, hole_size, 0, hole_size,
0, 0, 0);
- BUG_ON(err);
+ if (err)
+ break;
btrfs_drop_extent_cache(inode, hole_start,
last_byte - 1, 0);
@@ -3616,81 +3669,41 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
return err;
}
-static int btrfs_setattr_size(struct inode *inode, struct iattr *attr)
+static int btrfs_setsize(struct inode *inode, loff_t newsize)
{
- struct btrfs_root *root = BTRFS_I(inode)->root;
- struct btrfs_trans_handle *trans;
- unsigned long nr;
+ loff_t oldsize = i_size_read(inode);
int ret;
- if (attr->ia_size == inode->i_size)
+ if (newsize == oldsize)
return 0;
- if (attr->ia_size > inode->i_size) {
- unsigned long limit;
- limit = current->signal->rlim[RLIMIT_FSIZE].rlim_cur;
- if (attr->ia_size > inode->i_sb->s_maxbytes)
- return -EFBIG;
- if (limit != RLIM_INFINITY && attr->ia_size > limit) {
- send_sig(SIGXFSZ, current, 0);
- return -EFBIG;
- }
- }
-
- trans = btrfs_start_transaction(root, 5);
- if (IS_ERR(trans))
- return PTR_ERR(trans);
-
- btrfs_set_trans_block_group(trans, inode);
-
- ret = btrfs_orphan_add(trans, inode);
- BUG_ON(ret);
-
- nr = trans->blocks_used;
- btrfs_end_transaction(trans, root);
- btrfs_btree_balance_dirty(root, nr);
-
- if (attr->ia_size > inode->i_size) {
- ret = btrfs_cont_expand(inode, attr->ia_size);
+ if (newsize > oldsize) {
+ i_size_write(inode, newsize);
+ btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL);
+ truncate_pagecache(inode, oldsize, newsize);
+ ret = btrfs_cont_expand(inode, oldsize, newsize);
if (ret) {
- btrfs_truncate(inode);
+ btrfs_setsize(inode, oldsize);
return ret;
}
- i_size_write(inode, attr->ia_size);
- btrfs_ordered_update_i_size(inode, inode->i_size, NULL);
+ mark_inode_dirty(inode);
+ } else {
- trans = btrfs_start_transaction(root, 0);
- BUG_ON(IS_ERR(trans));
- btrfs_set_trans_block_group(trans, inode);
- trans->block_rsv = root->orphan_block_rsv;
- BUG_ON(!trans->block_rsv);
+ /*
+ * We're truncating a file that used to have good data down to
+ * zero. Make sure it gets into the ordered flush list so that
+ * any new writes get down to disk quickly.
+ */
+ if (newsize == 0)
+ BTRFS_I(inode)->ordered_data_close = 1;
- ret = btrfs_update_inode(trans, root, inode);
- BUG_ON(ret);
- if (inode->i_nlink > 0) {
- ret = btrfs_orphan_del(trans, inode);
- BUG_ON(ret);
- }
- nr = trans->blocks_used;
- btrfs_end_transaction(trans, root);
- btrfs_btree_balance_dirty(root, nr);
- return 0;
+ /* we don't support swapfiles, so vmtruncate shouldn't fail */
+ truncate_setsize(inode, newsize);
+ ret = btrfs_truncate(inode);
}
- /*
- * We're truncating a file that used to have good data down to
- * zero. Make sure it gets into the ordered flush list so that
- * any new writes get down to disk quickly.
- */
- if (attr->ia_size == 0)
- BTRFS_I(inode)->ordered_data_close = 1;
-
- /* we don't support swapfiles, so vmtruncate shouldn't fail */
- ret = vmtruncate(inode, attr->ia_size);
- BUG_ON(ret);
-
- return 0;
+ return ret;
}
static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
@@ -3707,7 +3720,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
return err;
if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
- err = btrfs_setattr_size(inode, attr);
+ err = btrfs_setsize(inode, attr->ia_size);
if (err)
return err;
}
@@ -3730,6 +3743,8 @@ void btrfs_evict_inode(struct inode *inode)
unsigned long nr;
int ret;
+ trace_btrfs_inode_evict(inode);
+
truncate_inode_pages(&inode->i_data, 0);
if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
root == root->fs_info->tree_root))
@@ -4072,7 +4087,6 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
BTRFS_I(inode)->root = root;
memcpy(&BTRFS_I(inode)->location, location, sizeof(*location));
btrfs_read_locked_inode(inode);
-
inode_tree_add(inode);
unlock_new_inode(inode);
if (new)
@@ -4147,8 +4161,10 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
if (!IS_ERR(inode) && root != sub_root) {
down_read(&root->fs_info->cleanup_work_sem);
if (!(inode->i_sb->s_flags & MS_RDONLY))
- btrfs_orphan_cleanup(sub_root);
+ ret = btrfs_orphan_cleanup(sub_root);
up_read(&root->fs_info->cleanup_work_sem);
+ if (ret)
+ inode = ERR_PTR(ret);
}
return inode;
@@ -4282,6 +4298,9 @@ static int btrfs_real_readdir(struct file *filp, void *dirent,
while (di_cur < di_total) {
struct btrfs_key location;
+ if (verify_dir_item(root, leaf, di))
+ break;
+
name_len = btrfs_dir_name_len(leaf, di);
if (name_len <= sizeof(tmp_name)) {
name_ptr = tmp_name;
@@ -4517,6 +4536,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
return ERR_PTR(-ENOMEM);
if (dir) {
+ trace_btrfs_inode_request(dir);
+
ret = btrfs_set_inode_index(dir, index);
if (ret) {
iput(inode);
@@ -4585,12 +4606,16 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
if ((mode & S_IFREG)) {
if (btrfs_test_opt(root, NODATASUM))
BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM;
- if (btrfs_test_opt(root, NODATACOW))
+ if (btrfs_test_opt(root, NODATACOW) ||
+ (BTRFS_I(dir)->flags & BTRFS_INODE_NODATACOW))
BTRFS_I(inode)->flags |= BTRFS_INODE_NODATACOW;
}
insert_inode_hash(inode);
inode_tree_add(inode);
+
+ trace_btrfs_inode_new(inode);
+
return inode;
fail:
if (dir)
@@ -4809,7 +4834,10 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
/* do not allow sys_link's with other subvols of the same device */
if (root->objectid != BTRFS_I(inode)->root->objectid)
- return -EPERM;
+ return -EXDEV;
+
+ if (inode->i_nlink == ~0U)
+ return -EMLINK;
btrfs_inc_nlink(inode);
inode->i_ctime = CURRENT_TIME;
@@ -5265,6 +5293,9 @@ insert:
}
write_unlock(&em_tree->lock);
out:
+
+ trace_btrfs_get_extent(root, em);
+
if (path)
btrfs_free_path(path);
if (trans) {
@@ -5748,6 +5779,10 @@ static void btrfs_endio_direct_read(struct bio *bio, int err)
kfree(dip->csums);
kfree(dip);
+
+ /* If we had a csum failure make sure to clear the uptodate flag */
+ if (err)
+ clear_bit(BIO_UPTODATE, &bio->bi_flags);
dio_end_io(bio, err);
}
@@ -5849,6 +5884,10 @@ out_done:
kfree(dip->csums);
kfree(dip);
+
+ /* If we had an error make sure to clear the uptodate flag */
+ if (err)
+ clear_bit(BIO_UPTODATE, &bio->bi_flags);
dio_end_io(bio, err);
}
@@ -5922,9 +5961,12 @@ static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode,
__btrfs_submit_bio_start_direct_io,
__btrfs_submit_bio_done);
goto err;
- } else if (!skip_sum)
- btrfs_lookup_bio_sums_dio(root, inode, bio,
+ } else if (!skip_sum) {
+ ret = btrfs_lookup_bio_sums_dio(root, inode, bio,
file_offset, csums);
+ if (ret)
+ goto err;
+ }
ret = btrfs_map_bio(root, rw, bio, 0, 1);
err:
@@ -5948,6 +5990,7 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
int nr_pages = 0;
u32 *csums = dip->csums;
int ret = 0;
+ int write = rw & REQ_WRITE;
bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS);
if (!bio)
@@ -5984,7 +6027,8 @@ static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip,
goto out_err;
}
- if (!skip_sum)
+ /* Write's use the ordered csums */
+ if (!write && !skip_sum)
csums = csums + nr_pages;
start_sector += submit_len >> 9;
file_offset += submit_len;
@@ -6052,7 +6096,8 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode,
}
dip->csums = NULL;
- if (!skip_sum) {
+ /* Write's use the ordered csum stuff, so we don't need dip->csums */
+ if (!write && !skip_sum) {
dip->csums = kmalloc(sizeof(u32) * bio->bi_vcnt, GFP_NOFS);
if (!dip->csums) {
kfree(dip);
@@ -6474,28 +6519,42 @@ out:
return ret;
}
-static void btrfs_truncate(struct inode *inode)
+static int btrfs_truncate(struct inode *inode)
{
struct btrfs_root *root = BTRFS_I(inode)->root;
int ret;
+ int err = 0;
struct btrfs_trans_handle *trans;
unsigned long nr;
u64 mask = root->sectorsize - 1;
- if (!S_ISREG(inode->i_mode)) {
- WARN_ON(1);
- return;
- }
-
ret = btrfs_truncate_page(inode->i_mapping, inode->i_size);
if (ret)
- return;
+ return ret;
btrfs_wait_ordered_range(inode, inode->i_size & (~mask), (u64)-1);
btrfs_ordered_update_i_size(inode, inode->i_size, NULL);
+ trans = btrfs_start_transaction(root, 5);
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
+
+ btrfs_set_trans_block_group(trans, inode);
+
+ ret = btrfs_orphan_add(trans, inode);
+ if (ret) {
+ btrfs_end_transaction(trans, root);
+ return ret;
+ }
+
+ nr = trans->blocks_used;
+ btrfs_end_transaction(trans, root);
+ btrfs_btree_balance_dirty(root, nr);
+
+ /* Now start a transaction for the truncate */
trans = btrfs_start_transaction(root, 0);
- BUG_ON(IS_ERR(trans));
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
btrfs_set_trans_block_group(trans, inode);
trans->block_rsv = root->orphan_block_rsv;
@@ -6522,29 +6581,38 @@ static void btrfs_truncate(struct inode *inode)
while (1) {
if (!trans) {
trans = btrfs_start_transaction(root, 0);
- BUG_ON(IS_ERR(trans));
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
btrfs_set_trans_block_group(trans, inode);
trans->block_rsv = root->orphan_block_rsv;
}
ret = btrfs_block_rsv_check(trans, root,
root->orphan_block_rsv, 0, 5);
- if (ret) {
- BUG_ON(ret != -EAGAIN);
+ if (ret == -EAGAIN) {
ret = btrfs_commit_transaction(trans, root);
- BUG_ON(ret);
+ if (ret)
+ return ret;
trans = NULL;
continue;
+ } else if (ret) {
+ err = ret;
+ break;
}
ret = btrfs_truncate_inode_items(trans, root, inode,
inode->i_size,
BTRFS_EXTENT_DATA_KEY);
- if (ret != -EAGAIN)
+ if (ret != -EAGAIN) {
+ err = ret;
break;
+ }
ret = btrfs_update_inode(trans, root, inode);
- BUG_ON(ret);
+ if (ret) {
+ err = ret;
+ break;
+ }
nr = trans->blocks_used;
btrfs_end_transaction(trans, root);
@@ -6554,16 +6622,27 @@ static void btrfs_truncate(struct inode *inode)
if (ret == 0 && inode->i_nlink > 0) {
ret = btrfs_orphan_del(trans, inode);
- BUG_ON(ret);
+ if (ret)
+ err = ret;
+ } else if (ret && inode->i_nlink > 0) {
+ /*
+ * Failed to do the truncate, remove us from the in memory
+ * orphan list.
+ */
+ ret = btrfs_orphan_del(NULL, inode);
}
ret = btrfs_update_inode(trans, root, inode);
- BUG_ON(ret);
+ if (ret && !err)
+ err = ret;
nr = trans->blocks_used;
ret = btrfs_end_transaction_throttle(trans, root);
- BUG_ON(ret);
+ if (ret && !err)
+ err = ret;
btrfs_btree_balance_dirty(root, nr);
+
+ return err;
}
/*
@@ -6630,9 +6709,8 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
ei->index_cnt = (u64)-1;
ei->last_unlink_trans = 0;
- spin_lock_init(&ei->accounting_lock);
atomic_set(&ei->outstanding_extents, 0);
- ei->reserved_extents = 0;
+ atomic_set(&ei->reserved_extents, 0);
ei->ordered_data_close = 0;
ei->orphan_meta_reserved = 0;
@@ -6668,7 +6746,7 @@ void btrfs_destroy_inode(struct inode *inode)
WARN_ON(!list_empty(&inode->i_dentry));
WARN_ON(inode->i_data.nrpages);
WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents));
- WARN_ON(BTRFS_I(inode)->reserved_extents);
+ WARN_ON(atomic_read(&BTRFS_I(inode)->reserved_extents));
/*
* This can happen where we create an inode, but somebody else also
@@ -6760,6 +6838,8 @@ void btrfs_destroy_cachep(void)
kmem_cache_destroy(btrfs_transaction_cachep);
if (btrfs_path_cachep)
kmem_cache_destroy(btrfs_path_cachep);
+ if (btrfs_free_space_cachep)
+ kmem_cache_destroy(btrfs_free_space_cachep);
}
int btrfs_init_cachep(void)
@@ -6788,6 +6868,12 @@ int btrfs_init_cachep(void)
if (!btrfs_path_cachep)
goto fail;
+ btrfs_free_space_cachep = kmem_cache_create("btrfs_free_space_cache",
+ sizeof(struct btrfs_free_space), 0,
+ SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD, NULL);
+ if (!btrfs_free_space_cachep)
+ goto fail;
+
return 0;
fail:
btrfs_destroy_cachep();
@@ -6806,6 +6892,26 @@ static int btrfs_getattr(struct vfsmount *mnt,
return 0;
}
+/*
+ * If a file is moved, it will inherit the cow and compression flags of the new
+ * directory.
+ */
+static void fixup_inode_flags(struct inode *dir, struct inode *inode)
+{
+ struct btrfs_inode *b_dir = BTRFS_I(dir);
+ struct btrfs_inode *b_inode = BTRFS_I(inode);
+
+ if (b_dir->flags & BTRFS_INODE_NODATACOW)
+ b_inode->flags |= BTRFS_INODE_NODATACOW;
+ else
+ b_inode->flags &= ~BTRFS_INODE_NODATACOW;
+
+ if (b_dir->flags & BTRFS_INODE_COMPRESS)
+ b_inode->flags |= BTRFS_INODE_COMPRESS;
+ else
+ b_inode->flags &= ~BTRFS_INODE_COMPRESS;
+}
+
static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
struct inode *new_dir, struct dentry *new_dentry)
{
@@ -6908,11 +7014,12 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
old_dentry->d_name.name,
old_dentry->d_name.len);
} else {
- btrfs_inc_nlink(old_dentry->d_inode);
- ret = btrfs_unlink_inode(trans, root, old_dir,
- old_dentry->d_inode,
- old_dentry->d_name.name,
- old_dentry->d_name.len);
+ ret = __btrfs_unlink_inode(trans, root, old_dir,
+ old_dentry->d_inode,
+ old_dentry->d_name.name,
+ old_dentry->d_name.len);
+ if (!ret)
+ ret = btrfs_update_inode(trans, root, old_inode);
}
BUG_ON(ret);
@@ -6939,6 +7046,8 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
}
}
+ fixup_inode_flags(new_dir, old_inode);
+
ret = btrfs_add_link(trans, new_dir, old_inode,
new_dentry->d_name.name,
new_dentry->d_name.len, 0, index);
@@ -7355,7 +7464,6 @@ static const struct address_space_operations btrfs_symlink_aops = {
};
static const struct inode_operations btrfs_file_inode_operations = {
- .truncate = btrfs_truncate,
.getattr = btrfs_getattr,
.setattr = btrfs_setattr,
.setxattr = btrfs_setxattr,
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index d1bace3df9b..7c07fe26b7c 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -40,6 +40,7 @@
#include <linux/xattr.h>
#include <linux/vmalloc.h>
#include <linux/slab.h>
+#include <linux/blkdev.h>
#include "compat.h"
#include "ctree.h"
#include "disk-io.h"
@@ -138,6 +139,24 @@ static int btrfs_ioctl_getflags(struct file *file, void __user *arg)
return 0;
}
+static int check_flags(unsigned int flags)
+{
+ if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
+ FS_NOATIME_FL | FS_NODUMP_FL | \
+ FS_SYNC_FL | FS_DIRSYNC_FL | \
+ FS_NOCOMP_FL | FS_COMPR_FL | \
+ FS_NOCOW_FL | FS_COW_FL))
+ return -EOPNOTSUPP;
+
+ if ((flags & FS_NOCOMP_FL) && (flags & FS_COMPR_FL))
+ return -EINVAL;
+
+ if ((flags & FS_NOCOW_FL) && (flags & FS_COW_FL))
+ return -EINVAL;
+
+ return 0;
+}
+
static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
{
struct inode *inode = file->f_path.dentry->d_inode;
@@ -153,10 +172,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
if (copy_from_user(&flags, arg, sizeof(flags)))
return -EFAULT;
- if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
- FS_NOATIME_FL | FS_NODUMP_FL | \
- FS_SYNC_FL | FS_DIRSYNC_FL))
- return -EOPNOTSUPP;
+ ret = check_flags(flags);
+ if (ret)
+ return ret;
if (!inode_owner_or_capable(inode))
return -EACCES;
@@ -201,6 +219,22 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
else
ip->flags &= ~BTRFS_INODE_DIRSYNC;
+ /*
+ * The COMPRESS flag can only be changed by users, while the NOCOMPRESS
+ * flag may be changed automatically if compression code won't make
+ * things smaller.
+ */
+ if (flags & FS_NOCOMP_FL) {
+ ip->flags &= ~BTRFS_INODE_COMPRESS;
+ ip->flags |= BTRFS_INODE_NOCOMPRESS;
+ } else if (flags & FS_COMPR_FL) {
+ ip->flags |= BTRFS_INODE_COMPRESS;
+ ip->flags &= ~BTRFS_INODE_NOCOMPRESS;
+ }
+ if (flags & FS_NOCOW_FL)
+ ip->flags |= BTRFS_INODE_NODATACOW;
+ else if (flags & FS_COW_FL)
+ ip->flags &= ~BTRFS_INODE_NODATACOW;
trans = btrfs_join_transaction(root, 1);
BUG_ON(IS_ERR(trans));
@@ -213,9 +247,11 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
btrfs_end_transaction(trans, root);
mnt_drop_write(file->f_path.mnt);
+
+ ret = 0;
out_unlock:
mutex_unlock(&inode->i_mutex);
- return 0;
+ return ret;
}
static int btrfs_ioctl_getversion(struct file *file, int __user *arg)
@@ -225,6 +261,49 @@ static int btrfs_ioctl_getversion(struct file *file, int __user *arg)
return put_user(inode->i_generation, arg);
}
+static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
+{
+ struct btrfs_root *root = fdentry(file)->d_sb->s_fs_info;
+ struct btrfs_fs_info *fs_info = root->fs_info;
+ struct btrfs_device *device;
+ struct request_queue *q;
+ struct fstrim_range range;
+ u64 minlen = ULLONG_MAX;
+ u64 num_devices = 0;
+ int ret;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ mutex_lock(&fs_info->fs_devices->device_list_mutex);
+ list_for_each_entry(device, &fs_info->fs_devices->devices, dev_list) {
+ if (!device->bdev)
+ continue;
+ q = bdev_get_queue(device->bdev);
+ if (blk_queue_discard(q)) {
+ num_devices++;
+ minlen = min((u64)q->limits.discard_granularity,
+ minlen);
+ }
+ }
+ mutex_unlock(&fs_info->fs_devices->device_list_mutex);
+ if (!num_devices)
+ return -EOPNOTSUPP;
+
+ if (copy_from_user(&range, arg, sizeof(range)))
+ return -EFAULT;
+
+ range.minlen = max(range.minlen, minlen);
+ ret = btrfs_trim_fs(root, &range);
+ if (ret < 0)
+ return ret;
+
+ if (copy_to_user(arg, &range, sizeof(range)))
+ return -EFAULT;
+
+ return 0;
+}
+
static noinline int create_subvol(struct btrfs_root *root,
struct dentry *dentry,
char *name, int namelen,
@@ -409,7 +488,9 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
if (ret)
goto fail;
- btrfs_orphan_cleanup(pending_snapshot->snap);
+ ret = btrfs_orphan_cleanup(pending_snapshot->snap);
+ if (ret)
+ goto fail;
parent = dget_parent(dentry);
inode = btrfs_lookup_dentry(parent->d_inode, dentry);
@@ -2348,12 +2429,15 @@ static noinline long btrfs_ioctl_start_sync(struct file *file, void __user *argp
struct btrfs_root *root = BTRFS_I(file->f_dentry->d_inode)->root;
struct btrfs_trans_handle *trans;
u64 transid;
+ int ret;
trans = btrfs_start_transaction(root, 0);
if (IS_ERR(trans))
return PTR_ERR(trans);
transid = trans->transid;
- btrfs_commit_transaction_async(trans, root, 0);
+ ret = btrfs_commit_transaction_async(trans, root, 0);
+ if (ret)
+ return ret;
if (argp)
if (copy_to_user(argp, &transid, sizeof(transid)))
@@ -2388,6 +2472,8 @@ long btrfs_ioctl(struct file *file, unsigned int
return btrfs_ioctl_setflags(file, argp);
case FS_IOC_GETVERSION:
return btrfs_ioctl_getversion(file, argp);
+ case FITRIM:
+ return btrfs_ioctl_fitrim(file, argp);
case BTRFS_IOC_SNAP_CREATE:
return btrfs_ioctl_snap_create(file, argp, 0);
case BTRFS_IOC_SNAP_CREATE_V2:
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index 083a5547737..a1c94042530 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -202,6 +202,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
INIT_LIST_HEAD(&entry->list);
INIT_LIST_HEAD(&entry->root_extent_list);
+ trace_btrfs_ordered_extent_add(inode, entry);
+
spin_lock(&tree->lock);
node = tree_insert(&tree->tree, file_offset,
&entry->rb_node);
@@ -387,6 +389,8 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
struct list_head *cur;
struct btrfs_ordered_sum *sum;
+ trace_btrfs_ordered_extent_put(entry->inode, entry);
+
if (atomic_dec_and_test(&entry->refs)) {
while (!list_empty(&entry->list)) {
cur = entry->list.next;
@@ -420,6 +424,8 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
spin_lock(&root->fs_info->ordered_extent_lock);
list_del_init(&entry->root_extent_list);
+ trace_btrfs_ordered_extent_remove(inode, entry);
+
/*
* we have no more ordered extents for this inode and
* no dirty pages. We can safely remove it from the
@@ -585,6 +591,8 @@ void btrfs_start_ordered_extent(struct inode *inode,
u64 start = entry->file_offset;
u64 end = start + entry->len - 1;
+ trace_btrfs_ordered_extent_start(inode, entry);
+
/*
* pages in the range can be dirty, clean or writeback. We
* start IO on any dirty ones so the wait doesn't stall waiting
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
index 31ade5802ae..58250e09eb0 100644
--- a/fs/btrfs/relocation.c
+++ b/fs/btrfs/relocation.c
@@ -1724,6 +1724,7 @@ again:
eb = read_tree_block(dest, old_bytenr, blocksize,
old_ptr_gen);
+ BUG_ON(!eb);
btrfs_tree_lock(eb);
if (cow) {
ret = btrfs_cow_block(trans, dest, eb, parent,
@@ -2513,6 +2514,10 @@ static int do_relocation(struct btrfs_trans_handle *trans,
blocksize = btrfs_level_size(root, node->level);
generation = btrfs_node_ptr_generation(upper->eb, slot);
eb = read_tree_block(root, bytenr, blocksize, generation);
+ if (!eb) {
+ err = -EIO;
+ goto next;
+ }
btrfs_tree_lock(eb);
btrfs_set_lock_blocking(eb);
@@ -2670,6 +2675,7 @@ static int get_tree_block_key(struct reloc_control *rc,
BUG_ON(block->key_ready);
eb = read_tree_block(rc->extent_root, block->bytenr,
block->key.objectid, block->key.offset);
+ BUG_ON(!eb);
WARN_ON(btrfs_header_level(eb) != block->level);
if (block->level == 0)
btrfs_item_key_to_cpu(eb, &block->key, 0);
@@ -4209,7 +4215,7 @@ out:
if (IS_ERR(fs_root))
err = PTR_ERR(fs_root);
else
- btrfs_orphan_cleanup(fs_root);
+ err = btrfs_orphan_cleanup(fs_root);
}
return err;
}
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index 6a1086e83ff..29b2d7c930e 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -88,7 +88,8 @@ int btrfs_find_last_root(struct btrfs_root *root, u64 objectid,
search_key.offset = (u64)-1;
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
ret = btrfs_search_slot(NULL, root, &search_key, path, 0, 0);
if (ret < 0)
goto out;
@@ -332,7 +333,8 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct extent_buffer *leaf;
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
ret = btrfs_search_slot(trans, root, key, path, -1, 1);
if (ret < 0)
goto out;
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index d39a9895d93..2edfc039f09 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -52,6 +52,9 @@
#include "export.h"
#include "compression.h"
+#define CREATE_TRACE_POINTS
+#include <trace/events/btrfs.h>
+
static const struct super_operations btrfs_super_ops;
static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno,
@@ -620,6 +623,8 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
struct btrfs_root *root = btrfs_sb(sb);
int ret;
+ trace_btrfs_sync_fs(wait);
+
if (!wait) {
filemap_flush(root->fs_info->btree_inode->i_mapping);
return 0;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 3d73c8d93bb..ce48eb59d61 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -57,7 +57,8 @@ static noinline int join_transaction(struct btrfs_root *root)
if (!cur_trans) {
cur_trans = kmem_cache_alloc(btrfs_transaction_cachep,
GFP_NOFS);
- BUG_ON(!cur_trans);
+ if (!cur_trans)
+ return -ENOMEM;
root->fs_info->generation++;
cur_trans->num_writers = 1;
cur_trans->num_joined = 0;
@@ -195,7 +196,11 @@ again:
wait_current_trans(root);
ret = join_transaction(root);
- BUG_ON(ret);
+ if (ret < 0) {
+ if (type != TRANS_JOIN_NOLOCK)
+ mutex_unlock(&root->fs_info->trans_mutex);
+ return ERR_PTR(ret);
+ }
cur_trans = root->fs_info->running_transaction;
cur_trans->use_count++;
@@ -1156,7 +1161,8 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
struct btrfs_transaction *cur_trans;
ac = kmalloc(sizeof(*ac), GFP_NOFS);
- BUG_ON(!ac);
+ if (!ac)
+ return -ENOMEM;
INIT_DELAYED_WORK(&ac->work, do_async_commit);
ac->root = root;
@@ -1389,6 +1395,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
put_transaction(cur_trans);
put_transaction(cur_trans);
+ trace_btrfs_transaction_commit(root);
+
mutex_unlock(&root->fs_info->trans_mutex);
if (current->journal_info == trans)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index a4bbb854dfd..c50271ad315 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -799,12 +799,12 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
struct inode *dir;
int ret;
struct btrfs_inode_ref *ref;
- struct btrfs_dir_item *di;
struct inode *inode;
char *name;
int namelen;
unsigned long ref_ptr;
unsigned long ref_end;
+ int search_done = 0;
/*
* it is possible that we didn't log all the parent directories
@@ -845,7 +845,10 @@ again:
* existing back reference, and we don't want to create
* dangling pointers in the directory.
*/
-conflict_again:
+
+ if (search_done)
+ goto insert;
+
ret = btrfs_search_slot(NULL, root, key, path, 0, 0);
if (ret == 0) {
char *victim_name;
@@ -886,37 +889,21 @@ conflict_again:
ret = btrfs_unlink_inode(trans, root, dir,
inode, victim_name,
victim_name_len);
- kfree(victim_name);
- btrfs_release_path(root, path);
- goto conflict_again;
}
kfree(victim_name);
ptr = (unsigned long)(victim_ref + 1) + victim_name_len;
}
BUG_ON(ret);
- }
- btrfs_release_path(root, path);
-
- /* look for a conflicting sequence number */
- di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino,
- btrfs_inode_ref_index(eb, ref),
- name, namelen, 0);
- if (di && !IS_ERR(di)) {
- ret = drop_one_dir_item(trans, root, path, dir, di);
- BUG_ON(ret);
- }
- btrfs_release_path(root, path);
-
- /* look for a conflicting name */
- di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino,
- name, namelen, 0);
- if (di && !IS_ERR(di)) {
- ret = drop_one_dir_item(trans, root, path, dir, di);
- BUG_ON(ret);
+ /*
+ * NOTE: we have searched root tree and checked the
+ * coresponding ref, it does not need to check again.
+ */
+ search_done = 1;
}
btrfs_release_path(root, path);
+insert:
/* insert our name */
ret = btrfs_add_link(trans, dir, inode, name, namelen, 0,
btrfs_inode_ref_index(eb, ref));
@@ -1286,6 +1273,8 @@ static noinline int replay_one_dir_item(struct btrfs_trans_handle *trans,
ptr_end = ptr + item_size;
while (ptr < ptr_end) {
di = (struct btrfs_dir_item *)ptr;
+ if (verify_dir_item(root, eb, di))
+ return -EIO;
name_len = btrfs_dir_name_len(eb, di);
ret = replay_one_name(trans, root, path, eb, di, key);
BUG_ON(ret);
@@ -1412,6 +1401,11 @@ again:
ptr_end = ptr + item_size;
while (ptr < ptr_end) {
di = (struct btrfs_dir_item *)ptr;
+ if (verify_dir_item(root, eb, di)) {
+ ret = -EIO;
+ goto out;
+ }
+
name_len = btrfs_dir_name_len(eb, di);
name = kmalloc(name_len, GFP_NOFS);
if (!name) {
@@ -1821,7 +1815,8 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
int orig_level;
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
level = btrfs_header_level(log->node);
orig_level = level;
@@ -3107,9 +3102,11 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
.stage = 0,
};
- fs_info->log_root_recovering = 1;
path = btrfs_alloc_path();
- BUG_ON(!path);
+ if (!path)
+ return -ENOMEM;
+
+ fs_info->log_root_recovering = 1;
trans = btrfs_start_transaction(fs_info->tree_root, 0);
BUG_ON(IS_ERR(trans));
@@ -3117,7 +3114,8 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
wc.trans = trans;
wc.pin = 1;
- walk_log_tree(trans, log_root_tree, &wc);
+ ret = walk_log_tree(trans, log_root_tree, &wc);
+ BUG_ON(ret);
again:
key.objectid = BTRFS_TREE_LOG_OBJECTID;
@@ -3141,8 +3139,7 @@ again:
log = btrfs_read_fs_root_no_radix(log_root_tree,
&found_key);
- BUG_ON(!log);
-
+ BUG_ON(IS_ERR(log));
tmp_key.objectid = found_key.offset;
tmp_key.type = BTRFS_ROOT_ITEM_KEY;
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 9d554e8e658..309a57b9fc8 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -33,17 +33,6 @@
#include "volumes.h"
#include "async-thread.h"
-struct map_lookup {
- u64 type;
- int io_align;
- int io_width;
- int stripe_len;
- int sector_size;
- int num_stripes;
- int sub_stripes;
- struct btrfs_bio_stripe stripes[];
-};
-
static int init_first_rw_device(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct btrfs_device *device);
@@ -1879,6 +1868,8 @@ static int btrfs_relocate_chunk(struct btrfs_root *root,
BUG_ON(ret);
+ trace_btrfs_chunk_free(root, map, chunk_offset, em->len);
+
if (map->type & BTRFS_BLOCK_GROUP_SYSTEM) {
ret = btrfs_del_sys_chunk(root, chunk_objectid, chunk_offset);
BUG_ON(ret);
@@ -2606,6 +2597,8 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
*num_bytes = chunk_bytes_by_type(type, calc_size,
map->num_stripes, sub_stripes);
+ trace_btrfs_chunk_alloc(info->chunk_root, map, start, *num_bytes);
+
em = alloc_extent_map(GFP_NOFS);
if (!em) {
ret = -ENOMEM;
@@ -2714,6 +2707,7 @@ static int __finish_chunk_alloc(struct btrfs_trans_handle *trans,
item_size);
BUG_ON(ret);
}
+
kfree(chunk);
return 0;
}
@@ -2918,7 +2912,10 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
struct extent_map_tree *em_tree = &map_tree->map_tree;
u64 offset;
u64 stripe_offset;
+ u64 stripe_end_offset;
u64 stripe_nr;
+ u64 stripe_nr_orig;
+ u64 stripe_nr_end;
int stripes_allocated = 8;
int stripes_required = 1;
int stripe_index;
@@ -2927,7 +2924,7 @@ static int __btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw,
int max_errors = 0;
struct btrfs_multi_bio *multi = NULL;
- if (multi_ret && !(rw & REQ_WRITE))
+ if (multi_ret && !(rw & (REQ_WRITE | REQ_DISCARD)))
stripes_allocated = 1;
again:
if (multi_ret) {
@@ -2968,7 +2965,15 @@ again:
max_errors = 1;
}
}
- if (multi_ret && (rw & REQ_WRITE) &&
+ if (rw & REQ_DISCARD) {
+ if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
+ BTRFS_BLOCK_GROUP_RAID1 |
+ BTRFS_BLOCK_GROUP_DUP |
+ BTRFS_BLOCK_GROUP_RAID10)) {
+ stripes_required = map->num_stripes;
+ }
+ }
+ if (multi_ret && (rw & (REQ_WRITE | REQ_DISCARD)) &&
stripes_allocated < stripes_required) {
stripes_allocated = map->num_stripes;
free_extent_map(em);
@@ -2988,12 +2993,15 @@ again:
/* stripe_offset is the offset of this block in its stripe*/
stripe_offset = offset - stripe_offset;
- if (map->type & (BTRFS_BLOCK_GROUP_RAID0 | BTRFS_BLOCK_GROUP_RAID1 |
- BTRFS_BLOCK_GROUP_RAID10 |
- BTRFS_BLOCK_GROUP_DUP)) {
+ if (rw & REQ_DISCARD)
+ *length = min_t(u64, em->len - offset, *length);
+ else if (map->type & (BTRFS_BLOCK_GROUP_RAID0 |
+ BTRFS_BLOCK_GROUP_RAID1 |
+ BTRFS_BLOCK_GROUP_RAID10 |
+ BTRFS_BLOCK_GROUP_DUP)) {
/* we limit the length of each bio to what fits in a stripe */
*length = min_t(u64, em->len - offset,
- map->stripe_len - stripe_offset);
+ map->stripe_len - stripe_offset);
} else {
*length = em->len - offset;
}
@@ -3003,8 +3011,19 @@ again:
num_stripes = 1;
stripe_index = 0;
- if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
- if (rw & REQ_WRITE)
+ stripe_nr_orig = stripe_nr;
+ stripe_nr_end = (offset + *length + map->stripe_len - 1) &
+ (~(map->stripe_len - 1));
+ do_div(stripe_nr_end, map->stripe_len);
+ stripe_end_offset = stripe_nr_end * map->stripe_len -
+ (offset + *length);
+ if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
+ if (rw & REQ_DISCARD)
+ num_stripes = min_t(u64, map->num_stripes,
+ stripe_nr_end - stripe_nr_orig);
+ stripe_index = do_div(stripe_nr, map->num_stripes);
+ } else if (map->type & BTRFS_BLOCK_GROUP_RAID1) {
+ if (rw & (REQ_WRITE | REQ_DISCARD))
num_stripes = map->num_stripes;
else if (mirror_num)
stripe_index = mirror_num - 1;
@@ -3015,7 +3034,7 @@ again:
}
} else if (map->type & BTRFS_BLOCK_GROUP_DUP) {
- if (rw & REQ_WRITE)
+ if (rw & (REQ_WRITE | REQ_DISCARD))
num_stripes = map->num_stripes;
else if (mirror_num)
stripe_index = mirror_num - 1;
@@ -3028,6 +3047,10 @@ again:
if (rw & REQ_WRITE)
num_stripes = map->sub_stripes;
+ else if (rw & REQ_DISCARD)
+ num_stripes = min_t(u64, map->sub_stripes *
+ (stripe_nr_end - stripe_nr_orig),
+ map->num_stripes);
else if (mirror_num)
stripe_index += mirror_num - 1;
else {
@@ -3045,12 +3068,101 @@ again:
}
BUG_ON(stripe_index >= map->num_stripes);
- for (i = 0; i < num_stripes; i++) {
- multi->stripes[i].physical =
- map->stripes[stripe_index].physical +
- stripe_offset + stripe_nr * map->stripe_len;
- multi->stripes[i].dev = map->stripes[stripe_index].dev;
- stripe_index++;
+ if (rw & REQ_DISCARD) {
+ for (i = 0; i < num_stripes; i++) {
+ multi->stripes[i].physical =
+ map->stripes[stripe_index].physical +
+ stripe_offset + stripe_nr * map->stripe_len;
+ multi->stripes[i].dev = map->stripes[stripe_index].dev;
+
+ if (map->type & BTRFS_BLOCK_GROUP_RAID0) {
+ u64 stripes;
+ u32 last_stripe = 0;
+ int j;
+
+ div_u64_rem(stripe_nr_end - 1,
+ map->num_stripes,
+ &last_stripe);
+
+ for (j = 0; j < map->num_stripes; j++) {
+ u32 test;
+
+ div_u64_rem(stripe_nr_end - 1 - j,
+ map->num_stripes, &test);
+ if (test == stripe_index)
+ break;
+ }
+ stripes = stripe_nr_end - 1 - j;
+ do_div(stripes, map->num_stripes);
+ multi->stripes[i].length = map->stripe_len *
+ (stripes - stripe_nr + 1);
+
+ if (i == 0) {
+ multi->stripes[i].length -=
+ stripe_offset;
+ stripe_offset = 0;
+ }
+ if (stripe_index == last_stripe)
+ multi->stripes[i].length -=
+ stripe_end_offset;
+ } else if (map->type & BTRFS_BLOCK_GROUP_RAID10) {
+ u64 stripes;
+ int j;
+ int factor = map->num_stripes /
+ map->sub_stripes;
+ u32 last_stripe = 0;
+
+ div_u64_rem(stripe_nr_end - 1,
+ factor, &last_stripe);
+ last_stripe *= map->sub_stripes;
+
+ for (j = 0; j < factor; j++) {
+ u32 test;
+
+ div_u64_rem(stripe_nr_end - 1 - j,
+ factor, &test);
+
+ if (test ==
+ stripe_index / map->sub_stripes)
+ break;
+ }
+ stripes = stripe_nr_end - 1 - j;
+ do_div(stripes, factor);
+ multi->stripes[i].length = map->stripe_len *
+ (stripes - stripe_nr + 1);
+
+ if (i < map->sub_stripes) {
+ multi->stripes[i].length -=
+ stripe_offset;
+ if (i == map->sub_stripes - 1)
+ stripe_offset = 0;
+ }
+ if (stripe_index >= last_stripe &&
+ stripe_index <= (last_stripe +
+ map->sub_stripes - 1)) {
+ multi->stripes[i].length -=
+ stripe_end_offset;
+ }
+ } else
+ multi->stripes[i].length = *length;
+
+ stripe_index++;
+ if (stripe_index == map->num_stripes) {
+ /* This could only happen for RAID0/10 */
+ stripe_index = 0;
+ stripe_nr++;
+ }
+ }
+ } else {
+ for (i = 0; i < num_stripes; i++) {
+ multi->stripes[i].physical =
+ map->stripes[stripe_index].physical +
+ stripe_offset +
+ stripe_nr * map->stripe_len;
+ multi->stripes[i].dev =
+ map->stripes[stripe_index].dev;
+ stripe_index++;
+ }
}
if (multi_ret) {
*multi_ret = multi;
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h
index 7fb59d45fe8..cc2eadaf7a2 100644
--- a/fs/btrfs/volumes.h
+++ b/fs/btrfs/volumes.h
@@ -126,6 +126,7 @@ struct btrfs_fs_devices {
struct btrfs_bio_stripe {
struct btrfs_device *dev;
u64 physical;
+ u64 length; /* only used for discard mappings */
};
struct btrfs_multi_bio {
@@ -145,6 +146,17 @@ struct btrfs_device_info {
u64 max_avail;
};
+struct map_lookup {
+ u64 type;
+ int io_align;
+ int io_width;
+ int stripe_len;
+ int sector_size;
+ int num_stripes;
+ int sub_stripes;
+ struct btrfs_bio_stripe stripes[];
+};
+
/* Used to sort the devices by max_avail(descending sort) */
int btrfs_cmp_device_free_bytes(const void *dev_info1, const void *dev_info2);
diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
index d779cefcfd7..a5303b871b1 100644
--- a/fs/btrfs/xattr.c
+++ b/fs/btrfs/xattr.c
@@ -242,6 +242,8 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
break;
di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
+ if (verify_dir_item(root, leaf, di))
+ continue;
name_len = btrfs_dir_name_len(leaf, di);
total_size += name_len + 1;
diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c
index 561438b6a50..37368ba2e67 100644
--- a/fs/ceph/addr.c
+++ b/fs/ceph/addr.c
@@ -92,7 +92,7 @@ static int ceph_set_page_dirty(struct page *page)
ci->i_head_snapc = ceph_get_snap_context(snapc);
++ci->i_wrbuffer_ref_head;
if (ci->i_wrbuffer_ref == 0)
- igrab(inode);
+ ihold(inode);
++ci->i_wrbuffer_ref;
dout("%p set_page_dirty %p idx %lu head %d/%d -> %d/%d "
"snapc %p seq %lld (%d snaps)\n",
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index a1ee8fa3a8e..f60b07b0feb 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -3215,9 +3215,15 @@ void ceph_mdsc_destroy(struct ceph_fs_client *fsc)
{
struct ceph_mds_client *mdsc = fsc->mdsc;
+ dout("mdsc_destroy %p\n", mdsc);
ceph_mdsc_stop(mdsc);
+
+ /* flush out any connection work with references to us */
+ ceph_msgr_flush();
+
fsc->mdsc = NULL;
kfree(mdsc);
+ dout("mdsc_destroy %p done\n", mdsc);
}
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index f40b9139e43..0aee66b92af 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -463,8 +463,8 @@ void ceph_queue_cap_snap(struct ceph_inode_info *ci)
dout("queue_cap_snap %p cap_snap %p queuing under %p\n", inode,
capsnap, snapc);
- igrab(inode);
-
+ ihold(inode);
+
atomic_set(&capsnap->nref, 1);
capsnap->ci = ci;
INIT_LIST_HEAD(&capsnap->ci_item);
diff --git a/fs/ceph/super.c b/fs/ceph/super.c
index a9e78b4a258..f2f77fd3c14 100644
--- a/fs/ceph/super.c
+++ b/fs/ceph/super.c
@@ -353,7 +353,7 @@ static int ceph_show_options(struct seq_file *m, struct vfsmount *mnt)
if (opt->name)
seq_printf(m, ",name=%s", opt->name);
- if (opt->secret)
+ if (opt->key)
seq_puts(m, ",secret=<hidden>");
if (opt->mount_timeout != CEPH_MOUNT_TIMEOUT_DEFAULT)
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index bfd8b680e64..d2a70a4561f 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -266,7 +266,6 @@ void ecryptfs_destroy_mount_crypt_stat(
&mount_crypt_stat->global_auth_tok_list,
mount_crypt_stat_list) {
list_del(&auth_tok->mount_crypt_stat_list);
- mount_crypt_stat->num_global_auth_toks--;
if (auth_tok->global_auth_tok_key
&& !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID))
key_put(auth_tok->global_auth_tok_key);
@@ -1389,6 +1388,7 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
rc = -ENOMEM;
goto out;
}
+ /* Zeroed page ensures the in-header unencrypted i_size is set to 0 */
rc = ecryptfs_write_headers_virt(virt, virt_len, &size, crypt_stat,
ecryptfs_dentry);
if (unlikely(rc)) {
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index e00753496e3..bd3cafd0949 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -233,7 +233,7 @@ ecryptfs_get_key_payload_data(struct key *key)
struct ecryptfs_key_sig {
struct list_head crypt_stat_list;
- char keysig[ECRYPTFS_SIG_SIZE_HEX];
+ char keysig[ECRYPTFS_SIG_SIZE_HEX + 1];
};
struct ecryptfs_filename {
@@ -257,19 +257,18 @@ struct ecryptfs_filename {
struct ecryptfs_crypt_stat {
#define ECRYPTFS_STRUCT_INITIALIZED 0x00000001
#define ECRYPTFS_POLICY_APPLIED 0x00000002
-#define ECRYPTFS_NEW_FILE 0x00000004
-#define ECRYPTFS_ENCRYPTED 0x00000008
-#define ECRYPTFS_SECURITY_WARNING 0x00000010
-#define ECRYPTFS_ENABLE_HMAC 0x00000020
-#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000040
-#define ECRYPTFS_KEY_VALID 0x00000080
-#define ECRYPTFS_METADATA_IN_XATTR 0x00000100
-#define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200
-#define ECRYPTFS_KEY_SET 0x00000400
-#define ECRYPTFS_ENCRYPT_FILENAMES 0x00000800
-#define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00001000
-#define ECRYPTFS_ENCFN_USE_FEK 0x00002000
-#define ECRYPTFS_UNLINK_SIGS 0x00004000
+#define ECRYPTFS_ENCRYPTED 0x00000004
+#define ECRYPTFS_SECURITY_WARNING 0x00000008
+#define ECRYPTFS_ENABLE_HMAC 0x00000010
+#define ECRYPTFS_ENCRYPT_IV_PAGES 0x00000020
+#define ECRYPTFS_KEY_VALID 0x00000040
+#define ECRYPTFS_METADATA_IN_XATTR 0x00000080
+#define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000100
+#define ECRYPTFS_KEY_SET 0x00000200
+#define ECRYPTFS_ENCRYPT_FILENAMES 0x00000400
+#define ECRYPTFS_ENCFN_USE_MOUNT_FNEK 0x00000800
+#define ECRYPTFS_ENCFN_USE_FEK 0x00001000
+#define ECRYPTFS_UNLINK_SIGS 0x00002000
u32 flags;
unsigned int file_version;
size_t iv_bytes;
@@ -297,7 +296,6 @@ struct ecryptfs_inode_info {
struct inode vfs_inode;
struct inode *wii_inode;
struct file *lower_file;
- struct mutex lower_file_mutex;
struct ecryptfs_crypt_stat crypt_stat;
};
@@ -333,7 +331,6 @@ struct ecryptfs_global_auth_tok {
u32 flags;
struct list_head mount_crypt_stat_list;
struct key *global_auth_tok_key;
- struct ecryptfs_auth_tok *global_auth_tok;
unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
};
@@ -380,7 +377,6 @@ struct ecryptfs_mount_crypt_stat {
u32 flags;
struct list_head global_auth_tok_list;
struct mutex global_auth_tok_list_mutex;
- size_t num_global_auth_toks;
size_t global_default_cipher_key_size;
size_t global_default_fn_cipher_key_bytes;
unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 7d1050e254f..cedc913d11b 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -273,7 +273,14 @@ static int ecryptfs_release(struct inode *inode, struct file *file)
static int
ecryptfs_fsync(struct file *file, int datasync)
{
- return vfs_fsync(ecryptfs_file_to_lower(file), datasync);
+ int rc = 0;
+
+ rc = generic_file_fsync(file, datasync);
+ if (rc)
+ goto out;
+ rc = vfs_fsync(ecryptfs_file_to_lower(file), datasync);
+out:
+ return rc;
}
static int ecryptfs_fasync(int fd, struct file *file, int flag)
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index b592938a84b..f99051b7ada 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -143,26 +143,6 @@ out:
}
/**
- * grow_file
- * @ecryptfs_dentry: the eCryptfs dentry
- *
- * This is the code which will grow the file to its correct size.
- */
-static int grow_file(struct dentry *ecryptfs_dentry)
-{
- struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
- char zero_virt[] = { 0x00 };
- int rc = 0;
-
- rc = ecryptfs_write(ecryptfs_inode, zero_virt, 0, 1);
- i_size_write(ecryptfs_inode, 0);
- rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
- ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |=
- ECRYPTFS_NEW_FILE;
- return rc;
-}
-
-/**
* ecryptfs_initialize_file
*
* Cause the file to be changed from a basic empty file to an ecryptfs
@@ -181,7 +161,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
goto out;
}
- crypt_stat->flags |= ECRYPTFS_NEW_FILE;
ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
rc = ecryptfs_new_file_context(ecryptfs_dentry);
if (rc) {
@@ -202,9 +181,6 @@ static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
goto out;
}
- rc = grow_file(ecryptfs_dentry);
- if (rc)
- printk(KERN_ERR "Error growing file; rc = [%d]\n", rc);
out:
return rc;
}
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index c1436cff6f2..03e609c4501 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -65,6 +65,24 @@ static int process_request_key_err(long err_code)
return rc;
}
+static int process_find_global_auth_tok_for_sig_err(int err_code)
+{
+ int rc = err_code;
+
+ switch (err_code) {
+ case -ENOENT:
+ ecryptfs_printk(KERN_WARNING, "Missing auth tok\n");
+ break;
+ case -EINVAL:
+ ecryptfs_printk(KERN_WARNING, "Invalid auth tok\n");
+ break;
+ default:
+ rc = process_request_key_err(err_code);
+ break;
+ }
+ return rc;
+}
+
/**
* ecryptfs_parse_packet_length
* @data: Pointer to memory containing length at offset
@@ -403,27 +421,120 @@ out:
return rc;
}
+/**
+ * ecryptfs_verify_version
+ * @version: The version number to confirm
+ *
+ * Returns zero on good version; non-zero otherwise
+ */
+static int ecryptfs_verify_version(u16 version)
+{
+ int rc = 0;
+ unsigned char major;
+ unsigned char minor;
+
+ major = ((version >> 8) & 0xFF);
+ minor = (version & 0xFF);
+ if (major != ECRYPTFS_VERSION_MAJOR) {
+ ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
+ "Expected [%d]; got [%d]\n",
+ ECRYPTFS_VERSION_MAJOR, major);
+ rc = -EINVAL;
+ goto out;
+ }
+ if (minor != ECRYPTFS_VERSION_MINOR) {
+ ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
+ "Expected [%d]; got [%d]\n",
+ ECRYPTFS_VERSION_MINOR, minor);
+ rc = -EINVAL;
+ goto out;
+ }
+out:
+ return rc;
+}
+
+/**
+ * ecryptfs_verify_auth_tok_from_key
+ * @auth_tok_key: key containing the authentication token
+ * @auth_tok: authentication token
+ *
+ * Returns zero on valid auth tok; -EINVAL otherwise
+ */
+static int
+ecryptfs_verify_auth_tok_from_key(struct key *auth_tok_key,
+ struct ecryptfs_auth_tok **auth_tok)
+{
+ int rc = 0;
+
+ (*auth_tok) = ecryptfs_get_key_payload_data(auth_tok_key);
+ if (ecryptfs_verify_version((*auth_tok)->version)) {
+ printk(KERN_ERR "Data structure version mismatch. Userspace "
+ "tools must match eCryptfs kernel module with major "
+ "version [%d] and minor version [%d]\n",
+ ECRYPTFS_VERSION_MAJOR, ECRYPTFS_VERSION_MINOR);
+ rc = -EINVAL;
+ goto out;
+ }
+ if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD
+ && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) {
+ printk(KERN_ERR "Invalid auth_tok structure "
+ "returned from key query\n");
+ rc = -EINVAL;
+ goto out;
+ }
+out:
+ return rc;
+}
+
static int
ecryptfs_find_global_auth_tok_for_sig(
- struct ecryptfs_global_auth_tok **global_auth_tok,
+ struct key **auth_tok_key,
+ struct ecryptfs_auth_tok **auth_tok,
struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig)
{
struct ecryptfs_global_auth_tok *walker;
int rc = 0;
- (*global_auth_tok) = NULL;
+ (*auth_tok_key) = NULL;
+ (*auth_tok) = NULL;
mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
list_for_each_entry(walker,
&mount_crypt_stat->global_auth_tok_list,
mount_crypt_stat_list) {
- if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) {
- rc = key_validate(walker->global_auth_tok_key);
- if (!rc)
- (*global_auth_tok) = walker;
+ if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX))
+ continue;
+
+ if (walker->flags & ECRYPTFS_AUTH_TOK_INVALID) {
+ rc = -EINVAL;
goto out;
}
+
+ rc = key_validate(walker->global_auth_tok_key);
+ if (rc) {
+ if (rc == -EKEYEXPIRED)
+ goto out;
+ goto out_invalid_auth_tok;
+ }
+
+ down_write(&(walker->global_auth_tok_key->sem));
+ rc = ecryptfs_verify_auth_tok_from_key(
+ walker->global_auth_tok_key, auth_tok);
+ if (rc)
+ goto out_invalid_auth_tok_unlock;
+
+ (*auth_tok_key) = walker->global_auth_tok_key;
+ key_get(*auth_tok_key);
+ goto out;
}
- rc = -EINVAL;
+ rc = -ENOENT;
+ goto out;
+out_invalid_auth_tok_unlock:
+ up_write(&(walker->global_auth_tok_key->sem));
+out_invalid_auth_tok:
+ printk(KERN_WARNING "Invalidating auth tok with sig = [%s]\n", sig);
+ walker->flags |= ECRYPTFS_AUTH_TOK_INVALID;
+ key_put(walker->global_auth_tok_key);
+ walker->global_auth_tok_key = NULL;
out:
mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
return rc;
@@ -451,14 +562,11 @@ ecryptfs_find_auth_tok_for_sig(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
char *sig)
{
- struct ecryptfs_global_auth_tok *global_auth_tok;
int rc = 0;
- (*auth_tok_key) = NULL;
- (*auth_tok) = NULL;
- if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
- mount_crypt_stat, sig)) {
-
+ rc = ecryptfs_find_global_auth_tok_for_sig(auth_tok_key, auth_tok,
+ mount_crypt_stat, sig);
+ if (rc == -ENOENT) {
/* if the flag ECRYPTFS_GLOBAL_MOUNT_AUTH_TOK_ONLY is set in the
* mount_crypt_stat structure, we prevent to use auth toks that
* are not inserted through the ecryptfs_add_global_auth_tok
@@ -470,8 +578,7 @@ ecryptfs_find_auth_tok_for_sig(
rc = ecryptfs_keyring_auth_tok_for_sig(auth_tok_key, auth_tok,
sig);
- } else
- (*auth_tok) = global_auth_tok->global_auth_tok;
+ }
return rc;
}
@@ -531,6 +638,16 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
}
s->desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
(*packet_size) = 0;
+ rc = ecryptfs_find_auth_tok_for_sig(
+ &auth_tok_key,
+ &s->auth_tok, mount_crypt_stat,
+ mount_crypt_stat->global_default_fnek_sig);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to find auth tok for "
+ "fnek sig [%s]; rc = [%d]\n", __func__,
+ mount_crypt_stat->global_default_fnek_sig, rc);
+ goto out;
+ }
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(
&s->desc.tfm,
&s->tfm_mutex, mount_crypt_stat->global_default_fn_cipher_name);
@@ -616,16 +733,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes,
goto out_free_unlock;
}
dest[s->i++] = s->cipher_code;
- rc = ecryptfs_find_auth_tok_for_sig(
- &auth_tok_key,
- &s->auth_tok, mount_crypt_stat,
- mount_crypt_stat->global_default_fnek_sig);
- if (rc) {
- printk(KERN_ERR "%s: Error attempting to find auth tok for "
- "fnek sig [%s]; rc = [%d]\n", __func__,
- mount_crypt_stat->global_default_fnek_sig, rc);
- goto out_free_unlock;
- }
/* TODO: Support other key modules than passphrase for
* filename encryption */
if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
@@ -765,8 +872,10 @@ out_free_unlock:
out_unlock:
mutex_unlock(s->tfm_mutex);
out:
- if (auth_tok_key)
+ if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
+ }
kfree(s);
return rc;
}
@@ -879,6 +988,15 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
__func__, s->cipher_code);
goto out;
}
+ rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key,
+ &s->auth_tok, mount_crypt_stat,
+ s->fnek_sig_hex);
+ if (rc) {
+ printk(KERN_ERR "%s: Error attempting to find auth tok for "
+ "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex,
+ rc);
+ goto out;
+ }
rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&s->desc.tfm,
&s->tfm_mutex,
s->cipher_string);
@@ -925,15 +1043,6 @@ ecryptfs_parse_tag_70_packet(char **filename, size_t *filename_size,
* >= ECRYPTFS_MAX_IV_BYTES. */
memset(s->iv, 0, ECRYPTFS_MAX_IV_BYTES);
s->desc.info = s->iv;
- rc = ecryptfs_find_auth_tok_for_sig(&auth_tok_key,
- &s->auth_tok, mount_crypt_stat,
- s->fnek_sig_hex);
- if (rc) {
- printk(KERN_ERR "%s: Error attempting to find auth tok for "
- "fnek sig [%s]; rc = [%d]\n", __func__, s->fnek_sig_hex,
- rc);
- goto out_free_unlock;
- }
/* TODO: Support other key modules than passphrase for
* filename encryption */
if (s->auth_tok->token_type != ECRYPTFS_PASSWORD) {
@@ -1002,8 +1111,10 @@ out:
(*filename_size) = 0;
(*filename) = NULL;
}
- if (auth_tok_key)
+ if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
+ }
kfree(s);
return rc;
}
@@ -1520,38 +1631,6 @@ out:
return rc;
}
-/**
- * ecryptfs_verify_version
- * @version: The version number to confirm
- *
- * Returns zero on good version; non-zero otherwise
- */
-static int ecryptfs_verify_version(u16 version)
-{
- int rc = 0;
- unsigned char major;
- unsigned char minor;
-
- major = ((version >> 8) & 0xFF);
- minor = (version & 0xFF);
- if (major != ECRYPTFS_VERSION_MAJOR) {
- ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
- "Expected [%d]; got [%d]\n",
- ECRYPTFS_VERSION_MAJOR, major);
- rc = -EINVAL;
- goto out;
- }
- if (minor != ECRYPTFS_VERSION_MINOR) {
- ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
- "Expected [%d]; got [%d]\n",
- ECRYPTFS_VERSION_MINOR, minor);
- rc = -EINVAL;
- goto out;
- }
-out:
- return rc;
-}
-
int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
struct ecryptfs_auth_tok **auth_tok,
char *sig)
@@ -1563,31 +1642,16 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
printk(KERN_ERR "Could not find key with description: [%s]\n",
sig);
rc = process_request_key_err(PTR_ERR(*auth_tok_key));
+ (*auth_tok_key) = NULL;
goto out;
}
- (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key);
- if (ecryptfs_verify_version((*auth_tok)->version)) {
- printk(KERN_ERR
- "Data structure version mismatch. "
- "Userspace tools must match eCryptfs "
- "kernel module with major version [%d] "
- "and minor version [%d]\n",
- ECRYPTFS_VERSION_MAJOR,
- ECRYPTFS_VERSION_MINOR);
- rc = -EINVAL;
- goto out_release_key;
- }
- if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD
- && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) {
- printk(KERN_ERR "Invalid auth_tok structure "
- "returned from key query\n");
- rc = -EINVAL;
- goto out_release_key;
- }
-out_release_key:
+ down_write(&(*auth_tok_key)->sem);
+ rc = ecryptfs_verify_auth_tok_from_key(*auth_tok_key, auth_tok);
if (rc) {
+ up_write(&(*auth_tok_key)->sem);
key_put(*auth_tok_key);
(*auth_tok_key) = NULL;
+ goto out;
}
out:
return rc;
@@ -1809,6 +1873,7 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
find_next_matching_auth_tok:
found_auth_tok = 0;
if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
auth_tok_key = NULL;
}
@@ -1895,8 +1960,10 @@ found_matching_auth_tok:
out_wipe_list:
wipe_auth_tok_list(&auth_tok_list);
out:
- if (auth_tok_key)
+ if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
key_put(auth_tok_key);
+ }
return rc;
}
@@ -2324,7 +2391,7 @@ ecryptfs_generate_key_packet_set(char *dest_base,
size_t max)
{
struct ecryptfs_auth_tok *auth_tok;
- struct ecryptfs_global_auth_tok *global_auth_tok;
+ struct key *auth_tok_key = NULL;
struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
&ecryptfs_superblock_to_private(
ecryptfs_dentry->d_sb)->mount_crypt_stat;
@@ -2343,21 +2410,16 @@ ecryptfs_generate_key_packet_set(char *dest_base,
list_for_each_entry(key_sig, &crypt_stat->keysig_list,
crypt_stat_list) {
memset(key_rec, 0, sizeof(*key_rec));
- rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
+ rc = ecryptfs_find_global_auth_tok_for_sig(&auth_tok_key,
+ &auth_tok,
mount_crypt_stat,
key_sig->keysig);
if (rc) {
- printk(KERN_ERR "Error attempting to get the global "
- "auth_tok; rc = [%d]\n", rc);
+ printk(KERN_WARNING "Unable to retrieve auth tok with "
+ "sig = [%s]\n", key_sig->keysig);
+ rc = process_find_global_auth_tok_for_sig_err(rc);
goto out_free;
}
- if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) {
- printk(KERN_WARNING
- "Skipping invalid auth tok with sig = [%s]\n",
- global_auth_tok->sig);
- continue;
- }
- auth_tok = global_auth_tok->global_auth_tok;
if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
rc = write_tag_3_packet((dest_base + (*len)),
&max, auth_tok,
@@ -2395,6 +2457,9 @@ ecryptfs_generate_key_packet_set(char *dest_base,
rc = -EINVAL;
goto out_free;
}
+ up_write(&(auth_tok_key->sem));
+ key_put(auth_tok_key);
+ auth_tok_key = NULL;
}
if (likely(max > 0)) {
dest_base[(*len)] = 0x00;
@@ -2407,6 +2472,11 @@ out_free:
out:
if (rc)
(*len) = 0;
+ if (auth_tok_key) {
+ up_write(&(auth_tok_key->sem));
+ key_put(auth_tok_key);
+ }
+
mutex_unlock(&crypt_stat->keysig_list_mutex);
return rc;
}
@@ -2424,6 +2494,7 @@ int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig)
return -ENOMEM;
}
memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX);
+ new_key_sig->keysig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
/* Caller must hold keysig_list_mutex */
list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list);
@@ -2453,7 +2524,6 @@ ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
list_add(&new_auth_tok->mount_crypt_stat_list,
&mount_crypt_stat->global_auth_tok_list);
- mount_crypt_stat->num_global_auth_toks++;
mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
out:
return rc;
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 758323a0f09..c27c0ecf90b 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -122,7 +122,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
int rc = 0;
- mutex_lock(&inode_info->lower_file_mutex);
if (!inode_info->lower_file) {
struct dentry *lower_dentry;
struct vfsmount *lower_mnt =
@@ -138,7 +137,6 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
inode_info->lower_file = NULL;
}
}
- mutex_unlock(&inode_info->lower_file_mutex);
return rc;
}
@@ -241,14 +239,14 @@ static int ecryptfs_init_global_auth_toks(
struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
{
struct ecryptfs_global_auth_tok *global_auth_tok;
+ struct ecryptfs_auth_tok *auth_tok;
int rc = 0;
list_for_each_entry(global_auth_tok,
&mount_crypt_stat->global_auth_tok_list,
mount_crypt_stat_list) {
rc = ecryptfs_keyring_auth_tok_for_sig(
- &global_auth_tok->global_auth_tok_key,
- &global_auth_tok->global_auth_tok,
+ &global_auth_tok->global_auth_tok_key, &auth_tok,
global_auth_tok->sig);
if (rc) {
printk(KERN_ERR "Could not find valid key in user "
@@ -256,8 +254,10 @@ static int ecryptfs_init_global_auth_toks(
"option: [%s]\n", global_auth_tok->sig);
global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID;
goto out;
- } else
+ } else {
global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID;
+ up_write(&(global_auth_tok->global_auth_tok_key)->sem);
+ }
}
out:
return rc;
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index cc64fca89f8..6a44148c5fb 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -62,6 +62,18 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
{
int rc;
+ /*
+ * Refuse to write the page out if we are called from reclaim context
+ * since our writepage() path may potentially allocate memory when
+ * calling into the lower fs vfs_write() which may in turn invoke
+ * us again.
+ */
+ if (current->flags & PF_MEMALLOC) {
+ redirty_page_for_writepage(wbc, page);
+ rc = 0;
+ goto out;
+ }
+
rc = ecryptfs_encrypt_page(page);
if (rc) {
ecryptfs_printk(KERN_WARNING, "Error encrypting "
@@ -70,8 +82,8 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
goto out;
}
SetPageUptodate(page);
- unlock_page(page);
out:
+ unlock_page(page);
return rc;
}
@@ -193,11 +205,7 @@ static int ecryptfs_readpage(struct file *file, struct page *page)
&ecryptfs_inode_to_private(page->mapping->host)->crypt_stat;
int rc = 0;
- if (!crypt_stat
- || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
- || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
- ecryptfs_printk(KERN_DEBUG,
- "Passing through unencrypted page\n");
+ if (!crypt_stat || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
PAGE_CACHE_SIZE,
page->mapping->host);
@@ -295,8 +303,7 @@ static int ecryptfs_write_begin(struct file *file,
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(mapping->host)->crypt_stat;
- if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
- || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
+ if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
rc = ecryptfs_read_lower_page_segment(
page, index, 0, PAGE_CACHE_SIZE, mapping->host);
if (rc) {
@@ -374,6 +381,11 @@ static int ecryptfs_write_begin(struct file *file,
&& (pos != 0))
zero_user(page, 0, PAGE_CACHE_SIZE);
out:
+ if (unlikely(rc)) {
+ unlock_page(page);
+ page_cache_release(page);
+ *pagep = NULL;
+ }
return rc;
}
@@ -486,13 +498,8 @@ static int ecryptfs_write_end(struct file *file,
struct ecryptfs_crypt_stat *crypt_stat =
&ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
int rc;
+ int need_unlock_page = 1;
- if (crypt_stat->flags & ECRYPTFS_NEW_FILE) {
- ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
- "crypt_stat at memory location [%p]\n", crypt_stat);
- crypt_stat->flags &= ~(ECRYPTFS_NEW_FILE);
- } else
- ecryptfs_printk(KERN_DEBUG, "Not a new file\n");
ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
"(page w/ index = [0x%.16lx], to = [%d])\n", index, to);
if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
@@ -512,26 +519,26 @@ static int ecryptfs_write_end(struct file *file,
"zeros in page with index = [0x%.16lx]\n", index);
goto out;
}
- rc = ecryptfs_encrypt_page(page);
- if (rc) {
- ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
- "index [0x%.16lx])\n", index);
- goto out;
- }
+ set_page_dirty(page);
+ unlock_page(page);
+ need_unlock_page = 0;
if (pos + copied > i_size_read(ecryptfs_inode)) {
i_size_write(ecryptfs_inode, pos + copied);
ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
"[0x%.16llx]\n",
(unsigned long long)i_size_read(ecryptfs_inode));
+ balance_dirty_pages_ratelimited(mapping);
+ rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
+ if (rc) {
+ printk(KERN_ERR "Error writing inode size to metadata; "
+ "rc = [%d]\n", rc);
+ goto out;
+ }
}
- rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
- if (rc)
- printk(KERN_ERR "Error writing inode size to metadata; "
- "rc = [%d]\n", rc);
- else
- rc = copied;
+ rc = copied;
out:
- unlock_page(page);
+ if (need_unlock_page)
+ unlock_page(page);
page_cache_release(page);
return rc;
}
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
index db184ef15d3..85d43096311 100644
--- a/fs/ecryptfs/read_write.c
+++ b/fs/ecryptfs/read_write.c
@@ -44,15 +44,11 @@ int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
ssize_t rc;
inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
- mutex_lock(&inode_info->lower_file_mutex);
BUG_ON(!inode_info->lower_file);
- inode_info->lower_file->f_pos = offset;
fs_save = get_fs();
set_fs(get_ds());
- rc = vfs_write(inode_info->lower_file, data, size,
- &inode_info->lower_file->f_pos);
+ rc = vfs_write(inode_info->lower_file, data, size, &offset);
set_fs(fs_save);
- mutex_unlock(&inode_info->lower_file_mutex);
mark_inode_dirty_sync(ecryptfs_inode);
return rc;
}
@@ -234,15 +230,11 @@ int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
mm_segment_t fs_save;
ssize_t rc;
- mutex_lock(&inode_info->lower_file_mutex);
BUG_ON(!inode_info->lower_file);
- inode_info->lower_file->f_pos = offset;
fs_save = get_fs();
set_fs(get_ds());
- rc = vfs_read(inode_info->lower_file, data, size,
- &inode_info->lower_file->f_pos);
+ rc = vfs_read(inode_info->lower_file, data, size, &offset);
set_fs(fs_save);
- mutex_unlock(&inode_info->lower_file_mutex);
return rc;
}
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 3042fe123a3..bacc882e1ae 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -55,7 +55,6 @@ static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
if (unlikely(!inode_info))
goto out;
ecryptfs_init_crypt_stat(&inode_info->crypt_stat);
- mutex_init(&inode_info->lower_file_mutex);
inode_info->lower_file = NULL;
inode = &inode_info->vfs_inode;
out:
@@ -198,7 +197,7 @@ static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt)
const struct super_operations ecryptfs_sops = {
.alloc_inode = ecryptfs_alloc_inode,
.destroy_inode = ecryptfs_destroy_inode,
- .drop_inode = generic_delete_inode,
+ .drop_inode = generic_drop_inode,
.statfs = ecryptfs_statfs,
.remount_fs = NULL,
.evict_inode = ecryptfs_evict_inode,
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index ad92bf731ff..9166fcb66da 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -192,13 +192,15 @@ static rpc_authflavor_t nfs_lookup_with_sec(struct nfs_server *server, struct de
auth = rpcauth_create(flavor, clone);
if (!auth) {
flavor = -EIO;
- goto out;
+ goto out_shutdown;
}
err = server->nfs_client->rpc_ops->lookup(clone, parent->d_inode,
&path->dentry->d_name,
fh, fattr);
if (err < 0)
flavor = err;
+out_shutdown:
+ rpc_shutdown_client(clone);
out:
return flavor;
}
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index ab1bf5bb021..a6804f704d9 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -590,7 +590,8 @@ nfs4_get_open_state(struct inode *inode, struct nfs4_state_owner *owner)
state->owner = owner;
atomic_inc(&owner->so_count);
list_add(&state->inode_states, &nfsi->open_states);
- state->inode = igrab(inode);
+ ihold(inode);
+ state->inode = inode;
spin_unlock(&inode->i_lock);
/* Note: The reclaim code dictates that we add stateless
* and read-only stateids to the end of the list */
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 87a593c2b05..c80add6e221 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -135,14 +135,14 @@ void nfs_clear_page_tag_locked(struct nfs_page *req)
nfs_unlock_request(req);
}
-/**
+/*
* nfs_clear_request - Free up all resources allocated to the request
* @req:
*
* Release page and open context resources associated with a read/write
* request after it has completed.
*/
-void nfs_clear_request(struct nfs_page *req)
+static void nfs_clear_request(struct nfs_page *req)
{
struct page *page = req->wb_page;
struct nfs_open_context *ctx = req->wb_context;
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 85d75254328..af0c6279a4a 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -389,11 +389,8 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req)
spin_lock(&inode->i_lock);
error = radix_tree_insert(&nfsi->nfs_page_tree, req->wb_index, req);
BUG_ON(error);
- if (!nfsi->npages) {
- igrab(inode);
- if (nfs_have_delegation(inode, FMODE_WRITE))
- nfsi->change_attr++;
- }
+ if (!nfsi->npages && nfs_have_delegation(inode, FMODE_WRITE))
+ nfsi->change_attr++;
set_bit(PG_MAPPED, &req->wb_flags);
SetPagePrivate(req->wb_page);
set_page_private(req->wb_page, (unsigned long)req);
@@ -423,11 +420,7 @@ static void nfs_inode_remove_request(struct nfs_page *req)
clear_bit(PG_MAPPED, &req->wb_flags);
radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index);
nfsi->npages--;
- if (!nfsi->npages) {
- spin_unlock(&inode->i_lock);
- iput(inode);
- } else
- spin_unlock(&inode->i_lock);
+ spin_unlock(&inode->i_lock);
nfs_release_request(req);
}
diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c
index 93589fccdd9..397e7325863 100644
--- a/fs/nilfs2/file.c
+++ b/fs/nilfs2/file.c
@@ -72,10 +72,9 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
/*
* check to see if the page is mapped already (no holes)
*/
- if (PageMappedToDisk(page)) {
- unlock_page(page);
+ if (PageMappedToDisk(page))
goto mapped;
- }
+
if (page_has_buffers(page)) {
struct buffer_head *bh, *head;
int fully_mapped = 1;
@@ -90,7 +89,6 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
if (fully_mapped) {
SetPageMappedToDisk(page);
- unlock_page(page);
goto mapped;
}
}
@@ -105,16 +103,17 @@ static int nilfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
return VM_FAULT_SIGBUS;
ret = block_page_mkwrite(vma, vmf, nilfs_get_block);
- if (unlikely(ret)) {
+ if (ret != VM_FAULT_LOCKED) {
nilfs_transaction_abort(inode->i_sb);
return ret;
}
+ nilfs_set_file_dirty(inode, 1 << (PAGE_SHIFT - inode->i_blkbits));
nilfs_transaction_commit(inode->i_sb);
mapped:
SetPageChecked(page);
wait_on_page_writeback(page);
- return 0;
+ return VM_FAULT_LOCKED;
}
static const struct vm_operations_struct nilfs_file_vm_ops = {
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index 856e8e4e0b7..a8dd344303c 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -114,19 +114,19 @@ enum {
* Macros to check inode numbers
*/
#define NILFS_MDT_INO_BITS \
- ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO | \
- 1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO | \
- 1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO))
+ ((unsigned int)(1 << NILFS_DAT_INO | 1 << NILFS_CPFILE_INO | \
+ 1 << NILFS_SUFILE_INO | 1 << NILFS_IFILE_INO | \
+ 1 << NILFS_ATIME_INO | 1 << NILFS_SKETCH_INO))
#define NILFS_SYS_INO_BITS \
- ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
+ ((unsigned int)(1 << NILFS_ROOT_INO) | NILFS_MDT_INO_BITS)
#define NILFS_FIRST_INO(sb) (((struct the_nilfs *)sb->s_fs_info)->ns_first_ino)
#define NILFS_MDT_INODE(sb, ino) \
- ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
+ ((ino) < NILFS_FIRST_INO(sb) && (NILFS_MDT_INO_BITS & (1 << (ino))))
#define NILFS_VALID_INODE(sb, ino) \
- ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino))))
+ ((ino) >= NILFS_FIRST_INO(sb) || (NILFS_SYS_INO_BITS & (1 << (ino))))
/**
* struct nilfs_transaction_info: context information for synchronization
@@ -285,7 +285,7 @@ extern void nilfs_destroy_inode(struct inode *);
extern void nilfs_error(struct super_block *, const char *, const char *, ...)
__attribute__ ((format (printf, 3, 4)));
extern void nilfs_warning(struct super_block *, const char *, const char *, ...)
- __attribute__ ((format (printf, 3, 4)));
+ __attribute__ ((format (printf, 3, 4)));
extern struct nilfs_super_block *
nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **);
extern int nilfs_store_magic_and_option(struct super_block *,
diff --git a/fs/nilfs2/page.c b/fs/nilfs2/page.c
index 4d2a1ee0eb4..9d2dc6b4348 100644
--- a/fs/nilfs2/page.c
+++ b/fs/nilfs2/page.c
@@ -495,12 +495,14 @@ unsigned nilfs_page_count_clean_buffers(struct page *page,
void nilfs_mapping_init(struct address_space *mapping,
struct backing_dev_info *bdi)
{
+ static const struct address_space_operations empty_aops;
+
mapping->host = NULL;
mapping->flags = 0;
mapping_set_gfp_mask(mapping, GFP_NOFS);
mapping->assoc_mapping = NULL;
mapping->backing_dev_info = bdi;
- mapping->a_ops = NULL;
+ mapping->a_ops = &empty_aops;
}
/*
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index 90f2729b7a5..e913ad130fd 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -24,7 +24,6 @@
#include <linux/slab.h>
#include <linux/string.h>
-#define MLOG_MASK_PREFIX ML_INODE
#include <cluster/masklog.h>
#include "ocfs2.h"
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index e4984e259cb..b27a0d86f8c 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -30,7 +30,6 @@
#include <linux/swap.h>
#include <linux/quotaops.h>
-#define MLOG_MASK_PREFIX ML_DISK_ALLOC
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -50,6 +49,7 @@
#include "uptodate.h"
#include "xattr.h"
#include "refcounttree.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -886,8 +886,7 @@ static int ocfs2_validate_extent_block(struct super_block *sb,
struct ocfs2_extent_block *eb =
(struct ocfs2_extent_block *)bh->b_data;
- mlog(0, "Validating extent block %llu\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_validate_extent_block((unsigned long long)bh->b_blocknr);
BUG_ON(!buffer_uptodate(bh));
@@ -965,8 +964,6 @@ int ocfs2_num_free_extents(struct ocfs2_super *osb,
struct buffer_head *eb_bh = NULL;
u64 last_eb_blk = 0;
- mlog_entry_void();
-
el = et->et_root_el;
last_eb_blk = ocfs2_et_get_last_eb_blk(et);
@@ -987,7 +984,7 @@ int ocfs2_num_free_extents(struct ocfs2_super *osb,
bail:
brelse(eb_bh);
- mlog_exit(retval);
+ trace_ocfs2_num_free_extents(retval);
return retval;
}
@@ -1010,8 +1007,6 @@ static int ocfs2_create_new_meta_bhs(handle_t *handle,
OCFS2_SB(ocfs2_metadata_cache_get_super(et->et_ci));
struct ocfs2_extent_block *eb;
- mlog_entry_void();
-
count = 0;
while (count < wanted) {
status = ocfs2_claim_metadata(handle,
@@ -1074,8 +1069,8 @@ bail:
brelse(bhs[i]);
bhs[i] = NULL;
}
+ mlog_errno(status);
}
- mlog_exit(status);
return status;
}
@@ -1173,8 +1168,6 @@ static int ocfs2_add_branch(handle_t *handle,
struct ocfs2_extent_list *el;
u32 new_cpos, root_end;
- mlog_entry_void();
-
BUG_ON(!last_eb_bh || !*last_eb_bh);
if (eb_bh) {
@@ -1200,8 +1193,11 @@ static int ocfs2_add_branch(handle_t *handle,
* from new_cpos).
*/
if (root_end > new_cpos) {
- mlog(0, "adjust the cluster end from %u to %u\n",
- root_end, new_cpos);
+ trace_ocfs2_adjust_rightmost_branch(
+ (unsigned long long)
+ ocfs2_metadata_cache_owner(et->et_ci),
+ root_end, new_cpos);
+
status = ocfs2_adjust_rightmost_branch(handle, et);
if (status) {
mlog_errno(status);
@@ -1332,7 +1328,6 @@ bail:
kfree(new_eb_bhs);
}
- mlog_exit(status);
return status;
}
@@ -1353,8 +1348,6 @@ static int ocfs2_shift_tree_depth(handle_t *handle,
struct ocfs2_extent_list *root_el;
struct ocfs2_extent_list *eb_el;
- mlog_entry_void();
-
status = ocfs2_create_new_meta_bhs(handle, et, 1, meta_ac,
&new_eb_bh);
if (status < 0) {
@@ -1415,7 +1408,6 @@ static int ocfs2_shift_tree_depth(handle_t *handle,
bail:
brelse(new_eb_bh);
- mlog_exit(status);
return status;
}
@@ -1446,8 +1438,6 @@ static int ocfs2_find_branch_target(struct ocfs2_extent_tree *et,
struct buffer_head *bh = NULL;
struct buffer_head *lowest_bh = NULL;
- mlog_entry_void();
-
*target_bh = NULL;
el = et->et_root_el;
@@ -1503,7 +1493,6 @@ static int ocfs2_find_branch_target(struct ocfs2_extent_tree *et,
bail:
brelse(bh);
- mlog_exit(status);
return status;
}
@@ -1540,7 +1529,10 @@ static int ocfs2_grow_tree(handle_t *handle, struct ocfs2_extent_tree *et,
* another tree level */
if (shift) {
BUG_ON(bh);
- mlog(0, "need to shift tree depth (current = %d)\n", depth);
+ trace_ocfs2_grow_tree(
+ (unsigned long long)
+ ocfs2_metadata_cache_owner(et->et_ci),
+ depth);
/* ocfs2_shift_tree_depth will return us a buffer with
* the new extent block (so we can pass that to
@@ -1570,7 +1562,6 @@ static int ocfs2_grow_tree(handle_t *handle, struct ocfs2_extent_tree *et,
/* call ocfs2_add_branch to add the final part of the tree with
* the new data. */
- mlog(0, "add branch. bh = %p\n", bh);
ret = ocfs2_add_branch(handle, et, bh, last_eb_bh,
meta_ac);
if (ret < 0) {
@@ -1645,8 +1636,9 @@ static void ocfs2_rotate_leaf(struct ocfs2_extent_list *el,
}
insert_index = i;
- mlog(0, "ins %u: index %d, has_empty %d, next_free %d, count %d\n",
- insert_cpos, insert_index, has_empty, next_free, le16_to_cpu(el->l_count));
+ trace_ocfs2_rotate_leaf(insert_cpos, insert_index,
+ has_empty, next_free,
+ le16_to_cpu(el->l_count));
BUG_ON(insert_index < 0);
BUG_ON(insert_index >= le16_to_cpu(el->l_count));
@@ -2059,7 +2051,7 @@ static void ocfs2_complete_edge_insert(handle_t *handle,
left_el = path_leaf_el(left_path);
right_el = path_leaf_el(right_path);
for(i = left_path->p_tree_depth - 1; i > subtree_index; i--) {
- mlog(0, "Adjust records at index %u\n", i);
+ trace_ocfs2_complete_edge_insert(i);
/*
* One nice property of knowing that all of these
@@ -2389,7 +2381,9 @@ static int ocfs2_rotate_tree_right(handle_t *handle,
goto out;
}
- mlog(0, "Insert: %u, first left path cpos: %u\n", insert_cpos, cpos);
+ trace_ocfs2_rotate_tree_right(
+ (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci),
+ insert_cpos, cpos);
/*
* What we want to do here is:
@@ -2418,8 +2412,10 @@ static int ocfs2_rotate_tree_right(handle_t *handle,
* rotating subtrees.
*/
while (cpos && insert_cpos <= cpos) {
- mlog(0, "Rotating a tree: ins. cpos: %u, left path cpos: %u\n",
- insert_cpos, cpos);
+ trace_ocfs2_rotate_tree_right(
+ (unsigned long long)
+ ocfs2_metadata_cache_owner(et->et_ci),
+ insert_cpos, cpos);
ret = ocfs2_find_path(et->et_ci, left_path, cpos);
if (ret) {
@@ -2461,10 +2457,10 @@ static int ocfs2_rotate_tree_right(handle_t *handle,
start = ocfs2_find_subtree_root(et, left_path, right_path);
- mlog(0, "Subtree root at index %d (blk %llu, depth %d)\n",
- start,
- (unsigned long long) right_path->p_node[start].bh->b_blocknr,
- right_path->p_tree_depth);
+ trace_ocfs2_rotate_subtree(start,
+ (unsigned long long)
+ right_path->p_node[start].bh->b_blocknr,
+ right_path->p_tree_depth);
ret = ocfs2_extend_rotate_transaction(handle, start,
orig_credits, right_path);
@@ -2964,8 +2960,7 @@ static int __ocfs2_rotate_tree_left(handle_t *handle,
subtree_root = ocfs2_find_subtree_root(et, left_path,
right_path);
- mlog(0, "Subtree root at index %d (blk %llu, depth %d)\n",
- subtree_root,
+ trace_ocfs2_rotate_subtree(subtree_root,
(unsigned long long)
right_path->p_node[subtree_root].bh->b_blocknr,
right_path->p_tree_depth);
@@ -3989,9 +3984,11 @@ static int ocfs2_append_rec_to_path(handle_t *handle,
goto out;
}
- mlog(0, "Append may need a left path update. cpos: %u, "
- "left_cpos: %u\n", le32_to_cpu(insert_rec->e_cpos),
- left_cpos);
+ trace_ocfs2_append_rec_to_path(
+ (unsigned long long)
+ ocfs2_metadata_cache_owner(et->et_ci),
+ le32_to_cpu(insert_rec->e_cpos),
+ left_cpos);
/*
* No need to worry if the append is already in the
@@ -4562,7 +4559,7 @@ static int ocfs2_figure_insert_type(struct ocfs2_extent_tree *et,
ocfs2_et_get_last_eb_blk(et),
&bh);
if (ret) {
- mlog_exit(ret);
+ mlog_errno(ret);
goto out;
}
eb = (struct ocfs2_extent_block *) bh->b_data;
@@ -4678,9 +4675,9 @@ int ocfs2_insert_extent(handle_t *handle,
struct ocfs2_insert_type insert = {0, };
struct ocfs2_extent_rec rec;
- mlog(0, "add %u clusters at position %u to owner %llu\n",
- new_clusters, cpos,
- (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci));
+ trace_ocfs2_insert_extent_start(
+ (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci),
+ cpos, new_clusters);
memset(&rec, 0, sizeof(rec));
rec.e_cpos = cpu_to_le32(cpos);
@@ -4700,11 +4697,9 @@ int ocfs2_insert_extent(handle_t *handle,
goto bail;
}
- mlog(0, "Insert.appending: %u, Insert.Contig: %u, "
- "Insert.contig_index: %d, Insert.free_records: %d, "
- "Insert.tree_depth: %d\n",
- insert.ins_appending, insert.ins_contig, insert.ins_contig_index,
- free_records, insert.ins_tree_depth);
+ trace_ocfs2_insert_extent(insert.ins_appending, insert.ins_contig,
+ insert.ins_contig_index, free_records,
+ insert.ins_tree_depth);
if (insert.ins_contig == CONTIG_NONE && free_records == 0) {
status = ocfs2_grow_tree(handle, et,
@@ -4726,7 +4721,6 @@ int ocfs2_insert_extent(handle_t *handle,
bail:
brelse(last_eb_bh);
- mlog_exit(status);
return status;
}
@@ -4746,7 +4740,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,
struct ocfs2_alloc_context *meta_ac,
enum ocfs2_alloc_restarted *reason_ret)
{
- int status = 0;
+ int status = 0, err = 0;
int free_extents;
enum ocfs2_alloc_restarted reason = RESTART_NONE;
u32 bit_off, num_bits;
@@ -4773,14 +4767,14 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,
* 2) we are so fragmented, we've needed to add metadata too
* many times. */
if (!free_extents && !meta_ac) {
- mlog(0, "we haven't reserved any metadata!\n");
+ err = -1;
status = -EAGAIN;
reason = RESTART_META;
goto leave;
} else if ((!free_extents)
&& (ocfs2_alloc_context_bits_left(meta_ac)
< ocfs2_extend_meta_needed(et->et_root_el))) {
- mlog(0, "filesystem is really fragmented...\n");
+ err = -2;
status = -EAGAIN;
reason = RESTART_META;
goto leave;
@@ -4805,9 +4799,9 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,
}
block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
- mlog(0, "Allocating %u clusters at block %u for owner %llu\n",
- num_bits, bit_off,
- (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci));
+ trace_ocfs2_add_clusters_in_btree(
+ (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci),
+ bit_off, num_bits);
status = ocfs2_insert_extent(handle, et, *logical_offset, block,
num_bits, flags, meta_ac);
if (status < 0) {
@@ -4821,16 +4815,15 @@ int ocfs2_add_clusters_in_btree(handle_t *handle,
*logical_offset += num_bits;
if (clusters_to_add) {
- mlog(0, "need to alloc once more, wanted = %u\n",
- clusters_to_add);
+ err = clusters_to_add;
status = -EAGAIN;
reason = RESTART_TRANS;
}
leave:
- mlog_exit(status);
if (reason_ret)
*reason_ret = reason;
+ trace_ocfs2_add_clusters_in_btree_ret(status, reason, err);
return status;
}
@@ -5039,7 +5032,7 @@ int ocfs2_split_extent(handle_t *handle,
ocfs2_et_get_last_eb_blk(et),
&last_eb_bh);
if (ret) {
- mlog_exit(ret);
+ mlog_errno(ret);
goto out;
}
@@ -5056,9 +5049,9 @@ int ocfs2_split_extent(handle_t *handle,
ctxt.c_has_empty_extent = ocfs2_is_empty_extent(&el->l_recs[0]);
- mlog(0, "index: %d, contig: %u, has_empty: %u, split_covers: %u\n",
- split_index, ctxt.c_contig_type, ctxt.c_has_empty_extent,
- ctxt.c_split_covers_rec);
+ trace_ocfs2_split_extent(split_index, ctxt.c_contig_type,
+ ctxt.c_has_empty_extent,
+ ctxt.c_split_covers_rec);
if (ctxt.c_contig_type == CONTIG_NONE) {
if (ctxt.c_split_covers_rec)
@@ -5192,8 +5185,9 @@ int ocfs2_mark_extent_written(struct inode *inode,
{
int ret;
- mlog(0, "Inode %lu cpos %u, len %u, phys clusters %u\n",
- inode->i_ino, cpos, len, phys);
+ trace_ocfs2_mark_extent_written(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ cpos, len, phys);
if (!ocfs2_writes_unwritten_extents(OCFS2_SB(inode->i_sb))) {
ocfs2_error(inode->i_sb, "Inode %llu has unwritten extents "
@@ -5512,11 +5506,10 @@ int ocfs2_remove_extent(handle_t *handle,
BUG_ON(cpos < le32_to_cpu(rec->e_cpos) || trunc_range > rec_range);
- mlog(0, "Owner %llu, remove (cpos %u, len %u). Existing index %d "
- "(cpos %u, len %u)\n",
- (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci),
- cpos, len, index,
- le32_to_cpu(rec->e_cpos), ocfs2_rec_clusters(el, rec));
+ trace_ocfs2_remove_extent(
+ (unsigned long long)ocfs2_metadata_cache_owner(et->et_ci),
+ cpos, len, index, le32_to_cpu(rec->e_cpos),
+ ocfs2_rec_clusters(el, rec));
if (le32_to_cpu(rec->e_cpos) == cpos || rec_range == trunc_range) {
ret = ocfs2_truncate_rec(handle, et, path, index, dealloc,
@@ -5795,9 +5788,6 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb,
struct ocfs2_dinode *di;
struct ocfs2_truncate_log *tl;
- mlog_entry("start_blk = %llu, num_clusters = %u\n",
- (unsigned long long)start_blk, num_clusters);
-
BUG_ON(mutex_trylock(&tl_inode->i_mutex));
start_cluster = ocfs2_blocks_to_clusters(osb->sb, start_blk);
@@ -5834,10 +5824,9 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb,
goto bail;
}
- mlog(0, "Log truncate of %u clusters starting at cluster %u to "
- "%llu (index = %d)\n", num_clusters, start_cluster,
- (unsigned long long)OCFS2_I(tl_inode)->ip_blkno, index);
-
+ trace_ocfs2_truncate_log_append(
+ (unsigned long long)OCFS2_I(tl_inode)->ip_blkno, index,
+ start_cluster, num_clusters);
if (ocfs2_truncate_log_can_coalesce(tl, start_cluster)) {
/*
* Move index back to the record we are coalescing with.
@@ -5846,9 +5835,10 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb,
index--;
num_clusters += le32_to_cpu(tl->tl_recs[index].t_clusters);
- mlog(0, "Coalesce with index %u (start = %u, clusters = %u)\n",
- index, le32_to_cpu(tl->tl_recs[index].t_start),
- num_clusters);
+ trace_ocfs2_truncate_log_append(
+ (unsigned long long)OCFS2_I(tl_inode)->ip_blkno,
+ index, le32_to_cpu(tl->tl_recs[index].t_start),
+ num_clusters);
} else {
tl->tl_recs[index].t_start = cpu_to_le32(start_cluster);
tl->tl_used = cpu_to_le16(index + 1);
@@ -5859,7 +5849,6 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb,
osb->truncated_clusters += num_clusters;
bail:
- mlog_exit(status);
return status;
}
@@ -5878,8 +5867,6 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
struct inode *tl_inode = osb->osb_tl_inode;
struct buffer_head *tl_bh = osb->osb_tl_bh;
- mlog_entry_void();
-
di = (struct ocfs2_dinode *) tl_bh->b_data;
tl = &di->id2.i_dealloc;
i = le16_to_cpu(tl->tl_used) - 1;
@@ -5915,8 +5902,9 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
/* if start_blk is not set, we ignore the record as
* invalid. */
if (start_blk) {
- mlog(0, "free record %d, start = %u, clusters = %u\n",
- i, le32_to_cpu(rec.t_start), num_clusters);
+ trace_ocfs2_replay_truncate_records(
+ (unsigned long long)OCFS2_I(tl_inode)->ip_blkno,
+ i, le32_to_cpu(rec.t_start), num_clusters);
status = ocfs2_free_clusters(handle, data_alloc_inode,
data_alloc_bh, start_blk,
@@ -5932,7 +5920,6 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
osb->truncated_clusters = 0;
bail:
- mlog_exit(status);
return status;
}
@@ -5949,8 +5936,6 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
struct ocfs2_dinode *di;
struct ocfs2_truncate_log *tl;
- mlog_entry_void();
-
BUG_ON(mutex_trylock(&tl_inode->i_mutex));
di = (struct ocfs2_dinode *) tl_bh->b_data;
@@ -5962,8 +5947,9 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
tl = &di->id2.i_dealloc;
num_to_flush = le16_to_cpu(tl->tl_used);
- mlog(0, "Flush %u records from truncate log #%llu\n",
- num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno);
+ trace_ocfs2_flush_truncate_log(
+ (unsigned long long)OCFS2_I(tl_inode)->ip_blkno,
+ num_to_flush);
if (!num_to_flush) {
status = 0;
goto out;
@@ -6009,7 +5995,6 @@ out_mutex:
iput(data_alloc_inode);
out:
- mlog_exit(status);
return status;
}
@@ -6032,15 +6017,11 @@ static void ocfs2_truncate_log_worker(struct work_struct *work)
container_of(work, struct ocfs2_super,
osb_truncate_log_wq.work);
- mlog_entry_void();
-
status = ocfs2_flush_truncate_log(osb);
if (status < 0)
mlog_errno(status);
else
ocfs2_init_steal_slots(osb);
-
- mlog_exit(status);
}
#define OCFS2_TRUNCATE_LOG_FLUSH_INTERVAL (2 * HZ)
@@ -6086,7 +6067,6 @@ static int ocfs2_get_truncate_log_info(struct ocfs2_super *osb,
*tl_inode = inode;
*tl_bh = bh;
bail:
- mlog_exit(status);
return status;
}
@@ -6106,7 +6086,7 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb,
*tl_copy = NULL;
- mlog(0, "recover truncate log from slot %d\n", slot_num);
+ trace_ocfs2_begin_truncate_log_recovery(slot_num);
status = ocfs2_get_truncate_log_info(osb, slot_num, &tl_inode, &tl_bh);
if (status < 0) {
@@ -6123,8 +6103,7 @@ int ocfs2_begin_truncate_log_recovery(struct ocfs2_super *osb,
tl = &di->id2.i_dealloc;
if (le16_to_cpu(tl->tl_used)) {
- mlog(0, "We'll have %u logs to recover\n",
- le16_to_cpu(tl->tl_used));
+ trace_ocfs2_truncate_log_recovery_num(le16_to_cpu(tl->tl_used));
*tl_copy = kmalloc(tl_bh->b_size, GFP_KERNEL);
if (!(*tl_copy)) {
@@ -6157,9 +6136,9 @@ bail:
if (status < 0 && (*tl_copy)) {
kfree(*tl_copy);
*tl_copy = NULL;
+ mlog_errno(status);
}
- mlog_exit(status);
return status;
}
@@ -6174,8 +6153,6 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
struct inode *tl_inode = osb->osb_tl_inode;
struct ocfs2_truncate_log *tl;
- mlog_entry_void();
-
if (OCFS2_I(tl_inode)->ip_blkno == le64_to_cpu(tl_copy->i_blkno)) {
mlog(ML_ERROR, "Asked to recover my own truncate log!\n");
return -EINVAL;
@@ -6183,8 +6160,9 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
tl = &tl_copy->id2.i_dealloc;
num_recs = le16_to_cpu(tl->tl_used);
- mlog(0, "cleanup %u records from %llu\n", num_recs,
- (unsigned long long)le64_to_cpu(tl_copy->i_blkno));
+ trace_ocfs2_complete_truncate_log_recovery(
+ (unsigned long long)le64_to_cpu(tl_copy->i_blkno),
+ num_recs);
mutex_lock(&tl_inode->i_mutex);
for(i = 0; i < num_recs; i++) {
@@ -6219,7 +6197,6 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
bail_up:
mutex_unlock(&tl_inode->i_mutex);
- mlog_exit(status);
return status;
}
@@ -6228,8 +6205,6 @@ void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb)
int status;
struct inode *tl_inode = osb->osb_tl_inode;
- mlog_entry_void();
-
if (tl_inode) {
cancel_delayed_work(&osb->osb_truncate_log_wq);
flush_workqueue(ocfs2_wq);
@@ -6241,8 +6216,6 @@ void ocfs2_truncate_log_shutdown(struct ocfs2_super *osb)
brelse(osb->osb_tl_bh);
iput(osb->osb_tl_inode);
}
-
- mlog_exit_void();
}
int ocfs2_truncate_log_init(struct ocfs2_super *osb)
@@ -6251,8 +6224,6 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb)
struct inode *tl_inode = NULL;
struct buffer_head *tl_bh = NULL;
- mlog_entry_void();
-
status = ocfs2_get_truncate_log_info(osb,
osb->slot_num,
&tl_inode,
@@ -6268,7 +6239,6 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb)
osb->osb_tl_bh = tl_bh;
osb->osb_tl_inode = tl_inode;
- mlog_exit(status);
return status;
}
@@ -6350,8 +6320,8 @@ static int ocfs2_free_cached_blocks(struct ocfs2_super *osb,
else
bg_blkno = ocfs2_which_suballoc_group(head->free_blk,
head->free_bit);
- mlog(0, "Free bit: (bit %u, blkno %llu)\n",
- head->free_bit, (unsigned long long)head->free_blk);
+ trace_ocfs2_free_cached_blocks(
+ (unsigned long long)head->free_blk, head->free_bit);
ret = ocfs2_free_suballoc_bits(handle, inode, di_bh,
head->free_bit, bg_blkno, 1);
@@ -6404,8 +6374,7 @@ int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
return ret;
}
- mlog(0, "Insert clusters: (bit %u, blk %llu)\n",
- bit, (unsigned long long)blkno);
+ trace_ocfs2_cache_cluster_dealloc((unsigned long long)blkno, bit);
item->free_blk = blkno;
item->free_bit = bit;
@@ -6480,8 +6449,8 @@ int ocfs2_run_deallocs(struct ocfs2_super *osb,
fl = ctxt->c_first_suballocator;
if (fl->f_first) {
- mlog(0, "Free items: (type %u, slot %d)\n",
- fl->f_inode_type, fl->f_slot);
+ trace_ocfs2_run_deallocs(fl->f_inode_type,
+ fl->f_slot);
ret2 = ocfs2_free_cached_blocks(osb,
fl->f_inode_type,
fl->f_slot,
@@ -6558,8 +6527,9 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
goto out;
}
- mlog(0, "Insert: (type %d, slot %u, bit %u, blk %llu)\n",
- type, slot, bit, (unsigned long long)blkno);
+ trace_ocfs2_cache_block_dealloc(type, slot,
+ (unsigned long long)suballoc,
+ (unsigned long long)blkno, bit);
item->free_bg = suballoc;
item->free_blk = blkno;
@@ -7005,8 +6975,6 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
struct ocfs2_extent_tree et;
struct ocfs2_cached_dealloc_ctxt dealloc;
- mlog_entry_void();
-
ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
ocfs2_init_dealloc_ctxt(&dealloc);
@@ -7041,8 +7009,11 @@ start:
goto bail;
}
- mlog(0, "inode->ip_clusters = %u, tree_depth = %u\n",
- OCFS2_I(inode)->ip_clusters, path->p_tree_depth);
+ trace_ocfs2_commit_truncate(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ new_highest_cpos,
+ OCFS2_I(inode)->ip_clusters,
+ path->p_tree_depth);
/*
* By now, el will point to the extent list on the bottom most
@@ -7136,7 +7107,6 @@ bail:
ocfs2_free_path(path);
- mlog_exit(status);
return status;
}
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index daea0359e97..ac97bca282d 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -29,7 +29,6 @@
#include <linux/mpage.h>
#include <linux/quotaops.h>
-#define MLOG_MASK_PREFIX ML_FILE_IO
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -45,6 +44,7 @@
#include "super.h"
#include "symlink.h"
#include "refcounttree.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -59,8 +59,9 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
void *kaddr;
- mlog_entry("(0x%p, %llu, 0x%p, %d)\n", inode,
- (unsigned long long)iblock, bh_result, create);
+ trace_ocfs2_symlink_get_block(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)iblock, bh_result, create);
BUG_ON(ocfs2_inode_is_fast_symlink(inode));
@@ -123,7 +124,6 @@ static int ocfs2_symlink_get_block(struct inode *inode, sector_t iblock,
bail:
brelse(bh);
- mlog_exit(err);
return err;
}
@@ -136,8 +136,8 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock,
u64 p_blkno, count, past_eof;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- mlog_entry("(0x%p, %llu, 0x%p, %d)\n", inode,
- (unsigned long long)iblock, bh_result, create);
+ trace_ocfs2_get_block((unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)iblock, bh_result, create);
if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_SYSTEM_FILE)
mlog(ML_NOTICE, "get_block on system inode 0x%p (%lu)\n",
@@ -199,8 +199,9 @@ int ocfs2_get_block(struct inode *inode, sector_t iblock,
}
past_eof = ocfs2_blocks_for_bytes(inode->i_sb, i_size_read(inode));
- mlog(0, "Inode %lu, past_eof = %llu\n", inode->i_ino,
- (unsigned long long)past_eof);
+
+ trace_ocfs2_get_block_end((unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)past_eof);
if (create && (iblock >= past_eof))
set_buffer_new(bh_result);
@@ -208,7 +209,6 @@ bail:
if (err < 0)
err = -EIO;
- mlog_exit(err);
return err;
}
@@ -278,7 +278,8 @@ static int ocfs2_readpage(struct file *file, struct page *page)
loff_t start = (loff_t)page->index << PAGE_CACHE_SHIFT;
int ret, unlock = 1;
- mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0));
+ trace_ocfs2_readpage((unsigned long long)oi->ip_blkno,
+ (page ? page->index : 0));
ret = ocfs2_inode_lock_with_page(inode, NULL, 0, page);
if (ret != 0) {
@@ -323,7 +324,6 @@ out_inode_unlock:
out:
if (unlock)
unlock_page(page);
- mlog_exit(ret);
return ret;
}
@@ -396,15 +396,11 @@ out_unlock:
*/
static int ocfs2_writepage(struct page *page, struct writeback_control *wbc)
{
- int ret;
-
- mlog_entry("(0x%p)\n", page);
-
- ret = block_write_full_page(page, ocfs2_get_block, wbc);
+ trace_ocfs2_writepage(
+ (unsigned long long)OCFS2_I(page->mapping->host)->ip_blkno,
+ page->index);
- mlog_exit(ret);
-
- return ret;
+ return block_write_full_page(page, ocfs2_get_block, wbc);
}
/* Taken from ext3. We don't necessarily need the full blown
@@ -450,7 +446,8 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
int err = 0;
struct inode *inode = mapping->host;
- mlog_entry("(block = %llu)\n", (unsigned long long)block);
+ trace_ocfs2_bmap((unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)block);
/* We don't need to lock journal system files, since they aren't
* accessed concurrently from multiple nodes.
@@ -484,8 +481,6 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
bail:
status = err ? 0 : p_blkno;
- mlog_exit((int)status);
-
return status;
}
@@ -616,9 +611,6 @@ static ssize_t ocfs2_direct_IO(int rw,
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_path.dentry->d_inode->i_mapping->host;
- int ret;
-
- mlog_entry_void();
/*
* Fallback to buffered I/O if we see an inode without
@@ -631,13 +623,10 @@ static ssize_t ocfs2_direct_IO(int rw,
if (i_size_read(inode) <= offset)
return 0;
- ret = __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
- iov, offset, nr_segs,
- ocfs2_direct_IO_get_blocks,
- ocfs2_dio_end_io, NULL, 0);
-
- mlog_exit(ret);
- return ret;
+ return __blockdev_direct_IO(rw, iocb, inode, inode->i_sb->s_bdev,
+ iov, offset, nr_segs,
+ ocfs2_direct_IO_get_blocks,
+ ocfs2_dio_end_io, NULL, 0);
}
static void ocfs2_figure_cluster_boundaries(struct ocfs2_super *osb,
@@ -1026,6 +1015,12 @@ static int ocfs2_prepare_page_for_write(struct inode *inode, u64 *p_blkno,
ocfs2_figure_cluster_boundaries(OCFS2_SB(inode->i_sb), cpos,
&cluster_start, &cluster_end);
+ /* treat the write as new if the a hole/lseek spanned across
+ * the page boundary.
+ */
+ new = new | ((i_size_read(inode) <= page_offset(page)) &&
+ (page_offset(page) <= user_pos));
+
if (page == wc->w_target_page) {
map_from = user_pos & (PAGE_CACHE_SIZE - 1);
map_to = map_from + user_len;
@@ -1534,9 +1529,9 @@ static int ocfs2_try_to_write_inline_data(struct address_space *mapping,
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_dinode *di = NULL;
- mlog(0, "Inode %llu, write of %u bytes at off %llu. features: 0x%x\n",
- (unsigned long long)oi->ip_blkno, len, (unsigned long long)pos,
- oi->ip_dyn_features);
+ trace_ocfs2_try_to_write_inline_data((unsigned long long)oi->ip_blkno,
+ len, (unsigned long long)pos,
+ oi->ip_dyn_features);
/*
* Handle inodes which already have inline data 1st.
@@ -1739,6 +1734,13 @@ try_again:
di = (struct ocfs2_dinode *)wc->w_di_bh->b_data;
+ trace_ocfs2_write_begin_nolock(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (long long)i_size_read(inode),
+ le32_to_cpu(di->i_clusters),
+ pos, len, flags, mmap_page,
+ clusters_to_alloc, extents_to_split);
+
/*
* We set w_target_from, w_target_to here so that
* ocfs2_write_end() knows which range in the target page to
@@ -1751,12 +1753,6 @@ try_again:
* ocfs2_lock_allocators(). It greatly over-estimates
* the work to be done.
*/
- mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u,"
- " clusters_to_add = %u, extents_to_split = %u\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- (long long)i_size_read(inode), le32_to_cpu(di->i_clusters),
- clusters_to_alloc, extents_to_split);
-
ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode),
wc->w_di_bh);
ret = ocfs2_lock_allocators(inode, &et,
@@ -1938,8 +1934,8 @@ static void ocfs2_write_end_inline(struct inode *inode, loff_t pos,
memcpy(di->id2.i_data.id_data + pos, kaddr + pos, *copied);
kunmap_atomic(kaddr, KM_USER0);
- mlog(0, "Data written to inode at offset %llu. "
- "id_count = %u, copied = %u, i_dyn_features = 0x%x\n",
+ trace_ocfs2_write_end_inline(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
(unsigned long long)pos, *copied,
le16_to_cpu(di->id2.i_data.id_count),
le16_to_cpu(di->i_dyn_features));
diff --git a/fs/ocfs2/buffer_head_io.c b/fs/ocfs2/buffer_head_io.c
index f9d5d3ffc75..5d18ad10c27 100644
--- a/fs/ocfs2/buffer_head_io.c
+++ b/fs/ocfs2/buffer_head_io.c
@@ -35,8 +35,8 @@
#include "inode.h"
#include "journal.h"
#include "uptodate.h"
-
#include "buffer_head_io.h"
+#include "ocfs2_trace.h"
/*
* Bits on bh->b_state used by ocfs2.
@@ -55,8 +55,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
{
int ret = 0;
- mlog_entry("(bh->b_blocknr = %llu, ci=%p)\n",
- (unsigned long long)bh->b_blocknr, ci);
+ trace_ocfs2_write_block((unsigned long long)bh->b_blocknr, ci);
BUG_ON(bh->b_blocknr < OCFS2_SUPER_BLOCK_BLKNO);
BUG_ON(buffer_jbd(bh));
@@ -66,6 +65,7 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
* can get modified during recovery even if read-only. */
if (ocfs2_is_hard_readonly(osb)) {
ret = -EROFS;
+ mlog_errno(ret);
goto out;
}
@@ -91,11 +91,11 @@ int ocfs2_write_block(struct ocfs2_super *osb, struct buffer_head *bh,
* uptodate. */
ret = -EIO;
put_bh(bh);
+ mlog_errno(ret);
}
ocfs2_metadata_cache_io_unlock(ci);
out:
- mlog_exit(ret);
return ret;
}
@@ -106,10 +106,10 @@ int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
unsigned int i;
struct buffer_head *bh;
- if (!nr) {
- mlog(ML_BH_IO, "No buffers will be read!\n");
+ trace_ocfs2_read_blocks_sync((unsigned long long)block, nr);
+
+ if (!nr)
goto bail;
- }
for (i = 0 ; i < nr ; i++) {
if (bhs[i] == NULL) {
@@ -123,10 +123,8 @@ int ocfs2_read_blocks_sync(struct ocfs2_super *osb, u64 block,
bh = bhs[i];
if (buffer_jbd(bh)) {
- mlog(ML_BH_IO,
- "trying to sync read a jbd "
- "managed bh (blocknr = %llu), skipping\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_read_blocks_sync_jbd(
+ (unsigned long long)bh->b_blocknr);
continue;
}
@@ -186,8 +184,7 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
struct buffer_head *bh;
struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
- mlog_entry("(ci=%p, block=(%llu), nr=(%d), flags=%d)\n",
- ci, (unsigned long long)block, nr, flags);
+ trace_ocfs2_read_blocks_begin(ci, (unsigned long long)block, nr, flags);
BUG_ON(!ci);
BUG_ON((flags & OCFS2_BH_READAHEAD) &&
@@ -207,7 +204,6 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
}
if (nr == 0) {
- mlog(ML_BH_IO, "No buffers will be read!\n");
status = 0;
goto bail;
}
@@ -251,8 +247,7 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
*/
if (!ignore_cache && !ocfs2_buffer_uptodate(ci, bh)) {
- mlog(ML_UPTODATE,
- "bh (%llu), owner %llu not uptodate\n",
+ trace_ocfs2_read_blocks_from_disk(
(unsigned long long)bh->b_blocknr,
(unsigned long long)ocfs2_metadata_cache_owner(ci));
/* We're using ignore_cache here to say
@@ -260,11 +255,10 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
ignore_cache = 1;
}
+ trace_ocfs2_read_blocks_bh((unsigned long long)bh->b_blocknr,
+ ignore_cache, buffer_jbd(bh), buffer_dirty(bh));
+
if (buffer_jbd(bh)) {
- if (ignore_cache)
- mlog(ML_BH_IO, "trying to sync read a jbd "
- "managed bh (blocknr = %llu)\n",
- (unsigned long long)bh->b_blocknr);
continue;
}
@@ -272,9 +266,6 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
if (buffer_dirty(bh)) {
/* This should probably be a BUG, or
* at least return an error. */
- mlog(ML_BH_IO, "asking me to sync read a dirty "
- "buffer! (blocknr = %llu)\n",
- (unsigned long long)bh->b_blocknr);
continue;
}
@@ -367,14 +358,11 @@ int ocfs2_read_blocks(struct ocfs2_caching_info *ci, u64 block, int nr,
}
ocfs2_metadata_cache_io_unlock(ci);
- mlog(ML_BH_IO, "block=(%llu), nr=(%d), cached=%s, flags=0x%x\n",
- (unsigned long long)block, nr,
- ((flags & OCFS2_BH_IGNORE_CACHE) || ignore_cache) ? "no" : "yes",
- flags);
+ trace_ocfs2_read_blocks_end((unsigned long long)block, nr,
+ flags, ignore_cache);
bail:
- mlog_exit(status);
return status;
}
@@ -408,13 +396,12 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
int ret = 0;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
- mlog_entry_void();
-
BUG_ON(buffer_jbd(bh));
ocfs2_check_super_or_backup(osb->sb, bh->b_blocknr);
if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb)) {
ret = -EROFS;
+ mlog_errno(ret);
goto out;
}
@@ -434,9 +421,9 @@ int ocfs2_write_super_or_backup(struct ocfs2_super *osb,
if (!buffer_uptodate(bh)) {
ret = -EIO;
put_bh(bh);
+ mlog_errno(ret);
}
out:
- mlog_exit(ret);
return ret;
}
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 1adab287bd2..2461eb3272e 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -1654,8 +1654,6 @@ static int o2hb_populate_slot_data(struct o2hb_region *reg)
struct o2hb_disk_slot *slot;
struct o2hb_disk_heartbeat_block *hb_block;
- mlog_entry_void();
-
ret = o2hb_read_slots(reg, reg->hr_blocks);
if (ret) {
mlog_errno(ret);
@@ -1677,7 +1675,6 @@ static int o2hb_populate_slot_data(struct o2hb_region *reg)
}
out:
- mlog_exit(ret);
return ret;
}
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c
index 6c61771469a..07ac24fd925 100644
--- a/fs/ocfs2/cluster/masklog.c
+++ b/fs/ocfs2/cluster/masklog.c
@@ -30,7 +30,7 @@
struct mlog_bits mlog_and_bits = MLOG_BITS_RHS(MLOG_INITIAL_AND_MASK);
EXPORT_SYMBOL_GPL(mlog_and_bits);
-struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(MLOG_INITIAL_NOT_MASK);
+struct mlog_bits mlog_not_bits = MLOG_BITS_RHS(0);
EXPORT_SYMBOL_GPL(mlog_not_bits);
static ssize_t mlog_mask_show(u64 mask, char *buf)
@@ -80,8 +80,6 @@ struct mlog_attribute {
}
static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = {
- define_mask(ENTRY),
- define_mask(EXIT),
define_mask(TCP),
define_mask(MSG),
define_mask(SOCKET),
@@ -93,27 +91,11 @@ static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = {
define_mask(DLM_THREAD),
define_mask(DLM_MASTER),
define_mask(DLM_RECOVERY),
- define_mask(AIO),
- define_mask(JOURNAL),
- define_mask(DISK_ALLOC),
- define_mask(SUPER),
- define_mask(FILE_IO),
- define_mask(EXTENT_MAP),
define_mask(DLM_GLUE),
- define_mask(BH_IO),
- define_mask(UPTODATE),
- define_mask(NAMEI),
- define_mask(INODE),
define_mask(VOTE),
- define_mask(DCACHE),
define_mask(CONN),
define_mask(QUORUM),
- define_mask(EXPORT),
- define_mask(XATTR),
- define_mask(QUOTA),
- define_mask(REFCOUNT),
define_mask(BASTS),
- define_mask(RESERVATIONS),
define_mask(CLUSTER),
define_mask(ERROR),
define_mask(NOTICE),
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 34d6544357d..baa2b9ef7ee 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -82,41 +82,23 @@
/* bits that are frequently given and infrequently matched in the low word */
/* NOTE: If you add a flag, you need to also update masklog.c! */
-#define ML_ENTRY 0x0000000000000001ULL /* func call entry */
-#define ML_EXIT 0x0000000000000002ULL /* func call exit */
-#define ML_TCP 0x0000000000000004ULL /* net cluster/tcp.c */
-#define ML_MSG 0x0000000000000008ULL /* net network messages */
-#define ML_SOCKET 0x0000000000000010ULL /* net socket lifetime */
-#define ML_HEARTBEAT 0x0000000000000020ULL /* hb all heartbeat tracking */
-#define ML_HB_BIO 0x0000000000000040ULL /* hb io tracing */
-#define ML_DLMFS 0x0000000000000080ULL /* dlm user dlmfs */
-#define ML_DLM 0x0000000000000100ULL /* dlm general debugging */
-#define ML_DLM_DOMAIN 0x0000000000000200ULL /* dlm domain debugging */
-#define ML_DLM_THREAD 0x0000000000000400ULL /* dlm domain thread */
-#define ML_DLM_MASTER 0x0000000000000800ULL /* dlm master functions */
-#define ML_DLM_RECOVERY 0x0000000000001000ULL /* dlm master functions */
-#define ML_AIO 0x0000000000002000ULL /* ocfs2 aio read and write */
-#define ML_JOURNAL 0x0000000000004000ULL /* ocfs2 journalling functions */
-#define ML_DISK_ALLOC 0x0000000000008000ULL /* ocfs2 disk allocation */
-#define ML_SUPER 0x0000000000010000ULL /* ocfs2 mount / umount */
-#define ML_FILE_IO 0x0000000000020000ULL /* ocfs2 file I/O */
-#define ML_EXTENT_MAP 0x0000000000040000ULL /* ocfs2 extent map caching */
-#define ML_DLM_GLUE 0x0000000000080000ULL /* ocfs2 dlm glue layer */
-#define ML_BH_IO 0x0000000000100000ULL /* ocfs2 buffer I/O */
-#define ML_UPTODATE 0x0000000000200000ULL /* ocfs2 caching sequence #'s */
-#define ML_NAMEI 0x0000000000400000ULL /* ocfs2 directory / namespace */
-#define ML_INODE 0x0000000000800000ULL /* ocfs2 inode manipulation */
-#define ML_VOTE 0x0000000001000000ULL /* ocfs2 node messaging */
-#define ML_DCACHE 0x0000000002000000ULL /* ocfs2 dcache operations */
-#define ML_CONN 0x0000000004000000ULL /* net connection management */
-#define ML_QUORUM 0x0000000008000000ULL /* net connection quorum */
-#define ML_EXPORT 0x0000000010000000ULL /* ocfs2 export operations */
-#define ML_XATTR 0x0000000020000000ULL /* ocfs2 extended attributes */
-#define ML_QUOTA 0x0000000040000000ULL /* ocfs2 quota operations */
-#define ML_REFCOUNT 0x0000000080000000ULL /* refcount tree operations */
-#define ML_BASTS 0x0000000100000000ULL /* dlmglue asts and basts */
-#define ML_RESERVATIONS 0x0000000200000000ULL /* ocfs2 alloc reservations */
-#define ML_CLUSTER 0x0000000400000000ULL /* cluster stack */
+#define ML_TCP 0x0000000000000001ULL /* net cluster/tcp.c */
+#define ML_MSG 0x0000000000000002ULL /* net network messages */
+#define ML_SOCKET 0x0000000000000004ULL /* net socket lifetime */
+#define ML_HEARTBEAT 0x0000000000000008ULL /* hb all heartbeat tracking */
+#define ML_HB_BIO 0x0000000000000010ULL /* hb io tracing */
+#define ML_DLMFS 0x0000000000000020ULL /* dlm user dlmfs */
+#define ML_DLM 0x0000000000000040ULL /* dlm general debugging */
+#define ML_DLM_DOMAIN 0x0000000000000080ULL /* dlm domain debugging */
+#define ML_DLM_THREAD 0x0000000000000100ULL /* dlm domain thread */
+#define ML_DLM_MASTER 0x0000000000000200ULL /* dlm master functions */
+#define ML_DLM_RECOVERY 0x0000000000000400ULL /* dlm master functions */
+#define ML_DLM_GLUE 0x0000000000000800ULL /* ocfs2 dlm glue layer */
+#define ML_VOTE 0x0000000000001000ULL /* ocfs2 node messaging */
+#define ML_CONN 0x0000000000002000ULL /* net connection management */
+#define ML_QUORUM 0x0000000000004000ULL /* net connection quorum */
+#define ML_BASTS 0x0000000000008000ULL /* dlmglue asts and basts */
+#define ML_CLUSTER 0x0000000000010000ULL /* cluster stack */
/* bits that are infrequently given and frequently matched in the high word */
#define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */
@@ -124,7 +106,6 @@
#define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */
#define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE)
-#define MLOG_INITIAL_NOT_MASK (ML_ENTRY|ML_EXIT)
#ifndef MLOG_MASK_PREFIX
#define MLOG_MASK_PREFIX 0
#endif
@@ -222,58 +203,6 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
mlog(ML_ERROR, "status = %lld\n", (long long)_st); \
} while (0)
-#if defined(CONFIG_OCFS2_DEBUG_MASKLOG)
-#define mlog_entry(fmt, args...) do { \
- mlog(ML_ENTRY, "ENTRY:" fmt , ##args); \
-} while (0)
-
-#define mlog_entry_void() do { \
- mlog(ML_ENTRY, "ENTRY:\n"); \
-} while (0)
-
-/*
- * We disable this for sparse.
- */
-#if !defined(__CHECKER__)
-#define mlog_exit(st) do { \
- if (__builtin_types_compatible_p(typeof(st), unsigned long)) \
- mlog(ML_EXIT, "EXIT: %lu\n", (unsigned long) (st)); \
- else if (__builtin_types_compatible_p(typeof(st), signed long)) \
- mlog(ML_EXIT, "EXIT: %ld\n", (signed long) (st)); \
- else if (__builtin_types_compatible_p(typeof(st), unsigned int) \
- || __builtin_types_compatible_p(typeof(st), unsigned short) \
- || __builtin_types_compatible_p(typeof(st), unsigned char)) \
- mlog(ML_EXIT, "EXIT: %u\n", (unsigned int) (st)); \
- else if (__builtin_types_compatible_p(typeof(st), signed int) \
- || __builtin_types_compatible_p(typeof(st), signed short) \
- || __builtin_types_compatible_p(typeof(st), signed char)) \
- mlog(ML_EXIT, "EXIT: %d\n", (signed int) (st)); \
- else if (__builtin_types_compatible_p(typeof(st), long long)) \
- mlog(ML_EXIT, "EXIT: %lld\n", (long long) (st)); \
- else \
- mlog(ML_EXIT, "EXIT: %llu\n", (unsigned long long) (st)); \
-} while (0)
-#else
-#define mlog_exit(st) do { \
- mlog(ML_EXIT, "EXIT: %lld\n", (long long) (st)); \
-} while (0)
-#endif
-
-#define mlog_exit_ptr(ptr) do { \
- mlog(ML_EXIT, "EXIT: %p\n", ptr); \
-} while (0)
-
-#define mlog_exit_void() do { \
- mlog(ML_EXIT, "EXIT\n"); \
-} while (0)
-#else
-#define mlog_entry(...) do { } while (0)
-#define mlog_entry_void(...) do { } while (0)
-#define mlog_exit(...) do { } while (0)
-#define mlog_exit_ptr(...) do { } while (0)
-#define mlog_exit_void(...) do { } while (0)
-#endif /* defined(CONFIG_OCFS2_DEBUG_MASKLOG) */
-
#define mlog_bug_on_msg(cond, fmt, args...) do { \
if (cond) { \
mlog(ML_ERROR, "bug expression: " #cond "\n"); \
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 3b11cb1e38f..ee04ff5ee60 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -210,10 +210,6 @@ static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc)
sc->sc_tv_func_stop = ktime_get();
}
-static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc)
-{
- return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start);
-}
#else /* CONFIG_DEBUG_FS */
# define o2net_init_nst(a, b, c, d, e)
# define o2net_set_nst_sock_time(a)
@@ -227,10 +223,14 @@ static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc)
# define o2net_set_advance_stop_time(a)
# define o2net_set_func_start_time(a)
# define o2net_set_func_stop_time(a)
-# define o2net_get_func_run_time(a) (ktime_t)0
#endif /* CONFIG_DEBUG_FS */
#ifdef CONFIG_OCFS2_FS_STATS
+static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc)
+{
+ return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start);
+}
+
static void o2net_update_send_stats(struct o2net_send_tracking *nst,
struct o2net_sock_container *sc)
{
diff --git a/fs/ocfs2/dcache.c b/fs/ocfs2/dcache.c
index 7eb90403fc8..e5ba3481833 100644
--- a/fs/ocfs2/dcache.c
+++ b/fs/ocfs2/dcache.c
@@ -28,7 +28,6 @@
#include <linux/slab.h>
#include <linux/namei.h>
-#define MLOG_MASK_PREFIX ML_DCACHE
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -39,6 +38,7 @@
#include "file.h"
#include "inode.h"
#include "super.h"
+#include "ocfs2_trace.h"
void ocfs2_dentry_attach_gen(struct dentry *dentry)
{
@@ -62,8 +62,8 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
inode = dentry->d_inode;
osb = OCFS2_SB(dentry->d_sb);
- mlog_entry("(0x%p, '%.*s')\n", dentry,
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_dentry_revalidate(dentry, dentry->d_name.len,
+ dentry->d_name.name);
/* For a negative dentry -
* check the generation number of the parent and compare with the
@@ -73,9 +73,10 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
unsigned long gen = (unsigned long) dentry->d_fsdata;
unsigned long pgen =
OCFS2_I(dentry->d_parent->d_inode)->ip_dir_lock_gen;
- mlog(0, "negative dentry: %.*s parent gen: %lu "
- "dentry gen: %lu\n",
- dentry->d_name.len, dentry->d_name.name, pgen, gen);
+
+ trace_ocfs2_dentry_revalidate_negative(dentry->d_name.len,
+ dentry->d_name.name,
+ pgen, gen);
if (gen != pgen)
goto bail;
goto valid;
@@ -90,8 +91,8 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
/* did we or someone else delete this inode? */
if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
spin_unlock(&OCFS2_I(inode)->ip_lock);
- mlog(0, "inode (%llu) deleted, returning false\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ trace_ocfs2_dentry_revalidate_delete(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
goto bail;
}
spin_unlock(&OCFS2_I(inode)->ip_lock);
@@ -101,10 +102,9 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
* inode nlink hits zero, it never goes back.
*/
if (inode->i_nlink == 0) {
- mlog(0, "Inode %llu orphaned, returning false "
- "dir = %d\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- S_ISDIR(inode->i_mode));
+ trace_ocfs2_dentry_revalidate_orphaned(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ S_ISDIR(inode->i_mode));
goto bail;
}
@@ -113,9 +113,8 @@ static int ocfs2_dentry_revalidate(struct dentry *dentry,
* redo it.
*/
if (!dentry->d_fsdata) {
- mlog(0, "Inode %llu doesn't have dentry lock, "
- "returning false\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ trace_ocfs2_dentry_revalidate_nofsdata(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
goto bail;
}
@@ -123,8 +122,7 @@ valid:
ret = 1;
bail:
- mlog_exit(ret);
-
+ trace_ocfs2_dentry_revalidate_ret(ret);
return ret;
}
@@ -181,8 +179,8 @@ struct dentry *ocfs2_find_local_alias(struct inode *inode,
spin_lock(&dentry->d_lock);
if (ocfs2_match_dentry(dentry, parent_blkno, skip_unhashed)) {
- mlog(0, "dentry found: %.*s\n",
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_find_local_alias(dentry->d_name.len,
+ dentry->d_name.name);
dget_dlock(dentry);
spin_unlock(&dentry->d_lock);
@@ -240,9 +238,8 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry,
struct dentry *alias;
struct ocfs2_dentry_lock *dl = dentry->d_fsdata;
- mlog(0, "Attach \"%.*s\", parent %llu, fsdata: %p\n",
- dentry->d_name.len, dentry->d_name.name,
- (unsigned long long)parent_blkno, dl);
+ trace_ocfs2_dentry_attach_lock(dentry->d_name.len, dentry->d_name.name,
+ (unsigned long long)parent_blkno, dl);
/*
* Negative dentry. We ignore these for now.
@@ -292,7 +289,9 @@ int ocfs2_dentry_attach_lock(struct dentry *dentry,
(unsigned long long)parent_blkno,
(unsigned long long)dl->dl_parent_blkno);
- mlog(0, "Found: %s\n", dl->dl_lockres.l_name);
+ trace_ocfs2_dentry_attach_lock_found(dl->dl_lockres.l_name,
+ (unsigned long long)parent_blkno,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
goto out_attach;
}
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index f97b6f1c61d..9fe5b8fd658 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -43,7 +43,6 @@
#include <linux/quotaops.h>
#include <linux/sort.h>
-#define MLOG_MASK_PREFIX ML_NAMEI
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -61,6 +60,7 @@
#include "super.h"
#include "sysfile.h"
#include "uptodate.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -322,21 +322,23 @@ static int ocfs2_check_dir_entry(struct inode * dir,
const char *error_msg = NULL;
const int rlen = le16_to_cpu(de->rec_len);
- if (rlen < OCFS2_DIR_REC_LEN(1))
+ if (unlikely(rlen < OCFS2_DIR_REC_LEN(1)))
error_msg = "rec_len is smaller than minimal";
- else if (rlen % 4 != 0)
+ else if (unlikely(rlen % 4 != 0))
error_msg = "rec_len % 4 != 0";
- else if (rlen < OCFS2_DIR_REC_LEN(de->name_len))
+ else if (unlikely(rlen < OCFS2_DIR_REC_LEN(de->name_len)))
error_msg = "rec_len is too small for name_len";
- else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize)
+ else if (unlikely(
+ ((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize))
error_msg = "directory entry across blocks";
- if (error_msg != NULL)
+ if (unlikely(error_msg != NULL))
mlog(ML_ERROR, "bad entry in directory #%llu: %s - "
"offset=%lu, inode=%llu, rec_len=%d, name_len=%d\n",
(unsigned long long)OCFS2_I(dir)->ip_blkno, error_msg,
offset, (unsigned long long)le64_to_cpu(de->inode), rlen,
de->name_len);
+
return error_msg == NULL ? 1 : 0;
}
@@ -367,8 +369,6 @@ static inline int ocfs2_search_dirblock(struct buffer_head *bh,
int de_len;
int ret = 0;
- mlog_entry_void();
-
de_buf = first_de;
dlimit = de_buf + bytes;
@@ -402,7 +402,7 @@ static inline int ocfs2_search_dirblock(struct buffer_head *bh,
}
bail:
- mlog_exit(ret);
+ trace_ocfs2_search_dirblock(ret);
return ret;
}
@@ -447,8 +447,7 @@ static int ocfs2_validate_dir_block(struct super_block *sb,
* We don't validate dirents here, that's handled
* in-place when the code walks them.
*/
- mlog(0, "Validating dirblock %llu\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_validate_dir_block((unsigned long long)bh->b_blocknr);
BUG_ON(!buffer_uptodate(bh));
@@ -706,8 +705,6 @@ static struct buffer_head *ocfs2_find_entry_el(const char *name, int namelen,
int num = 0;
int nblocks, i, err;
- mlog_entry_void();
-
sb = dir->i_sb;
nblocks = i_size_read(dir) >> sb->s_blocksize_bits;
@@ -788,7 +785,7 @@ cleanup_and_exit:
for (; ra_ptr < ra_max; ra_ptr++)
brelse(bh_use[ra_ptr]);
- mlog_exit_ptr(ret);
+ trace_ocfs2_find_entry_el(ret);
return ret;
}
@@ -950,11 +947,9 @@ static int ocfs2_dx_dir_search(const char *name, int namelen,
goto out;
}
- mlog(0, "Dir %llu: name: \"%.*s\", lookup of hash: %u.0x%x "
- "returns: %llu\n",
- (unsigned long long)OCFS2_I(dir)->ip_blkno,
- namelen, name, hinfo->major_hash, hinfo->minor_hash,
- (unsigned long long)phys);
+ trace_ocfs2_dx_dir_search((unsigned long long)OCFS2_I(dir)->ip_blkno,
+ namelen, name, hinfo->major_hash,
+ hinfo->minor_hash, (unsigned long long)phys);
ret = ocfs2_read_dx_leaf(dir, phys, &dx_leaf_bh);
if (ret) {
@@ -964,9 +959,9 @@ static int ocfs2_dx_dir_search(const char *name, int namelen,
dx_leaf = (struct ocfs2_dx_leaf *) dx_leaf_bh->b_data;
- mlog(0, "leaf info: num_used: %d, count: %d\n",
- le16_to_cpu(dx_leaf->dl_list.de_num_used),
- le16_to_cpu(dx_leaf->dl_list.de_count));
+ trace_ocfs2_dx_dir_search_leaf_info(
+ le16_to_cpu(dx_leaf->dl_list.de_num_used),
+ le16_to_cpu(dx_leaf->dl_list.de_count));
entry_list = &dx_leaf->dl_list;
@@ -1166,8 +1161,6 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
int i, status = -ENOENT;
ocfs2_journal_access_func access = ocfs2_journal_access_db;
- mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p)\n", handle, dir, de_del, bh);
-
if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL)
access = ocfs2_journal_access_di;
@@ -1202,7 +1195,6 @@ static int __ocfs2_delete_entry(handle_t *handle, struct inode *dir,
de = (struct ocfs2_dir_entry *)((char *)de + le16_to_cpu(de->rec_len));
}
bail:
- mlog_exit(status);
return status;
}
@@ -1348,8 +1340,8 @@ static int ocfs2_delete_entry_dx(handle_t *handle, struct inode *dir,
}
}
- mlog(0, "Dir %llu: delete entry at index: %d\n",
- (unsigned long long)OCFS2_I(dir)->ip_blkno, index);
+ trace_ocfs2_delete_entry_dx((unsigned long long)OCFS2_I(dir)->ip_blkno,
+ index);
ret = __ocfs2_delete_entry(handle, dir, lookup->dl_entry,
leaf_bh, leaf_bh->b_data, leaf_bh->b_size);
@@ -1632,8 +1624,6 @@ int __ocfs2_add_entry(handle_t *handle,
struct buffer_head *insert_bh = lookup->dl_leaf_bh;
char *data_start = insert_bh->b_data;
- mlog_entry_void();
-
if (!namelen)
return -EINVAL;
@@ -1765,8 +1755,9 @@ int __ocfs2_add_entry(handle_t *handle,
* from ever getting here. */
retval = -ENOSPC;
bail:
+ if (retval)
+ mlog_errno(retval);
- mlog_exit(retval);
return retval;
}
@@ -2028,8 +2019,7 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
struct inode *inode = filp->f_path.dentry->d_inode;
int lock_level = 0;
- mlog_entry("dirino=%llu\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ trace_ocfs2_readdir((unsigned long long)OCFS2_I(inode)->ip_blkno);
error = ocfs2_inode_lock_atime(inode, filp->f_vfsmnt, &lock_level);
if (lock_level && error >= 0) {
@@ -2051,9 +2041,10 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
dirent, filldir, NULL);
ocfs2_inode_unlock(inode, lock_level);
+ if (error)
+ mlog_errno(error);
bail_nolock:
- mlog_exit(error);
return error;
}
@@ -2069,8 +2060,8 @@ int ocfs2_find_files_on_disk(const char *name,
{
int status = -ENOENT;
- mlog(0, "name=%.*s, blkno=%p, inode=%llu\n", namelen, name, blkno,
- (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ trace_ocfs2_find_files_on_disk(namelen, name, blkno,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
status = ocfs2_find_entry(name, namelen, inode, lookup);
if (status)
@@ -2114,8 +2105,8 @@ int ocfs2_check_dir_for_entry(struct inode *dir,
int ret;
struct ocfs2_dir_lookup_result lookup = { NULL, };
- mlog_entry("dir %llu, name '%.*s'\n",
- (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name);
+ trace_ocfs2_check_dir_for_entry(
+ (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen, name);
ret = -EEXIST;
if (ocfs2_find_entry(name, namelen, dir, &lookup) == 0)
@@ -2125,7 +2116,8 @@ int ocfs2_check_dir_for_entry(struct inode *dir,
bail:
ocfs2_free_dir_lookup_result(&lookup);
- mlog_exit(ret);
+ if (ret)
+ mlog_errno(ret);
return ret;
}
@@ -2324,8 +2316,6 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,
struct buffer_head *new_bh = NULL;
struct ocfs2_dir_entry *de;
- mlog_entry_void();
-
if (ocfs2_new_dir_wants_trailer(inode))
size = ocfs2_dir_trailer_blk_off(parent->i_sb);
@@ -2380,7 +2370,6 @@ static int ocfs2_fill_new_dir_el(struct ocfs2_super *osb,
bail:
brelse(new_bh);
- mlog_exit(status);
return status;
}
@@ -2409,9 +2398,9 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb,
goto out;
}
- mlog(0, "Dir %llu, attach new index block: %llu\n",
- (unsigned long long)OCFS2_I(dir)->ip_blkno,
- (unsigned long long)dr_blkno);
+ trace_ocfs2_dx_dir_attach_index(
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)dr_blkno);
dx_root_bh = sb_getblk(osb->sb, dr_blkno);
if (dx_root_bh == NULL) {
@@ -2511,11 +2500,10 @@ static int ocfs2_dx_dir_format_cluster(struct ocfs2_super *osb,
dx_leaf->dl_list.de_count =
cpu_to_le16(ocfs2_dx_entries_per_leaf(osb->sb));
- mlog(0,
- "Dir %llu, format dx_leaf: %llu, entry count: %u\n",
- (unsigned long long)OCFS2_I(dir)->ip_blkno,
- (unsigned long long)bh->b_blocknr,
- le16_to_cpu(dx_leaf->dl_list.de_count));
+ trace_ocfs2_dx_dir_format_cluster(
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)bh->b_blocknr,
+ le16_to_cpu(dx_leaf->dl_list.de_count));
ocfs2_journal_dirty(handle, bh);
}
@@ -2759,12 +2747,11 @@ static void ocfs2_dx_dir_index_root_block(struct inode *dir,
ocfs2_dx_dir_name_hash(dir, de->name, de->name_len, &hinfo);
- mlog(0,
- "dir: %llu, major: 0x%x minor: 0x%x, index: %u, name: %.*s\n",
- (unsigned long long)dir->i_ino, hinfo.major_hash,
- hinfo.minor_hash,
- le16_to_cpu(dx_root->dr_entries.de_num_used),
- de->name_len, de->name);
+ trace_ocfs2_dx_dir_index_root_block(
+ (unsigned long long)dir->i_ino,
+ hinfo.major_hash, hinfo.minor_hash,
+ de->name_len, de->name,
+ le16_to_cpu(dx_root->dr_entries.de_num_used));
ocfs2_dx_entry_list_insert(&dx_root->dr_entries, &hinfo,
dirent_blk);
@@ -3235,7 +3222,6 @@ static int ocfs2_do_extend_dir(struct super_block *sb,
bail:
if (did_quota && status < 0)
dquot_free_space_nodirty(dir, ocfs2_clusters_to_bytes(sb, 1));
- mlog_exit(status);
return status;
}
@@ -3270,8 +3256,6 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
struct ocfs2_extent_tree et;
struct buffer_head *dx_root_bh = lookup->dl_dx_root_bh;
- mlog_entry_void();
-
if (OCFS2_I(dir)->ip_dyn_features & OCFS2_INLINE_DATA_FL) {
/*
* This would be a code error as an inline directory should
@@ -3320,8 +3304,8 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
down_write(&OCFS2_I(dir)->ip_alloc_sem);
drop_alloc_sem = 1;
dir_i_size = i_size_read(dir);
- mlog(0, "extending dir %llu (i_size = %lld)\n",
- (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size);
+ trace_ocfs2_extend_dir((unsigned long long)OCFS2_I(dir)->ip_blkno,
+ dir_i_size);
/* dir->i_size is always block aligned. */
spin_lock(&OCFS2_I(dir)->ip_lock);
@@ -3436,7 +3420,6 @@ bail:
brelse(new_bh);
- mlog_exit(status);
return status;
}
@@ -3583,8 +3566,9 @@ next:
status = 0;
bail:
brelse(bh);
+ if (status)
+ mlog_errno(status);
- mlog_exit(status);
return status;
}
@@ -3815,9 +3799,9 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir,
struct ocfs2_dx_root_block *dx_root;
struct ocfs2_dx_leaf *tmp_dx_leaf = NULL;
- mlog(0, "DX Dir: %llu, rebalance leaf leaf_blkno: %llu insert: %u\n",
- (unsigned long long)OCFS2_I(dir)->ip_blkno,
- (unsigned long long)leaf_blkno, insert_hash);
+ trace_ocfs2_dx_dir_rebalance((unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)leaf_blkno,
+ insert_hash);
ocfs2_init_dx_root_extent_tree(&et, INODE_CACHE(dir), dx_root_bh);
@@ -3897,8 +3881,7 @@ static int ocfs2_dx_dir_rebalance(struct ocfs2_super *osb, struct inode *dir,
goto out_commit;
}
- mlog(0, "Split leaf (%u) at %u, insert major hash is %u\n",
- leaf_cpos, split_hash, insert_hash);
+ trace_ocfs2_dx_dir_rebalance_split(leaf_cpos, split_hash, insert_hash);
/*
* We have to carefully order operations here. There are items
@@ -4355,8 +4338,8 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
unsigned int blocks_wanted = 1;
struct buffer_head *bh = NULL;
- mlog(0, "getting ready to insert namelen %d into dir %llu\n",
- namelen, (unsigned long long)OCFS2_I(dir)->ip_blkno);
+ trace_ocfs2_prepare_dir_for_insert(
+ (unsigned long long)OCFS2_I(dir)->ip_blkno, namelen);
if (!namelen) {
ret = -EINVAL;
diff --git a/fs/ocfs2/dlm/dlmconvert.c b/fs/ocfs2/dlm/dlmconvert.c
index 9f30491e5e8..29a886d1e82 100644
--- a/fs/ocfs2/dlm/dlmconvert.c
+++ b/fs/ocfs2/dlm/dlmconvert.c
@@ -128,8 +128,8 @@ static enum dlm_status __dlmconvert_master(struct dlm_ctxt *dlm,
assert_spin_locked(&res->spinlock);
- mlog_entry("type=%d, convert_type=%d, new convert_type=%d\n",
- lock->ml.type, lock->ml.convert_type, type);
+ mlog(0, "type=%d, convert_type=%d, new convert_type=%d\n",
+ lock->ml.type, lock->ml.convert_type, type);
spin_lock(&lock->spinlock);
@@ -353,7 +353,7 @@ static enum dlm_status dlm_send_remote_convert_request(struct dlm_ctxt *dlm,
struct kvec vec[2];
size_t veclen = 1;
- mlog_entry("%.*s\n", res->lockname.len, res->lockname.name);
+ mlog(0, "%.*s\n", res->lockname.len, res->lockname.name);
memset(&convert, 0, sizeof(struct dlm_convert_lock));
convert.node_idx = dlm->node_num;
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 7e38a072d72..7540a492eab 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -188,7 +188,7 @@ struct dlm_lock_resource * __dlm_lookup_lockres_full(struct dlm_ctxt *dlm,
struct hlist_head *bucket;
struct hlist_node *list;
- mlog_entry("%.*s\n", len, name);
+ mlog(0, "%.*s\n", len, name);
assert_spin_locked(&dlm->spinlock);
@@ -222,7 +222,7 @@ struct dlm_lock_resource * __dlm_lookup_lockres(struct dlm_ctxt *dlm,
{
struct dlm_lock_resource *res = NULL;
- mlog_entry("%.*s\n", len, name);
+ mlog(0, "%.*s\n", len, name);
assert_spin_locked(&dlm->spinlock);
@@ -531,7 +531,7 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data,
unsigned int node;
struct dlm_exit_domain *exit_msg = (struct dlm_exit_domain *) msg->buf;
- mlog_entry("%p %u %p", msg, len, data);
+ mlog(0, "%p %u %p", msg, len, data);
if (!dlm_grab(dlm))
return 0;
@@ -926,9 +926,10 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data,
}
static int dlm_match_regions(struct dlm_ctxt *dlm,
- struct dlm_query_region *qr)
+ struct dlm_query_region *qr,
+ char *local, int locallen)
{
- char *local = NULL, *remote = qr->qr_regions;
+ char *remote = qr->qr_regions;
char *l, *r;
int localnr, i, j, foundit;
int status = 0;
@@ -957,13 +958,8 @@ static int dlm_match_regions(struct dlm_ctxt *dlm,
r += O2HB_MAX_REGION_NAME_LEN;
}
- local = kmalloc(sizeof(qr->qr_regions), GFP_ATOMIC);
- if (!local) {
- status = -ENOMEM;
- goto bail;
- }
-
- localnr = o2hb_get_all_regions(local, O2NM_MAX_REGIONS);
+ localnr = min(O2NM_MAX_REGIONS, locallen/O2HB_MAX_REGION_NAME_LEN);
+ localnr = o2hb_get_all_regions(local, (u8)localnr);
/* compare local regions with remote */
l = local;
@@ -1012,8 +1008,6 @@ static int dlm_match_regions(struct dlm_ctxt *dlm,
}
bail:
- kfree(local);
-
return status;
}
@@ -1075,6 +1069,7 @@ static int dlm_query_region_handler(struct o2net_msg *msg, u32 len,
{
struct dlm_query_region *qr;
struct dlm_ctxt *dlm = NULL;
+ char *local = NULL;
int status = 0;
int locked = 0;
@@ -1083,6 +1078,13 @@ static int dlm_query_region_handler(struct o2net_msg *msg, u32 len,
mlog(0, "Node %u queries hb regions on domain %s\n", qr->qr_node,
qr->qr_domain);
+ /* buffer used in dlm_mast_regions() */
+ local = kmalloc(sizeof(qr->qr_regions), GFP_KERNEL);
+ if (!local) {
+ status = -ENOMEM;
+ goto bail;
+ }
+
status = -EINVAL;
spin_lock(&dlm_domain_lock);
@@ -1112,13 +1114,15 @@ static int dlm_query_region_handler(struct o2net_msg *msg, u32 len,
goto bail;
}
- status = dlm_match_regions(dlm, qr);
+ status = dlm_match_regions(dlm, qr, local, sizeof(qr->qr_regions));
bail:
if (locked)
spin_unlock(&dlm->spinlock);
spin_unlock(&dlm_domain_lock);
+ kfree(local);
+
return status;
}
@@ -1553,7 +1557,7 @@ static int dlm_try_to_join_domain(struct dlm_ctxt *dlm)
struct domain_join_ctxt *ctxt;
enum dlm_query_join_response_code response = JOIN_DISALLOW;
- mlog_entry("%p", dlm);
+ mlog(0, "%p", dlm);
ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL);
if (!ctxt) {
diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c
index 7009292aac5..8d39e0fd66f 100644
--- a/fs/ocfs2/dlm/dlmlock.c
+++ b/fs/ocfs2/dlm/dlmlock.c
@@ -128,7 +128,7 @@ static enum dlm_status dlmlock_master(struct dlm_ctxt *dlm,
int call_ast = 0, kick_thread = 0;
enum dlm_status status = DLM_NORMAL;
- mlog_entry("type=%d\n", lock->ml.type);
+ mlog(0, "type=%d\n", lock->ml.type);
spin_lock(&res->spinlock);
/* if called from dlm_create_lock_handler, need to
@@ -227,8 +227,8 @@ static enum dlm_status dlmlock_remote(struct dlm_ctxt *dlm,
enum dlm_status status = DLM_DENIED;
int lockres_changed = 1;
- mlog_entry("type=%d\n", lock->ml.type);
- mlog(0, "lockres %.*s, flags = 0x%x\n", res->lockname.len,
+ mlog(0, "type=%d, lockres %.*s, flags = 0x%x\n",
+ lock->ml.type, res->lockname.len,
res->lockname.name, flags);
spin_lock(&res->spinlock);
@@ -308,8 +308,6 @@ static enum dlm_status dlm_send_remote_lock_request(struct dlm_ctxt *dlm,
int tmpret, status = 0;
enum dlm_status ret;
- mlog_entry_void();
-
memset(&create, 0, sizeof(create));
create.node_idx = dlm->node_num;
create.requested_type = lock->ml.type;
@@ -477,8 +475,6 @@ int dlm_create_lock_handler(struct o2net_msg *msg, u32 len, void *data,
BUG_ON(!dlm);
- mlog_entry_void();
-
if (!dlm_grab(dlm))
return DLM_REJECTED;
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c
index 59f0f6bdfc6..9d67610dfc7 100644
--- a/fs/ocfs2/dlm/dlmmaster.c
+++ b/fs/ocfs2/dlm/dlmmaster.c
@@ -426,8 +426,6 @@ static void dlm_mle_release(struct kref *kref)
struct dlm_master_list_entry *mle;
struct dlm_ctxt *dlm;
- mlog_entry_void();
-
mle = container_of(kref, struct dlm_master_list_entry, mle_refs);
dlm = mle->dlm;
@@ -3120,8 +3118,6 @@ static int dlm_add_migration_mle(struct dlm_ctxt *dlm,
*oldmle = NULL;
- mlog_entry_void();
-
assert_spin_locked(&dlm->spinlock);
assert_spin_locked(&dlm->master_lock);
@@ -3261,7 +3257,7 @@ void dlm_clean_master_list(struct dlm_ctxt *dlm, u8 dead_node)
struct hlist_node *list;
unsigned int i;
- mlog_entry("dlm=%s, dead node=%u\n", dlm->name, dead_node);
+ mlog(0, "dlm=%s, dead node=%u\n", dlm->name, dead_node);
top:
assert_spin_locked(&dlm->spinlock);
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index aaaffbcbe91..f1beb6fc254 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -727,7 +727,6 @@ static int dlm_remaster_locks(struct dlm_ctxt *dlm, u8 dead_node)
if (destroy)
dlm_destroy_recovery_area(dlm, dead_node);
- mlog_exit(status);
return status;
}
@@ -1496,9 +1495,9 @@ leave:
kfree(buf);
if (item)
kfree(item);
+ mlog_errno(ret);
}
- mlog_exit(ret);
return ret;
}
@@ -1567,7 +1566,6 @@ leave:
dlm_lockres_put(res);
}
kfree(data);
- mlog_exit(ret);
}
@@ -1986,7 +1984,6 @@ leave:
dlm_lock_put(newlock);
}
- mlog_exit(ret);
return ret;
}
@@ -2083,8 +2080,6 @@ static void dlm_finish_local_lockres_recovery(struct dlm_ctxt *dlm,
struct hlist_head *bucket;
struct dlm_lock_resource *res, *next;
- mlog_entry_void();
-
assert_spin_locked(&dlm->spinlock);
list_for_each_entry_safe(res, next, &dlm->reco.resources, recovering) {
@@ -2607,8 +2602,6 @@ static int dlm_send_begin_reco_message(struct dlm_ctxt *dlm, u8 dead_node)
int nodenum;
int status;
- mlog_entry("%u\n", dead_node);
-
mlog(0, "%s: dead node is %u\n", dlm->name, dead_node);
spin_lock(&dlm->spinlock);
diff --git a/fs/ocfs2/dlm/dlmunlock.c b/fs/ocfs2/dlm/dlmunlock.c
index 817287c6a6d..850aa7e8753 100644
--- a/fs/ocfs2/dlm/dlmunlock.c
+++ b/fs/ocfs2/dlm/dlmunlock.c
@@ -317,7 +317,7 @@ static enum dlm_status dlm_send_remote_unlock_request(struct dlm_ctxt *dlm,
struct kvec vec[2];
size_t veclen = 1;
- mlog_entry("%.*s\n", res->lockname.len, res->lockname.name);
+ mlog(0, "%.*s\n", res->lockname.len, res->lockname.name);
if (owner == dlm->node_num) {
/* ended up trying to contact ourself. this means
@@ -588,8 +588,6 @@ enum dlm_status dlmunlock(struct dlm_ctxt *dlm, struct dlm_lockstatus *lksb,
struct dlm_lock *lock = NULL;
int call_ast, is_master;
- mlog_entry_void();
-
if (!lksb) {
dlm_error(DLM_BADARGS);
return DLM_BADARGS;
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index e8d94d722ec..7642d7ca73e 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -64,7 +64,7 @@ struct ocfs2_mask_waiter {
unsigned long mw_mask;
unsigned long mw_goal;
#ifdef CONFIG_OCFS2_FS_STATS
- unsigned long long mw_lock_start;
+ ktime_t mw_lock_start;
#endif
};
@@ -397,8 +397,6 @@ static void ocfs2_build_lock_name(enum ocfs2_lock_type type,
{
int len;
- mlog_entry_void();
-
BUG_ON(type >= OCFS2_NUM_LOCK_TYPES);
len = snprintf(name, OCFS2_LOCK_ID_MAX_LEN, "%c%s%016llx%08x",
@@ -408,8 +406,6 @@ static void ocfs2_build_lock_name(enum ocfs2_lock_type type,
BUG_ON(len != (OCFS2_LOCK_ID_MAX_LEN - 1));
mlog(0, "built lock resource with name: %s\n", name);
-
- mlog_exit_void();
}
static DEFINE_SPINLOCK(ocfs2_dlm_tracking_lock);
@@ -435,44 +431,41 @@ static void ocfs2_remove_lockres_tracking(struct ocfs2_lock_res *res)
#ifdef CONFIG_OCFS2_FS_STATS
static void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
{
- res->l_lock_num_prmode = 0;
- res->l_lock_num_prmode_failed = 0;
- res->l_lock_total_prmode = 0;
- res->l_lock_max_prmode = 0;
- res->l_lock_num_exmode = 0;
- res->l_lock_num_exmode_failed = 0;
- res->l_lock_total_exmode = 0;
- res->l_lock_max_exmode = 0;
res->l_lock_refresh = 0;
+ memset(&res->l_lock_prmode, 0, sizeof(struct ocfs2_lock_stats));
+ memset(&res->l_lock_exmode, 0, sizeof(struct ocfs2_lock_stats));
}
static void ocfs2_update_lock_stats(struct ocfs2_lock_res *res, int level,
struct ocfs2_mask_waiter *mw, int ret)
{
- unsigned long long *num, *sum;
- unsigned int *max, *failed;
- struct timespec ts = current_kernel_time();
- unsigned long long time = timespec_to_ns(&ts) - mw->mw_lock_start;
-
- if (level == LKM_PRMODE) {
- num = &res->l_lock_num_prmode;
- sum = &res->l_lock_total_prmode;
- max = &res->l_lock_max_prmode;
- failed = &res->l_lock_num_prmode_failed;
- } else if (level == LKM_EXMODE) {
- num = &res->l_lock_num_exmode;
- sum = &res->l_lock_total_exmode;
- max = &res->l_lock_max_exmode;
- failed = &res->l_lock_num_exmode_failed;
- } else
+ u32 usec;
+ ktime_t kt;
+ struct ocfs2_lock_stats *stats;
+
+ if (level == LKM_PRMODE)
+ stats = &res->l_lock_prmode;
+ else if (level == LKM_EXMODE)
+ stats = &res->l_lock_exmode;
+ else
return;
- (*num)++;
- (*sum) += time;
- if (time > *max)
- *max = time;
+ kt = ktime_sub(ktime_get(), mw->mw_lock_start);
+ usec = ktime_to_us(kt);
+
+ stats->ls_gets++;
+ stats->ls_total += ktime_to_ns(kt);
+ /* overflow */
+ if (unlikely(stats->ls_gets) == 0) {
+ stats->ls_gets++;
+ stats->ls_total = ktime_to_ns(kt);
+ }
+
+ if (stats->ls_max < usec)
+ stats->ls_max = usec;
+
if (ret)
- (*failed)++;
+ stats->ls_fail++;
}
static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
@@ -482,8 +475,7 @@ static inline void ocfs2_track_lock_refresh(struct ocfs2_lock_res *lockres)
static inline void ocfs2_init_start_time(struct ocfs2_mask_waiter *mw)
{
- struct timespec ts = current_kernel_time();
- mw->mw_lock_start = timespec_to_ns(&ts);
+ mw->mw_lock_start = ktime_get();
}
#else
static inline void ocfs2_init_lock_stats(struct ocfs2_lock_res *res)
@@ -729,8 +721,6 @@ void ocfs2_refcount_lock_res_init(struct ocfs2_lock_res *lockres,
void ocfs2_lock_res_free(struct ocfs2_lock_res *res)
{
- mlog_entry_void();
-
if (!(res->l_flags & OCFS2_LOCK_INITIALIZED))
return;
@@ -756,14 +746,11 @@ void ocfs2_lock_res_free(struct ocfs2_lock_res *res)
memset(&res->l_lksb, 0, sizeof(res->l_lksb));
res->l_flags = 0UL;
- mlog_exit_void();
}
static inline void ocfs2_inc_holders(struct ocfs2_lock_res *lockres,
int level)
{
- mlog_entry_void();
-
BUG_ON(!lockres);
switch(level) {
@@ -776,15 +763,11 @@ static inline void ocfs2_inc_holders(struct ocfs2_lock_res *lockres,
default:
BUG();
}
-
- mlog_exit_void();
}
static inline void ocfs2_dec_holders(struct ocfs2_lock_res *lockres,
int level)
{
- mlog_entry_void();
-
BUG_ON(!lockres);
switch(level) {
@@ -799,7 +782,6 @@ static inline void ocfs2_dec_holders(struct ocfs2_lock_res *lockres,
default:
BUG();
}
- mlog_exit_void();
}
/* WARNING: This function lives in a world where the only three lock
@@ -846,8 +828,6 @@ static void lockres_clear_flags(struct ocfs2_lock_res *lockres,
static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res *lockres)
{
- mlog_entry_void();
-
BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BUSY));
BUG_ON(!(lockres->l_flags & OCFS2_LOCK_ATTACHED));
BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BLOCKED));
@@ -860,14 +840,10 @@ static inline void ocfs2_generic_handle_downconvert_action(struct ocfs2_lock_res
lockres_clear_flags(lockres, OCFS2_LOCK_BLOCKED);
}
lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
-
- mlog_exit_void();
}
static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lockres)
{
- mlog_entry_void();
-
BUG_ON(!(lockres->l_flags & OCFS2_LOCK_BUSY));
BUG_ON(!(lockres->l_flags & OCFS2_LOCK_ATTACHED));
@@ -889,14 +865,10 @@ static inline void ocfs2_generic_handle_convert_action(struct ocfs2_lock_res *lo
lockres_or_flags(lockres, OCFS2_LOCK_UPCONVERT_FINISHING);
lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
-
- mlog_exit_void();
}
static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *lockres)
{
- mlog_entry_void();
-
BUG_ON((!(lockres->l_flags & OCFS2_LOCK_BUSY)));
BUG_ON(lockres->l_flags & OCFS2_LOCK_ATTACHED);
@@ -908,15 +880,12 @@ static inline void ocfs2_generic_handle_attach_action(struct ocfs2_lock_res *loc
lockres->l_level = lockres->l_requested;
lockres_or_flags(lockres, OCFS2_LOCK_ATTACHED);
lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
-
- mlog_exit_void();
}
static int ocfs2_generic_handle_bast(struct ocfs2_lock_res *lockres,
int level)
{
int needs_downconvert = 0;
- mlog_entry_void();
assert_spin_locked(&lockres->l_lock);
@@ -938,8 +907,7 @@ static int ocfs2_generic_handle_bast(struct ocfs2_lock_res *lockres,
if (needs_downconvert)
lockres_or_flags(lockres, OCFS2_LOCK_BLOCKED);
-
- mlog_exit(needs_downconvert);
+ mlog(0, "needs_downconvert = %d\n", needs_downconvert);
return needs_downconvert;
}
@@ -1151,8 +1119,6 @@ static void ocfs2_unlock_ast(struct ocfs2_dlm_lksb *lksb, int error)
struct ocfs2_lock_res *lockres = ocfs2_lksb_to_lock_res(lksb);
unsigned long flags;
- mlog_entry_void();
-
mlog(ML_BASTS, "UNLOCK AST fired for lockres %s, action = %d\n",
lockres->l_name, lockres->l_unlock_action);
@@ -1162,7 +1128,6 @@ static void ocfs2_unlock_ast(struct ocfs2_dlm_lksb *lksb, int error)
"unlock_action %d\n", error, lockres->l_name,
lockres->l_unlock_action);
spin_unlock_irqrestore(&lockres->l_lock, flags);
- mlog_exit_void();
return;
}
@@ -1186,8 +1151,6 @@ static void ocfs2_unlock_ast(struct ocfs2_dlm_lksb *lksb, int error)
lockres->l_unlock_action = OCFS2_UNLOCK_INVALID;
wake_up(&lockres->l_event);
spin_unlock_irqrestore(&lockres->l_lock, flags);
-
- mlog_exit_void();
}
/*
@@ -1233,7 +1196,6 @@ static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
{
unsigned long flags;
- mlog_entry_void();
spin_lock_irqsave(&lockres->l_lock, flags);
lockres_clear_flags(lockres, OCFS2_LOCK_BUSY);
lockres_clear_flags(lockres, OCFS2_LOCK_UPCONVERT_FINISHING);
@@ -1244,7 +1206,6 @@ static inline void ocfs2_recover_from_dlm_error(struct ocfs2_lock_res *lockres,
spin_unlock_irqrestore(&lockres->l_lock, flags);
wake_up(&lockres->l_event);
- mlog_exit_void();
}
/* Note: If we detect another process working on the lock (i.e.,
@@ -1260,8 +1221,6 @@ static int ocfs2_lock_create(struct ocfs2_super *osb,
unsigned long flags;
unsigned int gen;
- mlog_entry_void();
-
mlog(0, "lock %s, level = %d, flags = %u\n", lockres->l_name, level,
dlm_flags);
@@ -1293,7 +1252,6 @@ static int ocfs2_lock_create(struct ocfs2_super *osb,
mlog(0, "lock %s, return from ocfs2_dlm_lock\n", lockres->l_name);
bail:
- mlog_exit(ret);
return ret;
}
@@ -1416,8 +1374,6 @@ static int __ocfs2_cluster_lock(struct ocfs2_super *osb,
unsigned int gen;
int noqueue_attempted = 0;
- mlog_entry_void();
-
ocfs2_init_mask_waiter(&mw);
if (lockres->l_ops->flags & LOCK_TYPE_USES_LVB)
@@ -1583,7 +1539,6 @@ out:
caller_ip);
}
#endif
- mlog_exit(ret);
return ret;
}
@@ -1605,7 +1560,6 @@ static void __ocfs2_cluster_unlock(struct ocfs2_super *osb,
{
unsigned long flags;
- mlog_entry_void();
spin_lock_irqsave(&lockres->l_lock, flags);
ocfs2_dec_holders(lockres, level);
ocfs2_downconvert_on_unlock(osb, lockres);
@@ -1614,7 +1568,6 @@ static void __ocfs2_cluster_unlock(struct ocfs2_super *osb,
if (lockres->l_lockdep_map.key != NULL)
rwsem_release(&lockres->l_lockdep_map, 1, caller_ip);
#endif
- mlog_exit_void();
}
static int ocfs2_create_new_lock(struct ocfs2_super *osb,
@@ -1648,8 +1601,6 @@ int ocfs2_create_new_inode_locks(struct inode *inode)
BUG_ON(!inode);
BUG_ON(!ocfs2_inode_is_new(inode));
- mlog_entry_void();
-
mlog(0, "Inode %llu\n", (unsigned long long)OCFS2_I(inode)->ip_blkno);
/* NOTE: That we don't increment any of the holder counts, nor
@@ -1683,7 +1634,6 @@ int ocfs2_create_new_inode_locks(struct inode *inode)
}
bail:
- mlog_exit(ret);
return ret;
}
@@ -1695,16 +1645,12 @@ int ocfs2_rw_lock(struct inode *inode, int write)
BUG_ON(!inode);
- mlog_entry_void();
-
mlog(0, "inode %llu take %s RW lock\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno,
write ? "EXMODE" : "PRMODE");
- if (ocfs2_mount_local(osb)) {
- mlog_exit(0);
+ if (ocfs2_mount_local(osb))
return 0;
- }
lockres = &OCFS2_I(inode)->ip_rw_lockres;
@@ -1715,7 +1661,6 @@ int ocfs2_rw_lock(struct inode *inode, int write)
if (status < 0)
mlog_errno(status);
- mlog_exit(status);
return status;
}
@@ -1725,16 +1670,12 @@ void ocfs2_rw_unlock(struct inode *inode, int write)
struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_rw_lockres;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- mlog_entry_void();
-
mlog(0, "inode %llu drop %s RW lock\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno,
write ? "EXMODE" : "PRMODE");
if (!ocfs2_mount_local(osb))
ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
-
- mlog_exit_void();
}
/*
@@ -1748,8 +1689,6 @@ int ocfs2_open_lock(struct inode *inode)
BUG_ON(!inode);
- mlog_entry_void();
-
mlog(0, "inode %llu take PRMODE open lock\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -1764,7 +1703,6 @@ int ocfs2_open_lock(struct inode *inode)
mlog_errno(status);
out:
- mlog_exit(status);
return status;
}
@@ -1776,8 +1714,6 @@ int ocfs2_try_open_lock(struct inode *inode, int write)
BUG_ON(!inode);
- mlog_entry_void();
-
mlog(0, "inode %llu try to take %s open lock\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno,
write ? "EXMODE" : "PRMODE");
@@ -1799,7 +1735,6 @@ int ocfs2_try_open_lock(struct inode *inode, int write)
level, DLM_LKF_NOQUEUE, 0);
out:
- mlog_exit(status);
return status;
}
@@ -1811,8 +1746,6 @@ void ocfs2_open_unlock(struct inode *inode)
struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_open_lockres;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- mlog_entry_void();
-
mlog(0, "inode %llu drop open lock\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -1827,7 +1760,7 @@ void ocfs2_open_unlock(struct inode *inode)
DLM_LOCK_EX);
out:
- mlog_exit_void();
+ return;
}
static int ocfs2_flock_handle_signal(struct ocfs2_lock_res *lockres,
@@ -2043,8 +1976,6 @@ static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb,
{
int kick = 0;
- mlog_entry_void();
-
/* If we know that another node is waiting on our lock, kick
* the downconvert thread * pre-emptively when we reach a release
* condition. */
@@ -2065,8 +1996,6 @@ static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb,
if (kick)
ocfs2_wake_downconvert_thread(osb);
-
- mlog_exit_void();
}
#define OCFS2_SEC_BITS 34
@@ -2095,8 +2024,6 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
struct ocfs2_meta_lvb *lvb;
- mlog_entry_void();
-
lvb = ocfs2_dlm_lvb(&lockres->l_lksb);
/*
@@ -2128,8 +2055,6 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
out:
mlog_meta_lvb(0, lockres);
-
- mlog_exit_void();
}
static void ocfs2_unpack_timespec(struct timespec *spec,
@@ -2145,8 +2070,6 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
struct ocfs2_meta_lvb *lvb;
- mlog_entry_void();
-
mlog_meta_lvb(0, lockres);
lvb = ocfs2_dlm_lvb(&lockres->l_lksb);
@@ -2177,8 +2100,6 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
ocfs2_unpack_timespec(&inode->i_ctime,
be64_to_cpu(lvb->lvb_ictime_packed));
spin_unlock(&oi->ip_lock);
-
- mlog_exit_void();
}
static inline int ocfs2_meta_lvb_is_trustable(struct inode *inode,
@@ -2205,8 +2126,6 @@ static int ocfs2_should_refresh_lock_res(struct ocfs2_lock_res *lockres)
unsigned long flags;
int status = 0;
- mlog_entry_void();
-
refresh_check:
spin_lock_irqsave(&lockres->l_lock, flags);
if (!(lockres->l_flags & OCFS2_LOCK_NEEDS_REFRESH)) {
@@ -2227,7 +2146,7 @@ refresh_check:
status = 1;
bail:
- mlog_exit(status);
+ mlog(0, "status %d\n", status);
return status;
}
@@ -2237,7 +2156,6 @@ static inline void ocfs2_complete_lock_res_refresh(struct ocfs2_lock_res *lockre
int status)
{
unsigned long flags;
- mlog_entry_void();
spin_lock_irqsave(&lockres->l_lock, flags);
lockres_clear_flags(lockres, OCFS2_LOCK_REFRESHING);
@@ -2246,8 +2164,6 @@ static inline void ocfs2_complete_lock_res_refresh(struct ocfs2_lock_res *lockre
spin_unlock_irqrestore(&lockres->l_lock, flags);
wake_up(&lockres->l_event);
-
- mlog_exit_void();
}
/* may or may not return a bh if it went to disk. */
@@ -2260,8 +2176,6 @@ static int ocfs2_inode_lock_update(struct inode *inode,
struct ocfs2_dinode *fe;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- mlog_entry_void();
-
if (ocfs2_mount_local(osb))
goto bail;
@@ -2330,7 +2244,6 @@ static int ocfs2_inode_lock_update(struct inode *inode,
bail_refresh:
ocfs2_complete_lock_res_refresh(lockres, status);
bail:
- mlog_exit(status);
return status;
}
@@ -2374,8 +2287,6 @@ int ocfs2_inode_lock_full_nested(struct inode *inode,
BUG_ON(!inode);
- mlog_entry_void();
-
mlog(0, "inode %llu, take %s META lock\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno,
ex ? "EXMODE" : "PRMODE");
@@ -2467,7 +2378,6 @@ bail:
if (local_bh)
brelse(local_bh);
- mlog_exit(status);
return status;
}
@@ -2517,7 +2427,6 @@ int ocfs2_inode_lock_atime(struct inode *inode,
{
int ret;
- mlog_entry_void();
ret = ocfs2_inode_lock(inode, NULL, 0);
if (ret < 0) {
mlog_errno(ret);
@@ -2545,7 +2454,6 @@ int ocfs2_inode_lock_atime(struct inode *inode,
} else
*level = 0;
- mlog_exit(ret);
return ret;
}
@@ -2556,8 +2464,6 @@ void ocfs2_inode_unlock(struct inode *inode,
struct ocfs2_lock_res *lockres = &OCFS2_I(inode)->ip_inode_lockres;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- mlog_entry_void();
-
mlog(0, "inode %llu drop %s META lock\n",
(unsigned long long)OCFS2_I(inode)->ip_blkno,
ex ? "EXMODE" : "PRMODE");
@@ -2565,8 +2471,6 @@ void ocfs2_inode_unlock(struct inode *inode,
if (!ocfs2_is_hard_readonly(OCFS2_SB(inode->i_sb)) &&
!ocfs2_mount_local(osb))
ocfs2_cluster_unlock(OCFS2_SB(inode->i_sb), lockres, level);
-
- mlog_exit_void();
}
int ocfs2_orphan_scan_lock(struct ocfs2_super *osb, u32 *seqno)
@@ -2617,8 +2521,6 @@ int ocfs2_super_lock(struct ocfs2_super *osb,
int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR;
struct ocfs2_lock_res *lockres = &osb->osb_super_lockres;
- mlog_entry_void();
-
if (ocfs2_is_hard_readonly(osb))
return -EROFS;
@@ -2650,7 +2552,6 @@ int ocfs2_super_lock(struct ocfs2_super *osb,
ocfs2_track_lock_refresh(lockres);
}
bail:
- mlog_exit(status);
return status;
}
@@ -2869,8 +2770,15 @@ static void *ocfs2_dlm_seq_next(struct seq_file *m, void *v, loff_t *pos)
return iter;
}
-/* So that debugfs.ocfs2 can determine which format is being used */
-#define OCFS2_DLM_DEBUG_STR_VERSION 2
+/*
+ * Version is used by debugfs.ocfs2 to determine the format being used
+ *
+ * New in version 2
+ * - Lock stats printed
+ * New in version 3
+ * - Max time in lock stats is in usecs (instead of nsecs)
+ */
+#define OCFS2_DLM_DEBUG_STR_VERSION 3
static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
{
int i;
@@ -2912,18 +2820,18 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
seq_printf(m, "0x%x\t", lvb[i]);
#ifdef CONFIG_OCFS2_FS_STATS
-# define lock_num_prmode(_l) (_l)->l_lock_num_prmode
-# define lock_num_exmode(_l) (_l)->l_lock_num_exmode
-# define lock_num_prmode_failed(_l) (_l)->l_lock_num_prmode_failed
-# define lock_num_exmode_failed(_l) (_l)->l_lock_num_exmode_failed
-# define lock_total_prmode(_l) (_l)->l_lock_total_prmode
-# define lock_total_exmode(_l) (_l)->l_lock_total_exmode
-# define lock_max_prmode(_l) (_l)->l_lock_max_prmode
-# define lock_max_exmode(_l) (_l)->l_lock_max_exmode
-# define lock_refresh(_l) (_l)->l_lock_refresh
+# define lock_num_prmode(_l) ((_l)->l_lock_prmode.ls_gets)
+# define lock_num_exmode(_l) ((_l)->l_lock_exmode.ls_gets)
+# define lock_num_prmode_failed(_l) ((_l)->l_lock_prmode.ls_fail)
+# define lock_num_exmode_failed(_l) ((_l)->l_lock_exmode.ls_fail)
+# define lock_total_prmode(_l) ((_l)->l_lock_prmode.ls_total)
+# define lock_total_exmode(_l) ((_l)->l_lock_exmode.ls_total)
+# define lock_max_prmode(_l) ((_l)->l_lock_prmode.ls_max)
+# define lock_max_exmode(_l) ((_l)->l_lock_exmode.ls_max)
+# define lock_refresh(_l) ((_l)->l_lock_refresh)
#else
-# define lock_num_prmode(_l) (0ULL)
-# define lock_num_exmode(_l) (0ULL)
+# define lock_num_prmode(_l) (0)
+# define lock_num_exmode(_l) (0)
# define lock_num_prmode_failed(_l) (0)
# define lock_num_exmode_failed(_l) (0)
# define lock_total_prmode(_l) (0ULL)
@@ -2933,8 +2841,8 @@ static int ocfs2_dlm_seq_show(struct seq_file *m, void *v)
# define lock_refresh(_l) (0)
#endif
/* The following seq_print was added in version 2 of this output */
- seq_printf(m, "%llu\t"
- "%llu\t"
+ seq_printf(m, "%u\t"
+ "%u\t"
"%u\t"
"%u\t"
"%llu\t"
@@ -3054,8 +2962,6 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
int status = 0;
struct ocfs2_cluster_connection *conn = NULL;
- mlog_entry_void();
-
if (ocfs2_mount_local(osb)) {
osb->node_num = 0;
goto local;
@@ -3112,15 +3018,12 @@ bail:
kthread_stop(osb->dc_task);
}
- mlog_exit(status);
return status;
}
void ocfs2_dlm_shutdown(struct ocfs2_super *osb,
int hangup_pending)
{
- mlog_entry_void();
-
ocfs2_drop_osb_locks(osb);
/*
@@ -3143,8 +3046,6 @@ void ocfs2_dlm_shutdown(struct ocfs2_super *osb,
osb->cconn = NULL;
ocfs2_dlm_shutdown_debug(osb);
-
- mlog_exit_void();
}
static int ocfs2_drop_lock(struct ocfs2_super *osb,
@@ -3226,7 +3127,6 @@ static int ocfs2_drop_lock(struct ocfs2_super *osb,
ocfs2_wait_on_busy_lock(lockres);
out:
- mlog_exit(0);
return 0;
}
@@ -3284,8 +3184,6 @@ int ocfs2_drop_inode_locks(struct inode *inode)
{
int status, err;
- mlog_entry_void();
-
/* No need to call ocfs2_mark_lockres_freeing here -
* ocfs2_clear_inode has done it for us. */
@@ -3310,7 +3208,6 @@ int ocfs2_drop_inode_locks(struct inode *inode)
if (err < 0 && !status)
status = err;
- mlog_exit(status);
return status;
}
@@ -3352,8 +3249,6 @@ static int ocfs2_downconvert_lock(struct ocfs2_super *osb,
int ret;
u32 dlm_flags = DLM_LKF_CONVERT;
- mlog_entry_void();
-
mlog(ML_BASTS, "lockres %s, level %d => %d\n", lockres->l_name,
lockres->l_level, new_level);
@@ -3375,7 +3270,6 @@ static int ocfs2_downconvert_lock(struct ocfs2_super *osb,
ret = 0;
bail:
- mlog_exit(ret);
return ret;
}
@@ -3385,8 +3279,6 @@ static int ocfs2_prepare_cancel_convert(struct ocfs2_super *osb,
{
assert_spin_locked(&lockres->l_lock);
- mlog_entry_void();
-
if (lockres->l_unlock_action == OCFS2_UNLOCK_CANCEL_CONVERT) {
/* If we're already trying to cancel a lock conversion
* then just drop the spinlock and allow the caller to
@@ -3416,8 +3308,6 @@ static int ocfs2_cancel_convert(struct ocfs2_super *osb,
{
int ret;
- mlog_entry_void();
-
ret = ocfs2_dlm_unlock(osb->cconn, &lockres->l_lksb,
DLM_LKF_CANCEL);
if (ret) {
@@ -3427,7 +3317,6 @@ static int ocfs2_cancel_convert(struct ocfs2_super *osb,
mlog(ML_BASTS, "lockres %s\n", lockres->l_name);
- mlog_exit(ret);
return ret;
}
@@ -3443,8 +3332,6 @@ static int ocfs2_unblock_lock(struct ocfs2_super *osb,
int set_lvb = 0;
unsigned int gen;
- mlog_entry_void();
-
spin_lock_irqsave(&lockres->l_lock, flags);
recheck:
@@ -3619,14 +3506,14 @@ downconvert:
gen);
leave:
- mlog_exit(ret);
+ if (ret)
+ mlog_errno(ret);
return ret;
leave_requeue:
spin_unlock_irqrestore(&lockres->l_lock, flags);
ctl->requeue = 1;
- mlog_exit(0);
return 0;
}
@@ -3859,8 +3746,6 @@ static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres)
struct mem_dqinfo *info = sb_dqinfo(oinfo->dqi_gi.dqi_sb,
oinfo->dqi_gi.dqi_type);
- mlog_entry_void();
-
lvb = ocfs2_dlm_lvb(&lockres->l_lksb);
lvb->lvb_version = OCFS2_QINFO_LVB_VERSION;
lvb->lvb_bgrace = cpu_to_be32(info->dqi_bgrace);
@@ -3869,8 +3754,6 @@ static void ocfs2_set_qinfo_lvb(struct ocfs2_lock_res *lockres)
lvb->lvb_blocks = cpu_to_be32(oinfo->dqi_gi.dqi_blocks);
lvb->lvb_free_blk = cpu_to_be32(oinfo->dqi_gi.dqi_free_blk);
lvb->lvb_free_entry = cpu_to_be32(oinfo->dqi_gi.dqi_free_entry);
-
- mlog_exit_void();
}
void ocfs2_qinfo_unlock(struct ocfs2_mem_dqinfo *oinfo, int ex)
@@ -3879,10 +3762,8 @@ void ocfs2_qinfo_unlock(struct ocfs2_mem_dqinfo *oinfo, int ex)
struct ocfs2_super *osb = OCFS2_SB(oinfo->dqi_gi.dqi_sb);
int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR;
- mlog_entry_void();
if (!ocfs2_is_hard_readonly(osb) && !ocfs2_mount_local(osb))
ocfs2_cluster_unlock(osb, lockres, level);
- mlog_exit_void();
}
static int ocfs2_refresh_qinfo(struct ocfs2_mem_dqinfo *oinfo)
@@ -3937,8 +3818,6 @@ int ocfs2_qinfo_lock(struct ocfs2_mem_dqinfo *oinfo, int ex)
int level = ex ? DLM_LOCK_EX : DLM_LOCK_PR;
int status = 0;
- mlog_entry_void();
-
/* On RO devices, locking really isn't needed... */
if (ocfs2_is_hard_readonly(osb)) {
if (ex)
@@ -3961,7 +3840,6 @@ int ocfs2_qinfo_lock(struct ocfs2_mem_dqinfo *oinfo, int ex)
ocfs2_qinfo_unlock(oinfo, ex);
ocfs2_complete_lock_res_refresh(lockres, status);
bail:
- mlog_exit(status);
return status;
}
@@ -4007,8 +3885,6 @@ static void ocfs2_process_blocked_lock(struct ocfs2_super *osb,
* considered valid until we remove the OCFS2_LOCK_QUEUED
* flag. */
- mlog_entry_void();
-
BUG_ON(!lockres);
BUG_ON(!lockres->l_ops);
@@ -4042,15 +3918,11 @@ unqueue:
if (ctl.unblock_action != UNBLOCK_CONTINUE
&& lockres->l_ops->post_unlock)
lockres->l_ops->post_unlock(osb, lockres);
-
- mlog_exit_void();
}
static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb,
struct ocfs2_lock_res *lockres)
{
- mlog_entry_void();
-
assert_spin_locked(&lockres->l_lock);
if (lockres->l_flags & OCFS2_LOCK_FREEING) {
@@ -4071,8 +3943,6 @@ static void ocfs2_schedule_blocked_lock(struct ocfs2_super *osb,
osb->blocked_lock_count++;
}
spin_unlock(&osb->dc_task_lock);
-
- mlog_exit_void();
}
static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb)
@@ -4080,8 +3950,6 @@ static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb)
unsigned long processed;
struct ocfs2_lock_res *lockres;
- mlog_entry_void();
-
spin_lock(&osb->dc_task_lock);
/* grab this early so we know to try again if a state change and
* wake happens part-way through our work */
@@ -4105,8 +3973,6 @@ static void ocfs2_downconvert_thread_do_work(struct ocfs2_super *osb)
spin_lock(&osb->dc_task_lock);
}
spin_unlock(&osb->dc_task_lock);
-
- mlog_exit_void();
}
static int ocfs2_downconvert_thread_lists_empty(struct ocfs2_super *osb)
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index 254652a9b54..745db42528d 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -26,7 +26,6 @@
#include <linux/fs.h>
#include <linux/types.h>
-#define MLOG_MASK_PREFIX ML_EXPORT
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -40,6 +39,7 @@
#include "buffer_head_io.h"
#include "suballoc.h"
+#include "ocfs2_trace.h"
struct ocfs2_inode_handle
{
@@ -56,10 +56,9 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb,
int status, set;
struct dentry *result;
- mlog_entry("(0x%p, 0x%p)\n", sb, handle);
+ trace_ocfs2_get_dentry_begin(sb, handle, (unsigned long long)blkno);
if (blkno == 0) {
- mlog(0, "nfs wants inode with blkno: 0\n");
result = ERR_PTR(-ESTALE);
goto bail;
}
@@ -83,6 +82,7 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb,
}
status = ocfs2_test_inode_bit(osb, blkno, &set);
+ trace_ocfs2_get_dentry_test_bit(status, set);
if (status < 0) {
if (status == -EINVAL) {
/*
@@ -90,18 +90,14 @@ static struct dentry *ocfs2_get_dentry(struct super_block *sb,
* as an inode, we return -ESTALE to be
* nice
*/
- mlog(0, "test inode bit failed %d\n", status);
status = -ESTALE;
- } else {
+ } else
mlog(ML_ERROR, "test inode bit failed %d\n", status);
- }
goto unlock_nfs_sync;
}
/* If the inode allocator bit is clear, this inode must be stale */
if (!set) {
- mlog(0, "inode %llu suballoc bit is clear\n",
- (unsigned long long)blkno);
status = -ESTALE;
goto unlock_nfs_sync;
}
@@ -114,8 +110,8 @@ unlock_nfs_sync:
check_err:
if (status < 0) {
if (status == -ESTALE) {
- mlog(0, "stale inode ino: %llu generation: %u\n",
- (unsigned long long)blkno, handle->ih_generation);
+ trace_ocfs2_get_dentry_stale((unsigned long long)blkno,
+ handle->ih_generation);
}
result = ERR_PTR(status);
goto bail;
@@ -130,8 +126,9 @@ check_err:
check_gen:
if (handle->ih_generation != inode->i_generation) {
iput(inode);
- mlog(0, "stale inode ino: %llu generation: %u\n",
- (unsigned long long)blkno, handle->ih_generation);
+ trace_ocfs2_get_dentry_generation((unsigned long long)blkno,
+ handle->ih_generation,
+ inode->i_generation);
result = ERR_PTR(-ESTALE);
goto bail;
}
@@ -141,7 +138,7 @@ check_gen:
mlog_errno(PTR_ERR(result));
bail:
- mlog_exit_ptr(result);
+ trace_ocfs2_get_dentry_end(result);
return result;
}
@@ -152,11 +149,8 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
struct dentry *parent;
struct inode *dir = child->d_inode;
- mlog_entry("(0x%p, '%.*s')\n", child,
- child->d_name.len, child->d_name.name);
-
- mlog(0, "find parent of directory %llu\n",
- (unsigned long long)OCFS2_I(dir)->ip_blkno);
+ trace_ocfs2_get_parent(child, child->d_name.len, child->d_name.name,
+ (unsigned long long)OCFS2_I(dir)->ip_blkno);
status = ocfs2_inode_lock(dir, NULL, 0);
if (status < 0) {
@@ -178,7 +172,7 @@ bail_unlock:
ocfs2_inode_unlock(dir, 0);
bail:
- mlog_exit_ptr(parent);
+ trace_ocfs2_get_parent_end(parent);
return parent;
}
@@ -193,9 +187,9 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len,
u32 generation;
__le32 *fh = (__force __le32 *) fh_in;
- mlog_entry("(0x%p, '%.*s', 0x%p, %d, %d)\n", dentry,
- dentry->d_name.len, dentry->d_name.name,
- fh, len, connectable);
+ trace_ocfs2_encode_fh_begin(dentry, dentry->d_name.len,
+ dentry->d_name.name,
+ fh, len, connectable);
if (connectable && (len < 6)) {
*max_len = 6;
@@ -210,8 +204,7 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len,
blkno = OCFS2_I(inode)->ip_blkno;
generation = inode->i_generation;
- mlog(0, "Encoding fh: blkno: %llu, generation: %u\n",
- (unsigned long long)blkno, generation);
+ trace_ocfs2_encode_fh_self((unsigned long long)blkno, generation);
len = 3;
fh[0] = cpu_to_le32((u32)(blkno >> 32));
@@ -236,14 +229,14 @@ static int ocfs2_encode_fh(struct dentry *dentry, u32 *fh_in, int *max_len,
len = 6;
type = 2;
- mlog(0, "Encoding parent: blkno: %llu, generation: %u\n",
- (unsigned long long)blkno, generation);
+ trace_ocfs2_encode_fh_parent((unsigned long long)blkno,
+ generation);
}
*max_len = len;
bail:
- mlog_exit(type);
+ trace_ocfs2_encode_fh_type(type);
return type;
}
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index 09e3fdfa6d3..23457b491e8 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -28,7 +28,6 @@
#include <linux/types.h>
#include <linux/fiemap.h>
-#define MLOG_MASK_PREFIX ML_EXTENT_MAP
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -39,6 +38,7 @@
#include "inode.h"
#include "super.h"
#include "symlink.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -841,10 +841,9 @@ int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr,
u64 p_block, p_count;
int i, count, done = 0;
- mlog_entry("(inode = %p, v_block = %llu, nr = %d, bhs = %p, "
- "flags = %x, validate = %p)\n",
- inode, (unsigned long long)v_block, nr, bhs, flags,
- validate);
+ trace_ocfs2_read_virt_blocks(
+ inode, (unsigned long long)v_block, nr, bhs, flags,
+ validate);
if (((v_block + nr - 1) << inode->i_sb->s_blocksize_bits) >=
i_size_read(inode)) {
@@ -897,7 +896,6 @@ int ocfs2_read_virt_blocks(struct inode *inode, u64 v_block, int nr,
}
out:
- mlog_exit(rc);
return rc;
}
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index a6651956482..41565ae5285 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -38,7 +38,6 @@
#include <linux/quotaops.h>
#include <linux/blkdev.h>
-#define MLOG_MASK_PREFIX ML_INODE
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -61,6 +60,7 @@
#include "acl.h"
#include "quota.h"
#include "refcounttree.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -99,8 +99,10 @@ static int ocfs2_file_open(struct inode *inode, struct file *file)
int mode = file->f_flags;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
- mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file,
- file->f_path.dentry->d_name.len, file->f_path.dentry->d_name.name);
+ trace_ocfs2_file_open(inode, file, file->f_path.dentry,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ file->f_path.dentry->d_name.len,
+ file->f_path.dentry->d_name.name, mode);
if (file->f_mode & FMODE_WRITE)
dquot_initialize(inode);
@@ -135,7 +137,6 @@ static int ocfs2_file_open(struct inode *inode, struct file *file)
}
leave:
- mlog_exit(status);
return status;
}
@@ -143,19 +144,19 @@ static int ocfs2_file_release(struct inode *inode, struct file *file)
{
struct ocfs2_inode_info *oi = OCFS2_I(inode);
- mlog_entry("(0x%p, 0x%p, '%.*s')\n", inode, file,
- file->f_path.dentry->d_name.len,
- file->f_path.dentry->d_name.name);
-
spin_lock(&oi->ip_lock);
if (!--oi->ip_open_count)
oi->ip_flags &= ~OCFS2_INODE_OPEN_DIRECT;
+
+ trace_ocfs2_file_release(inode, file, file->f_path.dentry,
+ oi->ip_blkno,
+ file->f_path.dentry->d_name.len,
+ file->f_path.dentry->d_name.name,
+ oi->ip_open_count);
spin_unlock(&oi->ip_lock);
ocfs2_free_file_private(inode, file);
- mlog_exit(0);
-
return 0;
}
@@ -177,9 +178,11 @@ static int ocfs2_sync_file(struct file *file, int datasync)
struct inode *inode = file->f_mapping->host;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- mlog_entry("(0x%p, %d, 0x%p, '%.*s')\n", file, datasync,
- file->f_path.dentry, file->f_path.dentry->d_name.len,
- file->f_path.dentry->d_name.name);
+ trace_ocfs2_sync_file(inode, file, file->f_path.dentry,
+ OCFS2_I(inode)->ip_blkno,
+ file->f_path.dentry->d_name.len,
+ file->f_path.dentry->d_name.name,
+ (unsigned long long)datasync);
if (datasync && !(inode->i_state & I_DIRTY_DATASYNC)) {
/*
@@ -195,7 +198,8 @@ static int ocfs2_sync_file(struct file *file, int datasync)
err = jbd2_journal_force_commit(journal);
bail:
- mlog_exit(err);
+ if (err)
+ mlog_errno(err);
return (err < 0) ? -EIO : 0;
}
@@ -251,8 +255,6 @@ int ocfs2_update_inode_atime(struct inode *inode,
handle_t *handle;
struct ocfs2_dinode *di = (struct ocfs2_dinode *) bh->b_data;
- mlog_entry_void();
-
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
@@ -280,7 +282,6 @@ int ocfs2_update_inode_atime(struct inode *inode,
out_commit:
ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
out:
- mlog_exit(ret);
return ret;
}
@@ -291,7 +292,6 @@ static int ocfs2_set_inode_size(handle_t *handle,
{
int status;
- mlog_entry_void();
i_size_write(inode, new_i_size);
inode->i_blocks = ocfs2_inode_sector_count(inode);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
@@ -303,7 +303,6 @@ static int ocfs2_set_inode_size(handle_t *handle,
}
bail:
- mlog_exit(status);
return status;
}
@@ -375,8 +374,6 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
struct ocfs2_dinode *di;
u64 cluster_bytes;
- mlog_entry_void();
-
/*
* We need to CoW the cluster contains the offset if it is reflinked
* since we will call ocfs2_zero_range_for_truncate later which will
@@ -429,8 +426,6 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
out_commit:
ocfs2_commit_trans(osb, handle);
out:
-
- mlog_exit(status);
return status;
}
@@ -442,14 +437,14 @@ static int ocfs2_truncate_file(struct inode *inode,
struct ocfs2_dinode *fe = NULL;
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
- mlog_entry("(inode = %llu, new_i_size = %llu\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- (unsigned long long)new_i_size);
-
/* We trust di_bh because it comes from ocfs2_inode_lock(), which
* already validated it */
fe = (struct ocfs2_dinode *) di_bh->b_data;
+ trace_ocfs2_truncate_file((unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)le64_to_cpu(fe->i_size),
+ (unsigned long long)new_i_size);
+
mlog_bug_on_msg(le64_to_cpu(fe->i_size) != i_size_read(inode),
"Inode %llu, inode i_size = %lld != di "
"i_size = %llu, i_flags = 0x%x\n",
@@ -459,19 +454,14 @@ static int ocfs2_truncate_file(struct inode *inode,
le32_to_cpu(fe->i_flags));
if (new_i_size > le64_to_cpu(fe->i_size)) {
- mlog(0, "asked to truncate file with size (%llu) to size (%llu)!\n",
- (unsigned long long)le64_to_cpu(fe->i_size),
- (unsigned long long)new_i_size);
+ trace_ocfs2_truncate_file_error(
+ (unsigned long long)le64_to_cpu(fe->i_size),
+ (unsigned long long)new_i_size);
status = -EINVAL;
mlog_errno(status);
goto bail;
}
- mlog(0, "inode %llu, i_size = %llu, new_i_size = %llu\n",
- (unsigned long long)le64_to_cpu(fe->i_blkno),
- (unsigned long long)le64_to_cpu(fe->i_size),
- (unsigned long long)new_i_size);
-
/* lets handle the simple truncate cases before doing any more
* cluster locking. */
if (new_i_size == le64_to_cpu(fe->i_size))
@@ -525,7 +515,6 @@ bail:
if (!status && OCFS2_I(inode)->ip_clusters == 0)
status = ocfs2_try_remove_refcount_tree(inode, di_bh);
- mlog_exit(status);
return status;
}
@@ -578,8 +567,6 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
struct ocfs2_extent_tree et;
int did_quota = 0;
- mlog_entry("(clusters_to_add = %u)\n", clusters_to_add);
-
/*
* This function only exists for file systems which don't
* support holes.
@@ -596,11 +583,6 @@ static int __ocfs2_extend_allocation(struct inode *inode, u32 logical_start,
restart_all:
BUG_ON(le32_to_cpu(fe->i_clusters) != OCFS2_I(inode)->ip_clusters);
- mlog(0, "extend inode %llu, i_size = %lld, di->i_clusters = %u, "
- "clusters_to_add = %u\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- (long long)i_size_read(inode), le32_to_cpu(fe->i_clusters),
- clusters_to_add);
ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), bh);
status = ocfs2_lock_allocators(inode, &et, clusters_to_add, 0,
&data_ac, &meta_ac);
@@ -620,6 +602,12 @@ restart_all:
}
restarted_transaction:
+ trace_ocfs2_extend_allocation(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)i_size_read(inode),
+ le32_to_cpu(fe->i_clusters), clusters_to_add,
+ why, restart_func);
+
status = dquot_alloc_space_nodirty(inode,
ocfs2_clusters_to_bytes(osb->sb, clusters_to_add));
if (status)
@@ -666,13 +654,11 @@ restarted_transaction:
if (why != RESTART_NONE && clusters_to_add) {
if (why == RESTART_META) {
- mlog(0, "restarting function.\n");
restart_func = 1;
status = 0;
} else {
BUG_ON(why != RESTART_TRANS);
- mlog(0, "restarting transaction.\n");
/* TODO: This can be more intelligent. */
credits = ocfs2_calc_extend_credits(osb->sb,
&fe->id2.i_list,
@@ -689,11 +675,11 @@ restarted_transaction:
}
}
- mlog(0, "fe: i_clusters = %u, i_size=%llu\n",
+ trace_ocfs2_extend_allocation_end(OCFS2_I(inode)->ip_blkno,
le32_to_cpu(fe->i_clusters),
- (unsigned long long)le64_to_cpu(fe->i_size));
- mlog(0, "inode: ip_clusters=%u, i_size=%lld\n",
- OCFS2_I(inode)->ip_clusters, (long long)i_size_read(inode));
+ (unsigned long long)le64_to_cpu(fe->i_size),
+ OCFS2_I(inode)->ip_clusters,
+ (unsigned long long)i_size_read(inode));
leave:
if (status < 0 && did_quota)
@@ -718,7 +704,6 @@ leave:
brelse(bh);
bh = NULL;
- mlog_exit(status);
return status;
}
@@ -785,10 +770,11 @@ static int ocfs2_write_zero_page(struct inode *inode, u64 abs_from,
if (!zero_to)
zero_to = PAGE_CACHE_SIZE;
- mlog(0,
- "abs_from = %llu, abs_to = %llu, index = %lu, zero_from = %u, zero_to = %u\n",
- (unsigned long long)abs_from, (unsigned long long)abs_to,
- index, zero_from, zero_to);
+ trace_ocfs2_write_zero_page(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)abs_from,
+ (unsigned long long)abs_to,
+ index, zero_from, zero_to);
/* We know that zero_from is block aligned */
for (block_start = zero_from; block_start < zero_to;
@@ -928,9 +914,10 @@ static int ocfs2_zero_extend_range(struct inode *inode, u64 range_start,
u64 next_pos;
u64 zero_pos = range_start;
- mlog(0, "range_start = %llu, range_end = %llu\n",
- (unsigned long long)range_start,
- (unsigned long long)range_end);
+ trace_ocfs2_zero_extend_range(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)range_start,
+ (unsigned long long)range_end);
BUG_ON(range_start >= range_end);
while (zero_pos < range_end) {
@@ -962,9 +949,9 @@ int ocfs2_zero_extend(struct inode *inode, struct buffer_head *di_bh,
struct super_block *sb = inode->i_sb;
zero_start = ocfs2_align_bytes_to_blocks(sb, i_size_read(inode));
- mlog(0, "zero_start %llu for i_size %llu\n",
- (unsigned long long)zero_start,
- (unsigned long long)i_size_read(inode));
+ trace_ocfs2_zero_extend((unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)zero_start,
+ (unsigned long long)i_size_read(inode));
while (zero_start < zero_to_size) {
ret = ocfs2_zero_extend_get_range(inode, di_bh, zero_start,
zero_to_size,
@@ -1113,30 +1100,20 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
struct dquot *transfer_to[MAXQUOTAS] = { };
int qtype;
- mlog_entry("(0x%p, '%.*s')\n", dentry,
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_setattr(inode, dentry,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ dentry->d_name.len, dentry->d_name.name,
+ attr->ia_valid, attr->ia_mode,
+ attr->ia_uid, attr->ia_gid);
/* ensuring we don't even attempt to truncate a symlink */
if (S_ISLNK(inode->i_mode))
attr->ia_valid &= ~ATTR_SIZE;
- if (attr->ia_valid & ATTR_MODE)
- mlog(0, "mode change: %d\n", attr->ia_mode);
- if (attr->ia_valid & ATTR_UID)
- mlog(0, "uid change: %d\n", attr->ia_uid);
- if (attr->ia_valid & ATTR_GID)
- mlog(0, "gid change: %d\n", attr->ia_gid);
- if (attr->ia_valid & ATTR_SIZE)
- mlog(0, "size change...\n");
- if (attr->ia_valid & (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME))
- mlog(0, "time change...\n");
-
#define OCFS2_VALID_ATTRS (ATTR_ATIME | ATTR_MTIME | ATTR_CTIME | ATTR_SIZE \
| ATTR_GID | ATTR_UID | ATTR_MODE)
- if (!(attr->ia_valid & OCFS2_VALID_ATTRS)) {
- mlog(0, "can't handle attrs: 0x%x\n", attr->ia_valid);
+ if (!(attr->ia_valid & OCFS2_VALID_ATTRS))
return 0;
- }
status = inode_change_ok(inode, attr);
if (status)
@@ -1274,7 +1251,6 @@ bail:
mlog_errno(status);
}
- mlog_exit(status);
return status;
}
@@ -1287,8 +1263,6 @@ int ocfs2_getattr(struct vfsmount *mnt,
struct ocfs2_super *osb = sb->s_fs_info;
int err;
- mlog_entry_void();
-
err = ocfs2_inode_revalidate(dentry);
if (err) {
if (err != -ENOENT)
@@ -1302,8 +1276,6 @@ int ocfs2_getattr(struct vfsmount *mnt,
stat->blksize = osb->s_clustersize;
bail:
- mlog_exit(err);
-
return err;
}
@@ -1314,8 +1286,6 @@ int ocfs2_permission(struct inode *inode, int mask, unsigned int flags)
if (flags & IPERM_FLAG_RCU)
return -ECHILD;
- mlog_entry_void();
-
ret = ocfs2_inode_lock(inode, NULL, 0);
if (ret) {
if (ret != -ENOENT)
@@ -1327,7 +1297,6 @@ int ocfs2_permission(struct inode *inode, int mask, unsigned int flags)
ocfs2_inode_unlock(inode, 0);
out:
- mlog_exit(ret);
return ret;
}
@@ -1339,8 +1308,9 @@ static int __ocfs2_write_remove_suid(struct inode *inode,
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct ocfs2_dinode *di;
- mlog_entry("(Inode %llu, mode 0%o)\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno, inode->i_mode);
+ trace_ocfs2_write_remove_suid(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ inode->i_mode);
handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
if (IS_ERR(handle)) {
@@ -1368,7 +1338,6 @@ static int __ocfs2_write_remove_suid(struct inode *inode,
out_trans:
ocfs2_commit_trans(osb, handle);
out:
- mlog_exit(ret);
return ret;
}
@@ -1547,8 +1516,9 @@ static int ocfs2_zero_partial_clusters(struct inode *inode,
* partial clusters here. There's no need to worry about
* physical allocation - the zeroing code knows to skip holes.
*/
- mlog(0, "byte start: %llu, end: %llu\n",
- (unsigned long long)start, (unsigned long long)end);
+ trace_ocfs2_zero_partial_clusters(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)start, (unsigned long long)end);
/*
* If both edges are on a cluster boundary then there's no
@@ -1572,8 +1542,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode,
if (tmpend > end)
tmpend = end;
- mlog(0, "1st range: start: %llu, tmpend: %llu\n",
- (unsigned long long)start, (unsigned long long)tmpend);
+ trace_ocfs2_zero_partial_clusters_range1((unsigned long long)start,
+ (unsigned long long)tmpend);
ret = ocfs2_zero_range_for_truncate(inode, handle, start, tmpend);
if (ret)
@@ -1587,8 +1557,8 @@ static int ocfs2_zero_partial_clusters(struct inode *inode,
*/
start = end & ~(osb->s_clustersize - 1);
- mlog(0, "2nd range: start: %llu, end: %llu\n",
- (unsigned long long)start, (unsigned long long)end);
+ trace_ocfs2_zero_partial_clusters_range2(
+ (unsigned long long)start, (unsigned long long)end);
ret = ocfs2_zero_range_for_truncate(inode, handle, start, end);
if (ret)
@@ -1688,6 +1658,11 @@ static int ocfs2_remove_inode_range(struct inode *inode,
ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
ocfs2_init_dealloc_ctxt(&dealloc);
+ trace_ocfs2_remove_inode_range(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)byte_start,
+ (unsigned long long)byte_len);
+
if (byte_len == 0)
return 0;
@@ -1734,11 +1709,6 @@ static int ocfs2_remove_inode_range(struct inode *inode,
trunc_end = (byte_start + byte_len) >> osb->s_clustersize_bits;
cluster_in_el = trunc_end;
- mlog(0, "Inode: %llu, start: %llu, len: %llu, cstart: %u, cend: %u\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- (unsigned long long)byte_start,
- (unsigned long long)byte_len, trunc_start, trunc_end);
-
ret = ocfs2_zero_partial_clusters(inode, byte_start, byte_len);
if (ret) {
mlog_errno(ret);
@@ -2093,7 +2063,7 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
int ret = 0, meta_level = 0;
struct dentry *dentry = file->f_path.dentry;
struct inode *inode = dentry->d_inode;
- loff_t saved_pos, end;
+ loff_t saved_pos = 0, end;
/*
* We start with a read level meta lock and only jump to an ex
@@ -2132,12 +2102,10 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
/* work on a copy of ppos until we're sure that we won't have
* to recalculate it due to relocking. */
- if (appending) {
+ if (appending)
saved_pos = i_size_read(inode);
- mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos);
- } else {
+ else
saved_pos = *ppos;
- }
end = saved_pos + count;
@@ -2208,6 +2176,10 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
*ppos = saved_pos;
out_unlock:
+ trace_ocfs2_prepare_inode_for_write(OCFS2_I(inode)->ip_blkno,
+ saved_pos, appending, count,
+ direct_io, has_refcount);
+
if (meta_level >= 0)
ocfs2_inode_unlock(inode, meta_level);
@@ -2233,10 +2205,11 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
int full_coherency = !(osb->s_mount_opt &
OCFS2_MOUNT_COHERENCY_BUFFERED);
- mlog_entry("(0x%p, %u, '%.*s')\n", file,
- (unsigned int)nr_segs,
- file->f_path.dentry->d_name.len,
- file->f_path.dentry->d_name.name);
+ trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ file->f_path.dentry->d_name.len,
+ file->f_path.dentry->d_name.name,
+ (unsigned int)nr_segs);
if (iocb->ki_left == 0)
return 0;
@@ -2402,7 +2375,6 @@ out_sems:
if (written)
ret = written;
- mlog_exit(ret);
return ret;
}
@@ -2438,10 +2410,11 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
.u.file = out,
};
- mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", out, pipe,
- (unsigned int)len,
- out->f_path.dentry->d_name.len,
- out->f_path.dentry->d_name.name);
+
+ trace_ocfs2_file_splice_write(inode, out, out->f_path.dentry,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ out->f_path.dentry->d_name.len,
+ out->f_path.dentry->d_name.name, len);
if (pipe->inode)
mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT);
@@ -2485,7 +2458,6 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
balance_dirty_pages_ratelimited_nr(mapping, nr_pages);
}
- mlog_exit(ret);
return ret;
}
@@ -2498,10 +2470,10 @@ static ssize_t ocfs2_file_splice_read(struct file *in,
int ret = 0, lock_level = 0;
struct inode *inode = in->f_path.dentry->d_inode;
- mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", in, pipe,
- (unsigned int)len,
- in->f_path.dentry->d_name.len,
- in->f_path.dentry->d_name.name);
+ trace_ocfs2_file_splice_read(inode, in, in->f_path.dentry,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ in->f_path.dentry->d_name.len,
+ in->f_path.dentry->d_name.name, len);
/*
* See the comment in ocfs2_file_aio_read()
@@ -2516,7 +2488,6 @@ static ssize_t ocfs2_file_splice_read(struct file *in,
ret = generic_file_splice_read(in, ppos, pipe, len, flags);
bail:
- mlog_exit(ret);
return ret;
}
@@ -2529,10 +2500,11 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
struct file *filp = iocb->ki_filp;
struct inode *inode = filp->f_path.dentry->d_inode;
- mlog_entry("(0x%p, %u, '%.*s')\n", filp,
- (unsigned int)nr_segs,
- filp->f_path.dentry->d_name.len,
- filp->f_path.dentry->d_name.name);
+ trace_ocfs2_file_aio_read(inode, filp, filp->f_path.dentry,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ filp->f_path.dentry->d_name.len,
+ filp->f_path.dentry->d_name.name, nr_segs);
+
if (!inode) {
ret = -EINVAL;
@@ -2578,8 +2550,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
ocfs2_inode_unlock(inode, lock_level);
ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos);
- if (ret == -EINVAL)
- mlog(0, "generic_file_aio_read returned -EINVAL\n");
+ trace_generic_file_aio_read_ret(ret);
/* buffered aio wouldn't have proper lock coverage today */
BUG_ON(ret == -EIOCBQUEUED && !(filp->f_flags & O_DIRECT));
@@ -2597,7 +2568,6 @@ bail:
}
if (rw_level != -1)
ocfs2_rw_unlock(inode, rw_level);
- mlog_exit(ret);
return ret;
}
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c
index 1aa863dd901..d8208b20dc5 100644
--- a/fs/ocfs2/heartbeat.c
+++ b/fs/ocfs2/heartbeat.c
@@ -28,7 +28,6 @@
#include <linux/types.h>
#include <linux/highmem.h>
-#define MLOG_MASK_PREFIX ML_SUPER
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -37,6 +36,7 @@
#include "heartbeat.h"
#include "inode.h"
#include "journal.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -66,7 +66,7 @@ void ocfs2_do_node_down(int node_num, void *data)
BUG_ON(osb->node_num == node_num);
- mlog(0, "ocfs2: node down event for %d\n", node_num);
+ trace_ocfs2_do_node_down(node_num);
if (!osb->cconn) {
/*
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 4068c6c4c6f..177d3a6c2a5 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -31,7 +31,6 @@
#include <asm/byteorder.h>
-#define MLOG_MASK_PREFIX ML_INODE
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -53,6 +52,7 @@
#include "uptodate.h"
#include "xattr.h"
#include "refcounttree.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -131,7 +131,8 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,
struct super_block *sb = osb->sb;
struct ocfs2_find_inode_args args;
- mlog_entry("(blkno = %llu)\n", (unsigned long long)blkno);
+ trace_ocfs2_iget_begin((unsigned long long)blkno, flags,
+ sysfile_type);
/* Ok. By now we've either got the offsets passed to us by the
* caller, or we just pulled them off the bh. Lets do some
@@ -152,16 +153,16 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,
/* inode was *not* in the inode cache. 2.6.x requires
* us to do our own read_inode call and unlock it
* afterwards. */
- if (inode && inode->i_state & I_NEW) {
- mlog(0, "Inode was not in inode cache, reading it.\n");
- ocfs2_read_locked_inode(inode, &args);
- unlock_new_inode(inode);
- }
if (inode == NULL) {
inode = ERR_PTR(-ENOMEM);
mlog_errno(PTR_ERR(inode));
goto bail;
}
+ trace_ocfs2_iget5_locked(inode->i_state);
+ if (inode->i_state & I_NEW) {
+ ocfs2_read_locked_inode(inode, &args);
+ unlock_new_inode(inode);
+ }
if (is_bad_inode(inode)) {
iput(inode);
inode = ERR_PTR(-ESTALE);
@@ -170,9 +171,8 @@ struct inode *ocfs2_iget(struct ocfs2_super *osb, u64 blkno, unsigned flags,
bail:
if (!IS_ERR(inode)) {
- mlog(0, "returning inode with number %llu\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno);
- mlog_exit_ptr(inode);
+ trace_ocfs2_iget_end(inode,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
}
return inode;
@@ -192,18 +192,17 @@ static int ocfs2_find_actor(struct inode *inode, void *opaque)
struct ocfs2_inode_info *oi = OCFS2_I(inode);
int ret = 0;
- mlog_entry("(0x%p, %lu, 0x%p)\n", inode, inode->i_ino, opaque);
-
args = opaque;
mlog_bug_on_msg(!inode, "No inode in find actor!\n");
+ trace_ocfs2_find_actor(inode, inode->i_ino, opaque, args->fi_blkno);
+
if (oi->ip_blkno != args->fi_blkno)
goto bail;
ret = 1;
bail:
- mlog_exit(ret);
return ret;
}
@@ -218,8 +217,6 @@ static int ocfs2_init_locked_inode(struct inode *inode, void *opaque)
static struct lock_class_key ocfs2_quota_ip_alloc_sem_key,
ocfs2_file_ip_alloc_sem_key;
- mlog_entry("inode = %p, opaque = %p\n", inode, opaque);
-
inode->i_ino = args->fi_ino;
OCFS2_I(inode)->ip_blkno = args->fi_blkno;
if (args->fi_sysfile_type != 0)
@@ -235,7 +232,6 @@ static int ocfs2_init_locked_inode(struct inode *inode, void *opaque)
lockdep_set_class(&OCFS2_I(inode)->ip_alloc_sem,
&ocfs2_file_ip_alloc_sem_key);
- mlog_exit(0);
return 0;
}
@@ -246,9 +242,6 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
struct ocfs2_super *osb;
int use_plocks = 1;
- mlog_entry("(0x%p, size:%llu)\n", inode,
- (unsigned long long)le64_to_cpu(fe->i_size));
-
sb = inode->i_sb;
osb = OCFS2_SB(sb);
@@ -300,20 +293,20 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
inode->i_nlink = ocfs2_read_links_count(fe);
+ trace_ocfs2_populate_inode(OCFS2_I(inode)->ip_blkno,
+ le32_to_cpu(fe->i_flags));
if (fe->i_flags & cpu_to_le32(OCFS2_SYSTEM_FL)) {
OCFS2_I(inode)->ip_flags |= OCFS2_INODE_SYSTEM_FILE;
inode->i_flags |= S_NOQUOTA;
}
-
+
if (fe->i_flags & cpu_to_le32(OCFS2_LOCAL_ALLOC_FL)) {
OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
- mlog(0, "local alloc inode: i_ino=%lu\n", inode->i_ino);
} else if (fe->i_flags & cpu_to_le32(OCFS2_BITMAP_FL)) {
OCFS2_I(inode)->ip_flags |= OCFS2_INODE_BITMAP;
} else if (fe->i_flags & cpu_to_le32(OCFS2_QUOTA_FL)) {
inode->i_flags |= S_NOQUOTA;
} else if (fe->i_flags & cpu_to_le32(OCFS2_SUPER_BLOCK_FL)) {
- mlog(0, "superblock inode: i_ino=%lu\n", inode->i_ino);
/* we can't actually hit this as read_inode can't
* handle superblocks today ;-) */
BUG();
@@ -381,7 +374,6 @@ void ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
if (S_ISDIR(inode->i_mode))
ocfs2_resv_set_type(&OCFS2_I(inode)->ip_la_data_resv,
OCFS2_RESV_FLAG_DIR);
- mlog_exit_void();
}
static int ocfs2_read_locked_inode(struct inode *inode,
@@ -394,8 +386,6 @@ static int ocfs2_read_locked_inode(struct inode *inode,
int status, can_lock;
u32 generation = 0;
- mlog_entry("(0x%p, 0x%p)\n", inode, args);
-
status = -EINVAL;
if (inode == NULL || inode->i_sb == NULL) {
mlog(ML_ERROR, "bad inode\n");
@@ -443,6 +433,9 @@ static int ocfs2_read_locked_inode(struct inode *inode,
&& !(args->fi_flags & OCFS2_FI_FLAG_ORPHAN_RECOVERY)
&& !ocfs2_mount_local(osb);
+ trace_ocfs2_read_locked_inode(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno, can_lock);
+
/*
* To maintain backwards compatibility with older versions of
* ocfs2-tools, we still store the generation value for system
@@ -534,7 +527,6 @@ bail:
if (args && bh)
brelse(bh);
- mlog_exit(status);
return status;
}
@@ -551,8 +543,6 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
struct ocfs2_dinode *fe;
handle_t *handle = NULL;
- mlog_entry_void();
-
fe = (struct ocfs2_dinode *) fe_bh->b_data;
/*
@@ -600,7 +590,6 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
out:
if (handle)
ocfs2_commit_trans(osb, handle);
- mlog_exit(status);
return status;
}
@@ -696,8 +685,6 @@ static int ocfs2_check_orphan_recovery_state(struct ocfs2_super *osb,
spin_lock(&osb->osb_lock);
if (ocfs2_node_map_test_bit(osb, &osb->osb_recovering_orphan_dirs, slot)) {
- mlog(0, "Recovery is happening on orphan dir %d, will skip "
- "this inode\n", slot);
ret = -EDEADLK;
goto out;
}
@@ -706,6 +693,7 @@ static int ocfs2_check_orphan_recovery_state(struct ocfs2_super *osb,
osb->osb_orphan_wipes[slot]++;
out:
spin_unlock(&osb->osb_lock);
+ trace_ocfs2_check_orphan_recovery_state(slot, ret);
return ret;
}
@@ -816,6 +804,10 @@ static int ocfs2_inode_is_valid_to_delete(struct inode *inode)
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
+ trace_ocfs2_inode_is_valid_to_delete(current, osb->dc_task,
+ (unsigned long long)oi->ip_blkno,
+ oi->ip_flags);
+
/* We shouldn't be getting here for the root directory
* inode.. */
if (inode == osb->root_inode) {
@@ -828,11 +820,8 @@ static int ocfs2_inode_is_valid_to_delete(struct inode *inode)
* have to skip deleting this guy. That's OK though because
* the node who's doing the actual deleting should handle it
* anyway. */
- if (current == osb->dc_task) {
- mlog(0, "Skipping delete of %lu because we're currently "
- "in downconvert\n", inode->i_ino);
+ if (current == osb->dc_task)
goto bail;
- }
spin_lock(&oi->ip_lock);
/* OCFS2 *never* deletes system files. This should technically
@@ -847,11 +836,8 @@ static int ocfs2_inode_is_valid_to_delete(struct inode *inode)
/* If we have allowd wipe of this inode for another node, it
* will be marked here so we can safely skip it. Recovery will
* cleanup any inodes we might inadvertantly skip here. */
- if (oi->ip_flags & OCFS2_INODE_SKIP_DELETE) {
- mlog(0, "Skipping delete of %lu because another node "
- "has done this for us.\n", inode->i_ino);
+ if (oi->ip_flags & OCFS2_INODE_SKIP_DELETE)
goto bail_unlock;
- }
ret = 1;
bail_unlock:
@@ -868,28 +854,27 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
struct buffer_head *di_bh,
int *wipe)
{
- int status = 0;
+ int status = 0, reason = 0;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_dinode *di;
*wipe = 0;
+ trace_ocfs2_query_inode_wipe_begin((unsigned long long)oi->ip_blkno,
+ inode->i_nlink);
+
/* While we were waiting for the cluster lock in
* ocfs2_delete_inode, another node might have asked to delete
* the inode. Recheck our flags to catch this. */
if (!ocfs2_inode_is_valid_to_delete(inode)) {
- mlog(0, "Skipping delete of %llu because flags changed\n",
- (unsigned long long)oi->ip_blkno);
+ reason = 1;
goto bail;
}
/* Now that we have an up to date inode, we can double check
* the link count. */
- if (inode->i_nlink) {
- mlog(0, "Skipping delete of %llu because nlink = %u\n",
- (unsigned long long)oi->ip_blkno, inode->i_nlink);
+ if (inode->i_nlink)
goto bail;
- }
/* Do some basic inode verification... */
di = (struct ocfs2_dinode *) di_bh->b_data;
@@ -904,9 +889,7 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
* ORPHANED_FL not.
*/
if (di->i_dyn_features & cpu_to_le16(OCFS2_HAS_REFCOUNT_FL)) {
- mlog(0, "Reflinked inode %llu is no longer orphaned. "
- "it shouldn't be deleted\n",
- (unsigned long long)oi->ip_blkno);
+ reason = 2;
goto bail;
}
@@ -943,8 +926,7 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
status = ocfs2_try_open_lock(inode, 1);
if (status == -EAGAIN) {
status = 0;
- mlog(0, "Skipping delete of %llu because it is in use on "
- "other nodes\n", (unsigned long long)oi->ip_blkno);
+ reason = 3;
goto bail;
}
if (status < 0) {
@@ -953,11 +935,10 @@ static int ocfs2_query_inode_wipe(struct inode *inode,
}
*wipe = 1;
- mlog(0, "Inode %llu is ok to wipe from orphan dir %u\n",
- (unsigned long long)oi->ip_blkno,
- le16_to_cpu(di->i_orphaned_slot));
+ trace_ocfs2_query_inode_wipe_succ(le16_to_cpu(di->i_orphaned_slot));
bail:
+ trace_ocfs2_query_inode_wipe_end(status, reason);
return status;
}
@@ -967,8 +948,8 @@ bail:
static void ocfs2_cleanup_delete_inode(struct inode *inode,
int sync_data)
{
- mlog(0, "Cleanup inode %llu, sync = %d\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data);
+ trace_ocfs2_cleanup_delete_inode(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno, sync_data);
if (sync_data)
write_inode_now(inode, 1);
truncate_inode_pages(&inode->i_data, 0);
@@ -980,15 +961,15 @@ static void ocfs2_delete_inode(struct inode *inode)
sigset_t oldset;
struct buffer_head *di_bh = NULL;
- mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
+ trace_ocfs2_delete_inode(inode->i_ino,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ is_bad_inode(inode));
/* When we fail in read_inode() we mark inode as bad. The second test
* catches the case when inode allocation fails before allocating
* a block for inode. */
- if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno) {
- mlog(0, "Skipping delete of bad inode\n");
+ if (is_bad_inode(inode) || !OCFS2_I(inode)->ip_blkno)
goto bail;
- }
dquot_initialize(inode);
@@ -1080,7 +1061,7 @@ bail_unlock_nfs_sync:
bail_unblock:
ocfs2_unblock_signals(&oldset);
bail:
- mlog_exit_void();
+ return;
}
static void ocfs2_clear_inode(struct inode *inode)
@@ -1088,11 +1069,9 @@ static void ocfs2_clear_inode(struct inode *inode)
int status;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
- mlog_entry_void();
-
end_writeback(inode);
- mlog(0, "Clearing inode: %llu, nlink = %u\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno, inode->i_nlink);
+ trace_ocfs2_clear_inode((unsigned long long)oi->ip_blkno,
+ inode->i_nlink);
mlog_bug_on_msg(OCFS2_SB(inode->i_sb) == NULL,
"Inode=%lu\n", inode->i_ino);
@@ -1181,8 +1160,6 @@ static void ocfs2_clear_inode(struct inode *inode)
*/
jbd2_journal_release_jbd_inode(OCFS2_SB(inode->i_sb)->journal->j_journal,
&oi->ip_jinode);
-
- mlog_exit_void();
}
void ocfs2_evict_inode(struct inode *inode)
@@ -1204,17 +1181,14 @@ int ocfs2_drop_inode(struct inode *inode)
struct ocfs2_inode_info *oi = OCFS2_I(inode);
int res;
- mlog_entry_void();
-
- mlog(0, "Drop inode %llu, nlink = %u, ip_flags = 0x%x\n",
- (unsigned long long)oi->ip_blkno, inode->i_nlink, oi->ip_flags);
+ trace_ocfs2_drop_inode((unsigned long long)oi->ip_blkno,
+ inode->i_nlink, oi->ip_flags);
if (oi->ip_flags & OCFS2_INODE_MAYBE_ORPHANED)
res = 1;
else
res = generic_drop_inode(inode);
- mlog_exit_void();
return res;
}
@@ -1226,11 +1200,11 @@ int ocfs2_inode_revalidate(struct dentry *dentry)
struct inode *inode = dentry->d_inode;
int status = 0;
- mlog_entry("(inode = 0x%p, ino = %llu)\n", inode,
- inode ? (unsigned long long)OCFS2_I(inode)->ip_blkno : 0ULL);
+ trace_ocfs2_inode_revalidate(inode,
+ inode ? (unsigned long long)OCFS2_I(inode)->ip_blkno : 0ULL,
+ inode ? (unsigned long long)OCFS2_I(inode)->ip_flags : 0);
if (!inode) {
- mlog(0, "eep, no inode!\n");
status = -ENOENT;
goto bail;
}
@@ -1238,7 +1212,6 @@ int ocfs2_inode_revalidate(struct dentry *dentry)
spin_lock(&OCFS2_I(inode)->ip_lock);
if (OCFS2_I(inode)->ip_flags & OCFS2_INODE_DELETED) {
spin_unlock(&OCFS2_I(inode)->ip_lock);
- mlog(0, "inode deleted!\n");
status = -ENOENT;
goto bail;
}
@@ -1254,8 +1227,6 @@ int ocfs2_inode_revalidate(struct dentry *dentry)
}
ocfs2_inode_unlock(inode, 0);
bail:
- mlog_exit(status);
-
return status;
}
@@ -1271,8 +1242,7 @@ int ocfs2_mark_inode_dirty(handle_t *handle,
int status;
struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;
- mlog_entry("(inode %llu)\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ trace_ocfs2_mark_inode_dirty((unsigned long long)OCFS2_I(inode)->ip_blkno);
status = ocfs2_journal_access_di(handle, INODE_CACHE(inode), bh,
OCFS2_JOURNAL_ACCESS_WRITE);
@@ -1302,7 +1272,6 @@ int ocfs2_mark_inode_dirty(handle_t *handle,
ocfs2_journal_dirty(handle, bh);
leave:
- mlog_exit(status);
return status;
}
@@ -1345,8 +1314,7 @@ int ocfs2_validate_inode_block(struct super_block *sb,
int rc;
struct ocfs2_dinode *di = (struct ocfs2_dinode *)bh->b_data;
- mlog(0, "Validating dinode %llu\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_validate_inode_block((unsigned long long)bh->b_blocknr);
BUG_ON(!buffer_uptodate(bh));
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
index 09de77ce002..8f13c5989ea 100644
--- a/fs/ocfs2/ioctl.c
+++ b/fs/ocfs2/ioctl.c
@@ -9,7 +9,6 @@
#include <linux/mount.h>
#include <linux/compat.h>
-#define MLOG_MASK_PREFIX ML_INODE
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -46,6 +45,22 @@ static inline void __o2info_set_request_error(struct ocfs2_info_request *kreq,
#define o2info_set_request_error(a, b) \
__o2info_set_request_error((struct ocfs2_info_request *)&(a), b)
+static inline void __o2info_set_request_filled(struct ocfs2_info_request *req)
+{
+ req->ir_flags |= OCFS2_INFO_FL_FILLED;
+}
+
+#define o2info_set_request_filled(a) \
+ __o2info_set_request_filled((struct ocfs2_info_request *)&(a))
+
+static inline void __o2info_clear_request_filled(struct ocfs2_info_request *req)
+{
+ req->ir_flags &= ~OCFS2_INFO_FL_FILLED;
+}
+
+#define o2info_clear_request_filled(a) \
+ __o2info_clear_request_filled((struct ocfs2_info_request *)&(a))
+
static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
{
int status;
@@ -59,7 +74,6 @@ static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
*flags = OCFS2_I(inode)->ip_attr;
ocfs2_inode_unlock(inode, 0);
- mlog_exit(status);
return status;
}
@@ -125,7 +139,6 @@ bail:
brelse(bh);
- mlog_exit(status);
return status;
}
@@ -139,7 +152,8 @@ int ocfs2_info_handle_blocksize(struct inode *inode,
goto bail;
oib.ib_blocksize = inode->i_sb->s_blocksize;
- oib.ib_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+ o2info_set_request_filled(oib);
if (o2info_to_user(oib, req))
goto bail;
@@ -163,7 +177,8 @@ int ocfs2_info_handle_clustersize(struct inode *inode,
goto bail;
oic.ic_clustersize = osb->s_clustersize;
- oic.ic_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+ o2info_set_request_filled(oic);
if (o2info_to_user(oic, req))
goto bail;
@@ -187,7 +202,8 @@ int ocfs2_info_handle_maxslots(struct inode *inode,
goto bail;
oim.im_max_slots = osb->max_slots;
- oim.im_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+ o2info_set_request_filled(oim);
if (o2info_to_user(oim, req))
goto bail;
@@ -211,7 +227,8 @@ int ocfs2_info_handle_label(struct inode *inode,
goto bail;
memcpy(oil.il_label, osb->vol_label, OCFS2_MAX_VOL_LABEL_LEN);
- oil.il_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+ o2info_set_request_filled(oil);
if (o2info_to_user(oil, req))
goto bail;
@@ -235,7 +252,8 @@ int ocfs2_info_handle_uuid(struct inode *inode,
goto bail;
memcpy(oiu.iu_uuid_str, osb->uuid_str, OCFS2_TEXT_UUID_LEN + 1);
- oiu.iu_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+ o2info_set_request_filled(oiu);
if (o2info_to_user(oiu, req))
goto bail;
@@ -261,7 +279,8 @@ int ocfs2_info_handle_fs_features(struct inode *inode,
oif.if_compat_features = osb->s_feature_compat;
oif.if_incompat_features = osb->s_feature_incompat;
oif.if_ro_compat_features = osb->s_feature_ro_compat;
- oif.if_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+
+ o2info_set_request_filled(oif);
if (o2info_to_user(oif, req))
goto bail;
@@ -286,7 +305,7 @@ int ocfs2_info_handle_journal_size(struct inode *inode,
oij.ij_journal_size = osb->journal->j_inode->i_size;
- oij.ij_req.ir_flags |= OCFS2_INFO_FL_FILLED;
+ o2info_set_request_filled(oij);
if (o2info_to_user(oij, req))
goto bail;
@@ -308,7 +327,7 @@ int ocfs2_info_handle_unknown(struct inode *inode,
if (o2info_from_user(oir, req))
goto bail;
- oir.ir_flags &= ~OCFS2_INFO_FL_FILLED;
+ o2info_clear_request_filled(oir);
if (o2info_to_user(oir, req))
goto bail;
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index faa2303dbf0..dcc2d932715 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -31,7 +31,6 @@
#include <linux/time.h>
#include <linux/random.h>
-#define MLOG_MASK_PREFIX ML_JOURNAL
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -52,6 +51,7 @@
#include "quota.h"
#include "buffer_head_io.h"
+#include "ocfs2_trace.h"
DEFINE_SPINLOCK(trans_inc_lock);
@@ -303,16 +303,15 @@ static int ocfs2_commit_cache(struct ocfs2_super *osb)
unsigned int flushed;
struct ocfs2_journal *journal = NULL;
- mlog_entry_void();
-
journal = osb->journal;
/* Flush all pending commits and checkpoint the journal. */
down_write(&journal->j_trans_barrier);
- if (atomic_read(&journal->j_num_trans) == 0) {
+ flushed = atomic_read(&journal->j_num_trans);
+ trace_ocfs2_commit_cache_begin(flushed);
+ if (flushed == 0) {
up_write(&journal->j_trans_barrier);
- mlog(0, "No transactions for me to flush!\n");
goto finally;
}
@@ -331,13 +330,11 @@ static int ocfs2_commit_cache(struct ocfs2_super *osb)
atomic_set(&journal->j_num_trans, 0);
up_write(&journal->j_trans_barrier);
- mlog(0, "commit_thread: flushed transaction %lu (%u handles)\n",
- journal->j_trans_id, flushed);
+ trace_ocfs2_commit_cache_end(journal->j_trans_id, flushed);
ocfs2_wake_downconvert_thread(osb);
wake_up(&journal->j_checkpointed);
finally:
- mlog_exit(status);
return status;
}
@@ -425,9 +422,8 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks)
return 0;
old_nblocks = handle->h_buffer_credits;
- mlog_entry_void();
- mlog(0, "Trying to extend transaction by %d blocks\n", nblocks);
+ trace_ocfs2_extend_trans(old_nblocks, nblocks);
#ifdef CONFIG_OCFS2_DEBUG_FS
status = 1;
@@ -440,9 +436,7 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks)
#endif
if (status > 0) {
- mlog(0,
- "jbd2_journal_extend failed, trying "
- "jbd2_journal_restart\n");
+ trace_ocfs2_extend_trans_restart(old_nblocks + nblocks);
status = jbd2_journal_restart(handle,
old_nblocks + nblocks);
if (status < 0) {
@@ -453,8 +447,6 @@ int ocfs2_extend_trans(handle_t *handle, int nblocks)
status = 0;
bail:
-
- mlog_exit(status);
return status;
}
@@ -622,12 +614,9 @@ static int __ocfs2_journal_access(handle_t *handle,
BUG_ON(!handle);
BUG_ON(!bh);
- mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n",
- (unsigned long long)bh->b_blocknr, type,
- (type == OCFS2_JOURNAL_ACCESS_CREATE) ?
- "OCFS2_JOURNAL_ACCESS_CREATE" :
- "OCFS2_JOURNAL_ACCESS_WRITE",
- bh->b_size);
+ trace_ocfs2_journal_access(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)bh->b_blocknr, type, bh->b_size);
/* we can safely remove this assertion after testing. */
if (!buffer_uptodate(bh)) {
@@ -668,7 +657,6 @@ static int __ocfs2_journal_access(handle_t *handle,
mlog(ML_ERROR, "Error %d getting %d access to buffer!\n",
status, type);
- mlog_exit(status);
return status;
}
@@ -737,13 +725,10 @@ void ocfs2_journal_dirty(handle_t *handle, struct buffer_head *bh)
{
int status;
- mlog_entry("(bh->b_blocknr=%llu)\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_journal_dirty((unsigned long long)bh->b_blocknr);
status = jbd2_journal_dirty_metadata(handle, bh);
BUG_ON(status);
-
- mlog_exit_void();
}
#define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE)
@@ -775,8 +760,6 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty)
struct ocfs2_super *osb;
int inode_lock = 0;
- mlog_entry_void();
-
BUG_ON(!journal);
osb = journal->j_osb;
@@ -820,10 +803,9 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty)
goto done;
}
- mlog(0, "inode->i_size = %lld\n", inode->i_size);
- mlog(0, "inode->i_blocks = %llu\n",
- (unsigned long long)inode->i_blocks);
- mlog(0, "inode->ip_clusters = %u\n", OCFS2_I(inode)->ip_clusters);
+ trace_ocfs2_journal_init(inode->i_size,
+ (unsigned long long)inode->i_blocks,
+ OCFS2_I(inode)->ip_clusters);
/* call the kernels journal init function now */
j_journal = jbd2_journal_init_inode(inode);
@@ -833,8 +815,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty)
goto done;
}
- mlog(0, "Returned from jbd2_journal_init_inode\n");
- mlog(0, "j_journal->j_maxlen = %u\n", j_journal->j_maxlen);
+ trace_ocfs2_journal_init_maxlen(j_journal->j_maxlen);
*dirty = (le32_to_cpu(di->id1.journal1.ij_flags) &
OCFS2_JOURNAL_DIRTY_FL);
@@ -859,7 +840,6 @@ done:
}
}
- mlog_exit(status);
return status;
}
@@ -882,8 +862,6 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
struct buffer_head *bh = journal->j_bh;
struct ocfs2_dinode *fe;
- mlog_entry_void();
-
fe = (struct ocfs2_dinode *)bh->b_data;
/* The journal bh on the osb always comes from ocfs2_journal_init()
@@ -906,7 +884,6 @@ static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
if (status < 0)
mlog_errno(status);
- mlog_exit(status);
return status;
}
@@ -921,8 +898,6 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
struct inode *inode = NULL;
int num_running_trans = 0;
- mlog_entry_void();
-
BUG_ON(!osb);
journal = osb->journal;
@@ -939,10 +914,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
BUG();
num_running_trans = atomic_read(&(osb->journal->j_num_trans));
- if (num_running_trans > 0)
- mlog(0, "Shutting down journal: must wait on %d "
- "running transactions!\n",
- num_running_trans);
+ trace_ocfs2_journal_shutdown(num_running_trans);
/* Do a commit_cache here. It will flush our journal, *and*
* release any locks that are still held.
@@ -955,7 +927,7 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
* completely destroy the journal. */
if (osb->commit_task) {
/* Wait for the commit thread */
- mlog(0, "Waiting for ocfs2commit to exit....\n");
+ trace_ocfs2_journal_shutdown_wait(osb->commit_task);
kthread_stop(osb->commit_task);
osb->commit_task = NULL;
}
@@ -998,7 +970,6 @@ void ocfs2_journal_shutdown(struct ocfs2_super *osb)
done:
if (inode)
iput(inode);
- mlog_exit_void();
}
static void ocfs2_clear_journal_error(struct super_block *sb,
@@ -1024,8 +995,6 @@ int ocfs2_journal_load(struct ocfs2_journal *journal, int local, int replayed)
int status = 0;
struct ocfs2_super *osb;
- mlog_entry_void();
-
BUG_ON(!journal);
osb = journal->j_osb;
@@ -1059,7 +1028,6 @@ int ocfs2_journal_load(struct ocfs2_journal *journal, int local, int replayed)
osb->commit_task = NULL;
done:
- mlog_exit(status);
return status;
}
@@ -1070,8 +1038,6 @@ int ocfs2_journal_wipe(struct ocfs2_journal *journal, int full)
{
int status;
- mlog_entry_void();
-
BUG_ON(!journal);
status = jbd2_journal_wipe(journal->j_journal, full);
@@ -1085,7 +1051,6 @@ int ocfs2_journal_wipe(struct ocfs2_journal *journal, int full)
mlog_errno(status);
bail:
- mlog_exit(status);
return status;
}
@@ -1124,8 +1089,6 @@ static int ocfs2_force_read_journal(struct inode *inode)
#define CONCURRENT_JOURNAL_FILL 32ULL
struct buffer_head *bhs[CONCURRENT_JOURNAL_FILL];
- mlog_entry_void();
-
memset(bhs, 0, sizeof(struct buffer_head *) * CONCURRENT_JOURNAL_FILL);
num_blocks = ocfs2_blocks_for_bytes(inode->i_sb, inode->i_size);
@@ -1161,7 +1124,6 @@ static int ocfs2_force_read_journal(struct inode *inode)
bail:
for(i = 0; i < CONCURRENT_JOURNAL_FILL; i++)
brelse(bhs[i]);
- mlog_exit(status);
return status;
}
@@ -1185,7 +1147,7 @@ struct ocfs2_la_recovery_item {
*/
void ocfs2_complete_recovery(struct work_struct *work)
{
- int ret;
+ int ret = 0;
struct ocfs2_journal *journal =
container_of(work, struct ocfs2_journal, j_recovery_work);
struct ocfs2_super *osb = journal->j_osb;
@@ -1194,9 +1156,8 @@ void ocfs2_complete_recovery(struct work_struct *work)
struct ocfs2_quota_recovery *qrec;
LIST_HEAD(tmp_la_list);
- mlog_entry_void();
-
- mlog(0, "completing recovery from keventd\n");
+ trace_ocfs2_complete_recovery(
+ (unsigned long long)OCFS2_I(journal->j_inode)->ip_blkno);
spin_lock(&journal->j_lock);
list_splice_init(&journal->j_la_cleanups, &tmp_la_list);
@@ -1205,15 +1166,18 @@ void ocfs2_complete_recovery(struct work_struct *work)
list_for_each_entry_safe(item, n, &tmp_la_list, lri_list) {
list_del_init(&item->lri_list);
- mlog(0, "Complete recovery for slot %d\n", item->lri_slot);
-
ocfs2_wait_on_quotas(osb);
la_dinode = item->lri_la_dinode;
- if (la_dinode) {
- mlog(0, "Clean up local alloc %llu\n",
- (unsigned long long)le64_to_cpu(la_dinode->i_blkno));
+ tl_dinode = item->lri_tl_dinode;
+ qrec = item->lri_qrec;
+
+ trace_ocfs2_complete_recovery_slot(item->lri_slot,
+ la_dinode ? le64_to_cpu(la_dinode->i_blkno) : 0,
+ tl_dinode ? le64_to_cpu(tl_dinode->i_blkno) : 0,
+ qrec);
+ if (la_dinode) {
ret = ocfs2_complete_local_alloc_recovery(osb,
la_dinode);
if (ret < 0)
@@ -1222,11 +1186,7 @@ void ocfs2_complete_recovery(struct work_struct *work)
kfree(la_dinode);
}
- tl_dinode = item->lri_tl_dinode;
if (tl_dinode) {
- mlog(0, "Clean up truncate log %llu\n",
- (unsigned long long)le64_to_cpu(tl_dinode->i_blkno));
-
ret = ocfs2_complete_truncate_log_recovery(osb,
tl_dinode);
if (ret < 0)
@@ -1239,9 +1199,7 @@ void ocfs2_complete_recovery(struct work_struct *work)
if (ret < 0)
mlog_errno(ret);
- qrec = item->lri_qrec;
if (qrec) {
- mlog(0, "Recovering quota files");
ret = ocfs2_finish_quota_recovery(osb, qrec,
item->lri_slot);
if (ret < 0)
@@ -1252,8 +1210,7 @@ void ocfs2_complete_recovery(struct work_struct *work)
kfree(item);
}
- mlog(0, "Recovery completion\n");
- mlog_exit_void();
+ trace_ocfs2_complete_recovery_end(ret);
}
/* NOTE: This function always eats your references to la_dinode and
@@ -1339,8 +1296,6 @@ static int __ocfs2_recovery_thread(void *arg)
int rm_quota_used = 0, i;
struct ocfs2_quota_recovery *qrec;
- mlog_entry_void();
-
status = ocfs2_wait_on_mount(osb);
if (status < 0) {
goto bail;
@@ -1372,15 +1327,12 @@ restart:
* clear it until ocfs2_recover_node() has succeeded. */
node_num = rm->rm_entries[0];
spin_unlock(&osb->osb_lock);
- mlog(0, "checking node %d\n", node_num);
slot_num = ocfs2_node_num_to_slot(osb, node_num);
+ trace_ocfs2_recovery_thread_node(node_num, slot_num);
if (slot_num == -ENOENT) {
status = 0;
- mlog(0, "no slot for this node, so no recovery"
- "required.\n");
goto skip_recovery;
}
- mlog(0, "node %d was using slot %d\n", node_num, slot_num);
/* It is a bit subtle with quota recovery. We cannot do it
* immediately because we have to obtain cluster locks from
@@ -1407,7 +1359,7 @@ skip_recovery:
spin_lock(&osb->osb_lock);
}
spin_unlock(&osb->osb_lock);
- mlog(0, "All nodes recovered\n");
+ trace_ocfs2_recovery_thread_end(status);
/* Refresh all journal recovery generations from disk */
status = ocfs2_check_journals_nolocks(osb);
@@ -1451,7 +1403,6 @@ bail:
if (rm_quota)
kfree(rm_quota);
- mlog_exit(status);
/* no one is callint kthread_stop() for us so the kthread() api
* requires that we call do_exit(). And it isn't exported, but
* complete_and_exit() seems to be a minimal wrapper around it. */
@@ -1461,19 +1412,15 @@ bail:
void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
{
- mlog_entry("(node_num=%d, osb->node_num = %d)\n",
- node_num, osb->node_num);
-
mutex_lock(&osb->recovery_lock);
- if (osb->disable_recovery)
- goto out;
- /* People waiting on recovery will wait on
- * the recovery map to empty. */
- if (ocfs2_recovery_map_set(osb, node_num))
- mlog(0, "node %d already in recovery map.\n", node_num);
+ trace_ocfs2_recovery_thread(node_num, osb->node_num,
+ osb->disable_recovery, osb->recovery_thread_task,
+ osb->disable_recovery ?
+ -1 : ocfs2_recovery_map_set(osb, node_num));
- mlog(0, "starting recovery thread...\n");
+ if (osb->disable_recovery)
+ goto out;
if (osb->recovery_thread_task)
goto out;
@@ -1488,8 +1435,6 @@ void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
out:
mutex_unlock(&osb->recovery_lock);
wake_up(&osb->recovery_event);
-
- mlog_exit_void();
}
static int ocfs2_read_journal_inode(struct ocfs2_super *osb,
@@ -1563,7 +1508,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
* If not, it needs recovery.
*/
if (osb->slot_recovery_generations[slot_num] != slot_reco_gen) {
- mlog(0, "Slot %u already recovered (old/new=%u/%u)\n", slot_num,
+ trace_ocfs2_replay_journal_recovered(slot_num,
osb->slot_recovery_generations[slot_num], slot_reco_gen);
osb->slot_recovery_generations[slot_num] = slot_reco_gen;
status = -EBUSY;
@@ -1574,7 +1519,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
status = ocfs2_inode_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY);
if (status < 0) {
- mlog(0, "status returned from ocfs2_inode_lock=%d\n", status);
+ trace_ocfs2_replay_journal_lock_err(status);
if (status != -ERESTARTSYS)
mlog(ML_ERROR, "Could not lock journal!\n");
goto done;
@@ -1587,7 +1532,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
slot_reco_gen = ocfs2_get_recovery_generation(fe);
if (!(flags & OCFS2_JOURNAL_DIRTY_FL)) {
- mlog(0, "No recovery required for node %d\n", node_num);
+ trace_ocfs2_replay_journal_skip(node_num);
/* Refresh recovery generation for the slot */
osb->slot_recovery_generations[slot_num] = slot_reco_gen;
goto done;
@@ -1608,7 +1553,6 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
goto done;
}
- mlog(0, "calling journal_init_inode\n");
journal = jbd2_journal_init_inode(inode);
if (journal == NULL) {
mlog(ML_ERROR, "Linux journal layer error\n");
@@ -1628,7 +1572,6 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
ocfs2_clear_journal_error(osb->sb, journal, slot_num);
/* wipe the journal */
- mlog(0, "flushing the journal.\n");
jbd2_journal_lock_updates(journal);
status = jbd2_journal_flush(journal);
jbd2_journal_unlock_updates(journal);
@@ -1665,7 +1608,6 @@ done:
brelse(bh);
- mlog_exit(status);
return status;
}
@@ -1688,8 +1630,7 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
struct ocfs2_dinode *la_copy = NULL;
struct ocfs2_dinode *tl_copy = NULL;
- mlog_entry("(node_num=%d, slot_num=%d, osb->node_num = %d)\n",
- node_num, slot_num, osb->node_num);
+ trace_ocfs2_recover_node(node_num, slot_num, osb->node_num);
/* Should not ever be called to recover ourselves -- in that
* case we should've called ocfs2_journal_load instead. */
@@ -1698,9 +1639,7 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
status = ocfs2_replay_journal(osb, node_num, slot_num);
if (status < 0) {
if (status == -EBUSY) {
- mlog(0, "Skipping recovery for slot %u (node %u) "
- "as another node has recovered it\n", slot_num,
- node_num);
+ trace_ocfs2_recover_node_skip(slot_num, node_num);
status = 0;
goto done;
}
@@ -1735,7 +1674,6 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
status = 0;
done:
- mlog_exit(status);
return status;
}
@@ -1808,8 +1746,8 @@ int ocfs2_mark_dead_nodes(struct ocfs2_super *osb)
spin_lock(&osb->osb_lock);
osb->slot_recovery_generations[i] = gen;
- mlog(0, "Slot %u recovery generation is %u\n", i,
- osb->slot_recovery_generations[i]);
+ trace_ocfs2_mark_dead_nodes(i,
+ osb->slot_recovery_generations[i]);
if (i == osb->slot_num) {
spin_unlock(&osb->osb_lock);
@@ -1845,7 +1783,6 @@ int ocfs2_mark_dead_nodes(struct ocfs2_super *osb)
status = 0;
bail:
- mlog_exit(status);
return status;
}
@@ -1884,11 +1821,12 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
os = &osb->osb_orphan_scan;
- mlog(0, "Begin orphan scan\n");
-
if (atomic_read(&os->os_state) == ORPHAN_SCAN_INACTIVE)
goto out;
+ trace_ocfs2_queue_orphan_scan_begin(os->os_count, os->os_seqno,
+ atomic_read(&os->os_state));
+
status = ocfs2_orphan_scan_lock(osb, &seqno);
if (status < 0) {
if (status != -EAGAIN)
@@ -1918,7 +1856,8 @@ void ocfs2_queue_orphan_scan(struct ocfs2_super *osb)
unlock:
ocfs2_orphan_scan_unlock(osb, seqno);
out:
- mlog(0, "Orphan scan completed\n");
+ trace_ocfs2_queue_orphan_scan_end(os->os_count, os->os_seqno,
+ atomic_read(&os->os_state));
return;
}
@@ -2002,8 +1941,7 @@ static int ocfs2_orphan_filldir(void *priv, const char *name, int name_len,
if (IS_ERR(iter))
return 0;
- mlog(0, "queue orphan %llu\n",
- (unsigned long long)OCFS2_I(iter)->ip_blkno);
+ trace_ocfs2_orphan_filldir((unsigned long long)OCFS2_I(iter)->ip_blkno);
/* No locking is required for the next_orphan queue as there
* is only ever a single process doing orphan recovery. */
OCFS2_I(iter)->ip_next_orphan = p->head;
@@ -2119,7 +2057,7 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,
struct inode *iter;
struct ocfs2_inode_info *oi;
- mlog(0, "Recover inodes from orphan dir in slot %d\n", slot);
+ trace_ocfs2_recover_orphans(slot);
ocfs2_mark_recovering_orphan_dir(osb, slot);
ret = ocfs2_queue_orphans(osb, slot, &inode);
@@ -2132,7 +2070,8 @@ static int ocfs2_recover_orphans(struct ocfs2_super *osb,
while (inode) {
oi = OCFS2_I(inode);
- mlog(0, "iput orphan %llu\n", (unsigned long long)oi->ip_blkno);
+ trace_ocfs2_recover_orphans_iput(
+ (unsigned long long)oi->ip_blkno);
iter = oi->ip_next_orphan;
@@ -2170,6 +2109,7 @@ static int __ocfs2_wait_on_mount(struct ocfs2_super *osb, int quota)
* MOUNTED flag, but this is set right before
* dismount_volume() so we can trust it. */
if (atomic_read(&osb->vol_state) == VOLUME_DISABLED) {
+ trace_ocfs2_wait_on_mount(VOLUME_DISABLED);
mlog(0, "mount error, exiting!\n");
return -EBUSY;
}
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index ec6adbf8f55..210c3523754 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -29,7 +29,6 @@
#include <linux/highmem.h>
#include <linux/bitops.h>
-#define MLOG_MASK_PREFIX ML_DISK_ALLOC
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -43,6 +42,7 @@
#include "suballoc.h"
#include "super.h"
#include "sysfile.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -201,8 +201,7 @@ void ocfs2_la_set_sizes(struct ocfs2_super *osb, int requested_mb)
la_max_mb = ocfs2_clusters_to_megabytes(sb,
ocfs2_local_alloc_size(sb) * 8);
- mlog(0, "requested: %dM, max: %uM, default: %uM\n",
- requested_mb, la_max_mb, la_default_mb);
+ trace_ocfs2_la_set_sizes(requested_mb, la_max_mb, la_default_mb);
if (requested_mb == -1) {
/* No user request - use defaults */
@@ -276,8 +275,8 @@ int ocfs2_alloc_should_use_local(struct ocfs2_super *osb, u64 bits)
ret = 1;
bail:
- mlog(0, "state=%d, bits=%llu, la_bits=%d, ret=%d\n",
- osb->local_alloc_state, (unsigned long long)bits, la_bits, ret);
+ trace_ocfs2_alloc_should_use_local(
+ (unsigned long long)bits, osb->local_alloc_state, la_bits, ret);
spin_unlock(&osb->osb_lock);
return ret;
}
@@ -291,8 +290,6 @@ int ocfs2_load_local_alloc(struct ocfs2_super *osb)
struct inode *inode = NULL;
struct ocfs2_local_alloc *la;
- mlog_entry_void();
-
if (osb->local_alloc_bits == 0)
goto bail;
@@ -364,9 +361,10 @@ bail:
if (inode)
iput(inode);
- mlog(0, "Local alloc window bits = %d\n", osb->local_alloc_bits);
+ trace_ocfs2_load_local_alloc(osb->local_alloc_bits);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -388,8 +386,6 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
struct ocfs2_dinode *alloc_copy = NULL;
struct ocfs2_dinode *alloc = NULL;
- mlog_entry_void();
-
cancel_delayed_work(&osb->la_enable_wq);
flush_workqueue(ocfs2_wq);
@@ -482,8 +478,6 @@ out:
if (alloc_copy)
kfree(alloc_copy);
-
- mlog_exit_void();
}
/*
@@ -502,7 +496,7 @@ int ocfs2_begin_local_alloc_recovery(struct ocfs2_super *osb,
struct inode *inode = NULL;
struct ocfs2_dinode *alloc;
- mlog_entry("(slot_num = %d)\n", slot_num);
+ trace_ocfs2_begin_local_alloc_recovery(slot_num);
*alloc_copy = NULL;
@@ -552,7 +546,8 @@ bail:
iput(inode);
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -570,8 +565,6 @@ int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb,
struct buffer_head *main_bm_bh = NULL;
struct inode *main_bm_inode;
- mlog_entry_void();
-
main_bm_inode = ocfs2_get_system_file_inode(osb,
GLOBAL_BITMAP_SYSTEM_INODE,
OCFS2_INVALID_SLOT);
@@ -620,7 +613,8 @@ out_mutex:
out:
if (!status)
ocfs2_init_steal_slots(osb);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -640,8 +634,6 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
struct inode *local_alloc_inode;
unsigned int free_bits;
- mlog_entry_void();
-
BUG_ON(!ac);
local_alloc_inode =
@@ -712,10 +704,6 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
goto bail;
}
- if (ac->ac_max_block)
- mlog(0, "Calling in_range for max block %llu\n",
- (unsigned long long)ac->ac_max_block);
-
ac->ac_inode = local_alloc_inode;
/* We should never use localalloc from another slot */
ac->ac_alloc_slot = osb->slot_num;
@@ -729,10 +717,12 @@ bail:
iput(local_alloc_inode);
}
- mlog(0, "bits=%d, slot=%d, ret=%d\n", bits_wanted, osb->slot_num,
- status);
+ trace_ocfs2_reserve_local_alloc_bits(
+ (unsigned long long)ac->ac_max_block,
+ bits_wanted, osb->slot_num, status);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -749,7 +739,6 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
struct ocfs2_dinode *alloc;
struct ocfs2_local_alloc *la;
- mlog_entry_void();
BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL);
local_alloc_inode = ac->ac_inode;
@@ -788,7 +777,8 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
ocfs2_journal_dirty(handle, osb->local_alloc_bh);
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -799,13 +789,11 @@ static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc)
u32 count = 0;
struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc);
- mlog_entry_void();
-
buffer = la->la_bitmap;
for (i = 0; i < le16_to_cpu(la->la_size); i++)
count += hweight8(buffer[i]);
- mlog_exit(count);
+ trace_ocfs2_local_alloc_count_bits(count);
return count;
}
@@ -820,10 +808,7 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
void *bitmap = NULL;
struct ocfs2_reservation_map *resmap = &osb->osb_la_resmap;
- mlog_entry("(numbits wanted = %u)\n", *numbits);
-
if (!alloc->id1.bitmap1.i_total) {
- mlog(0, "No bits in my window!\n");
bitoff = -1;
goto bail;
}
@@ -883,8 +868,7 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
}
}
- mlog(0, "Exiting loop, bitoff = %d, numfound = %d\n", bitoff,
- numfound);
+ trace_ocfs2_local_alloc_find_clear_bits_search_bitmap(bitoff, numfound);
if (numfound == *numbits)
bitoff = startoff - numfound;
@@ -895,7 +879,10 @@ bail:
if (local_resv)
ocfs2_resv_discard(resmap, resv);
- mlog_exit(bitoff);
+ trace_ocfs2_local_alloc_find_clear_bits(*numbits,
+ le32_to_cpu(alloc->id1.bitmap1.i_total),
+ bitoff, numfound);
+
return bitoff;
}
@@ -903,15 +890,12 @@ static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc)
{
struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc);
int i;
- mlog_entry_void();
alloc->id1.bitmap1.i_total = 0;
alloc->id1.bitmap1.i_used = 0;
la->la_bm_off = 0;
for(i = 0; i < le16_to_cpu(la->la_size); i++)
la->la_bitmap[i] = 0;
-
- mlog_exit_void();
}
#if 0
@@ -952,18 +936,16 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
void *bitmap;
struct ocfs2_local_alloc *la = OCFS2_LOCAL_ALLOC(alloc);
- mlog_entry("total = %u, used = %u\n",
- le32_to_cpu(alloc->id1.bitmap1.i_total),
- le32_to_cpu(alloc->id1.bitmap1.i_used));
+ trace_ocfs2_sync_local_to_main(
+ le32_to_cpu(alloc->id1.bitmap1.i_total),
+ le32_to_cpu(alloc->id1.bitmap1.i_used));
if (!alloc->id1.bitmap1.i_total) {
- mlog(0, "nothing to sync!\n");
goto bail;
}
if (le32_to_cpu(alloc->id1.bitmap1.i_used) ==
le32_to_cpu(alloc->id1.bitmap1.i_total)) {
- mlog(0, "all bits were taken!\n");
goto bail;
}
@@ -985,8 +967,7 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
ocfs2_clusters_to_blocks(osb->sb,
start - count);
- mlog(0, "freeing %u bits starting at local alloc bit "
- "%u (la_start_blk = %llu, blkno = %llu)\n",
+ trace_ocfs2_sync_local_to_main_free(
count, start - count,
(unsigned long long)la_start_blk,
(unsigned long long)blkno);
@@ -1007,7 +988,8 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
}
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1132,7 +1114,8 @@ bail:
*ac = NULL;
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1148,17 +1131,12 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
struct ocfs2_dinode *alloc = NULL;
struct ocfs2_local_alloc *la;
- mlog_entry_void();
-
alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data;
la = OCFS2_LOCAL_ALLOC(alloc);
- if (alloc->id1.bitmap1.i_total)
- mlog(0, "asking me to alloc a new window over a non-empty "
- "one\n");
-
- mlog(0, "Allocating %u clusters for a new window.\n",
- osb->local_alloc_bits);
+ trace_ocfs2_local_alloc_new_window(
+ le32_to_cpu(alloc->id1.bitmap1.i_total),
+ osb->local_alloc_bits);
/* Instruct the allocation code to try the most recently used
* cluster group. We'll re-record the group used this pass
@@ -1220,13 +1198,13 @@ retry_enospc:
ocfs2_resmap_restart(&osb->osb_la_resmap, cluster_count,
OCFS2_LOCAL_ALLOC(alloc)->la_bitmap);
- mlog(0, "New window allocated:\n");
- mlog(0, "window la_bm_off = %u\n",
- OCFS2_LOCAL_ALLOC(alloc)->la_bm_off);
- mlog(0, "window bits = %u\n", le32_to_cpu(alloc->id1.bitmap1.i_total));
+ trace_ocfs2_local_alloc_new_window_result(
+ OCFS2_LOCAL_ALLOC(alloc)->la_bm_off,
+ le32_to_cpu(alloc->id1.bitmap1.i_total));
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1243,8 +1221,6 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
struct ocfs2_dinode *alloc_copy = NULL;
struct ocfs2_alloc_context *ac = NULL;
- mlog_entry_void();
-
ocfs2_recalc_la_window(osb, OCFS2_LA_EVENT_SLIDE);
/* This will lock the main bitmap for us. */
@@ -1324,7 +1300,8 @@ bail:
if (ac)
ocfs2_free_alloc_context(ac);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
diff --git a/fs/ocfs2/locks.c b/fs/ocfs2/locks.c
index b5cb3ede940..e57c804069e 100644
--- a/fs/ocfs2/locks.c
+++ b/fs/ocfs2/locks.c
@@ -26,7 +26,6 @@
#include <linux/fs.h>
#include <linux/fcntl.h>
-#define MLOG_MASK_PREFIX ML_INODE
#include <cluster/masklog.h>
#include "ocfs2.h"
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 7e32db9c2c9..3e9393ca39e 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -31,7 +31,6 @@
#include <linux/signal.h>
#include <linux/rbtree.h>
-#define MLOG_MASK_PREFIX ML_FILE_IO
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -42,6 +41,7 @@
#include "inode.h"
#include "mmap.h"
#include "super.h"
+#include "ocfs2_trace.h"
static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
@@ -49,13 +49,12 @@ static int ocfs2_fault(struct vm_area_struct *area, struct vm_fault *vmf)
sigset_t oldset;
int ret;
- mlog_entry("(area=%p, page offset=%lu)\n", area, vmf->pgoff);
-
ocfs2_block_signals(&oldset);
ret = filemap_fault(area, vmf);
ocfs2_unblock_signals(&oldset);
- mlog_exit_ptr(vmf->page);
+ trace_ocfs2_fault(OCFS2_I(area->vm_file->f_mapping->host)->ip_blkno,
+ area, vmf->page, vmf->pgoff);
return ret;
}
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index d6c25d76b53..28f2cc1080d 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -42,7 +42,6 @@
#include <linux/highmem.h>
#include <linux/quotaops.h>
-#define MLOG_MASK_PREFIX ML_NAMEI
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -63,6 +62,7 @@
#include "uptodate.h"
#include "xattr.h"
#include "acl.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -106,17 +106,15 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
struct dentry *ret;
struct ocfs2_inode_info *oi;
- mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry,
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_lookup(dir, dentry, dentry->d_name.len,
+ dentry->d_name.name,
+ (unsigned long long)OCFS2_I(dir)->ip_blkno, 0);
if (dentry->d_name.len > OCFS2_MAX_FILENAME_LEN) {
ret = ERR_PTR(-ENAMETOOLONG);
goto bail;
}
- mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len,
- dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno);
-
status = ocfs2_inode_lock_nested(dir, NULL, 0, OI_LS_PARENT);
if (status < 0) {
if (status != -ENOENT)
@@ -182,7 +180,7 @@ bail_unlock:
bail:
- mlog_exit_ptr(ret);
+ trace_ocfs2_lookup_ret(ret);
return ret;
}
@@ -235,9 +233,9 @@ static int ocfs2_mknod(struct inode *dir,
sigset_t oldset;
int did_block_signals = 0;
- mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry, mode,
- (unsigned long)dev, dentry->d_name.len,
- dentry->d_name.name);
+ trace_ocfs2_mknod(dir, dentry, dentry->d_name.len, dentry->d_name.name,
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long)dev, mode);
dquot_initialize(dir);
@@ -354,10 +352,6 @@ static int ocfs2_mknod(struct inode *dir,
goto leave;
did_quota_inode = 1;
- mlog_entry("(0x%p, 0x%p, %d, %lu, '%.*s')\n", dir, dentry,
- inode->i_mode, (unsigned long)dev, dentry->d_name.len,
- dentry->d_name.name);
-
/* do the real work now. */
status = ocfs2_mknod_locked(osb, dir, inode, dev,
&new_fe_bh, parent_fe_bh, handle,
@@ -436,9 +430,6 @@ leave:
if (did_block_signals)
ocfs2_unblock_signals(&oldset);
- if (status == -ENOSPC)
- mlog(0, "Disk is full\n");
-
brelse(new_fe_bh);
brelse(parent_fe_bh);
kfree(si.name);
@@ -466,7 +457,8 @@ leave:
iput(inode);
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -577,7 +569,8 @@ leave:
}
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -615,10 +608,11 @@ static int ocfs2_mkdir(struct inode *dir,
{
int ret;
- mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry, mode,
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_mkdir(dir, dentry, dentry->d_name.len, dentry->d_name.name,
+ OCFS2_I(dir)->ip_blkno, mode);
ret = ocfs2_mknod(dir, dentry, mode | S_IFDIR, 0);
- mlog_exit(ret);
+ if (ret)
+ mlog_errno(ret);
return ret;
}
@@ -630,10 +624,11 @@ static int ocfs2_create(struct inode *dir,
{
int ret;
- mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry, mode,
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_create(dir, dentry, dentry->d_name.len, dentry->d_name.name,
+ (unsigned long long)OCFS2_I(dir)->ip_blkno, mode);
ret = ocfs2_mknod(dir, dentry, mode | S_IFREG, 0);
- mlog_exit(ret);
+ if (ret)
+ mlog_errno(ret);
return ret;
}
@@ -652,9 +647,9 @@ static int ocfs2_link(struct dentry *old_dentry,
struct ocfs2_dir_lookup_result lookup = { NULL, };
sigset_t oldset;
- mlog_entry("(inode=%lu, old='%.*s' new='%.*s')\n", inode->i_ino,
- old_dentry->d_name.len, old_dentry->d_name.name,
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_link((unsigned long long)OCFS2_I(inode)->ip_blkno,
+ old_dentry->d_name.len, old_dentry->d_name.name,
+ dentry->d_name.len, dentry->d_name.name);
if (S_ISDIR(inode->i_mode))
return -EPERM;
@@ -757,7 +752,8 @@ out:
ocfs2_free_dir_lookup_result(&lookup);
- mlog_exit(err);
+ if (err)
+ mlog_errno(err);
return err;
}
@@ -809,19 +805,17 @@ static int ocfs2_unlink(struct inode *dir,
struct ocfs2_dir_lookup_result lookup = { NULL, };
struct ocfs2_dir_lookup_result orphan_insert = { NULL, };
- mlog_entry("(0x%p, 0x%p, '%.*s')\n", dir, dentry,
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_unlink(dir, dentry, dentry->d_name.len,
+ dentry->d_name.name,
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
dquot_initialize(dir);
BUG_ON(dentry->d_parent->d_inode != dir);
- mlog(0, "ino = %llu\n", (unsigned long long)OCFS2_I(inode)->ip_blkno);
-
- if (inode == osb->root_inode) {
- mlog(0, "Cannot delete the root directory\n");
+ if (inode == osb->root_inode)
return -EPERM;
- }
status = ocfs2_inode_lock_nested(dir, &parent_node_bh, 1,
OI_LS_PARENT);
@@ -843,9 +837,10 @@ static int ocfs2_unlink(struct inode *dir,
if (OCFS2_I(inode)->ip_blkno != blkno) {
status = -ENOENT;
- mlog(0, "ip_blkno %llu != dirent blkno %llu ip_flags = %x\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- (unsigned long long)blkno, OCFS2_I(inode)->ip_flags);
+ trace_ocfs2_unlink_noent(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)blkno,
+ OCFS2_I(inode)->ip_flags);
goto leave;
}
@@ -954,7 +949,8 @@ leave:
ocfs2_free_dir_lookup_result(&orphan_insert);
ocfs2_free_dir_lookup_result(&lookup);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -975,9 +971,8 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
struct buffer_head **tmpbh;
struct inode *tmpinode;
- mlog_entry("(inode1 = %llu, inode2 = %llu)\n",
- (unsigned long long)oi1->ip_blkno,
- (unsigned long long)oi2->ip_blkno);
+ trace_ocfs2_double_lock((unsigned long long)oi1->ip_blkno,
+ (unsigned long long)oi2->ip_blkno);
if (*bh1)
*bh1 = NULL;
@@ -988,7 +983,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
if (oi1->ip_blkno != oi2->ip_blkno) {
if (oi1->ip_blkno < oi2->ip_blkno) {
/* switch id1 and id2 around */
- mlog(0, "switching them around...\n");
tmpbh = bh2;
bh2 = bh1;
bh1 = tmpbh;
@@ -1024,8 +1018,13 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
mlog_errno(status);
}
+ trace_ocfs2_double_lock_end(
+ (unsigned long long)OCFS2_I(inode1)->ip_blkno,
+ (unsigned long long)OCFS2_I(inode2)->ip_blkno);
+
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1067,10 +1066,9 @@ static int ocfs2_rename(struct inode *old_dir,
/* At some point it might be nice to break this function up a
* bit. */
- mlog_entry("(0x%p, 0x%p, 0x%p, 0x%p, from='%.*s' to='%.*s')\n",
- old_dir, old_dentry, new_dir, new_dentry,
- old_dentry->d_name.len, old_dentry->d_name.name,
- new_dentry->d_name.len, new_dentry->d_name.name);
+ trace_ocfs2_rename(old_dir, old_dentry, new_dir, new_dentry,
+ old_dentry->d_name.len, old_dentry->d_name.name,
+ new_dentry->d_name.len, new_dentry->d_name.name);
dquot_initialize(old_dir);
dquot_initialize(new_dir);
@@ -1227,16 +1225,15 @@ static int ocfs2_rename(struct inode *old_dir,
if (!new_inode) {
status = -EACCES;
- mlog(0, "We found an inode for name %.*s but VFS "
- "didn't give us one.\n", new_dentry->d_name.len,
- new_dentry->d_name.name);
+ trace_ocfs2_rename_target_exists(new_dentry->d_name.len,
+ new_dentry->d_name.name);
goto bail;
}
if (OCFS2_I(new_inode)->ip_blkno != newfe_blkno) {
status = -EACCES;
- mlog(0, "Inode %llu and dir %llu disagree. flags = %x\n",
+ trace_ocfs2_rename_disagree(
(unsigned long long)OCFS2_I(new_inode)->ip_blkno,
(unsigned long long)newfe_blkno,
OCFS2_I(new_inode)->ip_flags);
@@ -1259,8 +1256,7 @@ static int ocfs2_rename(struct inode *old_dir,
newfe = (struct ocfs2_dinode *) newfe_bh->b_data;
- mlog(0, "aha rename over existing... new_blkno=%llu "
- "newfebh=%p bhblocknr=%llu\n",
+ trace_ocfs2_rename_over_existing(
(unsigned long long)newfe_blkno, newfe_bh, newfe_bh ?
(unsigned long long)newfe_bh->b_blocknr : 0ULL);
@@ -1476,7 +1472,8 @@ bail:
brelse(old_dir_bh);
brelse(new_dir_bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1501,9 +1498,8 @@ static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
* write i_size + 1 bytes. */
blocks = (bytes_left + sb->s_blocksize - 1) >> sb->s_blocksize_bits;
- mlog_entry("i_blocks = %llu, i_size = %llu, blocks = %d\n",
- (unsigned long long)inode->i_blocks,
- i_size_read(inode), blocks);
+ trace_ocfs2_create_symlink_data((unsigned long long)inode->i_blocks,
+ i_size_read(inode), blocks);
/* Sanity check -- make sure we're going to fit. */
if (bytes_left >
@@ -1579,7 +1575,8 @@ bail:
kfree(bhs);
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1610,8 +1607,8 @@ static int ocfs2_symlink(struct inode *dir,
sigset_t oldset;
int did_block_signals = 0;
- mlog_entry("(0x%p, 0x%p, symname='%s' actual='%.*s')\n", dir,
- dentry, symname, dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_symlink_begin(dir, dentry, symname,
+ dentry->d_name.len, dentry->d_name.name);
dquot_initialize(dir);
@@ -1713,9 +1710,10 @@ static int ocfs2_symlink(struct inode *dir,
goto bail;
did_quota_inode = 1;
- mlog_entry("(0x%p, 0x%p, %d, '%.*s')\n", dir, dentry,
- inode->i_mode, dentry->d_name.len,
- dentry->d_name.name);
+ trace_ocfs2_symlink_create(dir, dentry, dentry->d_name.len,
+ dentry->d_name.name,
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ inode->i_mode);
status = ocfs2_mknod_locked(osb, dir, inode,
0, &new_fe_bh, parent_fe_bh, handle,
@@ -1835,7 +1833,8 @@ bail:
iput(inode);
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1844,8 +1843,6 @@ static int ocfs2_blkno_stringify(u64 blkno, char *name)
{
int status, namelen;
- mlog_entry_void();
-
namelen = snprintf(name, OCFS2_ORPHAN_NAMELEN + 1, "%016llx",
(long long)blkno);
if (namelen <= 0) {
@@ -1862,12 +1859,12 @@ static int ocfs2_blkno_stringify(u64 blkno, char *name)
goto bail;
}
- mlog(0, "built filename '%s' for orphan dir (len=%d)\n", name,
- namelen);
+ trace_ocfs2_blkno_stringify(blkno, name, namelen);
status = 0;
bail:
- mlog_exit(status);
+ if (status < 0)
+ mlog_errno(status);
return status;
}
@@ -1980,7 +1977,8 @@ out:
iput(orphan_dir_inode);
}
- mlog_exit(ret);
+ if (ret)
+ mlog_errno(ret);
return ret;
}
@@ -1997,7 +1995,8 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
struct ocfs2_dinode *orphan_fe;
struct ocfs2_dinode *fe = (struct ocfs2_dinode *) fe_bh->b_data;
- mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
+ trace_ocfs2_orphan_add_begin(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
status = ocfs2_read_inode_block(orphan_dir_inode, &orphan_dir_bh);
if (status < 0) {
@@ -2056,13 +2055,14 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
ocfs2_journal_dirty(handle, fe_bh);
- mlog(0, "Inode %llu orphaned in slot %d\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num);
+ trace_ocfs2_orphan_add_end((unsigned long long)OCFS2_I(inode)->ip_blkno,
+ osb->slot_num);
leave:
brelse(orphan_dir_bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2078,17 +2078,15 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
int status = 0;
struct ocfs2_dir_lookup_result lookup = { NULL, };
- mlog_entry_void();
-
status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
if (status < 0) {
mlog_errno(status);
goto leave;
}
- mlog(0, "removing '%s' from orphan dir %llu (namelen=%d)\n",
- name, (unsigned long long)OCFS2_I(orphan_dir_inode)->ip_blkno,
- OCFS2_ORPHAN_NAMELEN);
+ trace_ocfs2_orphan_del(
+ (unsigned long long)OCFS2_I(orphan_dir_inode)->ip_blkno,
+ name, OCFS2_ORPHAN_NAMELEN);
/* find it's spot in the orphan directory */
status = ocfs2_find_entry(name, OCFS2_ORPHAN_NAMELEN, orphan_dir_inode,
@@ -2124,7 +2122,8 @@ int ocfs2_orphan_del(struct ocfs2_super *osb,
leave:
ocfs2_free_dir_lookup_result(&lookup);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2321,9 +2320,6 @@ leave:
iput(orphan_dir);
}
- if (status == -ENOSPC)
- mlog(0, "Disk is full\n");
-
if ((status < 0) && inode) {
clear_nlink(inode);
iput(inode);
@@ -2358,8 +2354,10 @@ int ocfs2_mv_orphaned_inode_to_new(struct inode *dir,
struct buffer_head *di_bh = NULL;
struct ocfs2_dir_lookup_result lookup = { NULL, };
- mlog_entry("(0x%p, 0x%p, %.*s')\n", dir, dentry,
- dentry->d_name.len, dentry->d_name.name);
+ trace_ocfs2_mv_orphaned_inode_to_new(dir, dentry,
+ dentry->d_name.len, dentry->d_name.name,
+ (unsigned long long)OCFS2_I(dir)->ip_blkno,
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
status = ocfs2_inode_lock(dir, &parent_di_bh, 1);
if (status < 0) {
@@ -2476,7 +2474,8 @@ leave:
ocfs2_free_dir_lookup_result(&lookup);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 1a97ba1ec3f..409285854f6 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -147,6 +147,17 @@ struct ocfs2_lock_res_ops;
typedef void (*ocfs2_lock_callback)(int status, unsigned long data);
+#ifdef CONFIG_OCFS2_FS_STATS
+struct ocfs2_lock_stats {
+ u64 ls_total; /* Total wait in NSEC */
+ u32 ls_gets; /* Num acquires */
+ u32 ls_fail; /* Num failed acquires */
+
+ /* Storing max wait in usecs saves 24 bytes per inode */
+ u32 ls_max; /* Max wait in USEC */
+};
+#endif
+
struct ocfs2_lock_res {
void *l_priv;
struct ocfs2_lock_res_ops *l_ops;
@@ -182,15 +193,9 @@ struct ocfs2_lock_res {
struct list_head l_debug_list;
#ifdef CONFIG_OCFS2_FS_STATS
- unsigned long long l_lock_num_prmode; /* PR acquires */
- unsigned long long l_lock_num_exmode; /* EX acquires */
- unsigned int l_lock_num_prmode_failed; /* Failed PR gets */
- unsigned int l_lock_num_exmode_failed; /* Failed EX gets */
- unsigned long long l_lock_total_prmode; /* Tot wait for PR */
- unsigned long long l_lock_total_exmode; /* Tot wait for EX */
- unsigned int l_lock_max_prmode; /* Max wait for PR */
- unsigned int l_lock_max_exmode; /* Max wait for EX */
- unsigned int l_lock_refresh; /* Disk refreshes */
+ struct ocfs2_lock_stats l_lock_prmode; /* PR mode stats */
+ u32 l_lock_refresh; /* Disk refreshes */
+ struct ocfs2_lock_stats l_lock_exmode; /* EX mode stats */
#endif
#ifdef CONFIG_DEBUG_LOCK_ALLOC
struct lockdep_map l_lockdep_map;
diff --git a/fs/ocfs2/ocfs2_trace.h b/fs/ocfs2/ocfs2_trace.h
new file mode 100644
index 00000000000..a1dae5bb54a
--- /dev/null
+++ b/fs/ocfs2/ocfs2_trace.h
@@ -0,0 +1,2739 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM ocfs2
+
+#if !defined(_TRACE_OCFS2_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_OCFS2_H
+
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(ocfs2__int,
+ TP_PROTO(int num),
+ TP_ARGS(num),
+ TP_STRUCT__entry(
+ __field(int, num)
+ ),
+ TP_fast_assign(
+ __entry->num = num;
+ ),
+ TP_printk("%d", __entry->num)
+);
+
+#define DEFINE_OCFS2_INT_EVENT(name) \
+DEFINE_EVENT(ocfs2__int, name, \
+ TP_PROTO(int num), \
+ TP_ARGS(num))
+
+DECLARE_EVENT_CLASS(ocfs2__uint,
+ TP_PROTO(unsigned int num),
+ TP_ARGS(num),
+ TP_STRUCT__entry(
+ __field( unsigned int, num )
+ ),
+ TP_fast_assign(
+ __entry->num = num;
+ ),
+ TP_printk("%u", __entry->num)
+);
+
+#define DEFINE_OCFS2_UINT_EVENT(name) \
+DEFINE_EVENT(ocfs2__uint, name, \
+ TP_PROTO(unsigned int num), \
+ TP_ARGS(num))
+
+DECLARE_EVENT_CLASS(ocfs2__ull,
+ TP_PROTO(unsigned long long blkno),
+ TP_ARGS(blkno),
+ TP_STRUCT__entry(
+ __field(unsigned long long, blkno)
+ ),
+ TP_fast_assign(
+ __entry->blkno = blkno;
+ ),
+ TP_printk("%llu", __entry->blkno)
+);
+
+#define DEFINE_OCFS2_ULL_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull, name, \
+ TP_PROTO(unsigned long long num), \
+ TP_ARGS(num))
+
+DECLARE_EVENT_CLASS(ocfs2__pointer,
+ TP_PROTO(void *pointer),
+ TP_ARGS(pointer),
+ TP_STRUCT__entry(
+ __field(void *, pointer)
+ ),
+ TP_fast_assign(
+ __entry->pointer = pointer;
+ ),
+ TP_printk("%p", __entry->pointer)
+);
+
+#define DEFINE_OCFS2_POINTER_EVENT(name) \
+DEFINE_EVENT(ocfs2__pointer, name, \
+ TP_PROTO(void *pointer), \
+ TP_ARGS(pointer))
+
+DECLARE_EVENT_CLASS(ocfs2__string,
+ TP_PROTO(const char *name),
+ TP_ARGS(name),
+ TP_STRUCT__entry(
+ __string(name,name)
+ ),
+ TP_fast_assign(
+ __assign_str(name, name);
+ ),
+ TP_printk("%s", __get_str(name))
+);
+
+#define DEFINE_OCFS2_STRING_EVENT(name) \
+DEFINE_EVENT(ocfs2__string, name, \
+ TP_PROTO(const char *name), \
+ TP_ARGS(name))
+
+DECLARE_EVENT_CLASS(ocfs2__int_int,
+ TP_PROTO(int value1, int value2),
+ TP_ARGS(value1, value2),
+ TP_STRUCT__entry(
+ __field(int, value1)
+ __field(int, value2)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ ),
+ TP_printk("%d %d", __entry->value1, __entry->value2)
+);
+
+#define DEFINE_OCFS2_INT_INT_EVENT(name) \
+DEFINE_EVENT(ocfs2__int_int, name, \
+ TP_PROTO(int val1, int val2), \
+ TP_ARGS(val1, val2))
+
+DECLARE_EVENT_CLASS(ocfs2__uint_int,
+ TP_PROTO(unsigned int value1, int value2),
+ TP_ARGS(value1, value2),
+ TP_STRUCT__entry(
+ __field(unsigned int, value1)
+ __field(int, value2)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ ),
+ TP_printk("%u %d", __entry->value1, __entry->value2)
+);
+
+#define DEFINE_OCFS2_UINT_INT_EVENT(name) \
+DEFINE_EVENT(ocfs2__uint_int, name, \
+ TP_PROTO(unsigned int val1, int val2), \
+ TP_ARGS(val1, val2))
+
+DECLARE_EVENT_CLASS(ocfs2__uint_uint,
+ TP_PROTO(unsigned int value1, unsigned int value2),
+ TP_ARGS(value1, value2),
+ TP_STRUCT__entry(
+ __field(unsigned int, value1)
+ __field(unsigned int, value2)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ ),
+ TP_printk("%u %u", __entry->value1, __entry->value2)
+);
+
+#define DEFINE_OCFS2_UINT_UINT_EVENT(name) \
+DEFINE_EVENT(ocfs2__uint_uint, name, \
+ TP_PROTO(unsigned int val1, unsigned int val2), \
+ TP_ARGS(val1, val2))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_uint,
+ TP_PROTO(unsigned long long value1, unsigned int value2),
+ TP_ARGS(value1, value2),
+ TP_STRUCT__entry(
+ __field(unsigned long long, value1)
+ __field(unsigned int, value2)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ ),
+ TP_printk("%llu %u", __entry->value1, __entry->value2)
+);
+
+#define DEFINE_OCFS2_ULL_UINT_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_uint, name, \
+ TP_PROTO(unsigned long long val1, unsigned int val2), \
+ TP_ARGS(val1, val2))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_int,
+ TP_PROTO(unsigned long long value1, int value2),
+ TP_ARGS(value1, value2),
+ TP_STRUCT__entry(
+ __field(unsigned long long, value1)
+ __field(int, value2)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ ),
+ TP_printk("%llu %d", __entry->value1, __entry->value2)
+);
+
+#define DEFINE_OCFS2_ULL_INT_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_int, name, \
+ TP_PROTO(unsigned long long val1, int val2), \
+ TP_ARGS(val1, val2))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_ull,
+ TP_PROTO(unsigned long long value1, unsigned long long value2),
+ TP_ARGS(value1, value2),
+ TP_STRUCT__entry(
+ __field(unsigned long long, value1)
+ __field(unsigned long long, value2)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ ),
+ TP_printk("%llu %llu", __entry->value1, __entry->value2)
+);
+
+#define DEFINE_OCFS2_ULL_ULL_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_ull, name, \
+ TP_PROTO(unsigned long long val1, unsigned long long val2), \
+ TP_ARGS(val1, val2))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_ull_uint,
+ TP_PROTO(unsigned long long value1,
+ unsigned long long value2, unsigned int value3),
+ TP_ARGS(value1, value2, value3),
+ TP_STRUCT__entry(
+ __field(unsigned long long, value1)
+ __field(unsigned long long, value2)
+ __field(unsigned int, value3)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ __entry->value3 = value3;
+ ),
+ TP_printk("%llu %llu %u",
+ __entry->value1, __entry->value2, __entry->value3)
+);
+
+#define DEFINE_OCFS2_ULL_ULL_UINT_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_ull_uint, name, \
+ TP_PROTO(unsigned long long val1, \
+ unsigned long long val2, unsigned int val3), \
+ TP_ARGS(val1, val2, val3))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_uint_uint,
+ TP_PROTO(unsigned long long value1,
+ unsigned int value2, unsigned int value3),
+ TP_ARGS(value1, value2, value3),
+ TP_STRUCT__entry(
+ __field(unsigned long long, value1)
+ __field(unsigned int, value2)
+ __field(unsigned int, value3)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ __entry->value3 = value3;
+ ),
+ TP_printk("%llu %u %u", __entry->value1,
+ __entry->value2, __entry->value3)
+);
+
+#define DEFINE_OCFS2_ULL_UINT_UINT_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_uint_uint, name, \
+ TP_PROTO(unsigned long long val1, \
+ unsigned int val2, unsigned int val3), \
+ TP_ARGS(val1, val2, val3))
+
+DECLARE_EVENT_CLASS(ocfs2__uint_uint_uint,
+ TP_PROTO(unsigned int value1, unsigned int value2,
+ unsigned int value3),
+ TP_ARGS(value1, value2, value3),
+ TP_STRUCT__entry(
+ __field( unsigned int, value1 )
+ __field( unsigned int, value2 )
+ __field( unsigned int, value3 )
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ __entry->value3 = value3;
+ ),
+ TP_printk("%u %u %u", __entry->value1, __entry->value2, __entry->value3)
+);
+
+#define DEFINE_OCFS2_UINT_UINT_UINT_EVENT(name) \
+DEFINE_EVENT(ocfs2__uint_uint_uint, name, \
+ TP_PROTO(unsigned int value1, unsigned int value2, \
+ unsigned int value3), \
+ TP_ARGS(value1, value2, value3))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_ull_ull,
+ TP_PROTO(unsigned long long value1,
+ unsigned long long value2, unsigned long long value3),
+ TP_ARGS(value1, value2, value3),
+ TP_STRUCT__entry(
+ __field(unsigned long long, value1)
+ __field(unsigned long long, value2)
+ __field(unsigned long long, value3)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ __entry->value3 = value3;
+ ),
+ TP_printk("%llu %llu %llu",
+ __entry->value1, __entry->value2, __entry->value3)
+);
+
+#define DEFINE_OCFS2_ULL_ULL_ULL_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_ull_ull, name, \
+ TP_PROTO(unsigned long long value1, unsigned long long value2, \
+ unsigned long long value3), \
+ TP_ARGS(value1, value2, value3))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_int_int_int,
+ TP_PROTO(unsigned long long ull, int value1, int value2, int value3),
+ TP_ARGS(ull, value1, value2, value3),
+ TP_STRUCT__entry(
+ __field( unsigned long long, ull )
+ __field( int, value1 )
+ __field( int, value2 )
+ __field( int, value3 )
+ ),
+ TP_fast_assign(
+ __entry->ull = ull;
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ __entry->value3 = value3;
+ ),
+ TP_printk("%llu %d %d %d",
+ __entry->ull, __entry->value1,
+ __entry->value2, __entry->value3)
+);
+
+#define DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_int_int_int, name, \
+ TP_PROTO(unsigned long long ull, int value1, \
+ int value2, int value3), \
+ TP_ARGS(ull, value1, value2, value3))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_uint_uint_uint,
+ TP_PROTO(unsigned long long ull, unsigned int value1,
+ unsigned int value2, unsigned int value3),
+ TP_ARGS(ull, value1, value2, value3),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ull)
+ __field(unsigned int, value1)
+ __field(unsigned int, value2)
+ __field(unsigned int, value3)
+ ),
+ TP_fast_assign(
+ __entry->ull = ull;
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ __entry->value3 = value3;
+ ),
+ TP_printk("%llu %u %u %u",
+ __entry->ull, __entry->value1,
+ __entry->value2, __entry->value3)
+);
+
+#define DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_uint_uint_uint, name, \
+ TP_PROTO(unsigned long long ull, unsigned int value1, \
+ unsigned int value2, unsigned int value3), \
+ TP_ARGS(ull, value1, value2, value3))
+
+DECLARE_EVENT_CLASS(ocfs2__ull_ull_uint_uint,
+ TP_PROTO(unsigned long long value1, unsigned long long value2,
+ unsigned int value3, unsigned int value4),
+ TP_ARGS(value1, value2, value3, value4),
+ TP_STRUCT__entry(
+ __field(unsigned long long, value1)
+ __field(unsigned long long, value2)
+ __field(unsigned int, value3)
+ __field(unsigned int, value4)
+ ),
+ TP_fast_assign(
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ __entry->value3 = value3;
+ __entry->value4 = value4;
+ ),
+ TP_printk("%llu %llu %u %u",
+ __entry->value1, __entry->value2,
+ __entry->value3, __entry->value4)
+);
+
+#define DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(name) \
+DEFINE_EVENT(ocfs2__ull_ull_uint_uint, name, \
+ TP_PROTO(unsigned long long ull, unsigned long long ull1, \
+ unsigned int value2, unsigned int value3), \
+ TP_ARGS(ull, ull1, value2, value3))
+
+/* Trace events for fs/ocfs2/alloc.c. */
+DECLARE_EVENT_CLASS(ocfs2__btree_ops,
+ TP_PROTO(unsigned long long owner,\
+ unsigned int value1, unsigned int value2),
+ TP_ARGS(owner, value1, value2),
+ TP_STRUCT__entry(
+ __field(unsigned long long, owner)
+ __field(unsigned int, value1)
+ __field(unsigned int, value2)
+ ),
+ TP_fast_assign(
+ __entry->owner = owner;
+ __entry->value1 = value1;
+ __entry->value2 = value2;
+ ),
+ TP_printk("%llu %u %u",
+ __entry->owner, __entry->value1, __entry->value2)
+);
+
+#define DEFINE_OCFS2_BTREE_EVENT(name) \
+DEFINE_EVENT(ocfs2__btree_ops, name, \
+ TP_PROTO(unsigned long long owner, \
+ unsigned int value1, unsigned int value2), \
+ TP_ARGS(owner, value1, value2))
+
+DEFINE_OCFS2_BTREE_EVENT(ocfs2_adjust_rightmost_branch);
+
+DEFINE_OCFS2_BTREE_EVENT(ocfs2_rotate_tree_right);
+
+DEFINE_OCFS2_BTREE_EVENT(ocfs2_append_rec_to_path);
+
+DEFINE_OCFS2_BTREE_EVENT(ocfs2_insert_extent_start);
+
+DEFINE_OCFS2_BTREE_EVENT(ocfs2_add_clusters_in_btree);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_num_free_extents);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_complete_edge_insert);
+
+TRACE_EVENT(ocfs2_grow_tree,
+ TP_PROTO(unsigned long long owner, int depth),
+ TP_ARGS(owner, depth),
+ TP_STRUCT__entry(
+ __field(unsigned long long, owner)
+ __field(int, depth)
+ ),
+ TP_fast_assign(
+ __entry->owner = owner;
+ __entry->depth = depth;
+ ),
+ TP_printk("%llu %d", __entry->owner, __entry->depth)
+);
+
+TRACE_EVENT(ocfs2_rotate_subtree,
+ TP_PROTO(int subtree_root, unsigned long long blkno,
+ int depth),
+ TP_ARGS(subtree_root, blkno, depth),
+ TP_STRUCT__entry(
+ __field(int, subtree_root)
+ __field(unsigned long long, blkno)
+ __field(int, depth)
+ ),
+ TP_fast_assign(
+ __entry->subtree_root = subtree_root;
+ __entry->blkno = blkno;
+ __entry->depth = depth;
+ ),
+ TP_printk("%d %llu %d", __entry->subtree_root,
+ __entry->blkno, __entry->depth)
+);
+
+TRACE_EVENT(ocfs2_insert_extent,
+ TP_PROTO(unsigned int ins_appending, unsigned int ins_contig,
+ int ins_contig_index, int free_records, int ins_tree_depth),
+ TP_ARGS(ins_appending, ins_contig, ins_contig_index, free_records,
+ ins_tree_depth),
+ TP_STRUCT__entry(
+ __field(unsigned int, ins_appending)
+ __field(unsigned int, ins_contig)
+ __field(int, ins_contig_index)
+ __field(int, free_records)
+ __field(int, ins_tree_depth)
+ ),
+ TP_fast_assign(
+ __entry->ins_appending = ins_appending;
+ __entry->ins_contig = ins_contig;
+ __entry->ins_contig_index = ins_contig_index;
+ __entry->free_records = free_records;
+ __entry->ins_tree_depth = ins_tree_depth;
+ ),
+ TP_printk("%u %u %d %d %d",
+ __entry->ins_appending, __entry->ins_contig,
+ __entry->ins_contig_index, __entry->free_records,
+ __entry->ins_tree_depth)
+);
+
+TRACE_EVENT(ocfs2_split_extent,
+ TP_PROTO(int split_index, unsigned int c_contig_type,
+ unsigned int c_has_empty_extent,
+ unsigned int c_split_covers_rec),
+ TP_ARGS(split_index, c_contig_type,
+ c_has_empty_extent, c_split_covers_rec),
+ TP_STRUCT__entry(
+ __field(int, split_index)
+ __field(unsigned int, c_contig_type)
+ __field(unsigned int, c_has_empty_extent)
+ __field(unsigned int, c_split_covers_rec)
+ ),
+ TP_fast_assign(
+ __entry->split_index = split_index;
+ __entry->c_contig_type = c_contig_type;
+ __entry->c_has_empty_extent = c_has_empty_extent;
+ __entry->c_split_covers_rec = c_split_covers_rec;
+ ),
+ TP_printk("%d %u %u %u", __entry->split_index, __entry->c_contig_type,
+ __entry->c_has_empty_extent, __entry->c_split_covers_rec)
+);
+
+TRACE_EVENT(ocfs2_remove_extent,
+ TP_PROTO(unsigned long long owner, unsigned int cpos,
+ unsigned int len, int index,
+ unsigned int e_cpos, unsigned int clusters),
+ TP_ARGS(owner, cpos, len, index, e_cpos, clusters),
+ TP_STRUCT__entry(
+ __field(unsigned long long, owner)
+ __field(unsigned int, cpos)
+ __field(unsigned int, len)
+ __field(int, index)
+ __field(unsigned int, e_cpos)
+ __field(unsigned int, clusters)
+ ),
+ TP_fast_assign(
+ __entry->owner = owner;
+ __entry->cpos = cpos;
+ __entry->len = len;
+ __entry->index = index;
+ __entry->e_cpos = e_cpos;
+ __entry->clusters = clusters;
+ ),
+ TP_printk("%llu %u %u %d %u %u",
+ __entry->owner, __entry->cpos, __entry->len, __entry->index,
+ __entry->e_cpos, __entry->clusters)
+);
+
+TRACE_EVENT(ocfs2_commit_truncate,
+ TP_PROTO(unsigned long long ino, unsigned int new_cpos,
+ unsigned int clusters, unsigned int depth),
+ TP_ARGS(ino, new_cpos, clusters, depth),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned int, new_cpos)
+ __field(unsigned int, clusters)
+ __field(unsigned int, depth)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->new_cpos = new_cpos;
+ __entry->clusters = clusters;
+ __entry->depth = depth;
+ ),
+ TP_printk("%llu %u %u %u",
+ __entry->ino, __entry->new_cpos,
+ __entry->clusters, __entry->depth)
+);
+
+TRACE_EVENT(ocfs2_validate_extent_block,
+ TP_PROTO(unsigned long long blkno),
+ TP_ARGS(blkno),
+ TP_STRUCT__entry(
+ __field(unsigned long long, blkno)
+ ),
+ TP_fast_assign(
+ __entry->blkno = blkno;
+ ),
+ TP_printk("%llu ", __entry->blkno)
+);
+
+TRACE_EVENT(ocfs2_rotate_leaf,
+ TP_PROTO(unsigned int insert_cpos, int insert_index,
+ int has_empty, int next_free,
+ unsigned int l_count),
+ TP_ARGS(insert_cpos, insert_index, has_empty,
+ next_free, l_count),
+ TP_STRUCT__entry(
+ __field(unsigned int, insert_cpos)
+ __field(int, insert_index)
+ __field(int, has_empty)
+ __field(int, next_free)
+ __field(unsigned int, l_count)
+ ),
+ TP_fast_assign(
+ __entry->insert_cpos = insert_cpos;
+ __entry->insert_index = insert_index;
+ __entry->has_empty = has_empty;
+ __entry->next_free = next_free;
+ __entry->l_count = l_count;
+ ),
+ TP_printk("%u %d %d %d %u", __entry->insert_cpos,
+ __entry->insert_index, __entry->has_empty,
+ __entry->next_free, __entry->l_count)
+);
+
+TRACE_EVENT(ocfs2_add_clusters_in_btree_ret,
+ TP_PROTO(int status, int reason, int err),
+ TP_ARGS(status, reason, err),
+ TP_STRUCT__entry(
+ __field(int, status)
+ __field(int, reason)
+ __field(int, err)
+ ),
+ TP_fast_assign(
+ __entry->status = status;
+ __entry->reason = reason;
+ __entry->err = err;
+ ),
+ TP_printk("%d %d %d", __entry->status,
+ __entry->reason, __entry->err)
+);
+
+TRACE_EVENT(ocfs2_mark_extent_written,
+ TP_PROTO(unsigned long long owner, unsigned int cpos,
+ unsigned int len, unsigned int phys),
+ TP_ARGS(owner, cpos, len, phys),
+ TP_STRUCT__entry(
+ __field(unsigned long long, owner)
+ __field(unsigned int, cpos)
+ __field(unsigned int, len)
+ __field(unsigned int, phys)
+ ),
+ TP_fast_assign(
+ __entry->owner = owner;
+ __entry->cpos = cpos;
+ __entry->len = len;
+ __entry->phys = phys;
+ ),
+ TP_printk("%llu %u %u %u",
+ __entry->owner, __entry->cpos,
+ __entry->len, __entry->phys)
+);
+
+DECLARE_EVENT_CLASS(ocfs2__truncate_log_ops,
+ TP_PROTO(unsigned long long blkno, int index,
+ unsigned int start, unsigned int num),
+ TP_ARGS(blkno, index, start, num),
+ TP_STRUCT__entry(
+ __field(unsigned long long, blkno)
+ __field(int, index)
+ __field(unsigned int, start)
+ __field(unsigned int, num)
+ ),
+ TP_fast_assign(
+ __entry->blkno = blkno;
+ __entry->index = index;
+ __entry->start = start;
+ __entry->num = num;
+ ),
+ TP_printk("%llu %d %u %u",
+ __entry->blkno, __entry->index,
+ __entry->start, __entry->num)
+);
+
+#define DEFINE_OCFS2_TRUNCATE_LOG_OPS_EVENT(name) \
+DEFINE_EVENT(ocfs2__truncate_log_ops, name, \
+ TP_PROTO(unsigned long long blkno, int index, \
+ unsigned int start, unsigned int num), \
+ TP_ARGS(blkno, index, start, num))
+
+DEFINE_OCFS2_TRUNCATE_LOG_OPS_EVENT(ocfs2_truncate_log_append);
+
+DEFINE_OCFS2_TRUNCATE_LOG_OPS_EVENT(ocfs2_replay_truncate_records);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_flush_truncate_log);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_begin_truncate_log_recovery);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_truncate_log_recovery_num);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_complete_truncate_log_recovery);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_free_cached_blocks);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_cache_cluster_dealloc);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_run_deallocs);
+
+TRACE_EVENT(ocfs2_cache_block_dealloc,
+ TP_PROTO(int type, int slot, unsigned long long suballoc,
+ unsigned long long blkno, unsigned int bit),
+ TP_ARGS(type, slot, suballoc, blkno, bit),
+ TP_STRUCT__entry(
+ __field(int, type)
+ __field(int, slot)
+ __field(unsigned long long, suballoc)
+ __field(unsigned long long, blkno)
+ __field(unsigned int, bit)
+ ),
+ TP_fast_assign(
+ __entry->type = type;
+ __entry->slot = slot;
+ __entry->suballoc = suballoc;
+ __entry->blkno = blkno;
+ __entry->bit = bit;
+ ),
+ TP_printk("%d %d %llu %llu %u",
+ __entry->type, __entry->slot, __entry->suballoc,
+ __entry->blkno, __entry->bit)
+);
+
+/* End of trace events for fs/ocfs2/alloc.c. */
+
+/* Trace events for fs/ocfs2/localalloc.c. */
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_la_set_sizes);
+
+DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_alloc_should_use_local);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_load_local_alloc);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_begin_local_alloc_recovery);
+
+DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_reserve_local_alloc_bits);
+
+DEFINE_OCFS2_UINT_EVENT(ocfs2_local_alloc_count_bits);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_local_alloc_find_clear_bits_search_bitmap);
+
+DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_local_alloc_find_clear_bits);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_sync_local_to_main);
+
+TRACE_EVENT(ocfs2_sync_local_to_main_free,
+ TP_PROTO(int count, int bit, unsigned long long start_blk,
+ unsigned long long blkno),
+ TP_ARGS(count, bit, start_blk, blkno),
+ TP_STRUCT__entry(
+ __field(int, count)
+ __field(int, bit)
+ __field(unsigned long long, start_blk)
+ __field(unsigned long long, blkno)
+ ),
+ TP_fast_assign(
+ __entry->count = count;
+ __entry->bit = bit;
+ __entry->start_blk = start_blk;
+ __entry->blkno = blkno;
+ ),
+ TP_printk("%d %d %llu %llu",
+ __entry->count, __entry->bit, __entry->start_blk,
+ __entry->blkno)
+);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_local_alloc_new_window);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_local_alloc_new_window_result);
+
+/* End of trace events for fs/ocfs2/localalloc.c. */
+
+/* Trace events for fs/ocfs2/resize.c. */
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_update_last_group_and_inode);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_group_extend);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_group_add);
+
+/* End of trace events for fs/ocfs2/resize.c. */
+
+/* Trace events for fs/ocfs2/suballoc.c. */
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_group_descriptor);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_block_group_alloc_contig);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_block_group_alloc_discontig);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_block_group_alloc);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_reserve_suballoc_bits_nospc);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_reserve_suballoc_bits_no_new_group);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_reserve_new_inode_new_group);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_block_group_set_bits);
+
+TRACE_EVENT(ocfs2_relink_block_group,
+ TP_PROTO(unsigned long long i_blkno, unsigned int chain,
+ unsigned long long bg_blkno,
+ unsigned long long prev_blkno),
+ TP_ARGS(i_blkno, chain, bg_blkno, prev_blkno),
+ TP_STRUCT__entry(
+ __field(unsigned long long, i_blkno)
+ __field(unsigned int, chain)
+ __field(unsigned long long, bg_blkno)
+ __field(unsigned long long, prev_blkno)
+ ),
+ TP_fast_assign(
+ __entry->i_blkno = i_blkno;
+ __entry->chain = chain;
+ __entry->bg_blkno = bg_blkno;
+ __entry->prev_blkno = prev_blkno;
+ ),
+ TP_printk("%llu %u %llu %llu",
+ __entry->i_blkno, __entry->chain, __entry->bg_blkno,
+ __entry->prev_blkno)
+);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_cluster_group_search_wrong_max_bits);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_cluster_group_search_max_block);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_block_group_search_max_block);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_search_chain_begin);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_search_chain_succ);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_search_chain_end);
+
+DEFINE_OCFS2_UINT_EVENT(ocfs2_claim_suballoc_bits);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_claim_new_inode_at_loc);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_block_group_clear_bits);
+
+TRACE_EVENT(ocfs2_free_suballoc_bits,
+ TP_PROTO(unsigned long long inode, unsigned long long group,
+ unsigned int start_bit, unsigned int count),
+ TP_ARGS(inode, group, start_bit, count),
+ TP_STRUCT__entry(
+ __field(unsigned long long, inode)
+ __field(unsigned long long, group)
+ __field(unsigned int, start_bit)
+ __field(unsigned int, count)
+ ),
+ TP_fast_assign(
+ __entry->inode = inode;
+ __entry->group = group;
+ __entry->start_bit = start_bit;
+ __entry->count = count;
+ ),
+ TP_printk("%llu %llu %u %u", __entry->inode, __entry->group,
+ __entry->start_bit, __entry->count)
+);
+
+TRACE_EVENT(ocfs2_free_clusters,
+ TP_PROTO(unsigned long long bg_blkno, unsigned long long start_blk,
+ unsigned int start_bit, unsigned int count),
+ TP_ARGS(bg_blkno, start_blk, start_bit, count),
+ TP_STRUCT__entry(
+ __field(unsigned long long, bg_blkno)
+ __field(unsigned long long, start_blk)
+ __field(unsigned int, start_bit)
+ __field(unsigned int, count)
+ ),
+ TP_fast_assign(
+ __entry->bg_blkno = bg_blkno;
+ __entry->start_blk = start_blk;
+ __entry->start_bit = start_bit;
+ __entry->count = count;
+ ),
+ TP_printk("%llu %llu %u %u", __entry->bg_blkno, __entry->start_blk,
+ __entry->start_bit, __entry->count)
+);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_get_suballoc_slot_bit);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_test_suballoc_bit);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_test_inode_bit);
+
+/* End of trace events for fs/ocfs2/suballoc.c. */
+
+/* Trace events for fs/ocfs2/refcounttree.c. */
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_refcount_block);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_purge_refcount_trees);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_create_refcount_tree);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_create_refcount_tree_blkno);
+
+DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_change_refcount_rec);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_expand_inline_ref_root);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_divide_leaf_refcount_block);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_new_leaf_refcount_block);
+
+DECLARE_EVENT_CLASS(ocfs2__refcount_tree_ops,
+ TP_PROTO(unsigned long long blkno, int index,
+ unsigned long long cpos,
+ unsigned int clusters, unsigned int refcount),
+ TP_ARGS(blkno, index, cpos, clusters, refcount),
+ TP_STRUCT__entry(
+ __field(unsigned long long, blkno)
+ __field(int, index)
+ __field(unsigned long long, cpos)
+ __field(unsigned int, clusters)
+ __field(unsigned int, refcount)
+ ),
+ TP_fast_assign(
+ __entry->blkno = blkno;
+ __entry->index = index;
+ __entry->cpos = cpos;
+ __entry->clusters = clusters;
+ __entry->refcount = refcount;
+ ),
+ TP_printk("%llu %d %llu %u %u", __entry->blkno, __entry->index,
+ __entry->cpos, __entry->clusters, __entry->refcount)
+);
+
+#define DEFINE_OCFS2_REFCOUNT_TREE_OPS_EVENT(name) \
+DEFINE_EVENT(ocfs2__refcount_tree_ops, name, \
+ TP_PROTO(unsigned long long blkno, int index, \
+ unsigned long long cpos, \
+ unsigned int count, unsigned int refcount), \
+ TP_ARGS(blkno, index, cpos, count, refcount))
+
+DEFINE_OCFS2_REFCOUNT_TREE_OPS_EVENT(ocfs2_insert_refcount_rec);
+
+TRACE_EVENT(ocfs2_split_refcount_rec,
+ TP_PROTO(unsigned long long cpos,
+ unsigned int clusters, unsigned int refcount,
+ unsigned long long split_cpos,
+ unsigned int split_clusters, unsigned int split_refcount),
+ TP_ARGS(cpos, clusters, refcount,
+ split_cpos, split_clusters, split_refcount),
+ TP_STRUCT__entry(
+ __field(unsigned long long, cpos)
+ __field(unsigned int, clusters)
+ __field(unsigned int, refcount)
+ __field(unsigned long long, split_cpos)
+ __field(unsigned int, split_clusters)
+ __field(unsigned int, split_refcount)
+ ),
+ TP_fast_assign(
+ __entry->cpos = cpos;
+ __entry->clusters = clusters;
+ __entry->refcount = refcount;
+ __entry->split_cpos = split_cpos;
+ __entry->split_clusters = split_clusters;
+ __entry->split_refcount = split_refcount;
+ ),
+ TP_printk("%llu %u %u %llu %u %u",
+ __entry->cpos, __entry->clusters, __entry->refcount,
+ __entry->split_cpos, __entry->split_clusters,
+ __entry->split_refcount)
+);
+
+DEFINE_OCFS2_REFCOUNT_TREE_OPS_EVENT(ocfs2_split_refcount_rec_insert);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_increase_refcount_begin);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_increase_refcount_change);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_increase_refcount_insert);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_increase_refcount_split);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_remove_refcount_extent);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_restore_refcount_block);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_decrease_refcount_rec);
+
+TRACE_EVENT(ocfs2_decrease_refcount,
+ TP_PROTO(unsigned long long owner,
+ unsigned long long cpos,
+ unsigned int len, int delete),
+ TP_ARGS(owner, cpos, len, delete),
+ TP_STRUCT__entry(
+ __field(unsigned long long, owner)
+ __field(unsigned long long, cpos)
+ __field(unsigned int, len)
+ __field(int, delete)
+ ),
+ TP_fast_assign(
+ __entry->owner = owner;
+ __entry->cpos = cpos;
+ __entry->len = len;
+ __entry->delete = delete;
+ ),
+ TP_printk("%llu %llu %u %d",
+ __entry->owner, __entry->cpos, __entry->len, __entry->delete)
+);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_mark_extent_refcounted);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_calc_refcount_meta_credits);
+
+TRACE_EVENT(ocfs2_calc_refcount_meta_credits_iterate,
+ TP_PROTO(int recs_add, unsigned long long cpos,
+ unsigned int clusters, unsigned long long r_cpos,
+ unsigned int r_clusters, unsigned int refcount, int index),
+ TP_ARGS(recs_add, cpos, clusters, r_cpos, r_clusters, refcount, index),
+ TP_STRUCT__entry(
+ __field(int, recs_add)
+ __field(unsigned long long, cpos)
+ __field(unsigned int, clusters)
+ __field(unsigned long long, r_cpos)
+ __field(unsigned int, r_clusters)
+ __field(unsigned int, refcount)
+ __field(int, index)
+ ),
+ TP_fast_assign(
+ __entry->recs_add = recs_add;
+ __entry->cpos = cpos;
+ __entry->clusters = clusters;
+ __entry->r_cpos = r_cpos;
+ __entry->r_clusters = r_clusters;
+ __entry->refcount = refcount;
+ __entry->index = index;
+ ),
+ TP_printk("%d %llu %u %llu %u %u %d",
+ __entry->recs_add, __entry->cpos, __entry->clusters,
+ __entry->r_cpos, __entry->r_clusters,
+ __entry->refcount, __entry->index)
+);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_add_refcount_flag);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_prepare_refcount_change_for_del);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_lock_refcount_allocators);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_duplicate_clusters_by_page);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_duplicate_clusters_by_jbd);
+
+TRACE_EVENT(ocfs2_clear_ext_refcount,
+ TP_PROTO(unsigned long long ino, unsigned int cpos,
+ unsigned int len, unsigned int p_cluster,
+ unsigned int ext_flags),
+ TP_ARGS(ino, cpos, len, p_cluster, ext_flags),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned int, cpos)
+ __field(unsigned int, len)
+ __field(unsigned int, p_cluster)
+ __field(unsigned int, ext_flags)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->cpos = cpos;
+ __entry->len = len;
+ __entry->p_cluster = p_cluster;
+ __entry->ext_flags = ext_flags;
+ ),
+ TP_printk("%llu %u %u %u %u",
+ __entry->ino, __entry->cpos, __entry->len,
+ __entry->p_cluster, __entry->ext_flags)
+);
+
+TRACE_EVENT(ocfs2_replace_clusters,
+ TP_PROTO(unsigned long long ino, unsigned int cpos,
+ unsigned int old, unsigned int new, unsigned int len,
+ unsigned int ext_flags),
+ TP_ARGS(ino, cpos, old, new, len, ext_flags),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned int, cpos)
+ __field(unsigned int, old)
+ __field(unsigned int, new)
+ __field(unsigned int, len)
+ __field(unsigned int, ext_flags)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->cpos = cpos;
+ __entry->old = old;
+ __entry->new = new;
+ __entry->len = len;
+ __entry->ext_flags = ext_flags;
+ ),
+ TP_printk("%llu %u %u %u %u %u",
+ __entry->ino, __entry->cpos, __entry->old, __entry->new,
+ __entry->len, __entry->ext_flags)
+);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_make_clusters_writable);
+
+TRACE_EVENT(ocfs2_refcount_cow_hunk,
+ TP_PROTO(unsigned long long ino, unsigned int cpos,
+ unsigned int write_len, unsigned int max_cpos,
+ unsigned int cow_start, unsigned int cow_len),
+ TP_ARGS(ino, cpos, write_len, max_cpos, cow_start, cow_len),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned int, cpos)
+ __field(unsigned int, write_len)
+ __field(unsigned int, max_cpos)
+ __field(unsigned int, cow_start)
+ __field(unsigned int, cow_len)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->cpos = cpos;
+ __entry->write_len = write_len;
+ __entry->max_cpos = max_cpos;
+ __entry->cow_start = cow_start;
+ __entry->cow_len = cow_len;
+ ),
+ TP_printk("%llu %u %u %u %u %u",
+ __entry->ino, __entry->cpos, __entry->write_len,
+ __entry->max_cpos, __entry->cow_start, __entry->cow_len)
+);
+
+/* End of trace events for fs/ocfs2/refcounttree.c. */
+
+/* Trace events for fs/ocfs2/aops.c. */
+
+DECLARE_EVENT_CLASS(ocfs2__get_block,
+ TP_PROTO(unsigned long long ino, unsigned long long iblock,
+ void *bh_result, int create),
+ TP_ARGS(ino, iblock, bh_result, create),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned long long, iblock)
+ __field(void *, bh_result)
+ __field(int, create)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->iblock = iblock;
+ __entry->bh_result = bh_result;
+ __entry->create = create;
+ ),
+ TP_printk("%llu %llu %p %d",
+ __entry->ino, __entry->iblock,
+ __entry->bh_result, __entry->create)
+);
+
+#define DEFINE_OCFS2_GET_BLOCK_EVENT(name) \
+DEFINE_EVENT(ocfs2__get_block, name, \
+ TP_PROTO(unsigned long long ino, unsigned long long iblock, \
+ void *bh_result, int create), \
+ TP_ARGS(ino, iblock, bh_result, create))
+
+DEFINE_OCFS2_GET_BLOCK_EVENT(ocfs2_symlink_get_block);
+
+DEFINE_OCFS2_GET_BLOCK_EVENT(ocfs2_get_block);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_get_block_end);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_readpage);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_writepage);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_bmap);
+
+TRACE_EVENT(ocfs2_try_to_write_inline_data,
+ TP_PROTO(unsigned long long ino, unsigned int len,
+ unsigned long long pos, unsigned int flags),
+ TP_ARGS(ino, len, pos, flags),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned int, len)
+ __field(unsigned long long, pos)
+ __field(unsigned int, flags)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->len = len;
+ __entry->pos = pos;
+ __entry->flags = flags;
+ ),
+ TP_printk("%llu %u %llu 0x%x",
+ __entry->ino, __entry->len, __entry->pos, __entry->flags)
+);
+
+TRACE_EVENT(ocfs2_write_begin_nolock,
+ TP_PROTO(unsigned long long ino,
+ long long i_size, unsigned int i_clusters,
+ unsigned long long pos, unsigned int len,
+ unsigned int flags, void *page,
+ unsigned int clusters, unsigned int extents_to_split),
+ TP_ARGS(ino, i_size, i_clusters, pos, len, flags,
+ page, clusters, extents_to_split),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(long long, i_size)
+ __field(unsigned int, i_clusters)
+ __field(unsigned long long, pos)
+ __field(unsigned int, len)
+ __field(unsigned int, flags)
+ __field(void *, page)
+ __field(unsigned int, clusters)
+ __field(unsigned int, extents_to_split)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->i_size = i_size;
+ __entry->i_clusters = i_clusters;
+ __entry->pos = pos;
+ __entry->len = len;
+ __entry->flags = flags;
+ __entry->page = page;
+ __entry->clusters = clusters;
+ __entry->extents_to_split = extents_to_split;
+ ),
+ TP_printk("%llu %lld %u %llu %u %u %p %u %u",
+ __entry->ino, __entry->i_size, __entry->i_clusters,
+ __entry->pos, __entry->len,
+ __entry->flags, __entry->page, __entry->clusters,
+ __entry->extents_to_split)
+);
+
+TRACE_EVENT(ocfs2_write_end_inline,
+ TP_PROTO(unsigned long long ino,
+ unsigned long long pos, unsigned int copied,
+ unsigned int id_count, unsigned int features),
+ TP_ARGS(ino, pos, copied, id_count, features),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned long long, pos)
+ __field(unsigned int, copied)
+ __field(unsigned int, id_count)
+ __field(unsigned int, features)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->pos = pos;
+ __entry->copied = copied;
+ __entry->id_count = id_count;
+ __entry->features = features;
+ ),
+ TP_printk("%llu %llu %u %u %u",
+ __entry->ino, __entry->pos, __entry->copied,
+ __entry->id_count, __entry->features)
+);
+
+/* End of trace events for fs/ocfs2/aops.c. */
+
+/* Trace events for fs/ocfs2/mmap.c. */
+
+TRACE_EVENT(ocfs2_fault,
+ TP_PROTO(unsigned long long ino,
+ void *area, void *page, unsigned long pgoff),
+ TP_ARGS(ino, area, page, pgoff),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(void *, area)
+ __field(void *, page)
+ __field(unsigned long, pgoff)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->area = area;
+ __entry->page = page;
+ __entry->pgoff = pgoff;
+ ),
+ TP_printk("%llu %p %p %lu",
+ __entry->ino, __entry->area, __entry->page, __entry->pgoff)
+);
+
+/* End of trace events for fs/ocfs2/mmap.c. */
+
+/* Trace events for fs/ocfs2/file.c. */
+
+DECLARE_EVENT_CLASS(ocfs2__file_ops,
+ TP_PROTO(void *inode, void *file, void *dentry,
+ unsigned long long ino,
+ unsigned int d_len, const unsigned char *d_name,
+ unsigned long long para),
+ TP_ARGS(inode, file, dentry, ino, d_len, d_name, para),
+ TP_STRUCT__entry(
+ __field(void *, inode)
+ __field(void *, file)
+ __field(void *, dentry)
+ __field(unsigned long long, ino)
+ __field(unsigned int, d_len)
+ __string(d_name, d_name)
+ __field(unsigned long long, para)
+ ),
+ TP_fast_assign(
+ __entry->inode = inode;
+ __entry->file = file;
+ __entry->dentry = dentry;
+ __entry->ino = ino;
+ __entry->d_len = d_len;
+ __assign_str(d_name, d_name);
+ __entry->para = para;
+ ),
+ TP_printk("%p %p %p %llu %llu %.*s", __entry->inode, __entry->file,
+ __entry->dentry, __entry->ino, __entry->para,
+ __entry->d_len, __get_str(d_name))
+);
+
+#define DEFINE_OCFS2_FILE_OPS(name) \
+DEFINE_EVENT(ocfs2__file_ops, name, \
+TP_PROTO(void *inode, void *file, void *dentry, \
+ unsigned long long ino, \
+ unsigned int d_len, const unsigned char *d_name, \
+ unsigned long long mode), \
+ TP_ARGS(inode, file, dentry, ino, d_len, d_name, mode))
+
+DEFINE_OCFS2_FILE_OPS(ocfs2_file_open);
+
+DEFINE_OCFS2_FILE_OPS(ocfs2_file_release);
+
+DEFINE_OCFS2_FILE_OPS(ocfs2_sync_file);
+
+DEFINE_OCFS2_FILE_OPS(ocfs2_file_aio_write);
+
+DEFINE_OCFS2_FILE_OPS(ocfs2_file_splice_write);
+
+DEFINE_OCFS2_FILE_OPS(ocfs2_file_splice_read);
+
+DEFINE_OCFS2_FILE_OPS(ocfs2_file_aio_read);
+
+DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_truncate_file);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_truncate_file_error);
+
+TRACE_EVENT(ocfs2_extend_allocation,
+ TP_PROTO(unsigned long long ip_blkno, unsigned long long size,
+ unsigned int clusters, unsigned int clusters_to_add,
+ int why, int restart_func),
+ TP_ARGS(ip_blkno, size, clusters, clusters_to_add, why, restart_func),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ip_blkno)
+ __field(unsigned long long, size)
+ __field(unsigned int, clusters)
+ __field(unsigned int, clusters_to_add)
+ __field(int, why)
+ __field(int, restart_func)
+ ),
+ TP_fast_assign(
+ __entry->ip_blkno = ip_blkno;
+ __entry->size = size;
+ __entry->clusters = clusters;
+ __entry->clusters_to_add = clusters_to_add;
+ __entry->why = why;
+ __entry->restart_func = restart_func;
+ ),
+ TP_printk("%llu %llu %u %u %d %d",
+ __entry->ip_blkno, __entry->size, __entry->clusters,
+ __entry->clusters_to_add, __entry->why, __entry->restart_func)
+);
+
+TRACE_EVENT(ocfs2_extend_allocation_end,
+ TP_PROTO(unsigned long long ino,
+ unsigned int di_clusters, unsigned long long di_size,
+ unsigned int ip_clusters, unsigned long long i_size),
+ TP_ARGS(ino, di_clusters, di_size, ip_clusters, i_size),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned int, di_clusters)
+ __field(unsigned long long, di_size)
+ __field(unsigned int, ip_clusters)
+ __field(unsigned long long, i_size)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->di_clusters = di_clusters;
+ __entry->di_size = di_size;
+ __entry->ip_clusters = ip_clusters;
+ __entry->i_size = i_size;
+ ),
+ TP_printk("%llu %u %llu %u %llu", __entry->ino, __entry->di_clusters,
+ __entry->di_size, __entry->ip_clusters, __entry->i_size)
+);
+
+TRACE_EVENT(ocfs2_write_zero_page,
+ TP_PROTO(unsigned long long ino,
+ unsigned long long abs_from, unsigned long long abs_to,
+ unsigned long index, unsigned int zero_from,
+ unsigned int zero_to),
+ TP_ARGS(ino, abs_from, abs_to, index, zero_from, zero_to),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned long long, abs_from)
+ __field(unsigned long long, abs_to)
+ __field(unsigned long, index)
+ __field(unsigned int, zero_from)
+ __field(unsigned int, zero_to)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->abs_from = abs_from;
+ __entry->abs_to = abs_to;
+ __entry->index = index;
+ __entry->zero_from = zero_from;
+ __entry->zero_to = zero_to;
+ ),
+ TP_printk("%llu %llu %llu %lu %u %u", __entry->ino,
+ __entry->abs_from, __entry->abs_to,
+ __entry->index, __entry->zero_from, __entry->zero_to)
+);
+
+DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_zero_extend_range);
+
+DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_zero_extend);
+
+TRACE_EVENT(ocfs2_setattr,
+ TP_PROTO(void *inode, void *dentry,
+ unsigned long long ino,
+ unsigned int d_len, const unsigned char *d_name,
+ unsigned int ia_valid, unsigned int ia_mode,
+ unsigned int ia_uid, unsigned int ia_gid),
+ TP_ARGS(inode, dentry, ino, d_len, d_name,
+ ia_valid, ia_mode, ia_uid, ia_gid),
+ TP_STRUCT__entry(
+ __field(void *, inode)
+ __field(void *, dentry)
+ __field(unsigned long long, ino)
+ __field(unsigned int, d_len)
+ __string(d_name, d_name)
+ __field(unsigned int, ia_valid)
+ __field(unsigned int, ia_mode)
+ __field(unsigned int, ia_uid)
+ __field(unsigned int, ia_gid)
+ ),
+ TP_fast_assign(
+ __entry->inode = inode;
+ __entry->dentry = dentry;
+ __entry->ino = ino;
+ __entry->d_len = d_len;
+ __assign_str(d_name, d_name);
+ __entry->ia_valid = ia_valid;
+ __entry->ia_mode = ia_mode;
+ __entry->ia_uid = ia_uid;
+ __entry->ia_gid = ia_gid;
+ ),
+ TP_printk("%p %p %llu %.*s %u %u %u %u", __entry->inode,
+ __entry->dentry, __entry->ino, __entry->d_len,
+ __get_str(d_name), __entry->ia_valid, __entry->ia_mode,
+ __entry->ia_uid, __entry->ia_gid)
+);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_write_remove_suid);
+
+DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_zero_partial_clusters);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_zero_partial_clusters_range1);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_zero_partial_clusters_range2);
+
+DEFINE_OCFS2_ULL_ULL_ULL_EVENT(ocfs2_remove_inode_range);
+
+TRACE_EVENT(ocfs2_prepare_inode_for_write,
+ TP_PROTO(unsigned long long ino, unsigned long long saved_pos,
+ int appending, unsigned long count,
+ int *direct_io, int *has_refcount),
+ TP_ARGS(ino, saved_pos, appending, count, direct_io, has_refcount),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned long long, saved_pos)
+ __field(int, appending)
+ __field(unsigned long, count)
+ __field(int, direct_io)
+ __field(int, has_refcount)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->saved_pos = saved_pos;
+ __entry->appending = appending;
+ __entry->count = count;
+ __entry->direct_io = direct_io ? *direct_io : -1;
+ __entry->has_refcount = has_refcount ? *has_refcount : -1;
+ ),
+ TP_printk("%llu %llu %d %lu %d %d", __entry->ino,
+ __entry->saved_pos, __entry->appending, __entry->count,
+ __entry->direct_io, __entry->has_refcount)
+);
+
+DEFINE_OCFS2_INT_EVENT(generic_file_aio_read_ret);
+
+/* End of trace events for fs/ocfs2/file.c. */
+
+/* Trace events for fs/ocfs2/inode.c. */
+
+TRACE_EVENT(ocfs2_iget_begin,
+ TP_PROTO(unsigned long long ino, unsigned int flags, int sysfile_type),
+ TP_ARGS(ino, flags, sysfile_type),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(unsigned int, flags)
+ __field(int, sysfile_type)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->flags = flags;
+ __entry->sysfile_type = sysfile_type;
+ ),
+ TP_printk("%llu %u %d", __entry->ino,
+ __entry->flags, __entry->sysfile_type)
+);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_iget5_locked);
+
+TRACE_EVENT(ocfs2_iget_end,
+ TP_PROTO(void *inode, unsigned long long ino),
+ TP_ARGS(inode, ino),
+ TP_STRUCT__entry(
+ __field(void *, inode)
+ __field(unsigned long long, ino)
+ ),
+ TP_fast_assign(
+ __entry->inode = inode;
+ __entry->ino = ino;
+ ),
+ TP_printk("%p %llu", __entry->inode, __entry->ino)
+);
+
+TRACE_EVENT(ocfs2_find_actor,
+ TP_PROTO(void *inode, unsigned long long ino,
+ void *args, unsigned long long fi_blkno),
+ TP_ARGS(inode, ino, args, fi_blkno),
+ TP_STRUCT__entry(
+ __field(void *, inode)
+ __field(unsigned long long, ino)
+ __field(void *, args)
+ __field(unsigned long long, fi_blkno)
+ ),
+ TP_fast_assign(
+ __entry->inode = inode;
+ __entry->ino = ino;
+ __entry->args = args;
+ __entry->fi_blkno = fi_blkno;
+ ),
+ TP_printk("%p %llu %p %llu", __entry->inode, __entry->ino,
+ __entry->args, __entry->fi_blkno)
+);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_populate_inode);
+
+DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_read_locked_inode);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_check_orphan_recovery_state);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_inode_block);
+
+TRACE_EVENT(ocfs2_inode_is_valid_to_delete,
+ TP_PROTO(void *task, void *dc_task, unsigned long long ino,
+ unsigned int flags),
+ TP_ARGS(task, dc_task, ino, flags),
+ TP_STRUCT__entry(
+ __field(void *, task)
+ __field(void *, dc_task)
+ __field(unsigned long long, ino)
+ __field(unsigned int, flags)
+ ),
+ TP_fast_assign(
+ __entry->task = task;
+ __entry->dc_task = dc_task;
+ __entry->ino = ino;
+ __entry->flags = flags;
+ ),
+ TP_printk("%p %p %llu %u", __entry->task, __entry->dc_task,
+ __entry->ino, __entry->flags)
+);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_query_inode_wipe_begin);
+
+DEFINE_OCFS2_UINT_EVENT(ocfs2_query_inode_wipe_succ);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_query_inode_wipe_end);
+
+DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_cleanup_delete_inode);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_delete_inode);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_clear_inode);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_drop_inode);
+
+TRACE_EVENT(ocfs2_inode_revalidate,
+ TP_PROTO(void *inode, unsigned long long ino,
+ unsigned int flags),
+ TP_ARGS(inode, ino, flags),
+ TP_STRUCT__entry(
+ __field(void *, inode)
+ __field(unsigned long long, ino)
+ __field(unsigned int, flags)
+ ),
+ TP_fast_assign(
+ __entry->inode = inode;
+ __entry->ino = ino;
+ __entry->flags = flags;
+ ),
+ TP_printk("%p %llu %u", __entry->inode, __entry->ino, __entry->flags)
+);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_mark_inode_dirty);
+
+/* End of trace events for fs/ocfs2/inode.c. */
+
+/* Trace events for fs/ocfs2/extent_map.c. */
+
+TRACE_EVENT(ocfs2_read_virt_blocks,
+ TP_PROTO(void *inode, unsigned long long vblock, int nr,
+ void *bhs, unsigned int flags, void *validate),
+ TP_ARGS(inode, vblock, nr, bhs, flags, validate),
+ TP_STRUCT__entry(
+ __field(void *, inode)
+ __field(unsigned long long, vblock)
+ __field(int, nr)
+ __field(void *, bhs)
+ __field(unsigned int, flags)
+ __field(void *, validate)
+ ),
+ TP_fast_assign(
+ __entry->inode = inode;
+ __entry->vblock = vblock;
+ __entry->nr = nr;
+ __entry->bhs = bhs;
+ __entry->flags = flags;
+ __entry->validate = validate;
+ ),
+ TP_printk("%p %llu %d %p %x %p", __entry->inode, __entry->vblock,
+ __entry->nr, __entry->bhs, __entry->flags, __entry->validate)
+);
+
+/* End of trace events for fs/ocfs2/extent_map.c. */
+
+/* Trace events for fs/ocfs2/slot_map.c. */
+
+DEFINE_OCFS2_UINT_EVENT(ocfs2_refresh_slot_info);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_map_slot_buffers);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_map_slot_buffers_block);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_find_slot);
+
+/* End of trace events for fs/ocfs2/slot_map.c. */
+
+/* Trace events for fs/ocfs2/heartbeat.c. */
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_do_node_down);
+
+/* End of trace events for fs/ocfs2/heartbeat.c. */
+
+/* Trace events for fs/ocfs2/super.c. */
+
+TRACE_EVENT(ocfs2_remount,
+ TP_PROTO(unsigned long s_flags, unsigned long osb_flags, int flags),
+ TP_ARGS(s_flags, osb_flags, flags),
+ TP_STRUCT__entry(
+ __field(unsigned long, s_flags)
+ __field(unsigned long, osb_flags)
+ __field(int, flags)
+ ),
+ TP_fast_assign(
+ __entry->s_flags = s_flags;
+ __entry->osb_flags = osb_flags;
+ __entry->flags = flags;
+ ),
+ TP_printk("%lu %lu %d", __entry->s_flags,
+ __entry->osb_flags, __entry->flags)
+);
+
+TRACE_EVENT(ocfs2_fill_super,
+ TP_PROTO(void *sb, void *data, int silent),
+ TP_ARGS(sb, data, silent),
+ TP_STRUCT__entry(
+ __field(void *, sb)
+ __field(void *, data)
+ __field(int, silent)
+ ),
+ TP_fast_assign(
+ __entry->sb = sb;
+ __entry->data = data;
+ __entry->silent = silent;
+ ),
+ TP_printk("%p %p %d", __entry->sb,
+ __entry->data, __entry->silent)
+);
+
+TRACE_EVENT(ocfs2_parse_options,
+ TP_PROTO(int is_remount, char *options),
+ TP_ARGS(is_remount, options),
+ TP_STRUCT__entry(
+ __field(int, is_remount)
+ __string(options, options)
+ ),
+ TP_fast_assign(
+ __entry->is_remount = is_remount;
+ __assign_str(options, options);
+ ),
+ TP_printk("%d %s", __entry->is_remount, __get_str(options))
+);
+
+DEFINE_OCFS2_POINTER_EVENT(ocfs2_put_super);
+
+TRACE_EVENT(ocfs2_statfs,
+ TP_PROTO(void *sb, void *buf),
+ TP_ARGS(sb, buf),
+ TP_STRUCT__entry(
+ __field(void *, sb)
+ __field(void *, buf)
+ ),
+ TP_fast_assign(
+ __entry->sb = sb;
+ __entry->buf = buf;
+ ),
+ TP_printk("%p %p", __entry->sb, __entry->buf)
+);
+
+DEFINE_OCFS2_POINTER_EVENT(ocfs2_dismount_volume);
+
+TRACE_EVENT(ocfs2_initialize_super,
+ TP_PROTO(char *label, char *uuid_str, unsigned long long root_dir,
+ unsigned long long system_dir, int cluster_bits),
+ TP_ARGS(label, uuid_str, root_dir, system_dir, cluster_bits),
+ TP_STRUCT__entry(
+ __string(label, label)
+ __string(uuid_str, uuid_str)
+ __field(unsigned long long, root_dir)
+ __field(unsigned long long, system_dir)
+ __field(int, cluster_bits)
+ ),
+ TP_fast_assign(
+ __assign_str(label, label);
+ __assign_str(uuid_str, uuid_str);
+ __entry->root_dir = root_dir;
+ __entry->system_dir = system_dir;
+ __entry->cluster_bits = cluster_bits;
+ ),
+ TP_printk("%s %s %llu %llu %d", __get_str(label), __get_str(uuid_str),
+ __entry->root_dir, __entry->system_dir, __entry->cluster_bits)
+);
+
+/* End of trace events for fs/ocfs2/super.c. */
+
+/* Trace events for fs/ocfs2/xattr.c. */
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_xattr_block);
+
+DEFINE_OCFS2_UINT_EVENT(ocfs2_xattr_extend_allocation);
+
+TRACE_EVENT(ocfs2_init_xattr_set_ctxt,
+ TP_PROTO(const char *name, int meta, int clusters, int credits),
+ TP_ARGS(name, meta, clusters, credits),
+ TP_STRUCT__entry(
+ __string(name, name)
+ __field(int, meta)
+ __field(int, clusters)
+ __field(int, credits)
+ ),
+ TP_fast_assign(
+ __assign_str(name, name);
+ __entry->meta = meta;
+ __entry->clusters = clusters;
+ __entry->credits = credits;
+ ),
+ TP_printk("%s %d %d %d", __get_str(name), __entry->meta,
+ __entry->clusters, __entry->credits)
+);
+
+DECLARE_EVENT_CLASS(ocfs2__xattr_find,
+ TP_PROTO(unsigned long long ino, const char *name, int name_index,
+ unsigned int hash, unsigned long long location,
+ int xe_index),
+ TP_ARGS(ino, name, name_index, hash, location, xe_index),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __string(name, name)
+ __field(int, name_index)
+ __field(unsigned int, hash)
+ __field(unsigned long long, location)
+ __field(int, xe_index)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __assign_str(name, name);
+ __entry->name_index = name_index;
+ __entry->hash = hash;
+ __entry->location = location;
+ __entry->xe_index = xe_index;
+ ),
+ TP_printk("%llu %s %d %u %llu %d", __entry->ino, __get_str(name),
+ __entry->name_index, __entry->hash, __entry->location,
+ __entry->xe_index)
+);
+
+#define DEFINE_OCFS2_XATTR_FIND_EVENT(name) \
+DEFINE_EVENT(ocfs2__xattr_find, name, \
+TP_PROTO(unsigned long long ino, const char *name, int name_index, \
+ unsigned int hash, unsigned long long bucket, \
+ int xe_index), \
+ TP_ARGS(ino, name, name_index, hash, bucket, xe_index))
+
+DEFINE_OCFS2_XATTR_FIND_EVENT(ocfs2_xattr_bucket_find);
+
+DEFINE_OCFS2_XATTR_FIND_EVENT(ocfs2_xattr_index_block_find);
+
+DEFINE_OCFS2_XATTR_FIND_EVENT(ocfs2_xattr_index_block_find_rec);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_iterate_xattr_buckets);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_iterate_xattr_bucket);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_cp_xattr_block_to_bucket_begin);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_cp_xattr_block_to_bucket_end);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_xattr_create_index_block_begin);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_xattr_create_index_block);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_defrag_xattr_bucket);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_mv_xattr_bucket_cross_cluster);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_divide_xattr_bucket_begin);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_divide_xattr_bucket_move);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_cp_xattr_bucket);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_mv_xattr_buckets);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_adjust_xattr_cross_cluster);
+
+DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_add_new_xattr_cluster_begin);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_add_new_xattr_cluster);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_add_new_xattr_cluster_insert);
+
+DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_extend_xattr_bucket);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_add_new_xattr_bucket);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_xattr_bucket_value_truncate);
+
+DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_rm_xattr_cluster);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_reflink_xattr_header);
+
+DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_create_empty_xattr_block);
+
+DEFINE_OCFS2_STRING_EVENT(ocfs2_xattr_set_entry_bucket);
+
+DEFINE_OCFS2_STRING_EVENT(ocfs2_xattr_set_entry_index_block);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_xattr_bucket_value_refcount);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_reflink_xattr_buckets);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_reflink_xattr_rec);
+
+/* End of trace events for fs/ocfs2/xattr.c. */
+
+/* Trace events for fs/ocfs2/reservations.c. */
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_resv_insert);
+
+DEFINE_OCFS2_ULL_UINT_UINT_UINT_EVENT(ocfs2_resmap_find_free_bits_begin);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_resmap_find_free_bits_end);
+
+TRACE_EVENT(ocfs2_resv_find_window_begin,
+ TP_PROTO(unsigned int r_start, unsigned int r_end, unsigned int goal,
+ unsigned int wanted, int empty_root),
+ TP_ARGS(r_start, r_end, goal, wanted, empty_root),
+ TP_STRUCT__entry(
+ __field(unsigned int, r_start)
+ __field(unsigned int, r_end)
+ __field(unsigned int, goal)
+ __field(unsigned int, wanted)
+ __field(int, empty_root)
+ ),
+ TP_fast_assign(
+ __entry->r_start = r_start;
+ __entry->r_end = r_end;
+ __entry->goal = goal;
+ __entry->wanted = wanted;
+ __entry->empty_root = empty_root;
+ ),
+ TP_printk("%u %u %u %u %d", __entry->r_start, __entry->r_end,
+ __entry->goal, __entry->wanted, __entry->empty_root)
+);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_resv_find_window_prev);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_resv_find_window_next);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_cannibalize_resv_begin);
+
+TRACE_EVENT(ocfs2_cannibalize_resv_end,
+ TP_PROTO(unsigned int start, unsigned int end, unsigned int len,
+ unsigned int last_start, unsigned int last_len),
+ TP_ARGS(start, end, len, last_start, last_len),
+ TP_STRUCT__entry(
+ __field(unsigned int, start)
+ __field(unsigned int, end)
+ __field(unsigned int, len)
+ __field(unsigned int, last_start)
+ __field(unsigned int, last_len)
+ ),
+ TP_fast_assign(
+ __entry->start = start;
+ __entry->end = end;
+ __entry->len = len;
+ __entry->last_start = last_start;
+ __entry->last_len = last_len;
+ ),
+ TP_printk("%u %u %u %u %u", __entry->start, __entry->end,
+ __entry->len, __entry->last_start, __entry->last_len)
+);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_resmap_resv_bits);
+
+TRACE_EVENT(ocfs2_resmap_claimed_bits_begin,
+ TP_PROTO(unsigned int cstart, unsigned int cend, unsigned int clen,
+ unsigned int r_start, unsigned int r_end, unsigned int r_len,
+ unsigned int last_start, unsigned int last_len),
+ TP_ARGS(cstart, cend, clen, r_start, r_end,
+ r_len, last_start, last_len),
+ TP_STRUCT__entry(
+ __field(unsigned int, cstart)
+ __field(unsigned int, cend)
+ __field(unsigned int, clen)
+ __field(unsigned int, r_start)
+ __field(unsigned int, r_end)
+ __field(unsigned int, r_len)
+ __field(unsigned int, last_start)
+ __field(unsigned int, last_len)
+ ),
+ TP_fast_assign(
+ __entry->cstart = cstart;
+ __entry->cend = cend;
+ __entry->clen = clen;
+ __entry->r_start = r_start;
+ __entry->r_end = r_end;
+ __entry->r_len = r_len;
+ __entry->last_start = last_start;
+ __entry->last_len = last_len;
+ ),
+ TP_printk("%u %u %u %u %u %u %u %u",
+ __entry->cstart, __entry->cend, __entry->clen,
+ __entry->r_start, __entry->r_end, __entry->r_len,
+ __entry->last_start, __entry->last_len)
+);
+
+TRACE_EVENT(ocfs2_resmap_claimed_bits_end,
+ TP_PROTO(unsigned int start, unsigned int end, unsigned int len,
+ unsigned int last_start, unsigned int last_len),
+ TP_ARGS(start, end, len, last_start, last_len),
+ TP_STRUCT__entry(
+ __field(unsigned int, start)
+ __field(unsigned int, end)
+ __field(unsigned int, len)
+ __field(unsigned int, last_start)
+ __field(unsigned int, last_len)
+ ),
+ TP_fast_assign(
+ __entry->start = start;
+ __entry->end = end;
+ __entry->len = len;
+ __entry->last_start = last_start;
+ __entry->last_len = last_len;
+ ),
+ TP_printk("%u %u %u %u %u", __entry->start, __entry->end,
+ __entry->len, __entry->last_start, __entry->last_len)
+);
+
+/* End of trace events for fs/ocfs2/reservations.c. */
+
+/* Trace events for fs/ocfs2/quota_local.c. */
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_recover_local_quota_file);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_finish_quota_recovery);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(olq_set_dquot);
+
+/* End of trace events for fs/ocfs2/quota_local.c. */
+
+/* Trace events for fs/ocfs2/quota_global.c. */
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_quota_block);
+
+TRACE_EVENT(ocfs2_sync_dquot,
+ TP_PROTO(unsigned int dq_id, long long dqb_curspace,
+ long long spacechange, long long curinodes,
+ long long inodechange),
+ TP_ARGS(dq_id, dqb_curspace, spacechange, curinodes, inodechange),
+ TP_STRUCT__entry(
+ __field(unsigned int, dq_id)
+ __field(long long, dqb_curspace)
+ __field(long long, spacechange)
+ __field(long long, curinodes)
+ __field(long long, inodechange)
+ ),
+ TP_fast_assign(
+ __entry->dq_id = dq_id;
+ __entry->dqb_curspace = dqb_curspace;
+ __entry->spacechange = spacechange;
+ __entry->curinodes = curinodes;
+ __entry->inodechange = inodechange;
+ ),
+ TP_printk("%u %lld %lld %lld %lld", __entry->dq_id,
+ __entry->dqb_curspace, __entry->spacechange,
+ __entry->curinodes, __entry->inodechange)
+);
+
+TRACE_EVENT(ocfs2_sync_dquot_helper,
+ TP_PROTO(unsigned int dq_id, unsigned int dq_type, unsigned long type,
+ const char *s_id),
+ TP_ARGS(dq_id, dq_type, type, s_id),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, dq_id)
+ __field(unsigned int, dq_type)
+ __field(unsigned long, type)
+ __string(s_id, s_id)
+ ),
+ TP_fast_assign(
+ __entry->dq_id = dq_id;
+ __entry->dq_type = dq_type;
+ __entry->type = type;
+ __assign_str(s_id, s_id);
+ ),
+ TP_printk("%u %u %lu %s", __entry->dq_id, __entry->dq_type,
+ __entry->type, __get_str(s_id))
+);
+
+DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_write_dquot);
+
+DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_release_dquot);
+
+DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_acquire_dquot);
+
+DEFINE_OCFS2_UINT_INT_EVENT(ocfs2_mark_dquot_dirty);
+
+/* End of trace events for fs/ocfs2/quota_global.c. */
+
+/* Trace events for fs/ocfs2/dir.c. */
+DEFINE_OCFS2_INT_EVENT(ocfs2_search_dirblock);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_validate_dir_block);
+
+DEFINE_OCFS2_POINTER_EVENT(ocfs2_find_entry_el);
+
+TRACE_EVENT(ocfs2_dx_dir_search,
+ TP_PROTO(unsigned long long ino, int namelen, const char *name,
+ unsigned int major_hash, unsigned int minor_hash,
+ unsigned long long blkno),
+ TP_ARGS(ino, namelen, name, major_hash, minor_hash, blkno),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(int, namelen)
+ __string(name, name)
+ __field(unsigned int, major_hash)
+ __field(unsigned int,minor_hash)
+ __field(unsigned long long, blkno)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->namelen = namelen;
+ __assign_str(name, name);
+ __entry->major_hash = major_hash;
+ __entry->minor_hash = minor_hash;
+ __entry->blkno = blkno;
+ ),
+ TP_printk("%llu %.*s %u %u %llu", __entry->ino,
+ __entry->namelen, __get_str(name),
+ __entry->major_hash, __entry->minor_hash, __entry->blkno)
+);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_dx_dir_search_leaf_info);
+
+DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_delete_entry_dx);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_readdir);
+
+TRACE_EVENT(ocfs2_find_files_on_disk,
+ TP_PROTO(int namelen, const char *name, void *blkno,
+ unsigned long long dir),
+ TP_ARGS(namelen, name, blkno, dir),
+ TP_STRUCT__entry(
+ __field(int, namelen)
+ __string(name, name)
+ __field(void *, blkno)
+ __field(unsigned long long, dir)
+ ),
+ TP_fast_assign(
+ __entry->namelen = namelen;
+ __assign_str(name, name);
+ __entry->blkno = blkno;
+ __entry->dir = dir;
+ ),
+ TP_printk("%.*s %p %llu", __entry->namelen, __get_str(name),
+ __entry->blkno, __entry->dir)
+);
+
+TRACE_EVENT(ocfs2_check_dir_for_entry,
+ TP_PROTO(unsigned long long dir, int namelen, const char *name),
+ TP_ARGS(dir, namelen, name),
+ TP_STRUCT__entry(
+ __field(unsigned long long, dir)
+ __field(int, namelen)
+ __string(name, name)
+ ),
+ TP_fast_assign(
+ __entry->dir = dir;
+ __entry->namelen = namelen;
+ __assign_str(name, name);
+ ),
+ TP_printk("%llu %.*s", __entry->dir,
+ __entry->namelen, __get_str(name))
+);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_dx_dir_attach_index);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_dx_dir_format_cluster);
+
+TRACE_EVENT(ocfs2_dx_dir_index_root_block,
+ TP_PROTO(unsigned long long dir,
+ unsigned int major_hash, unsigned int minor_hash,
+ int namelen, const char *name, unsigned int num_used),
+ TP_ARGS(dir, major_hash, minor_hash, namelen, name, num_used),
+ TP_STRUCT__entry(
+ __field(unsigned long long, dir)
+ __field(unsigned int, major_hash)
+ __field(unsigned int, minor_hash)
+ __field(int, namelen)
+ __string(name, name)
+ __field(unsigned int, num_used)
+ ),
+ TP_fast_assign(
+ __entry->dir = dir;
+ __entry->major_hash = major_hash;
+ __entry->minor_hash = minor_hash;
+ __entry->namelen = namelen;
+ __assign_str(name, name);
+ __entry->num_used = num_used;
+ ),
+ TP_printk("%llu %x %x %.*s %u", __entry->dir,
+ __entry->major_hash, __entry->minor_hash,
+ __entry->namelen, __get_str(name), __entry->num_used)
+);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_extend_dir);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_dx_dir_rebalance);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_dx_dir_rebalance_split);
+
+DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_prepare_dir_for_insert);
+
+/* End of trace events for fs/ocfs2/dir.c. */
+
+/* Trace events for fs/ocfs2/namei.c. */
+
+DECLARE_EVENT_CLASS(ocfs2__dentry_ops,
+ TP_PROTO(void *dir, void *dentry, int name_len, const char *name,
+ unsigned long long dir_blkno, unsigned long long extra),
+ TP_ARGS(dir, dentry, name_len, name, dir_blkno, extra),
+ TP_STRUCT__entry(
+ __field(void *, dir)
+ __field(void *, dentry)
+ __field(int, name_len)
+ __string(name, name)
+ __field(unsigned long long, dir_blkno)
+ __field(unsigned long long, extra)
+ ),
+ TP_fast_assign(
+ __entry->dir = dir;
+ __entry->dentry = dentry;
+ __entry->name_len = name_len;
+ __assign_str(name, name);
+ __entry->dir_blkno = dir_blkno;
+ __entry->extra = extra;
+ ),
+ TP_printk("%p %p %.*s %llu %llu", __entry->dir, __entry->dentry,
+ __entry->name_len, __get_str(name),
+ __entry->dir_blkno, __entry->extra)
+);
+
+#define DEFINE_OCFS2_DENTRY_OPS(name) \
+DEFINE_EVENT(ocfs2__dentry_ops, name, \
+TP_PROTO(void *dir, void *dentry, int name_len, const char *name, \
+ unsigned long long dir_blkno, unsigned long long extra), \
+ TP_ARGS(dir, dentry, name_len, name, dir_blkno, extra))
+
+DEFINE_OCFS2_DENTRY_OPS(ocfs2_lookup);
+
+DEFINE_OCFS2_DENTRY_OPS(ocfs2_mkdir);
+
+DEFINE_OCFS2_DENTRY_OPS(ocfs2_create);
+
+DEFINE_OCFS2_DENTRY_OPS(ocfs2_unlink);
+
+DEFINE_OCFS2_DENTRY_OPS(ocfs2_symlink_create);
+
+DEFINE_OCFS2_DENTRY_OPS(ocfs2_mv_orphaned_inode_to_new);
+
+DEFINE_OCFS2_POINTER_EVENT(ocfs2_lookup_ret);
+
+TRACE_EVENT(ocfs2_mknod,
+ TP_PROTO(void *dir, void *dentry, int name_len, const char *name,
+ unsigned long long dir_blkno, unsigned long dev, int mode),
+ TP_ARGS(dir, dentry, name_len, name, dir_blkno, dev, mode),
+ TP_STRUCT__entry(
+ __field(void *, dir)
+ __field(void *, dentry)
+ __field(int, name_len)
+ __string(name, name)
+ __field(unsigned long long, dir_blkno)
+ __field(unsigned long, dev)
+ __field(int, mode)
+ ),
+ TP_fast_assign(
+ __entry->dir = dir;
+ __entry->dentry = dentry;
+ __entry->name_len = name_len;
+ __assign_str(name, name);
+ __entry->dir_blkno = dir_blkno;
+ __entry->dev = dev;
+ __entry->mode = mode;
+ ),
+ TP_printk("%p %p %.*s %llu %lu %d", __entry->dir, __entry->dentry,
+ __entry->name_len, __get_str(name),
+ __entry->dir_blkno, __entry->dev, __entry->mode)
+);
+
+TRACE_EVENT(ocfs2_link,
+ TP_PROTO(unsigned long long ino, int old_len, const char *old_name,
+ int name_len, const char *name),
+ TP_ARGS(ino, old_len, old_name, name_len, name),
+ TP_STRUCT__entry(
+ __field(unsigned long long, ino)
+ __field(int, old_len)
+ __string(old_name, old_name)
+ __field(int, name_len)
+ __string(name, name)
+ ),
+ TP_fast_assign(
+ __entry->ino = ino;
+ __entry->old_len = old_len;
+ __assign_str(old_name, old_name);
+ __entry->name_len = name_len;
+ __assign_str(name, name);
+ ),
+ TP_printk("%llu %.*s %.*s", __entry->ino,
+ __entry->old_len, __get_str(old_name),
+ __entry->name_len, __get_str(name))
+);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_unlink_noent);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_double_lock);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_double_lock_end);
+
+TRACE_EVENT(ocfs2_rename,
+ TP_PROTO(void *old_dir, void *old_dentry,
+ void *new_dir, void *new_dentry,
+ int old_len, const char *old_name,
+ int new_len, const char *new_name),
+ TP_ARGS(old_dir, old_dentry, new_dir, new_dentry,
+ old_len, old_name, new_len, new_name),
+ TP_STRUCT__entry(
+ __field(void *, old_dir)
+ __field(void *, old_dentry)
+ __field(void *, new_dir)
+ __field(void *, new_dentry)
+ __field(int, old_len)
+ __string(old_name, old_name)
+ __field(int, new_len)
+ __string(new_name, new_name)
+ ),
+ TP_fast_assign(
+ __entry->old_dir = old_dir;
+ __entry->old_dentry = old_dentry;
+ __entry->new_dir = new_dir;
+ __entry->new_dentry = new_dentry;
+ __entry->old_len = old_len;
+ __assign_str(old_name, old_name);
+ __entry->new_len = new_len;
+ __assign_str(new_name, new_name);
+ ),
+ TP_printk("%p %p %p %p %.*s %.*s",
+ __entry->old_dir, __entry->old_dentry,
+ __entry->new_dir, __entry->new_dentry,
+ __entry->old_len, __get_str(old_name),
+ __entry->new_len, __get_str(new_name))
+);
+
+TRACE_EVENT(ocfs2_rename_target_exists,
+ TP_PROTO(int new_len, const char *new_name),
+ TP_ARGS(new_len, new_name),
+ TP_STRUCT__entry(
+ __field(int, new_len)
+ __string(new_name, new_name)
+ ),
+ TP_fast_assign(
+ __entry->new_len = new_len;
+ __assign_str(new_name, new_name);
+ ),
+ TP_printk("%.*s", __entry->new_len, __get_str(new_name))
+);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_rename_disagree);
+
+TRACE_EVENT(ocfs2_rename_over_existing,
+ TP_PROTO(unsigned long long new_blkno, void *new_bh,
+ unsigned long long newdi_blkno),
+ TP_ARGS(new_blkno, new_bh, newdi_blkno),
+ TP_STRUCT__entry(
+ __field(unsigned long long, new_blkno)
+ __field(void *, new_bh)
+ __field(unsigned long long, newdi_blkno)
+ ),
+ TP_fast_assign(
+ __entry->new_blkno = new_blkno;
+ __entry->new_bh = new_bh;
+ __entry->newdi_blkno = newdi_blkno;
+ ),
+ TP_printk("%llu %p %llu", __entry->new_blkno, __entry->new_bh,
+ __entry->newdi_blkno)
+);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_create_symlink_data);
+
+TRACE_EVENT(ocfs2_symlink_begin,
+ TP_PROTO(void *dir, void *dentry, const char *symname,
+ int len, const char *name),
+ TP_ARGS(dir, dentry, symname, len, name),
+ TP_STRUCT__entry(
+ __field(void *, dir)
+ __field(void *, dentry)
+ __field(const char *, symname)
+ __field(int, len)
+ __string(name, name)
+ ),
+ TP_fast_assign(
+ __entry->dir = dir;
+ __entry->dentry = dentry;
+ __entry->symname = symname;
+ __entry->len = len;
+ __assign_str(name, name);
+ ),
+ TP_printk("%p %p %s %.*s", __entry->dir, __entry->dentry,
+ __entry->symname, __entry->len, __get_str(name))
+);
+
+TRACE_EVENT(ocfs2_blkno_stringify,
+ TP_PROTO(unsigned long long blkno, const char *name, int namelen),
+ TP_ARGS(blkno, name, namelen),
+ TP_STRUCT__entry(
+ __field(unsigned long long, blkno)
+ __string(name, name)
+ __field(int, namelen)
+ ),
+ TP_fast_assign(
+ __entry->blkno = blkno;
+ __assign_str(name, name);
+ __entry->namelen = namelen;
+ ),
+ TP_printk("%llu %s %d", __entry->blkno, __get_str(name),
+ __entry->namelen)
+);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_orphan_add_begin);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_orphan_add_end);
+
+TRACE_EVENT(ocfs2_orphan_del,
+ TP_PROTO(unsigned long long dir, const char *name, int namelen),
+ TP_ARGS(dir, name, namelen),
+ TP_STRUCT__entry(
+ __field(unsigned long long, dir)
+ __string(name, name)
+ __field(int, namelen)
+ ),
+ TP_fast_assign(
+ __entry->dir = dir;
+ __assign_str(name, name);
+ __entry->namelen = namelen;
+ ),
+ TP_printk("%llu %s %d", __entry->dir, __get_str(name),
+ __entry->namelen)
+);
+
+/* End of trace events for fs/ocfs2/namei.c. */
+
+/* Trace events for fs/ocfs2/dcache.c. */
+
+TRACE_EVENT(ocfs2_dentry_revalidate,
+ TP_PROTO(void *dentry, int len, const char *name),
+ TP_ARGS(dentry, len, name),
+ TP_STRUCT__entry(
+ __field(void *, dentry)
+ __field(int, len)
+ __string(name, name)
+ ),
+ TP_fast_assign(
+ __entry->dentry = dentry;
+ __entry->len = len;
+ __assign_str(name, name);
+ ),
+ TP_printk("%p %.*s", __entry->dentry, __entry->len, __get_str(name))
+);
+
+TRACE_EVENT(ocfs2_dentry_revalidate_negative,
+ TP_PROTO(int len, const char *name, unsigned long pgen,
+ unsigned long gen),
+ TP_ARGS(len, name, pgen, gen),
+ TP_STRUCT__entry(
+ __field(int, len)
+ __string(name, name)
+ __field(unsigned long, pgen)
+ __field(unsigned long, gen)
+ ),
+ TP_fast_assign(
+ __entry->len = len;
+ __assign_str(name, name);
+ __entry->pgen = pgen;
+ __entry->gen = gen;
+ ),
+ TP_printk("%.*s %lu %lu", __entry->len, __get_str(name),
+ __entry->pgen, __entry->gen)
+);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_dentry_revalidate_delete);
+
+DEFINE_OCFS2_ULL_INT_EVENT(ocfs2_dentry_revalidate_orphaned);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_dentry_revalidate_nofsdata);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_dentry_revalidate_ret);
+
+TRACE_EVENT(ocfs2_find_local_alias,
+ TP_PROTO(int len, const char *name),
+ TP_ARGS(len, name),
+ TP_STRUCT__entry(
+ __field(int, len)
+ __string(name, name)
+ ),
+ TP_fast_assign(
+ __entry->len = len;
+ __assign_str(name, name);
+ ),
+ TP_printk("%.*s", __entry->len, __get_str(name))
+);
+
+TRACE_EVENT(ocfs2_dentry_attach_lock,
+ TP_PROTO(int len, const char *name,
+ unsigned long long parent, void *fsdata),
+ TP_ARGS(len, name, parent, fsdata),
+ TP_STRUCT__entry(
+ __field(int, len)
+ __string(name, name)
+ __field(unsigned long long, parent)
+ __field(void *, fsdata)
+ ),
+ TP_fast_assign(
+ __entry->len = len;
+ __assign_str(name, name);
+ __entry->parent = parent;
+ __entry->fsdata = fsdata;
+ ),
+ TP_printk("%.*s %llu %p", __entry->len, __get_str(name),
+ __entry->parent, __entry->fsdata)
+);
+
+TRACE_EVENT(ocfs2_dentry_attach_lock_found,
+ TP_PROTO(const char *name, unsigned long long parent,
+ unsigned long long ino),
+ TP_ARGS(name, parent, ino),
+ TP_STRUCT__entry(
+ __string(name, name)
+ __field(unsigned long long, parent)
+ __field(unsigned long long, ino)
+ ),
+ TP_fast_assign(
+ __assign_str(name, name);
+ __entry->parent = parent;
+ __entry->ino = ino;
+ ),
+ TP_printk("%s %llu %llu", __get_str(name), __entry->parent, __entry->ino)
+);
+/* End of trace events for fs/ocfs2/dcache.c. */
+
+/* Trace events for fs/ocfs2/export.c. */
+
+TRACE_EVENT(ocfs2_get_dentry_begin,
+ TP_PROTO(void *sb, void *handle, unsigned long long blkno),
+ TP_ARGS(sb, handle, blkno),
+ TP_STRUCT__entry(
+ __field(void *, sb)
+ __field(void *, handle)
+ __field(unsigned long long, blkno)
+ ),
+ TP_fast_assign(
+ __entry->sb = sb;
+ __entry->handle = handle;
+ __entry->blkno = blkno;
+ ),
+ TP_printk("%p %p %llu", __entry->sb, __entry->handle, __entry->blkno)
+);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_get_dentry_test_bit);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_get_dentry_stale);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_get_dentry_generation);
+
+DEFINE_OCFS2_POINTER_EVENT(ocfs2_get_dentry_end);
+
+TRACE_EVENT(ocfs2_get_parent,
+ TP_PROTO(void *child, int len, const char *name,
+ unsigned long long ino),
+ TP_ARGS(child, len, name, ino),
+ TP_STRUCT__entry(
+ __field(void *, child)
+ __field(int, len)
+ __string(name, name)
+ __field(unsigned long long, ino)
+ ),
+ TP_fast_assign(
+ __entry->child = child;
+ __entry->len = len;
+ __assign_str(name, name);
+ __entry->ino = ino;
+ ),
+ TP_printk("%p %.*s %llu", __entry->child, __entry->len,
+ __get_str(name), __entry->ino)
+);
+
+DEFINE_OCFS2_POINTER_EVENT(ocfs2_get_parent_end);
+
+TRACE_EVENT(ocfs2_encode_fh_begin,
+ TP_PROTO(void *dentry, int name_len, const char *name,
+ void *fh, int len, int connectable),
+ TP_ARGS(dentry, name_len, name, fh, len, connectable),
+ TP_STRUCT__entry(
+ __field(void *, dentry)
+ __field(int, name_len)
+ __string(name, name)
+ __field(void *, fh)
+ __field(int, len)
+ __field(int, connectable)
+ ),
+ TP_fast_assign(
+ __entry->dentry = dentry;
+ __entry->name_len = name_len;
+ __assign_str(name, name);
+ __entry->fh = fh;
+ __entry->len = len;
+ __entry->connectable = connectable;
+ ),
+ TP_printk("%p %.*s %p %d %d", __entry->dentry, __entry->name_len,
+ __get_str(name), __entry->fh, __entry->len,
+ __entry->connectable)
+);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_encode_fh_self);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_encode_fh_parent);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_encode_fh_type);
+
+/* End of trace events for fs/ocfs2/export.c. */
+
+/* Trace events for fs/ocfs2/journal.c. */
+
+DEFINE_OCFS2_UINT_EVENT(ocfs2_commit_cache_begin);
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_commit_cache_end);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_extend_trans);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_extend_trans_restart);
+
+DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_journal_access);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_journal_dirty);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_journal_init);
+
+DEFINE_OCFS2_UINT_EVENT(ocfs2_journal_init_maxlen);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_journal_shutdown);
+
+DEFINE_OCFS2_POINTER_EVENT(ocfs2_journal_shutdown_wait);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_complete_recovery);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_complete_recovery_end);
+
+TRACE_EVENT(ocfs2_complete_recovery_slot,
+ TP_PROTO(int slot, unsigned long long la_ino,
+ unsigned long long tl_ino, void *qrec),
+ TP_ARGS(slot, la_ino, tl_ino, qrec),
+ TP_STRUCT__entry(
+ __field(int, slot)
+ __field(unsigned long long, la_ino)
+ __field(unsigned long long, tl_ino)
+ __field(void *, qrec)
+ ),
+ TP_fast_assign(
+ __entry->slot = slot;
+ __entry->la_ino = la_ino;
+ __entry->tl_ino = tl_ino;
+ __entry->qrec = qrec;
+ ),
+ TP_printk("%d %llu %llu %p", __entry->slot, __entry->la_ino,
+ __entry->tl_ino, __entry->qrec)
+);
+
+DEFINE_OCFS2_INT_INT_EVENT(ocfs2_recovery_thread_node);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_recovery_thread_end);
+
+TRACE_EVENT(ocfs2_recovery_thread,
+ TP_PROTO(int node_num, int osb_node_num, int disable,
+ void *recovery_thread, int map_set),
+ TP_ARGS(node_num, osb_node_num, disable, recovery_thread, map_set),
+ TP_STRUCT__entry(
+ __field(int, node_num)
+ __field(int, osb_node_num)
+ __field(int,disable)
+ __field(void *, recovery_thread)
+ __field(int,map_set)
+ ),
+ TP_fast_assign(
+ __entry->node_num = node_num;
+ __entry->osb_node_num = osb_node_num;
+ __entry->disable = disable;
+ __entry->recovery_thread = recovery_thread;
+ __entry->map_set = map_set;
+ ),
+ TP_printk("%d %d %d %p %d", __entry->node_num,
+ __entry->osb_node_num, __entry->disable,
+ __entry->recovery_thread, __entry->map_set)
+);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_replay_journal_recovered);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_replay_journal_lock_err);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_replay_journal_skip);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_recover_node);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_recover_node_skip);
+
+DEFINE_OCFS2_UINT_UINT_EVENT(ocfs2_mark_dead_nodes);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_queue_orphan_scan_begin);
+
+DEFINE_OCFS2_UINT_UINT_UINT_EVENT(ocfs2_queue_orphan_scan_end);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_orphan_filldir);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_recover_orphans);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_recover_orphans_iput);
+
+DEFINE_OCFS2_INT_EVENT(ocfs2_wait_on_mount);
+
+/* End of trace events for fs/ocfs2/journal.c. */
+
+/* Trace events for fs/ocfs2/buffer_head_io.c. */
+
+DEFINE_OCFS2_ULL_UINT_EVENT(ocfs2_read_blocks_sync);
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_read_blocks_sync_jbd);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_read_blocks_from_disk);
+
+DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_read_blocks_bh);
+
+DEFINE_OCFS2_ULL_INT_INT_INT_EVENT(ocfs2_read_blocks_end);
+
+TRACE_EVENT(ocfs2_write_block,
+ TP_PROTO(unsigned long long block, void *ci),
+ TP_ARGS(block, ci),
+ TP_STRUCT__entry(
+ __field(unsigned long long, block)
+ __field(void *, ci)
+ ),
+ TP_fast_assign(
+ __entry->block = block;
+ __entry->ci = ci;
+ ),
+ TP_printk("%llu %p", __entry->block, __entry->ci)
+);
+
+TRACE_EVENT(ocfs2_read_blocks_begin,
+ TP_PROTO(void *ci, unsigned long long block,
+ unsigned int nr, int flags),
+ TP_ARGS(ci, block, nr, flags),
+ TP_STRUCT__entry(
+ __field(void *, ci)
+ __field(unsigned long long, block)
+ __field(unsigned int, nr)
+ __field(int, flags)
+ ),
+ TP_fast_assign(
+ __entry->ci = ci;
+ __entry->block = block;
+ __entry->nr = nr;
+ __entry->flags = flags;
+ ),
+ TP_printk("%p %llu %u %d", __entry->ci, __entry->block,
+ __entry->nr, __entry->flags)
+);
+
+/* End of trace events for fs/ocfs2/buffer_head_io.c. */
+
+/* Trace events for fs/ocfs2/uptodate.c. */
+
+DEFINE_OCFS2_ULL_EVENT(ocfs2_purge_copied_metadata_tree);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_metadata_cache_purge);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_buffer_cached_begin);
+
+TRACE_EVENT(ocfs2_buffer_cached_end,
+ TP_PROTO(int index, void *item),
+ TP_ARGS(index, item),
+ TP_STRUCT__entry(
+ __field(int, index)
+ __field(void *, item)
+ ),
+ TP_fast_assign(
+ __entry->index = index;
+ __entry->item = item;
+ ),
+ TP_printk("%d %p", __entry->index, __entry->item)
+);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_append_cache_array);
+
+DEFINE_OCFS2_ULL_ULL_UINT_EVENT(ocfs2_insert_cache_tree);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_expand_cache);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_set_buffer_uptodate);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_set_buffer_uptodate_begin);
+
+DEFINE_OCFS2_ULL_UINT_UINT_EVENT(ocfs2_remove_metadata_array);
+
+DEFINE_OCFS2_ULL_ULL_EVENT(ocfs2_remove_metadata_tree);
+
+DEFINE_OCFS2_ULL_ULL_UINT_UINT_EVENT(ocfs2_remove_block_from_cache);
+
+/* End of trace events for fs/ocfs2/uptodate.c. */
+#endif /* _TRACE_OCFS2_H */
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#define TRACE_INCLUDE_FILE ocfs2_trace
+#include <trace/define_trace.h>
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index a73f6416648..279aef68025 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -11,7 +11,6 @@
#include <linux/writeback.h>
#include <linux/workqueue.h>
-#define MLOG_MASK_PREFIX ML_QUOTA
#include <cluster/masklog.h>
#include "ocfs2_fs.h"
@@ -27,6 +26,7 @@
#include "super.h"
#include "buffer_head_io.h"
#include "quota.h"
+#include "ocfs2_trace.h"
/*
* Locking of quotas with OCFS2 is rather complex. Here are rules that
@@ -130,8 +130,7 @@ int ocfs2_validate_quota_block(struct super_block *sb, struct buffer_head *bh)
struct ocfs2_disk_dqtrailer *dqt =
ocfs2_block_dqtrailer(sb->s_blocksize, bh->b_data);
- mlog(0, "Validating quota block %llu\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_validate_quota_block((unsigned long long)bh->b_blocknr);
BUG_ON(!buffer_uptodate(bh));
@@ -341,8 +340,6 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
u64 pcount;
int status;
- mlog_entry_void();
-
/* Read global header */
gqinode = ocfs2_get_system_file_inode(OCFS2_SB(sb), ino[type],
OCFS2_INVALID_SLOT);
@@ -402,7 +399,8 @@ int ocfs2_global_read_info(struct super_block *sb, int type)
msecs_to_jiffies(oinfo->dqi_syncms));
out_err:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
out_unlock:
ocfs2_unlock_global_qf(oinfo, 0);
@@ -508,9 +506,10 @@ int __ocfs2_sync_dquot(struct dquot *dquot, int freeing)
olditime = dquot->dq_dqb.dqb_itime;
oldbtime = dquot->dq_dqb.dqb_btime;
ocfs2_global_disk2memdqb(dquot, &dqblk);
- mlog(0, "Syncing global dquot %u space %lld+%lld, inodes %lld+%lld\n",
- dquot->dq_id, dquot->dq_dqb.dqb_curspace, (long long)spacechange,
- dquot->dq_dqb.dqb_curinodes, (long long)inodechange);
+ trace_ocfs2_sync_dquot(dquot->dq_id, dquot->dq_dqb.dqb_curspace,
+ (long long)spacechange,
+ dquot->dq_dqb.dqb_curinodes,
+ (long long)inodechange);
if (!test_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags))
dquot->dq_dqb.dqb_curspace += spacechange;
if (!test_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags))
@@ -594,8 +593,8 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type)
struct ocfs2_super *osb = OCFS2_SB(sb);
int status = 0;
- mlog_entry("id=%u qtype=%u type=%lu device=%s\n", dquot->dq_id,
- dquot->dq_type, type, sb->s_id);
+ trace_ocfs2_sync_dquot_helper(dquot->dq_id, dquot->dq_type,
+ type, sb->s_id);
if (type != dquot->dq_type)
goto out;
status = ocfs2_lock_global_qf(oinfo, 1);
@@ -621,7 +620,6 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type)
out_ilock:
ocfs2_unlock_global_qf(oinfo, 1);
out:
- mlog_exit(status);
return status;
}
@@ -647,7 +645,7 @@ static int ocfs2_write_dquot(struct dquot *dquot)
struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb);
int status = 0;
- mlog_entry("id=%u, type=%d", dquot->dq_id, dquot->dq_type);
+ trace_ocfs2_write_dquot(dquot->dq_id, dquot->dq_type);
handle = ocfs2_start_trans(osb, OCFS2_QWRITE_CREDITS);
if (IS_ERR(handle)) {
@@ -660,7 +658,6 @@ static int ocfs2_write_dquot(struct dquot *dquot)
mutex_unlock(&sb_dqopt(dquot->dq_sb)->dqio_mutex);
ocfs2_commit_trans(osb, handle);
out:
- mlog_exit(status);
return status;
}
@@ -686,7 +683,7 @@ static int ocfs2_release_dquot(struct dquot *dquot)
struct ocfs2_super *osb = OCFS2_SB(dquot->dq_sb);
int status = 0;
- mlog_entry("id=%u, type=%d", dquot->dq_id, dquot->dq_type);
+ trace_ocfs2_release_dquot(dquot->dq_id, dquot->dq_type);
mutex_lock(&dquot->dq_lock);
/* Check whether we are not racing with some other dqget() */
@@ -722,7 +719,8 @@ out_ilock:
ocfs2_unlock_global_qf(oinfo, 1);
out:
mutex_unlock(&dquot->dq_lock);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -743,7 +741,7 @@ static int ocfs2_acquire_dquot(struct dquot *dquot)
int need_alloc = ocfs2_global_qinit_alloc(sb, type);
handle_t *handle;
- mlog_entry("id=%u, type=%d", dquot->dq_id, type);
+ trace_ocfs2_acquire_dquot(dquot->dq_id, type);
mutex_lock(&dquot->dq_lock);
/*
* We need an exclusive lock, because we're going to update use count
@@ -809,7 +807,8 @@ out_dq:
set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
out:
mutex_unlock(&dquot->dq_lock);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -829,7 +828,7 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot)
handle_t *handle;
struct ocfs2_super *osb = OCFS2_SB(sb);
- mlog_entry("id=%u, type=%d", dquot->dq_id, type);
+ trace_ocfs2_mark_dquot_dirty(dquot->dq_id, type);
/* In case user set some limits, sync dquot immediately to global
* quota file so that information propagates quicker */
@@ -866,7 +865,8 @@ out_dlock:
out_ilock:
ocfs2_unlock_global_qf(oinfo, 1);
out:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -877,8 +877,6 @@ static int ocfs2_write_info(struct super_block *sb, int type)
int status = 0;
struct ocfs2_mem_dqinfo *oinfo = sb_dqinfo(sb, type)->dqi_priv;
- mlog_entry_void();
-
status = ocfs2_lock_global_qf(oinfo, 1);
if (status < 0)
goto out;
@@ -893,7 +891,8 @@ static int ocfs2_write_info(struct super_block *sb, int type)
out_ilock:
ocfs2_unlock_global_qf(oinfo, 1);
out:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
diff --git a/fs/ocfs2/quota_local.c b/fs/ocfs2/quota_local.c
index dc78764ccc4..dc8007fc924 100644
--- a/fs/ocfs2/quota_local.c
+++ b/fs/ocfs2/quota_local.c
@@ -8,7 +8,6 @@
#include <linux/quotaops.h>
#include <linux/module.h>
-#define MLOG_MASK_PREFIX ML_QUOTA
#include <cluster/masklog.h>
#include "ocfs2_fs.h"
@@ -23,6 +22,7 @@
#include "quota.h"
#include "uptodate.h"
#include "super.h"
+#include "ocfs2_trace.h"
/* Number of local quota structures per block */
static inline unsigned int ol_quota_entries_per_block(struct super_block *sb)
@@ -475,7 +475,7 @@ static int ocfs2_recover_local_quota_file(struct inode *lqinode,
struct ocfs2_recovery_chunk *rchunk, *next;
qsize_t spacechange, inodechange;
- mlog_entry("ino=%lu type=%u", (unsigned long)lqinode->i_ino, type);
+ trace_ocfs2_recover_local_quota_file((unsigned long)lqinode->i_ino, type);
list_for_each_entry_safe(rchunk, next, &(rec->r_list[type]), rc_list) {
chunk = rchunk->rc_chunk;
@@ -575,7 +575,8 @@ out_put_bh:
}
if (status < 0)
free_recovery_list(&(rec->r_list[type]));
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -600,7 +601,7 @@ int ocfs2_finish_quota_recovery(struct ocfs2_super *osb,
for (type = 0; type < MAXQUOTAS; type++) {
if (list_empty(&(rec->r_list[type])))
continue;
- mlog(0, "Recovering quota in slot %d\n", slot_num);
+ trace_ocfs2_finish_quota_recovery(slot_num);
lqinode = ocfs2_get_system_file_inode(osb, ino[type], slot_num);
if (!lqinode) {
status = -ENOENT;
@@ -882,9 +883,10 @@ static void olq_set_dquot(struct buffer_head *bh, void *private)
dqblk->dqb_inodemod = cpu_to_le64(od->dq_dquot.dq_dqb.dqb_curinodes -
od->dq_originodes);
spin_unlock(&dq_data_lock);
- mlog(0, "Writing local dquot %u space %lld inodes %lld\n",
- od->dq_dquot.dq_id, (long long)le64_to_cpu(dqblk->dqb_spacemod),
- (long long)le64_to_cpu(dqblk->dqb_inodemod));
+ trace_olq_set_dquot(
+ (unsigned long long)le64_to_cpu(dqblk->dqb_spacemod),
+ (unsigned long long)le64_to_cpu(dqblk->dqb_inodemod),
+ od->dq_dquot.dq_id);
}
/* Write dquot to local quota file */
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index c384d634872..5d32749c896 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -16,7 +16,6 @@
*/
#include <linux/sort.h>
-#define MLOG_MASK_PREFIX ML_REFCOUNT
#include <cluster/masklog.h>
#include "ocfs2.h"
#include "inode.h"
@@ -34,6 +33,7 @@
#include "aops.h"
#include "xattr.h"
#include "namei.h"
+#include "ocfs2_trace.h"
#include <linux/bio.h>
#include <linux/blkdev.h>
@@ -84,8 +84,7 @@ static int ocfs2_validate_refcount_block(struct super_block *sb,
struct ocfs2_refcount_block *rb =
(struct ocfs2_refcount_block *)bh->b_data;
- mlog(0, "Validating refcount block %llu\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_validate_refcount_block((unsigned long long)bh->b_blocknr);
BUG_ON(!buffer_uptodate(bh));
@@ -545,8 +544,8 @@ void ocfs2_purge_refcount_trees(struct ocfs2_super *osb)
while ((node = rb_last(root)) != NULL) {
tree = rb_entry(node, struct ocfs2_refcount_tree, rf_node);
- mlog(0, "Purge tree %llu\n",
- (unsigned long long) tree->rf_blkno);
+ trace_ocfs2_purge_refcount_trees(
+ (unsigned long long) tree->rf_blkno);
rb_erase(&tree->rf_node, root);
ocfs2_free_refcount_tree(tree);
@@ -575,7 +574,8 @@ static int ocfs2_create_refcount_tree(struct inode *inode,
BUG_ON(oi->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL);
- mlog(0, "create tree for inode %lu\n", inode->i_ino);
+ trace_ocfs2_create_refcount_tree(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno);
ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
if (ret) {
@@ -646,8 +646,7 @@ static int ocfs2_create_refcount_tree(struct inode *inode,
di->i_refcount_loc = cpu_to_le64(first_blkno);
spin_unlock(&oi->ip_lock);
- mlog(0, "created tree for inode %lu, refblock %llu\n",
- inode->i_ino, (unsigned long long)first_blkno);
+ trace_ocfs2_create_refcount_tree_blkno((unsigned long long)first_blkno);
ocfs2_journal_dirty(handle, di_bh);
@@ -1256,8 +1255,9 @@ static int ocfs2_change_refcount_rec(handle_t *handle,
goto out;
}
- mlog(0, "change index %d, old count %u, change %d\n", index,
- le32_to_cpu(rec->r_refcount), change);
+ trace_ocfs2_change_refcount_rec(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ index, le32_to_cpu(rec->r_refcount), change);
le32_add_cpu(&rec->r_refcount, change);
if (!rec->r_refcount) {
@@ -1353,8 +1353,8 @@ static int ocfs2_expand_inline_ref_root(handle_t *handle,
ocfs2_journal_dirty(handle, ref_root_bh);
- mlog(0, "new leaf block %llu, used %u\n", (unsigned long long)blkno,
- le16_to_cpu(new_rb->rf_records.rl_used));
+ trace_ocfs2_expand_inline_ref_root((unsigned long long)blkno,
+ le16_to_cpu(new_rb->rf_records.rl_used));
*ref_leaf_bh = new_bh;
new_bh = NULL;
@@ -1466,9 +1466,9 @@ static int ocfs2_divide_leaf_refcount_block(struct buffer_head *ref_leaf_bh,
(struct ocfs2_refcount_block *)new_bh->b_data;
struct ocfs2_refcount_list *new_rl = &new_rb->rf_records;
- mlog(0, "split old leaf refcount block %llu, count = %u, used = %u\n",
- (unsigned long long)ref_leaf_bh->b_blocknr,
- le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used));
+ trace_ocfs2_divide_leaf_refcount_block(
+ (unsigned long long)ref_leaf_bh->b_blocknr,
+ le32_to_cpu(rl->rl_count), le32_to_cpu(rl->rl_used));
/*
* XXX: Improvement later.
@@ -1601,8 +1601,8 @@ static int ocfs2_new_leaf_refcount_block(handle_t *handle,
ocfs2_init_refcount_extent_tree(&ref_et, ci, ref_root_bh);
- mlog(0, "insert new leaf block %llu at %u\n",
- (unsigned long long)new_bh->b_blocknr, new_cpos);
+ trace_ocfs2_new_leaf_refcount_block(
+ (unsigned long long)new_bh->b_blocknr, new_cpos);
/* Insert the new leaf block with the specific offset cpos. */
ret = ocfs2_insert_extent(handle, &ref_et, new_cpos, new_bh->b_blocknr,
@@ -1794,11 +1794,10 @@ static int ocfs2_insert_refcount_rec(handle_t *handle,
(le16_to_cpu(rf_list->rl_used) - index) *
sizeof(struct ocfs2_refcount_rec));
- mlog(0, "insert refcount record start %llu, len %u, count %u "
- "to leaf block %llu at index %d\n",
- (unsigned long long)le64_to_cpu(rec->r_cpos),
- le32_to_cpu(rec->r_clusters), le32_to_cpu(rec->r_refcount),
- (unsigned long long)ref_leaf_bh->b_blocknr, index);
+ trace_ocfs2_insert_refcount_rec(
+ (unsigned long long)ref_leaf_bh->b_blocknr, index,
+ (unsigned long long)le64_to_cpu(rec->r_cpos),
+ le32_to_cpu(rec->r_clusters), le32_to_cpu(rec->r_refcount));
rf_list->rl_recs[index] = *rec;
@@ -1850,10 +1849,12 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
BUG_ON(le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL);
- mlog(0, "original r_pos %llu, cluster %u, split %llu, cluster %u\n",
- le64_to_cpu(orig_rec->r_cpos), le32_to_cpu(orig_rec->r_clusters),
- le64_to_cpu(split_rec->r_cpos),
- le32_to_cpu(split_rec->r_clusters));
+ trace_ocfs2_split_refcount_rec(le64_to_cpu(orig_rec->r_cpos),
+ le32_to_cpu(orig_rec->r_clusters),
+ le32_to_cpu(orig_rec->r_refcount),
+ le64_to_cpu(split_rec->r_cpos),
+ le32_to_cpu(split_rec->r_clusters),
+ le32_to_cpu(split_rec->r_refcount));
/*
* If we just need to split the header or tail clusters,
@@ -1967,12 +1968,11 @@ static int ocfs2_split_refcount_rec(handle_t *handle,
if (split_rec->r_refcount) {
rf_list->rl_recs[index] = *split_rec;
- mlog(0, "insert refcount record start %llu, len %u, count %u "
- "to leaf block %llu at index %d\n",
- (unsigned long long)le64_to_cpu(split_rec->r_cpos),
- le32_to_cpu(split_rec->r_clusters),
- le32_to_cpu(split_rec->r_refcount),
- (unsigned long long)ref_leaf_bh->b_blocknr, index);
+ trace_ocfs2_split_refcount_rec_insert(
+ (unsigned long long)ref_leaf_bh->b_blocknr, index,
+ (unsigned long long)le64_to_cpu(split_rec->r_cpos),
+ le32_to_cpu(split_rec->r_clusters),
+ le32_to_cpu(split_rec->r_refcount));
if (merge)
ocfs2_refcount_rec_merge(rb, index);
@@ -1997,7 +1997,7 @@ static int __ocfs2_increase_refcount(handle_t *handle,
struct ocfs2_refcount_rec rec;
unsigned int set_len = 0;
- mlog(0, "Tree owner %llu, add refcount start %llu, len %u\n",
+ trace_ocfs2_increase_refcount_begin(
(unsigned long long)ocfs2_metadata_cache_owner(ci),
(unsigned long long)cpos, len);
@@ -2024,9 +2024,9 @@ static int __ocfs2_increase_refcount(handle_t *handle,
*/
if (rec.r_refcount && le64_to_cpu(rec.r_cpos) == cpos &&
set_len <= len) {
- mlog(0, "increase refcount rec, start %llu, len %u, "
- "count %u\n", (unsigned long long)cpos, set_len,
- le32_to_cpu(rec.r_refcount));
+ trace_ocfs2_increase_refcount_change(
+ (unsigned long long)cpos, set_len,
+ le32_to_cpu(rec.r_refcount));
ret = ocfs2_change_refcount_rec(handle, ci,
ref_leaf_bh, index,
merge, 1);
@@ -2037,7 +2037,7 @@ static int __ocfs2_increase_refcount(handle_t *handle,
} else if (!rec.r_refcount) {
rec.r_refcount = cpu_to_le32(1);
- mlog(0, "insert refcount rec, start %llu, len %u\n",
+ trace_ocfs2_increase_refcount_insert(
(unsigned long long)le64_to_cpu(rec.r_cpos),
set_len);
ret = ocfs2_insert_refcount_rec(handle, ci, ref_root_bh,
@@ -2055,8 +2055,7 @@ static int __ocfs2_increase_refcount(handle_t *handle,
rec.r_clusters = cpu_to_le32(set_len);
le32_add_cpu(&rec.r_refcount, 1);
- mlog(0, "split refcount rec, start %llu, "
- "len %u, count %u\n",
+ trace_ocfs2_increase_refcount_split(
(unsigned long long)le64_to_cpu(rec.r_cpos),
set_len, le32_to_cpu(rec.r_refcount));
ret = ocfs2_split_refcount_rec(handle, ci,
@@ -2095,6 +2094,11 @@ static int ocfs2_remove_refcount_extent(handle_t *handle,
BUG_ON(rb->rf_records.rl_used);
+ trace_ocfs2_remove_refcount_extent(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)ref_leaf_bh->b_blocknr,
+ le32_to_cpu(rb->rf_cpos));
+
ocfs2_init_refcount_extent_tree(&et, ci, ref_root_bh);
ret = ocfs2_remove_extent(handle, &et, le32_to_cpu(rb->rf_cpos),
1, meta_ac, dealloc);
@@ -2137,7 +2141,7 @@ static int ocfs2_remove_refcount_extent(handle_t *handle,
if (!rb->rf_list.l_next_free_rec) {
BUG_ON(rb->rf_clusters);
- mlog(0, "reset refcount tree root %llu to be a record block.\n",
+ trace_ocfs2_restore_refcount_block(
(unsigned long long)ref_root_bh->b_blocknr);
rb->rf_flags = 0;
@@ -2184,6 +2188,10 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle,
BUG_ON(cpos + len >
le64_to_cpu(rec->r_cpos) + le32_to_cpu(rec->r_clusters));
+ trace_ocfs2_decrease_refcount_rec(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)cpos, len);
+
if (cpos == le64_to_cpu(rec->r_cpos) &&
len == le32_to_cpu(rec->r_clusters))
ret = ocfs2_change_refcount_rec(handle, ci,
@@ -2195,12 +2203,6 @@ static int ocfs2_decrease_refcount_rec(handle_t *handle,
le32_add_cpu(&split.r_refcount, -1);
- mlog(0, "split refcount rec, start %llu, "
- "len %u, count %u, original start %llu, len %u\n",
- (unsigned long long)le64_to_cpu(split.r_cpos),
- len, le32_to_cpu(split.r_refcount),
- (unsigned long long)le64_to_cpu(rec->r_cpos),
- le32_to_cpu(rec->r_clusters));
ret = ocfs2_split_refcount_rec(handle, ci,
ref_root_bh, ref_leaf_bh,
&split, index, 1,
@@ -2239,10 +2241,9 @@ static int __ocfs2_decrease_refcount(handle_t *handle,
struct super_block *sb = ocfs2_metadata_cache_get_super(ci);
struct buffer_head *ref_leaf_bh = NULL;
- mlog(0, "Tree owner %llu, decrease refcount start %llu, "
- "len %u, delete %u\n",
- (unsigned long long)ocfs2_metadata_cache_owner(ci),
- (unsigned long long)cpos, len, delete);
+ trace_ocfs2_decrease_refcount(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)cpos, len, delete);
while (len) {
ret = ocfs2_get_refcount_rec(ci, ref_root_bh,
@@ -2352,8 +2353,8 @@ static int ocfs2_mark_extent_refcounted(struct inode *inode,
{
int ret;
- mlog(0, "Inode %lu refcount tree cpos %u, len %u, phys cluster %u\n",
- inode->i_ino, cpos, len, phys);
+ trace_ocfs2_mark_extent_refcounted(OCFS2_I(inode)->ip_blkno,
+ cpos, len, phys);
if (!ocfs2_refcount_tree(OCFS2_SB(inode->i_sb))) {
ocfs2_error(inode->i_sb, "Inode %lu want to use refcount "
@@ -2392,8 +2393,6 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
struct buffer_head *ref_leaf_bh = NULL, *prev_bh = NULL;
u32 len;
- mlog(0, "start_cpos %llu, clusters %u\n",
- (unsigned long long)start_cpos, clusters);
while (clusters) {
ret = ocfs2_get_refcount_rec(ci, ref_root_bh,
cpos, clusters, &rec,
@@ -2427,12 +2426,11 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
rb = (struct ocfs2_refcount_block *)ref_leaf_bh->b_data;
- mlog(0, "recs_add %d,cpos %llu, clusters %u, rec->r_cpos %llu,"
- "rec->r_clusters %u, rec->r_refcount %u, index %d\n",
- recs_add, (unsigned long long)cpos, clusters,
- (unsigned long long)le64_to_cpu(rec.r_cpos),
- le32_to_cpu(rec.r_clusters),
- le32_to_cpu(rec.r_refcount), index);
+ trace_ocfs2_calc_refcount_meta_credits_iterate(
+ recs_add, (unsigned long long)cpos, clusters,
+ (unsigned long long)le64_to_cpu(rec.r_cpos),
+ le32_to_cpu(rec.r_clusters),
+ le32_to_cpu(rec.r_refcount), index);
len = min((u64)cpos + clusters, le64_to_cpu(rec.r_cpos) +
le32_to_cpu(rec.r_clusters)) - cpos;
@@ -2488,7 +2486,6 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
if (!ref_blocks)
goto out;
- mlog(0, "we need ref_blocks %d\n", ref_blocks);
*meta_add += ref_blocks;
*credits += ref_blocks;
@@ -2514,6 +2511,10 @@ static int ocfs2_calc_refcount_meta_credits(struct super_block *sb,
}
out:
+
+ trace_ocfs2_calc_refcount_meta_credits(
+ (unsigned long long)start_cpos, clusters,
+ *meta_add, *credits);
brelse(ref_leaf_bh);
brelse(prev_bh);
return ret;
@@ -2578,8 +2579,7 @@ int ocfs2_prepare_refcount_change_for_del(struct inode *inode,
goto out;
}
- mlog(0, "reserve new metadata %d blocks, credits = %d\n",
- *ref_blocks, *credits);
+ trace_ocfs2_prepare_refcount_change_for_del(*ref_blocks, *credits);
out:
brelse(ref_root_bh);
@@ -2886,8 +2886,7 @@ static int ocfs2_lock_refcount_allocators(struct super_block *sb,
goto out;
}
- mlog(0, "reserve new metadata %d, clusters %u, credits = %d\n",
- meta_add, num_clusters, *credits);
+ trace_ocfs2_lock_refcount_allocators(meta_add, *credits);
ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(sb), meta_add,
meta_ac);
if (ret) {
@@ -2937,8 +2936,8 @@ static int ocfs2_duplicate_clusters_by_page(handle_t *handle,
loff_t offset, end, map_end;
struct address_space *mapping = context->inode->i_mapping;
- mlog(0, "old_cluster %u, new %u, len %u at offset %u\n", old_cluster,
- new_cluster, new_len, cpos);
+ trace_ocfs2_duplicate_clusters_by_page(cpos, old_cluster,
+ new_cluster, new_len);
readahead_pages =
(ocfs2_cow_contig_clusters(sb) <<
@@ -3031,8 +3030,8 @@ static int ocfs2_duplicate_clusters_by_jbd(handle_t *handle,
struct buffer_head *old_bh = NULL;
struct buffer_head *new_bh = NULL;
- mlog(0, "old_cluster %u, new %u, len %u\n", old_cluster,
- new_cluster, new_len);
+ trace_ocfs2_duplicate_clusters_by_page(cpos, old_cluster,
+ new_cluster, new_len);
for (i = 0; i < blocks; i++, old_block++, new_block++) {
new_bh = sb_getblk(osb->sb, new_block);
@@ -3085,8 +3084,8 @@ static int ocfs2_clear_ext_refcount(handle_t *handle,
struct super_block *sb = ocfs2_metadata_cache_get_super(et->et_ci);
u64 ino = ocfs2_metadata_cache_owner(et->et_ci);
- mlog(0, "inode %llu cpos %u, len %u, p_cluster %u, ext_flags %u\n",
- (unsigned long long)ino, cpos, len, p_cluster, ext_flags);
+ trace_ocfs2_clear_ext_refcount((unsigned long long)ino,
+ cpos, len, p_cluster, ext_flags);
memset(&replace_rec, 0, sizeof(replace_rec));
replace_rec.e_cpos = cpu_to_le32(cpos);
@@ -3141,8 +3140,8 @@ static int ocfs2_replace_clusters(handle_t *handle,
struct ocfs2_caching_info *ci = context->data_et.et_ci;
u64 ino = ocfs2_metadata_cache_owner(ci);
- mlog(0, "inode %llu, cpos %u, old %u, new %u, len %u, ext_flags %u\n",
- (unsigned long long)ino, cpos, old, new, len, ext_flags);
+ trace_ocfs2_replace_clusters((unsigned long long)ino,
+ cpos, old, new, len, ext_flags);
/*If the old clusters is unwritten, no need to duplicate. */
if (!(ext_flags & OCFS2_EXT_UNWRITTEN)) {
@@ -3236,8 +3235,8 @@ static int ocfs2_make_clusters_writable(struct super_block *sb,
struct ocfs2_caching_info *ref_ci = &context->ref_tree->rf_ci;
struct ocfs2_refcount_rec rec;
- mlog(0, "cpos %u, p_cluster %u, num_clusters %u, e_flags %u\n",
- cpos, p_cluster, num_clusters, e_flags);
+ trace_ocfs2_make_clusters_writable(cpos, p_cluster,
+ num_clusters, e_flags);
ret = ocfs2_lock_refcount_allocators(sb, p_cluster, num_clusters,
&context->data_et,
@@ -3475,9 +3474,9 @@ static int ocfs2_refcount_cow_hunk(struct inode *inode,
goto out;
}
- mlog(0, "CoW inode %lu, cpos %u, write_len %u, cow_start %u, "
- "cow_len %u\n", inode->i_ino,
- cpos, write_len, cow_start, cow_len);
+ trace_ocfs2_refcount_cow_hunk(OCFS2_I(inode)->ip_blkno,
+ cpos, write_len, max_cpos,
+ cow_start, cow_len);
BUG_ON(cow_len == 0);
@@ -3756,8 +3755,7 @@ int ocfs2_add_refcount_flag(struct inode *inode,
goto out;
}
- mlog(0, "reserve new metadata %d, credits = %d\n",
- ref_blocks, credits);
+ trace_ocfs2_add_refcount_flag(ref_blocks, credits);
if (ref_blocks) {
ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(inode->i_sb),
diff --git a/fs/ocfs2/reservations.c b/fs/ocfs2/reservations.c
index 3e78db361bc..41ffd36c689 100644
--- a/fs/ocfs2/reservations.c
+++ b/fs/ocfs2/reservations.c
@@ -30,10 +30,10 @@
#include <linux/bitops.h>
#include <linux/list.h>
-#define MLOG_MASK_PREFIX ML_RESERVATIONS
#include <cluster/masklog.h>
#include "ocfs2.h"
+#include "ocfs2_trace.h"
#ifdef CONFIG_OCFS2_DEBUG_FS
#define OCFS2_CHECK_RESERVATIONS
@@ -321,8 +321,7 @@ static void ocfs2_resv_insert(struct ocfs2_reservation_map *resmap,
assert_spin_locked(&resv_lock);
- mlog(0, "Insert reservation start: %u len: %u\n", new->r_start,
- new->r_len);
+ trace_ocfs2_resv_insert(new->r_start, new->r_len);
while (*p) {
parent = *p;
@@ -423,8 +422,8 @@ static int ocfs2_resmap_find_free_bits(struct ocfs2_reservation_map *resmap,
unsigned int best_start, best_len = 0;
int offset, start, found;
- mlog(0, "Find %u bits within range (%u, len %u) resmap len: %u\n",
- wanted, search_start, search_len, resmap->m_bitmap_len);
+ trace_ocfs2_resmap_find_free_bits_begin(search_start, search_len,
+ wanted, resmap->m_bitmap_len);
found = best_start = best_len = 0;
@@ -463,7 +462,7 @@ static int ocfs2_resmap_find_free_bits(struct ocfs2_reservation_map *resmap,
*rlen = best_len;
*rstart = best_start;
- mlog(0, "Found start: %u len: %u\n", best_start, best_len);
+ trace_ocfs2_resmap_find_free_bits_end(best_start, best_len);
return *rlen;
}
@@ -487,9 +486,8 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap,
* - our window should be last in all reservations
* - need to make sure we don't go past end of bitmap
*/
-
- mlog(0, "resv start: %u resv end: %u goal: %u wanted: %u\n",
- resv->r_start, ocfs2_resv_end(resv), goal, wanted);
+ trace_ocfs2_resv_find_window_begin(resv->r_start, ocfs2_resv_end(resv),
+ goal, wanted, RB_EMPTY_ROOT(root));
assert_spin_locked(&resv_lock);
@@ -498,9 +496,6 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap,
* Easiest case - empty tree. We can just take
* whatever window of free bits we want.
*/
-
- mlog(0, "Empty root\n");
-
clen = ocfs2_resmap_find_free_bits(resmap, wanted, goal,
resmap->m_bitmap_len - goal,
&cstart, &clen);
@@ -524,8 +519,6 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap,
prev_resv = ocfs2_find_resv_lhs(resmap, goal);
if (prev_resv == NULL) {
- mlog(0, "Goal on LHS of leftmost window\n");
-
/*
* A NULL here means that the search code couldn't
* find a window that starts before goal.
@@ -570,13 +563,15 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap,
next_resv = NULL;
}
+ trace_ocfs2_resv_find_window_prev(prev_resv->r_start,
+ ocfs2_resv_end(prev_resv));
+
prev = &prev_resv->r_node;
/* Now we do a linear search for a window, starting at 'prev_rsv' */
while (1) {
next = rb_next(prev);
if (next) {
- mlog(0, "One more resv found in linear search\n");
next_resv = rb_entry(next,
struct ocfs2_alloc_reservation,
r_node);
@@ -585,7 +580,6 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap,
gap_end = next_resv->r_start - 1;
gap_len = gap_end - gap_start + 1;
} else {
- mlog(0, "No next node\n");
/*
* We're at the rightmost edge of the
* tree. See if a reservation between this
@@ -596,6 +590,8 @@ static void __ocfs2_resv_find_window(struct ocfs2_reservation_map *resmap,
gap_end = resmap->m_bitmap_len - 1;
}
+ trace_ocfs2_resv_find_window_next(next ? next_resv->r_start: -1,
+ next ? ocfs2_resv_end(next_resv) : -1);
/*
* No need to check this gap if we have already found
* a larger region of free bits.
@@ -654,8 +650,9 @@ static void ocfs2_cannibalize_resv(struct ocfs2_reservation_map *resmap,
lru_resv = list_first_entry(&resmap->m_lru,
struct ocfs2_alloc_reservation, r_lru);
- mlog(0, "lru resv: start: %u len: %u end: %u\n", lru_resv->r_start,
- lru_resv->r_len, ocfs2_resv_end(lru_resv));
+ trace_ocfs2_cannibalize_resv_begin(lru_resv->r_start,
+ lru_resv->r_len,
+ ocfs2_resv_end(lru_resv));
/*
* Cannibalize (some or all) of the target reservation and
@@ -684,10 +681,9 @@ static void ocfs2_cannibalize_resv(struct ocfs2_reservation_map *resmap,
resv->r_len = shrink;
}
- mlog(0, "Reservation now looks like: r_start: %u r_end: %u "
- "r_len: %u r_last_start: %u r_last_len: %u\n",
- resv->r_start, ocfs2_resv_end(resv), resv->r_len,
- resv->r_last_start, resv->r_last_len);
+ trace_ocfs2_cannibalize_resv_end(resv->r_start, ocfs2_resv_end(resv),
+ resv->r_len, resv->r_last_start,
+ resv->r_last_len);
ocfs2_resv_insert(resmap, resv);
}
@@ -748,7 +744,6 @@ int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap,
if ((resv->r_flags & OCFS2_RESV_FLAG_TMP) || wanted < *clen)
wanted = *clen;
- mlog(0, "empty reservation, find new window\n");
/*
* Try to get a window here. If it works, we must fall
* through and test the bitmap . This avoids some
@@ -757,6 +752,7 @@ int ocfs2_resmap_resv_bits(struct ocfs2_reservation_map *resmap,
* that inode.
*/
ocfs2_resv_find_window(resmap, resv, wanted);
+ trace_ocfs2_resmap_resv_bits(resv->r_start, resv->r_len);
}
BUG_ON(ocfs2_resv_empty(resv));
@@ -813,10 +809,10 @@ void ocfs2_resmap_claimed_bits(struct ocfs2_reservation_map *resmap,
spin_lock(&resv_lock);
- mlog(0, "claim bits: cstart: %u cend: %u clen: %u r_start: %u "
- "r_end: %u r_len: %u, r_last_start: %u r_last_len: %u\n",
- cstart, cend, clen, resv->r_start, ocfs2_resv_end(resv),
- resv->r_len, resv->r_last_start, resv->r_last_len);
+ trace_ocfs2_resmap_claimed_bits_begin(cstart, cend, clen, resv->r_start,
+ ocfs2_resv_end(resv), resv->r_len,
+ resv->r_last_start,
+ resv->r_last_len);
BUG_ON(cstart < resv->r_start);
BUG_ON(cstart > ocfs2_resv_end(resv));
@@ -833,10 +829,9 @@ void ocfs2_resmap_claimed_bits(struct ocfs2_reservation_map *resmap,
if (!ocfs2_resv_empty(resv))
ocfs2_resv_mark_lru(resmap, resv);
- mlog(0, "Reservation now looks like: r_start: %u r_end: %u "
- "r_len: %u r_last_start: %u r_last_len: %u\n",
- resv->r_start, ocfs2_resv_end(resv), resv->r_len,
- resv->r_last_start, resv->r_last_len);
+ trace_ocfs2_resmap_claimed_bits_end(resv->r_start, ocfs2_resv_end(resv),
+ resv->r_len, resv->r_last_start,
+ resv->r_last_len);
ocfs2_check_resmap(resmap);
diff --git a/fs/ocfs2/resize.c b/fs/ocfs2/resize.c
index dacd553d861..ec55add7604 100644
--- a/fs/ocfs2/resize.c
+++ b/fs/ocfs2/resize.c
@@ -27,7 +27,6 @@
#include <linux/fs.h>
#include <linux/types.h>
-#define MLOG_MASK_PREFIX ML_DISK_ALLOC
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -39,6 +38,7 @@
#include "super.h"
#include "sysfile.h"
#include "uptodate.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
#include "suballoc.h"
@@ -82,7 +82,6 @@ static u16 ocfs2_calc_new_backup_super(struct inode *inode,
backups++;
}
- mlog_exit_void();
return backups;
}
@@ -103,8 +102,8 @@ static int ocfs2_update_last_group_and_inode(handle_t *handle,
u16 cl_bpc = le16_to_cpu(cl->cl_bpc);
u16 cl_cpg = le16_to_cpu(cl->cl_cpg);
- mlog_entry("(new_clusters=%d, first_new_cluster = %u)\n",
- new_clusters, first_new_cluster);
+ trace_ocfs2_update_last_group_and_inode(new_clusters,
+ first_new_cluster);
ret = ocfs2_journal_access_gd(handle, INODE_CACHE(bm_inode),
group_bh, OCFS2_JOURNAL_ACCESS_WRITE);
@@ -176,7 +175,8 @@ out_rollback:
le16_add_cpu(&group->bg_free_bits_count, -1 * num_bits);
}
out:
- mlog_exit(ret);
+ if (ret)
+ mlog_errno(ret);
return ret;
}
@@ -281,8 +281,6 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters)
u32 first_new_cluster;
u64 lgd_blkno;
- mlog_entry_void();
-
if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
return -EROFS;
@@ -342,7 +340,8 @@ int ocfs2_group_extend(struct inode * inode, int new_clusters)
goto out_unlock;
}
- mlog(0, "extend the last group at %llu, new clusters = %d\n",
+
+ trace_ocfs2_group_extend(
(unsigned long long)le64_to_cpu(group->bg_blkno), new_clusters);
handle = ocfs2_start_trans(osb, OCFS2_GROUP_EXTEND_CREDITS);
@@ -377,7 +376,6 @@ out_mutex:
iput(main_bm_inode);
out:
- mlog_exit_void();
return ret;
}
@@ -472,8 +470,6 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
struct ocfs2_chain_rec *cr;
u16 cl_bpc;
- mlog_entry_void();
-
if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
return -EROFS;
@@ -520,8 +516,8 @@ int ocfs2_group_add(struct inode *inode, struct ocfs2_new_group_input *input)
goto out_unlock;
}
- mlog(0, "Add a new group %llu in chain = %u, length = %u\n",
- (unsigned long long)input->group, input->chain, input->clusters);
+ trace_ocfs2_group_add((unsigned long long)input->group,
+ input->chain, input->clusters, input->frees);
handle = ocfs2_start_trans(osb, OCFS2_GROUP_ADD_CREDITS);
if (IS_ERR(handle)) {
@@ -589,6 +585,5 @@ out_mutex:
iput(main_bm_inode);
out:
- mlog_exit_void();
return ret;
}
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
index ab4e0172cc1..26fc0014d50 100644
--- a/fs/ocfs2/slot_map.c
+++ b/fs/ocfs2/slot_map.c
@@ -27,7 +27,6 @@
#include <linux/slab.h>
#include <linux/highmem.h>
-#define MLOG_MASK_PREFIX ML_SUPER
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -39,6 +38,7 @@
#include "slot_map.h"
#include "super.h"
#include "sysfile.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -142,8 +142,7 @@ int ocfs2_refresh_slot_info(struct ocfs2_super *osb)
BUG_ON(si->si_blocks == 0);
BUG_ON(si->si_bh == NULL);
- mlog(0, "Refreshing slot map, reading %u block(s)\n",
- si->si_blocks);
+ trace_ocfs2_refresh_slot_info(si->si_blocks);
/*
* We pass -1 as blocknr because we expect all of si->si_bh to
@@ -381,8 +380,7 @@ static int ocfs2_map_slot_buffers(struct ocfs2_super *osb,
/* The size checks above should ensure this */
BUG_ON((osb->max_slots / si->si_slots_per_block) > blocks);
- mlog(0, "Slot map needs %u buffers for %llu bytes\n",
- si->si_blocks, bytes);
+ trace_ocfs2_map_slot_buffers(bytes, si->si_blocks);
si->si_bh = kzalloc(sizeof(struct buffer_head *) * si->si_blocks,
GFP_KERNEL);
@@ -400,8 +398,7 @@ static int ocfs2_map_slot_buffers(struct ocfs2_super *osb,
goto bail;
}
- mlog(0, "Reading slot map block %u at %llu\n", i,
- (unsigned long long)blkno);
+ trace_ocfs2_map_slot_buffers_block((unsigned long long)blkno, i);
bh = NULL; /* Acquire a fresh bh */
status = ocfs2_read_blocks(INODE_CACHE(si->si_inode), blkno,
@@ -475,8 +472,6 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
int slot;
struct ocfs2_slot_info *si;
- mlog_entry_void();
-
si = osb->slot_info;
spin_lock(&osb->osb_lock);
@@ -505,14 +500,13 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
osb->slot_num = slot;
spin_unlock(&osb->osb_lock);
- mlog(0, "taking node slot %d\n", osb->slot_num);
+ trace_ocfs2_find_slot(osb->slot_num);
status = ocfs2_update_disk_slot(osb, si, osb->slot_num);
if (status < 0)
mlog_errno(status);
bail:
- mlog_exit(status);
return status;
}
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 71998d4d61d..ab6e2061074 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -29,7 +29,6 @@
#include <linux/slab.h>
#include <linux/highmem.h>
-#define MLOG_MASK_PREFIX ML_DISK_ALLOC
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -44,6 +43,7 @@
#include "super.h"
#include "sysfile.h"
#include "uptodate.h"
+#include "ocfs2_trace.h"
#include "buffer_head_io.h"
@@ -308,8 +308,8 @@ static int ocfs2_validate_group_descriptor(struct super_block *sb,
int rc;
struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
- mlog(0, "Validating group descriptor %llu\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_validate_group_descriptor(
+ (unsigned long long)bh->b_blocknr);
BUG_ON(!buffer_uptodate(bh));
@@ -389,8 +389,6 @@ static int ocfs2_block_group_fill(handle_t *handle,
struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;
struct super_block * sb = alloc_inode->i_sb;
- mlog_entry_void();
-
if (((unsigned long long) bg_bh->b_blocknr) != group_blkno) {
ocfs2_error(alloc_inode->i_sb, "group block (%llu) != "
"b_blocknr (%llu)",
@@ -436,7 +434,8 @@ static int ocfs2_block_group_fill(handle_t *handle,
* allocation time. */
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -477,8 +476,8 @@ ocfs2_block_group_alloc_contig(struct ocfs2_super *osb, handle_t *handle,
/* setup the group */
bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off);
- mlog(0, "new descriptor, record %u, at block %llu\n",
- alloc_rec, (unsigned long long)bg_blkno);
+ trace_ocfs2_block_group_alloc_contig(
+ (unsigned long long)bg_blkno, alloc_rec);
bg_bh = sb_getblk(osb->sb, bg_blkno);
if (!bg_bh) {
@@ -657,8 +656,8 @@ ocfs2_block_group_alloc_discontig(handle_t *handle,
/* setup the group */
bg_blkno = ocfs2_clusters_to_blocks(osb->sb, bit_off);
- mlog(0, "new descriptor, record %u, at block %llu\n",
- alloc_rec, (unsigned long long)bg_blkno);
+ trace_ocfs2_block_group_alloc_discontig(
+ (unsigned long long)bg_blkno, alloc_rec);
bg_bh = sb_getblk(osb->sb, bg_blkno);
if (!bg_bh) {
@@ -707,8 +706,6 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
BUG_ON(ocfs2_is_cluster_bitmap(alloc_inode));
- mlog_entry_void();
-
cl = &fe->id2.i_chain;
status = ocfs2_reserve_clusters_with_limit(osb,
le16_to_cpu(cl->cl_cpg),
@@ -730,8 +727,8 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
}
if (last_alloc_group && *last_alloc_group != 0) {
- mlog(0, "use old allocation group %llu for block group alloc\n",
- (unsigned long long)*last_alloc_group);
+ trace_ocfs2_block_group_alloc(
+ (unsigned long long)*last_alloc_group);
ac->ac_last_group = *last_alloc_group;
}
@@ -796,7 +793,8 @@ bail:
brelse(bg_bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -814,8 +812,6 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
struct ocfs2_dinode *fe;
u32 free_bits;
- mlog_entry_void();
-
alloc_inode = ocfs2_get_system_file_inode(osb, type, slot);
if (!alloc_inode) {
mlog_errno(-EINVAL);
@@ -855,16 +851,15 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
if (bits_wanted > free_bits) {
/* cluster bitmap never grows */
if (ocfs2_is_cluster_bitmap(alloc_inode)) {
- mlog(0, "Disk Full: wanted=%u, free_bits=%u\n",
- bits_wanted, free_bits);
+ trace_ocfs2_reserve_suballoc_bits_nospc(bits_wanted,
+ free_bits);
status = -ENOSPC;
goto bail;
}
if (!(flags & ALLOC_NEW_GROUP)) {
- mlog(0, "Alloc File %u Full: wanted=%u, free_bits=%u, "
- "and we don't alloc a new group for it.\n",
- slot, bits_wanted, free_bits);
+ trace_ocfs2_reserve_suballoc_bits_no_new_group(
+ slot, bits_wanted, free_bits);
status = -ENOSPC;
goto bail;
}
@@ -890,7 +885,8 @@ static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
bail:
brelse(bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1052,7 +1048,8 @@ bail:
*ac = NULL;
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1119,8 +1116,8 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
spin_lock(&osb->osb_lock);
osb->osb_inode_alloc_group = alloc_group;
spin_unlock(&osb->osb_lock);
- mlog(0, "after reservation, new allocation group is "
- "%llu\n", (unsigned long long)alloc_group);
+ trace_ocfs2_reserve_new_inode_new_group(
+ (unsigned long long)alloc_group);
/*
* Some inodes must be freed by us, so try to allocate
@@ -1152,7 +1149,8 @@ bail:
*ac = NULL;
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1189,8 +1187,6 @@ static int ocfs2_reserve_clusters_with_limit(struct ocfs2_super *osb,
{
int status;
- mlog_entry_void();
-
*ac = kzalloc(sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
if (!(*ac)) {
status = -ENOMEM;
@@ -1229,7 +1225,8 @@ bail:
*ac = NULL;
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1357,15 +1354,12 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle,
void *bitmap = bg->bg_bitmap;
int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;
- mlog_entry_void();
-
/* All callers get the descriptor via
* ocfs2_read_group_descriptor(). Any corruption is a code bug. */
BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg));
BUG_ON(le16_to_cpu(bg->bg_free_bits_count) < num_bits);
- mlog(0, "block_group_set_bits: off = %u, num = %u\n", bit_off,
- num_bits);
+ trace_ocfs2_block_group_set_bits(bit_off, num_bits);
if (ocfs2_is_cluster_bitmap(alloc_inode))
journal_type = OCFS2_JOURNAL_ACCESS_UNDO;
@@ -1394,7 +1388,8 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle,
ocfs2_journal_dirty(handle, group_bh);
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1437,10 +1432,10 @@ static int ocfs2_relink_block_group(handle_t *handle,
BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg));
BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(prev_bg));
- mlog(0, "Suballoc %llu, chain %u, move group %llu to top, prev = %llu\n",
- (unsigned long long)le64_to_cpu(fe->i_blkno), chain,
- (unsigned long long)le64_to_cpu(bg->bg_blkno),
- (unsigned long long)le64_to_cpu(prev_bg->bg_blkno));
+ trace_ocfs2_relink_block_group(
+ (unsigned long long)le64_to_cpu(fe->i_blkno), chain,
+ (unsigned long long)le64_to_cpu(bg->bg_blkno),
+ (unsigned long long)le64_to_cpu(prev_bg->bg_blkno));
fe_ptr = le64_to_cpu(fe->id2.i_chain.cl_recs[chain].c_blkno);
bg_ptr = le64_to_cpu(bg->bg_next_group);
@@ -1484,7 +1479,8 @@ out_rollback:
prev_bg->bg_next_group = cpu_to_le64(prev_bg_ptr);
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1525,10 +1521,10 @@ static int ocfs2_cluster_group_search(struct inode *inode,
if ((gd_cluster_off + max_bits) >
OCFS2_I(inode)->ip_clusters) {
max_bits = OCFS2_I(inode)->ip_clusters - gd_cluster_off;
- mlog(0, "Desc %llu, bg_bits %u, clusters %u, use %u\n",
- (unsigned long long)le64_to_cpu(gd->bg_blkno),
- le16_to_cpu(gd->bg_bits),
- OCFS2_I(inode)->ip_clusters, max_bits);
+ trace_ocfs2_cluster_group_search_wrong_max_bits(
+ (unsigned long long)le64_to_cpu(gd->bg_blkno),
+ le16_to_cpu(gd->bg_bits),
+ OCFS2_I(inode)->ip_clusters, max_bits);
}
ret = ocfs2_block_group_find_clear_bits(OCFS2_SB(inode->i_sb),
@@ -1542,9 +1538,9 @@ static int ocfs2_cluster_group_search(struct inode *inode,
gd_cluster_off +
res->sr_bit_offset +
res->sr_bits);
- mlog(0, "Checking %llu against %llu\n",
- (unsigned long long)blkoff,
- (unsigned long long)max_block);
+ trace_ocfs2_cluster_group_search_max_block(
+ (unsigned long long)blkoff,
+ (unsigned long long)max_block);
if (blkoff > max_block)
return -ENOSPC;
}
@@ -1588,9 +1584,9 @@ static int ocfs2_block_group_search(struct inode *inode,
if (!ret && max_block) {
blkoff = le64_to_cpu(bg->bg_blkno) +
res->sr_bit_offset + res->sr_bits;
- mlog(0, "Checking %llu against %llu\n",
- (unsigned long long)blkoff,
- (unsigned long long)max_block);
+ trace_ocfs2_block_group_search_max_block(
+ (unsigned long long)blkoff,
+ (unsigned long long)max_block);
if (blkoff > max_block)
ret = -ENOSPC;
}
@@ -1756,9 +1752,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
struct ocfs2_group_desc *bg;
chain = ac->ac_chain;
- mlog(0, "trying to alloc %u bits from chain %u, inode %llu\n",
- bits_wanted, chain,
- (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno);
+ trace_ocfs2_search_chain_begin(
+ (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno,
+ bits_wanted, chain);
status = ocfs2_read_group_descriptor(alloc_inode, fe,
le64_to_cpu(cl->cl_recs[chain].c_blkno),
@@ -1799,8 +1795,8 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
goto bail;
}
- mlog(0, "alloc succeeds: we give %u bits from block group %llu\n",
- res->sr_bits, (unsigned long long)le64_to_cpu(bg->bg_blkno));
+ trace_ocfs2_search_chain_succ(
+ (unsigned long long)le64_to_cpu(bg->bg_blkno), res->sr_bits);
res->sr_bg_blkno = le64_to_cpu(bg->bg_blkno);
@@ -1861,8 +1857,9 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
goto bail;
}
- mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits,
- (unsigned long long)le64_to_cpu(fe->i_blkno));
+ trace_ocfs2_search_chain_end(
+ (unsigned long long)le64_to_cpu(fe->i_blkno),
+ res->sr_bits);
out_loc_only:
*bits_left = le16_to_cpu(bg->bg_free_bits_count);
@@ -1870,7 +1867,8 @@ bail:
brelse(group_bh);
brelse(prev_group_bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1888,8 +1886,6 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac,
struct ocfs2_chain_list *cl;
struct ocfs2_dinode *fe;
- mlog_entry_void();
-
BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted);
BUG_ON(bits_wanted > (ac->ac_bits_wanted - ac->ac_bits_given));
BUG_ON(!ac->ac_bh);
@@ -1945,8 +1941,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac,
goto bail;
}
- mlog(0, "Search of victim chain %u came up with nothing, "
- "trying all chains now.\n", victim);
+ trace_ocfs2_claim_suballoc_bits(victim);
/* If we didn't pick a good victim, then just default to
* searching each chain in order. Don't allow chain relinking
@@ -1984,7 +1979,8 @@ set_hint:
}
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2021,7 +2017,8 @@ int ocfs2_claim_metadata(handle_t *handle,
*num_bits = res.sr_bits;
status = 0;
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2172,8 +2169,8 @@ int ocfs2_claim_new_inode_at_loc(handle_t *handle,
goto out;
}
- mlog(0, "Allocated %u bits from suballocator %llu\n", res->sr_bits,
- (unsigned long long)di_blkno);
+ trace_ocfs2_claim_new_inode_at_loc((unsigned long long)di_blkno,
+ res->sr_bits);
atomic_inc(&OCFS2_SB(ac->ac_inode->i_sb)->alloc_stats.bg_allocs);
@@ -2201,8 +2198,6 @@ int ocfs2_claim_new_inode(handle_t *handle,
int status;
struct ocfs2_suballoc_result res;
- mlog_entry_void();
-
BUG_ON(!ac);
BUG_ON(ac->ac_bits_given != 0);
BUG_ON(ac->ac_bits_wanted != 1);
@@ -2230,7 +2225,8 @@ int ocfs2_claim_new_inode(handle_t *handle,
ocfs2_save_inode_ac_group(dir, ac);
status = 0;
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2307,8 +2303,6 @@ int __ocfs2_claim_clusters(handle_t *handle,
struct ocfs2_suballoc_result res = { .sr_blkno = 0, };
struct ocfs2_super *osb = OCFS2_SB(ac->ac_inode->i_sb);
- mlog_entry_void();
-
BUG_ON(ac->ac_bits_given >= ac->ac_bits_wanted);
BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL
@@ -2363,7 +2357,8 @@ int __ocfs2_claim_clusters(handle_t *handle,
ac->ac_bits_given += *num_clusters;
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2392,13 +2387,11 @@ static int ocfs2_block_group_clear_bits(handle_t *handle,
unsigned int tmp;
struct ocfs2_group_desc *undo_bg = NULL;
- mlog_entry_void();
-
/* The caller got this descriptor from
* ocfs2_read_group_descriptor(). Any corruption is a code bug. */
BUG_ON(!OCFS2_IS_VALID_GROUP_DESC(bg));
- mlog(0, "off = %u, num = %u\n", bit_off, num_bits);
+ trace_ocfs2_block_group_clear_bits(bit_off, num_bits);
BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode));
status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode),
@@ -2463,8 +2456,6 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle,
struct buffer_head *group_bh = NULL;
struct ocfs2_group_desc *group;
- mlog_entry_void();
-
/* The alloc_bh comes from ocfs2_free_dinode() or
* ocfs2_free_clusters(). The callers have all locked the
* allocator and gotten alloc_bh from the lock call. This
@@ -2473,9 +2464,10 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle,
BUG_ON(!OCFS2_IS_VALID_DINODE(fe));
BUG_ON((count + start_bit) > ocfs2_bits_per_group(cl));
- mlog(0, "%llu: freeing %u bits from group %llu, starting at %u\n",
- (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count,
- (unsigned long long)bg_blkno, start_bit);
+ trace_ocfs2_free_suballoc_bits(
+ (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno,
+ (unsigned long long)bg_blkno,
+ start_bit, count);
status = ocfs2_read_group_descriptor(alloc_inode, fe, bg_blkno,
&group_bh);
@@ -2511,7 +2503,8 @@ static int _ocfs2_free_suballoc_bits(handle_t *handle,
bail:
brelse(group_bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2556,11 +2549,8 @@ static int _ocfs2_free_clusters(handle_t *handle,
/* You can't ever have a contiguous set of clusters
* bigger than a block group bitmap so we never have to worry
- * about looping on them. */
-
- mlog_entry_void();
-
- /* This is expensive. We can safely remove once this stuff has
+ * about looping on them.
+ * This is expensive. We can safely remove once this stuff has
* gotten tested really well. */
BUG_ON(start_blk != ocfs2_clusters_to_blocks(bitmap_inode->i_sb, ocfs2_blocks_to_clusters(bitmap_inode->i_sb, start_blk)));
@@ -2569,10 +2559,9 @@ static int _ocfs2_free_clusters(handle_t *handle,
ocfs2_block_to_cluster_group(bitmap_inode, start_blk, &bg_blkno,
&bg_start_bit);
- mlog(0, "want to free %u clusters starting at block %llu\n",
- num_clusters, (unsigned long long)start_blk);
- mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n",
- (unsigned long long)bg_blkno, bg_start_bit);
+ trace_ocfs2_free_clusters((unsigned long long)bg_blkno,
+ (unsigned long long)start_blk,
+ bg_start_bit, num_clusters);
status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,
bg_start_bit, bg_blkno,
@@ -2586,7 +2575,8 @@ static int _ocfs2_free_clusters(handle_t *handle,
num_clusters);
out:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2756,7 +2746,7 @@ static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno,
struct buffer_head *inode_bh = NULL;
struct ocfs2_dinode *inode_fe;
- mlog_entry("blkno: %llu\n", (unsigned long long)blkno);
+ trace_ocfs2_get_suballoc_slot_bit((unsigned long long)blkno);
/* dirty read disk */
status = ocfs2_read_blocks_sync(osb, blkno, 1, &inode_bh);
@@ -2793,7 +2783,8 @@ static int ocfs2_get_suballoc_slot_bit(struct ocfs2_super *osb, u64 blkno,
bail:
brelse(inode_bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2816,8 +2807,8 @@ static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb,
u64 bg_blkno;
int status;
- mlog_entry("blkno: %llu bit: %u\n", (unsigned long long)blkno,
- (unsigned int)bit);
+ trace_ocfs2_test_suballoc_bit((unsigned long long)blkno,
+ (unsigned int)bit);
alloc_di = (struct ocfs2_dinode *)alloc_bh->b_data;
if ((bit + 1) > ocfs2_bits_per_group(&alloc_di->id2.i_chain)) {
@@ -2844,7 +2835,8 @@ static int ocfs2_test_suballoc_bit(struct ocfs2_super *osb,
bail:
brelse(group_bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2869,7 +2861,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res)
struct inode *inode_alloc_inode;
struct buffer_head *alloc_bh = NULL;
- mlog_entry("blkno: %llu", (unsigned long long)blkno);
+ trace_ocfs2_test_inode_bit((unsigned long long)blkno);
status = ocfs2_get_suballoc_slot_bit(osb, blkno, &suballoc_slot,
&group_blkno, &suballoc_bit);
@@ -2910,6 +2902,7 @@ int ocfs2_test_inode_bit(struct ocfs2_super *osb, u64 blkno, int *res)
iput(inode_alloc_inode);
brelse(alloc_bh);
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 236ed1bdca2..69fa11b35aa 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -42,7 +42,9 @@
#include <linux/seq_file.h>
#include <linux/quotaops.h>
-#define MLOG_MASK_PREFIX ML_SUPER
+#define CREATE_TRACE_POINTS
+#include "ocfs2_trace.h"
+
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -441,8 +443,6 @@ static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb)
int status = 0;
int i;
- mlog_entry_void();
-
new = ocfs2_iget(osb, osb->root_blkno, OCFS2_FI_FLAG_SYSFILE, 0);
if (IS_ERR(new)) {
status = PTR_ERR(new);
@@ -478,7 +478,8 @@ static int ocfs2_init_global_system_inodes(struct ocfs2_super *osb)
}
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -488,8 +489,6 @@ static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb)
int status = 0;
int i;
- mlog_entry_void();
-
for (i = OCFS2_LAST_GLOBAL_SYSTEM_INODE + 1;
i < NUM_SYSTEM_INODES;
i++) {
@@ -508,7 +507,8 @@ static int ocfs2_init_local_system_inodes(struct ocfs2_super *osb)
}
bail:
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -517,8 +517,6 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb)
int i;
struct inode *inode;
- mlog_entry_void();
-
for (i = 0; i < NUM_GLOBAL_SYSTEM_INODES; i++) {
inode = osb->global_system_inodes[i];
if (inode) {
@@ -540,7 +538,7 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb)
}
if (!osb->local_system_inodes)
- goto out;
+ return;
for (i = 0; i < NUM_LOCAL_SYSTEM_INODES * osb->max_slots; i++) {
if (osb->local_system_inodes[i]) {
@@ -551,9 +549,6 @@ static void ocfs2_release_system_inodes(struct ocfs2_super *osb)
kfree(osb->local_system_inodes);
osb->local_system_inodes = NULL;
-
-out:
- mlog_exit(0);
}
/* We're allocating fs objects, use GFP_NOFS */
@@ -684,12 +679,9 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
}
if (*flags & MS_RDONLY) {
- mlog(0, "Going to ro mode.\n");
sb->s_flags |= MS_RDONLY;
osb->osb_flags |= OCFS2_OSB_SOFT_RO;
} else {
- mlog(0, "Making ro filesystem writeable.\n");
-
if (osb->osb_flags & OCFS2_OSB_ERROR_FS) {
mlog(ML_ERROR, "Cannot remount RDWR "
"filesystem due to previous errors.\n");
@@ -707,6 +699,7 @@ static int ocfs2_remount(struct super_block *sb, int *flags, char *data)
sb->s_flags &= ~MS_RDONLY;
osb->osb_flags &= ~OCFS2_OSB_SOFT_RO;
}
+ trace_ocfs2_remount(sb->s_flags, osb->osb_flags, *flags);
unlock_osb:
spin_unlock(&osb->osb_lock);
/* Enable quota accounting after remounting RW */
@@ -1032,7 +1025,7 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
char nodestr[8];
struct ocfs2_blockcheck_stats stats;
- mlog_entry("%p, %p, %i", sb, data, silent);
+ trace_ocfs2_fill_super(sb, data, silent);
if (!ocfs2_parse_options(sb, data, &parsed_options, 0)) {
status = -EINVAL;
@@ -1208,7 +1201,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
mlog_errno(status);
atomic_set(&osb->vol_state, VOLUME_DISABLED);
wake_up(&osb->osb_mount_event);
- mlog_exit(status);
return status;
}
}
@@ -1222,7 +1214,6 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
/* Start this when the mount is almost sure of being successful */
ocfs2_orphan_scan_start(osb);
- mlog_exit(status);
return status;
read_super_error:
@@ -1237,7 +1228,8 @@ read_super_error:
ocfs2_dismount_volume(sb, 1);
}
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1320,8 +1312,7 @@ static int ocfs2_parse_options(struct super_block *sb,
char *p;
u32 tmp;
- mlog_entry("remount: %d, options: \"%s\"\n", is_remount,
- options ? options : "(none)");
+ trace_ocfs2_parse_options(is_remount, options ? options : "(none)");
mopt->commit_interval = 0;
mopt->mount_opt = OCFS2_MOUNT_NOINTR;
@@ -1538,7 +1529,6 @@ static int ocfs2_parse_options(struct super_block *sb,
status = 1;
bail:
- mlog_exit(status);
return status;
}
@@ -1629,8 +1619,6 @@ static int __init ocfs2_init(void)
{
int status;
- mlog_entry_void();
-
ocfs2_print_version();
status = init_ocfs2_uptodate_cache();
@@ -1664,10 +1652,9 @@ leave:
if (status < 0) {
ocfs2_free_mem_caches();
exit_ocfs2_uptodate_cache();
+ mlog_errno(status);
}
- mlog_exit(status);
-
if (status >= 0) {
return register_filesystem(&ocfs2_fs_type);
} else
@@ -1676,8 +1663,6 @@ leave:
static void __exit ocfs2_exit(void)
{
- mlog_entry_void();
-
if (ocfs2_wq) {
flush_workqueue(ocfs2_wq);
destroy_workqueue(ocfs2_wq);
@@ -1692,18 +1677,14 @@ static void __exit ocfs2_exit(void)
unregister_filesystem(&ocfs2_fs_type);
exit_ocfs2_uptodate_cache();
-
- mlog_exit_void();
}
static void ocfs2_put_super(struct super_block *sb)
{
- mlog_entry("(0x%p)\n", sb);
+ trace_ocfs2_put_super(sb);
ocfs2_sync_blockdev(sb);
ocfs2_dismount_volume(sb, 0);
-
- mlog_exit_void();
}
static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -1715,7 +1696,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
struct buffer_head *bh = NULL;
struct inode *inode = NULL;
- mlog_entry("(%p, %p)\n", dentry->d_sb, buf);
+ trace_ocfs2_statfs(dentry->d_sb, buf);
osb = OCFS2_SB(dentry->d_sb);
@@ -1762,7 +1743,8 @@ bail:
if (inode)
iput(inode);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -1882,8 +1864,6 @@ static int ocfs2_mount_volume(struct super_block *sb)
int unlock_super = 0;
struct ocfs2_super *osb = OCFS2_SB(sb);
- mlog_entry_void();
-
if (ocfs2_is_hard_readonly(osb))
goto leave;
@@ -1928,7 +1908,6 @@ leave:
if (unlock_super)
ocfs2_super_unlock(osb, 1);
- mlog_exit(status);
return status;
}
@@ -1938,7 +1917,7 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
struct ocfs2_super *osb = NULL;
char nodestr[8];
- mlog_entry("(0x%p)\n", sb);
+ trace_ocfs2_dismount_volume(sb);
BUG_ON(!sb);
osb = OCFS2_SB(sb);
@@ -2090,8 +2069,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
struct ocfs2_super *osb;
u64 total_blocks;
- mlog_entry_void();
-
osb = kzalloc(sizeof(struct ocfs2_super), GFP_KERNEL);
if (!osb) {
status = -ENOMEM;
@@ -2155,7 +2132,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
status = -EINVAL;
goto bail;
}
- mlog(0, "max_slots for this device: %u\n", osb->max_slots);
ocfs2_orphan_scan_init(osb);
@@ -2294,7 +2270,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
osb->s_clustersize_bits =
le32_to_cpu(di->id2.i_super.s_clustersize_bits);
osb->s_clustersize = 1 << osb->s_clustersize_bits;
- mlog(0, "clusterbits=%d\n", osb->s_clustersize_bits);
if (osb->s_clustersize < OCFS2_MIN_CLUSTERSIZE ||
osb->s_clustersize > OCFS2_MAX_CLUSTERSIZE) {
@@ -2333,11 +2308,10 @@ static int ocfs2_initialize_super(struct super_block *sb,
le64_to_cpu(di->id2.i_super.s_first_cluster_group);
osb->fs_generation = le32_to_cpu(di->i_fs_generation);
osb->uuid_hash = le32_to_cpu(di->id2.i_super.s_uuid_hash);
- mlog(0, "vol_label: %s\n", osb->vol_label);
- mlog(0, "uuid: %s\n", osb->uuid_str);
- mlog(0, "root_blkno=%llu, system_dir_blkno=%llu\n",
- (unsigned long long)osb->root_blkno,
- (unsigned long long)osb->system_dir_blkno);
+ trace_ocfs2_initialize_super(osb->vol_label, osb->uuid_str,
+ (unsigned long long)osb->root_blkno,
+ (unsigned long long)osb->system_dir_blkno,
+ osb->s_clustersize_bits);
osb->osb_dlm_debug = ocfs2_new_dlm_debug();
if (!osb->osb_dlm_debug) {
@@ -2380,7 +2354,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
}
bail:
- mlog_exit(status);
return status;
}
@@ -2396,8 +2369,6 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di,
{
int status = -EAGAIN;
- mlog_entry_void();
-
if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE,
strlen(OCFS2_SUPER_BLOCK_SIGNATURE)) == 0) {
/* We have to do a raw check of the feature here */
@@ -2452,7 +2423,8 @@ static int ocfs2_verify_volume(struct ocfs2_dinode *di,
}
out:
- mlog_exit(status);
+ if (status && status != -EAGAIN)
+ mlog_errno(status);
return status;
}
@@ -2465,8 +2437,6 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
* recover
* ourselves. */
- mlog_entry_void();
-
/* Init our journal object. */
status = ocfs2_journal_init(osb->journal, &dirty);
if (status < 0) {
@@ -2516,8 +2486,6 @@ static int ocfs2_check_volume(struct ocfs2_super *osb)
* ourselves as mounted. */
}
- mlog(0, "Journal loaded.\n");
-
status = ocfs2_load_local_alloc(osb);
if (status < 0) {
mlog_errno(status);
@@ -2549,7 +2517,8 @@ finally:
if (local_alloc)
kfree(local_alloc);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return status;
}
@@ -2561,8 +2530,6 @@ finally:
*/
static void ocfs2_delete_osb(struct ocfs2_super *osb)
{
- mlog_entry_void();
-
/* This function assumes that the caller has the main osb resource */
ocfs2_free_slot_info(osb);
@@ -2580,8 +2547,6 @@ static void ocfs2_delete_osb(struct ocfs2_super *osb)
kfree(osb->uuid_str);
ocfs2_put_dlm_debug(osb->osb_dlm_debug);
memset(osb, 0, sizeof(struct ocfs2_super));
-
- mlog_exit_void();
}
/* Put OCFS2 into a readonly state, or (if the user specifies it),
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index 9975457c981..5d22872e2bb 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -40,7 +40,6 @@
#include <linux/pagemap.h>
#include <linux/namei.h>
-#define MLOG_MASK_PREFIX ML_NAMEI
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -62,8 +61,6 @@ static char *ocfs2_fast_symlink_getlink(struct inode *inode,
char *link = NULL;
struct ocfs2_dinode *fe;
- mlog_entry_void();
-
status = ocfs2_read_inode_block(inode, bh);
if (status < 0) {
mlog_errno(status);
@@ -74,7 +71,6 @@ static char *ocfs2_fast_symlink_getlink(struct inode *inode,
fe = (struct ocfs2_dinode *) (*bh)->b_data;
link = (char *) fe->id2.i_symlink;
bail:
- mlog_exit(status);
return link;
}
@@ -88,8 +84,6 @@ static int ocfs2_readlink(struct dentry *dentry,
struct buffer_head *bh = NULL;
struct inode *inode = dentry->d_inode;
- mlog_entry_void();
-
link = ocfs2_fast_symlink_getlink(inode, &bh);
if (IS_ERR(link)) {
ret = PTR_ERR(link);
@@ -104,7 +98,8 @@ static int ocfs2_readlink(struct dentry *dentry,
brelse(bh);
out:
- mlog_exit(ret);
+ if (ret < 0)
+ mlog_errno(ret);
return ret;
}
@@ -117,8 +112,6 @@ static void *ocfs2_fast_follow_link(struct dentry *dentry,
struct inode *inode = dentry->d_inode;
struct buffer_head *bh = NULL;
- mlog_entry_void();
-
BUG_ON(!ocfs2_inode_is_fast_symlink(inode));
target = ocfs2_fast_symlink_getlink(inode, &bh);
if (IS_ERR(target)) {
@@ -142,7 +135,8 @@ bail:
nd_set_link(nd, status ? ERR_PTR(status) : link);
brelse(bh);
- mlog_exit(status);
+ if (status)
+ mlog_errno(status);
return NULL;
}
diff --git a/fs/ocfs2/sysfile.c b/fs/ocfs2/sysfile.c
index 902efb23b6a..3d635f4bbb2 100644
--- a/fs/ocfs2/sysfile.c
+++ b/fs/ocfs2/sysfile.c
@@ -27,7 +27,6 @@
#include <linux/types.h>
#include <linux/highmem.h>
-#define MLOG_MASK_PREFIX ML_INODE
#include <cluster/masklog.h>
#include "ocfs2.h"
diff --git a/fs/ocfs2/uptodate.c b/fs/ocfs2/uptodate.c
index a0a120e82b9..52eaf33d346 100644
--- a/fs/ocfs2/uptodate.c
+++ b/fs/ocfs2/uptodate.c
@@ -54,14 +54,13 @@
#include <linux/buffer_head.h>
#include <linux/rbtree.h>
-#define MLOG_MASK_PREFIX ML_UPTODATE
-
#include <cluster/masklog.h>
#include "ocfs2.h"
#include "inode.h"
#include "uptodate.h"
+#include "ocfs2_trace.h"
struct ocfs2_meta_cache_item {
struct rb_node c_node;
@@ -152,8 +151,8 @@ static unsigned int ocfs2_purge_copied_metadata_tree(struct rb_root *root)
while ((node = rb_last(root)) != NULL) {
item = rb_entry(node, struct ocfs2_meta_cache_item, c_node);
- mlog(0, "Purge item %llu\n",
- (unsigned long long) item->c_block);
+ trace_ocfs2_purge_copied_metadata_tree(
+ (unsigned long long) item->c_block);
rb_erase(&item->c_node, root);
kmem_cache_free(ocfs2_uptodate_cachep, item);
@@ -180,9 +179,9 @@ void ocfs2_metadata_cache_purge(struct ocfs2_caching_info *ci)
tree = !(ci->ci_flags & OCFS2_CACHE_FL_INLINE);
to_purge = ci->ci_num_cached;
- mlog(0, "Purge %u %s items from Owner %llu\n", to_purge,
- tree ? "array" : "tree",
- (unsigned long long)ocfs2_metadata_cache_owner(ci));
+ trace_ocfs2_metadata_cache_purge(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ to_purge, tree);
/* If we're a tree, save off the root so that we can safely
* initialize the cache. We do the work to free tree members
@@ -249,10 +248,10 @@ static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci,
ocfs2_metadata_cache_lock(ci);
- mlog(0, "Owner %llu, query block %llu (inline = %u)\n",
- (unsigned long long)ocfs2_metadata_cache_owner(ci),
- (unsigned long long) bh->b_blocknr,
- !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE));
+ trace_ocfs2_buffer_cached_begin(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long) bh->b_blocknr,
+ !!(ci->ci_flags & OCFS2_CACHE_FL_INLINE));
if (ci->ci_flags & OCFS2_CACHE_FL_INLINE)
index = ocfs2_search_cache_array(ci, bh->b_blocknr);
@@ -261,7 +260,7 @@ static int ocfs2_buffer_cached(struct ocfs2_caching_info *ci,
ocfs2_metadata_cache_unlock(ci);
- mlog(0, "index = %d, item = %p\n", index, item);
+ trace_ocfs2_buffer_cached_end(index, item);
return (index != -1) || (item != NULL);
}
@@ -306,8 +305,9 @@ static void ocfs2_append_cache_array(struct ocfs2_caching_info *ci,
{
BUG_ON(ci->ci_num_cached >= OCFS2_CACHE_INFO_MAX_ARRAY);
- mlog(0, "block %llu takes position %u\n", (unsigned long long) block,
- ci->ci_num_cached);
+ trace_ocfs2_append_cache_array(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)block, ci->ci_num_cached);
ci->ci_cache.ci_array[ci->ci_num_cached] = block;
ci->ci_num_cached++;
@@ -324,8 +324,9 @@ static void __ocfs2_insert_cache_tree(struct ocfs2_caching_info *ci,
struct rb_node **p = &ci->ci_cache.ci_tree.rb_node;
struct ocfs2_meta_cache_item *tmp;
- mlog(0, "Insert block %llu num = %u\n", (unsigned long long) block,
- ci->ci_num_cached);
+ trace_ocfs2_insert_cache_tree(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)block, ci->ci_num_cached);
while(*p) {
parent = *p;
@@ -389,9 +390,9 @@ static void ocfs2_expand_cache(struct ocfs2_caching_info *ci,
tree[i] = NULL;
}
- mlog(0, "Expanded %llu to a tree cache: flags 0x%x, num = %u\n",
- (unsigned long long)ocfs2_metadata_cache_owner(ci),
- ci->ci_flags, ci->ci_num_cached);
+ trace_ocfs2_expand_cache(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ ci->ci_flags, ci->ci_num_cached);
}
/* Slow path function - memory allocation is necessary. See the
@@ -405,9 +406,9 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
struct ocfs2_meta_cache_item *tree[OCFS2_CACHE_INFO_MAX_ARRAY] =
{ NULL, };
- mlog(0, "Owner %llu, block %llu, expand = %d\n",
- (unsigned long long)ocfs2_metadata_cache_owner(ci),
- (unsigned long long)block, expand_tree);
+ trace_ocfs2_set_buffer_uptodate(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)block, expand_tree);
new = kmem_cache_alloc(ocfs2_uptodate_cachep, GFP_NOFS);
if (!new) {
@@ -433,7 +434,6 @@ static void __ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
ocfs2_metadata_cache_lock(ci);
if (ocfs2_insert_can_use_array(ci)) {
- mlog(0, "Someone cleared the tree underneath us\n");
/* Ok, items were removed from the cache in between
* locks. Detect this and revert back to the fast path */
ocfs2_append_cache_array(ci, block);
@@ -490,9 +490,9 @@ void ocfs2_set_buffer_uptodate(struct ocfs2_caching_info *ci,
if (ocfs2_buffer_cached(ci, bh))
return;
- mlog(0, "Owner %llu, inserting block %llu\n",
- (unsigned long long)ocfs2_metadata_cache_owner(ci),
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_set_buffer_uptodate_begin(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)bh->b_blocknr);
/* No need to recheck under spinlock - insertion is guarded by
* co_io_lock() */
@@ -542,8 +542,9 @@ static void ocfs2_remove_metadata_array(struct ocfs2_caching_info *ci,
BUG_ON(index >= ci->ci_num_cached);
BUG_ON(!ci->ci_num_cached);
- mlog(0, "remove index %d (num_cached = %u\n", index,
- ci->ci_num_cached);
+ trace_ocfs2_remove_metadata_array(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ index, ci->ci_num_cached);
ci->ci_num_cached--;
@@ -559,8 +560,9 @@ static void ocfs2_remove_metadata_array(struct ocfs2_caching_info *ci,
static void ocfs2_remove_metadata_tree(struct ocfs2_caching_info *ci,
struct ocfs2_meta_cache_item *item)
{
- mlog(0, "remove block %llu from tree\n",
- (unsigned long long) item->c_block);
+ trace_ocfs2_remove_metadata_tree(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long)item->c_block);
rb_erase(&item->c_node, &ci->ci_cache.ci_tree);
ci->ci_num_cached--;
@@ -573,10 +575,10 @@ static void ocfs2_remove_block_from_cache(struct ocfs2_caching_info *ci,
struct ocfs2_meta_cache_item *item = NULL;
ocfs2_metadata_cache_lock(ci);
- mlog(0, "Owner %llu, remove %llu, items = %u, array = %u\n",
- (unsigned long long)ocfs2_metadata_cache_owner(ci),
- (unsigned long long) block, ci->ci_num_cached,
- ci->ci_flags & OCFS2_CACHE_FL_INLINE);
+ trace_ocfs2_remove_block_from_cache(
+ (unsigned long long)ocfs2_metadata_cache_owner(ci),
+ (unsigned long long) block, ci->ci_num_cached,
+ ci->ci_flags);
if (ci->ci_flags & OCFS2_CACHE_FL_INLINE) {
index = ocfs2_search_cache_array(ci, block);
@@ -626,9 +628,6 @@ int __init init_ocfs2_uptodate_cache(void)
if (!ocfs2_uptodate_cachep)
return -ENOMEM;
- mlog(0, "%u inlined cache items per inode.\n",
- OCFS2_CACHE_INFO_MAX_ARRAY);
-
return 0;
}
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 6bb602486c6..57a215dc2d9 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -37,7 +37,6 @@
#include <linux/string.h>
#include <linux/security.h>
-#define MLOG_MASK_PREFIX ML_XATTR
#include <cluster/masklog.h>
#include "ocfs2.h"
@@ -57,6 +56,7 @@
#include "xattr.h"
#include "refcounttree.h"
#include "acl.h"
+#include "ocfs2_trace.h"
struct ocfs2_xattr_def_value_root {
struct ocfs2_xattr_value_root xv;
@@ -474,8 +474,7 @@ static int ocfs2_validate_xattr_block(struct super_block *sb,
struct ocfs2_xattr_block *xb =
(struct ocfs2_xattr_block *)bh->b_data;
- mlog(0, "Validating xattr block %llu\n",
- (unsigned long long)bh->b_blocknr);
+ trace_ocfs2_validate_xattr_block((unsigned long long)bh->b_blocknr);
BUG_ON(!buffer_uptodate(bh));
@@ -715,11 +714,11 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters);
struct ocfs2_extent_tree et;
- mlog(0, "(clusters_to_add for xattr= %u)\n", clusters_to_add);
-
ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb);
while (clusters_to_add) {
+ trace_ocfs2_xattr_extend_allocation(clusters_to_add);
+
status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) {
@@ -754,8 +753,6 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
*/
BUG_ON(why == RESTART_META);
- mlog(0, "restarting xattr value extension for %u"
- " clusters,.\n", clusters_to_add);
credits = ocfs2_calc_extend_credits(inode->i_sb,
&vb->vb_xv->xr_list,
clusters_to_add);
@@ -3246,8 +3243,8 @@ static int ocfs2_init_xattr_set_ctxt(struct inode *inode,
}
meta_add += extra_meta;
- mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d, "
- "credits = %d\n", xi->xi_name, meta_add, clusters_add, *credits);
+ trace_ocfs2_init_xattr_set_ctxt(xi->xi_name, meta_add,
+ clusters_add, *credits);
if (meta_add) {
ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add,
@@ -3887,8 +3884,10 @@ static int ocfs2_xattr_bucket_find(struct inode *inode,
if (found) {
xs->here = &xs->header->xh_entries[index];
- mlog(0, "find xattr %s in bucket %llu, entry = %u\n", name,
- (unsigned long long)bucket_blkno(xs->bucket), index);
+ trace_ocfs2_xattr_bucket_find(OCFS2_I(inode)->ip_blkno,
+ name, name_index, name_hash,
+ (unsigned long long)bucket_blkno(xs->bucket),
+ index);
} else
ret = -ENODATA;
@@ -3915,8 +3914,10 @@ static int ocfs2_xattr_index_block_find(struct inode *inode,
if (le16_to_cpu(el->l_next_free_rec) == 0)
return -ENODATA;
- mlog(0, "find xattr %s, hash = %u, index = %d in xattr tree\n",
- name, name_hash, name_index);
+ trace_ocfs2_xattr_index_block_find(OCFS2_I(inode)->ip_blkno,
+ name, name_index, name_hash,
+ (unsigned long long)root_bh->b_blocknr,
+ -1);
ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, &first_hash,
&num_clusters, el);
@@ -3927,9 +3928,10 @@ static int ocfs2_xattr_index_block_find(struct inode *inode,
BUG_ON(p_blkno == 0 || num_clusters == 0 || first_hash > name_hash);
- mlog(0, "find xattr extent rec %u clusters from %llu, the first hash "
- "in the rec is %u\n", num_clusters, (unsigned long long)p_blkno,
- first_hash);
+ trace_ocfs2_xattr_index_block_find_rec(OCFS2_I(inode)->ip_blkno,
+ name, name_index, first_hash,
+ (unsigned long long)p_blkno,
+ num_clusters);
ret = ocfs2_xattr_bucket_find(inode, name_index, name, name_hash,
p_blkno, first_hash, num_clusters, xs);
@@ -3955,8 +3957,9 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode,
return -ENOMEM;
}
- mlog(0, "iterating xattr buckets in %u clusters starting from %llu\n",
- clusters, (unsigned long long)blkno);
+ trace_ocfs2_iterate_xattr_buckets(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)blkno, clusters);
for (i = 0; i < num_buckets; i++, blkno += bucket->bu_blocks) {
ret = ocfs2_read_xattr_bucket(bucket, blkno);
@@ -3972,8 +3975,7 @@ static int ocfs2_iterate_xattr_buckets(struct inode *inode,
if (i == 0)
num_buckets = le16_to_cpu(bucket_xh(bucket)->xh_num_buckets);
- mlog(0, "iterating xattr bucket %llu, first hash %u\n",
- (unsigned long long)blkno,
+ trace_ocfs2_iterate_xattr_bucket((unsigned long long)blkno,
le32_to_cpu(bucket_xh(bucket)->xh_entries[0].xe_name_hash));
if (func) {
ret = func(inode, bucket, para);
@@ -4173,9 +4175,9 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
char *src = xb_bh->b_data;
char *target = bucket_block(bucket, blks - 1);
- mlog(0, "cp xattr from block %llu to bucket %llu\n",
- (unsigned long long)xb_bh->b_blocknr,
- (unsigned long long)bucket_blkno(bucket));
+ trace_ocfs2_cp_xattr_block_to_bucket_begin(
+ (unsigned long long)xb_bh->b_blocknr,
+ (unsigned long long)bucket_blkno(bucket));
for (i = 0; i < blks; i++)
memset(bucket_block(bucket, i), 0, blocksize);
@@ -4211,8 +4213,7 @@ static void ocfs2_cp_xattr_block_to_bucket(struct inode *inode,
for (i = 0; i < count; i++)
le16_add_cpu(&xh->xh_entries[i].xe_name_offset, off_change);
- mlog(0, "copy entry: start = %u, size = %u, offset_change = %u\n",
- offset, size, off_change);
+ trace_ocfs2_cp_xattr_block_to_bucket_end(offset, size, off_change);
sort(target + offset, count, sizeof(struct ocfs2_xattr_entry),
cmp_xe, swap_xe);
@@ -4261,8 +4262,8 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
struct ocfs2_xattr_tree_root *xr;
u16 xb_flags = le16_to_cpu(xb->xb_flags);
- mlog(0, "create xattr index block for %llu\n",
- (unsigned long long)xb_bh->b_blocknr);
+ trace_ocfs2_xattr_create_index_block_begin(
+ (unsigned long long)xb_bh->b_blocknr);
BUG_ON(xb_flags & OCFS2_XATTR_INDEXED);
BUG_ON(!xs->bucket);
@@ -4295,8 +4296,7 @@ static int ocfs2_xattr_create_index_block(struct inode *inode,
*/
blkno = ocfs2_clusters_to_blocks(inode->i_sb, bit_off);
- mlog(0, "allocate 1 cluster from %llu to xattr block\n",
- (unsigned long long)blkno);
+ trace_ocfs2_xattr_create_index_block((unsigned long long)blkno);
ret = ocfs2_init_xattr_bucket(xs->bucket, blkno);
if (ret) {
@@ -4400,8 +4400,7 @@ static int ocfs2_defrag_xattr_bucket(struct inode *inode,
entries = (char *)xh->xh_entries;
xh_free_start = le16_to_cpu(xh->xh_free_start);
- mlog(0, "adjust xattr bucket in %llu, count = %u, "
- "xh_free_start = %u, xh_name_value_len = %u.\n",
+ trace_ocfs2_defrag_xattr_bucket(
(unsigned long long)blkno, le16_to_cpu(xh->xh_count),
xh_free_start, le16_to_cpu(xh->xh_name_value_len));
@@ -4503,8 +4502,9 @@ static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode,
BUG_ON(le16_to_cpu(bucket_xh(first)->xh_num_buckets) < num_buckets);
BUG_ON(OCFS2_XATTR_BUCKET_SIZE == OCFS2_SB(sb)->s_clustersize);
- mlog(0, "move half of xattrs in cluster %llu to %llu\n",
- (unsigned long long)last_cluster_blkno, (unsigned long long)new_blkno);
+ trace_ocfs2_mv_xattr_bucket_cross_cluster(
+ (unsigned long long)last_cluster_blkno,
+ (unsigned long long)new_blkno);
ret = ocfs2_mv_xattr_buckets(inode, handle, bucket_blkno(first),
last_cluster_blkno, new_blkno,
@@ -4614,8 +4614,8 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
struct ocfs2_xattr_entry *xe;
int blocksize = inode->i_sb->s_blocksize;
- mlog(0, "move some of xattrs from bucket %llu to %llu\n",
- (unsigned long long)blk, (unsigned long long)new_blk);
+ trace_ocfs2_divide_xattr_bucket_begin((unsigned long long)blk,
+ (unsigned long long)new_blk);
s_bucket = ocfs2_xattr_bucket_new(inode);
t_bucket = ocfs2_xattr_bucket_new(inode);
@@ -4714,9 +4714,9 @@ static int ocfs2_divide_xattr_bucket(struct inode *inode,
*/
xe = &xh->xh_entries[start];
len = sizeof(struct ocfs2_xattr_entry) * (count - start);
- mlog(0, "mv xattr entry len %d from %d to %d\n", len,
- (int)((char *)xe - (char *)xh),
- (int)((char *)xh->xh_entries - (char *)xh));
+ trace_ocfs2_divide_xattr_bucket_move(len,
+ (int)((char *)xe - (char *)xh),
+ (int)((char *)xh->xh_entries - (char *)xh));
memmove((char *)xh->xh_entries, (char *)xe, len);
xe = &xh->xh_entries[count - start];
len = sizeof(struct ocfs2_xattr_entry) * start;
@@ -4788,9 +4788,9 @@ static int ocfs2_cp_xattr_bucket(struct inode *inode,
BUG_ON(s_blkno == t_blkno);
- mlog(0, "cp bucket %llu to %llu, target is %d\n",
- (unsigned long long)s_blkno, (unsigned long long)t_blkno,
- t_is_new);
+ trace_ocfs2_cp_xattr_bucket((unsigned long long)s_blkno,
+ (unsigned long long)t_blkno,
+ t_is_new);
s_bucket = ocfs2_xattr_bucket_new(inode);
t_bucket = ocfs2_xattr_bucket_new(inode);
@@ -4862,8 +4862,8 @@ static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle,
int num_buckets = ocfs2_xattr_buckets_per_cluster(osb);
struct ocfs2_xattr_bucket *old_first, *new_first;
- mlog(0, "mv xattrs from cluster %llu to %llu\n",
- (unsigned long long)last_blk, (unsigned long long)to_blk);
+ trace_ocfs2_mv_xattr_buckets((unsigned long long)last_blk,
+ (unsigned long long)to_blk);
BUG_ON(start_bucket >= num_buckets);
if (start_bucket) {
@@ -5013,9 +5013,9 @@ static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode,
{
int ret;
- mlog(0, "adjust xattrs from cluster %llu len %u to %llu\n",
- (unsigned long long)bucket_blkno(first), prev_clusters,
- (unsigned long long)new_blk);
+ trace_ocfs2_adjust_xattr_cross_cluster(
+ (unsigned long long)bucket_blkno(first),
+ (unsigned long long)new_blk, prev_clusters);
if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) {
ret = ocfs2_mv_xattr_bucket_cross_cluster(inode,
@@ -5088,10 +5088,10 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct ocfs2_extent_tree et;
- mlog(0, "Add new xattr cluster for %llu, previous xattr hash = %u, "
- "previous xattr blkno = %llu\n",
- (unsigned long long)OCFS2_I(inode)->ip_blkno,
- prev_cpos, (unsigned long long)bucket_blkno(first));
+ trace_ocfs2_add_new_xattr_cluster_begin(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)bucket_blkno(first),
+ prev_cpos, prev_clusters);
ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(inode), root_bh);
@@ -5113,8 +5113,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
BUG_ON(num_bits > clusters_to_add);
block = ocfs2_clusters_to_blocks(osb->sb, bit_off);
- mlog(0, "Allocating %u clusters at block %u for xattr in inode %llu\n",
- num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
+ trace_ocfs2_add_new_xattr_cluster((unsigned long long)block, num_bits);
if (bucket_blkno(first) + (prev_clusters * bpc) == block &&
(prev_clusters + num_bits) << osb->s_clustersize_bits <=
@@ -5130,8 +5129,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
*/
v_start = prev_cpos + prev_clusters;
*num_clusters = prev_clusters + num_bits;
- mlog(0, "Add contiguous %u clusters to previous extent rec.\n",
- num_bits);
} else {
ret = ocfs2_adjust_xattr_cross_cluster(inode,
handle,
@@ -5147,8 +5144,8 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
}
}
- mlog(0, "Insert %u clusters at block %llu for xattr at %u\n",
- num_bits, (unsigned long long)block, v_start);
+ trace_ocfs2_add_new_xattr_cluster_insert((unsigned long long)block,
+ v_start, num_bits);
ret = ocfs2_insert_extent(handle, &et, v_start, block,
num_bits, 0, ctxt->meta_ac);
if (ret < 0) {
@@ -5183,9 +5180,9 @@ static int ocfs2_extend_xattr_bucket(struct inode *inode,
u64 end_blk;
u16 new_bucket = le16_to_cpu(bucket_xh(first)->xh_num_buckets);
- mlog(0, "extend xattr bucket in %llu, xattr extend rec starting "
- "from %llu, len = %u\n", (unsigned long long)target_blk,
- (unsigned long long)bucket_blkno(first), num_clusters);
+ trace_ocfs2_extend_xattr_bucket((unsigned long long)target_blk,
+ (unsigned long long)bucket_blkno(first),
+ num_clusters, new_bucket);
/* The extent must have room for an additional bucket */
BUG_ON(new_bucket >=
@@ -5265,8 +5262,8 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
/* The bucket at the front of the extent */
struct ocfs2_xattr_bucket *first;
- mlog(0, "Add new xattr bucket starting from %llu\n",
- (unsigned long long)bucket_blkno(target));
+ trace_ocfs2_add_new_xattr_bucket(
+ (unsigned long long)bucket_blkno(target));
/* The first bucket of the original extent */
first = ocfs2_xattr_bucket_new(inode);
@@ -5382,8 +5379,8 @@ static int ocfs2_xattr_bucket_value_truncate(struct inode *inode,
* modified something. We have to assume they did, and dirty
* the whole bucket. This leaves us in a consistent state.
*/
- mlog(0, "truncate %u in xattr bucket %llu to %d bytes.\n",
- xe_off, (unsigned long long)bucket_blkno(bucket), len);
+ trace_ocfs2_xattr_bucket_value_truncate(
+ (unsigned long long)bucket_blkno(bucket), xe_off, len);
ret = ocfs2_xattr_value_truncate(inode, &vb, len, ctxt);
if (ret) {
mlog_errno(ret);
@@ -5433,8 +5430,9 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode,
ocfs2_init_dealloc_ctxt(&dealloc);
- mlog(0, "rm xattr extent rec at %u len = %u, start from %llu\n",
- cpos, len, (unsigned long long)blkno);
+ trace_ocfs2_rm_xattr_cluster(
+ (unsigned long long)OCFS2_I(inode)->ip_blkno,
+ (unsigned long long)blkno, cpos, len);
ocfs2_remove_xattr_clusters_from_cache(INODE_CACHE(inode), blkno,
len);
@@ -5538,7 +5536,7 @@ static int ocfs2_xattr_set_entry_bucket(struct inode *inode,
int ret;
struct ocfs2_xa_loc loc;
- mlog_entry("Set xattr %s in xattr bucket\n", xi->xi_name);
+ trace_ocfs2_xattr_set_entry_bucket(xi->xi_name);
ocfs2_init_xattr_bucket_xa_loc(&loc, xs->bucket,
xs->not_found ? NULL : xs->here);
@@ -5570,7 +5568,6 @@ static int ocfs2_xattr_set_entry_bucket(struct inode *inode,
out:
- mlog_exit(ret);
return ret;
}
@@ -5581,7 +5578,7 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
{
int ret;
- mlog_entry("Set xattr %s in xattr index block\n", xi->xi_name);
+ trace_ocfs2_xattr_set_entry_index_block(xi->xi_name);
ret = ocfs2_xattr_set_entry_bucket(inode, xi, xs, ctxt);
if (!ret)
@@ -5637,7 +5634,6 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
mlog_errno(ret);
out:
- mlog_exit(ret);
return ret;
}
@@ -6041,9 +6037,9 @@ static int ocfs2_xattr_bucket_value_refcount(struct inode *inode,
if (ocfs2_meta_ecc(OCFS2_SB(inode->i_sb)))
p = &refcount;
- mlog(0, "refcount bucket %llu, count = %u\n",
- (unsigned long long)bucket_blkno(bucket),
- le16_to_cpu(xh->xh_count));
+ trace_ocfs2_xattr_bucket_value_refcount(
+ (unsigned long long)bucket_blkno(bucket),
+ le16_to_cpu(xh->xh_count));
for (i = 0; i < le16_to_cpu(xh->xh_count); i++) {
xe = &xh->xh_entries[i];
@@ -6339,8 +6335,8 @@ static int ocfs2_reflink_xattr_header(handle_t *handle,
u32 clusters, cpos, p_cluster, num_clusters;
unsigned int ext_flags = 0;
- mlog(0, "reflink xattr in container %llu, count = %u\n",
- (unsigned long long)old_bh->b_blocknr, le16_to_cpu(xh->xh_count));
+ trace_ocfs2_reflink_xattr_header((unsigned long long)old_bh->b_blocknr,
+ le16_to_cpu(xh->xh_count));
last = &new_xh->xh_entries[le16_to_cpu(new_xh->xh_count)];
for (i = 0, j = 0; i < le16_to_cpu(xh->xh_count); i++, j++) {
@@ -6540,8 +6536,8 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
goto out;
}
- mlog(0, "create new xattr block for inode %llu, index = %d\n",
- (unsigned long long)fe_bh->b_blocknr, indexed);
+ trace_ocfs2_create_empty_xattr_block(
+ (unsigned long long)fe_bh->b_blocknr, indexed);
ret = ocfs2_create_xattr_block(inode, fe_bh, &ctxt, indexed,
ret_bh);
if (ret)
@@ -6952,8 +6948,8 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
if (ret)
mlog_errno(ret);
- mlog(0, "insert new xattr extent rec start %llu len %u to %u\n",
- (unsigned long long)new_blkno, num_clusters, reflink_cpos);
+ trace_ocfs2_reflink_xattr_buckets((unsigned long long)new_blkno,
+ num_clusters, reflink_cpos);
len -= num_clusters;
blkno += ocfs2_clusters_to_blocks(inode->i_sb, num_clusters);
@@ -6982,8 +6978,7 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
struct ocfs2_alloc_context *data_ac = NULL;
struct ocfs2_extent_tree et;
- mlog(0, "reflink xattr buckets %llu len %u\n",
- (unsigned long long)blkno, len);
+ trace_ocfs2_reflink_xattr_rec((unsigned long long)blkno, len);
ocfs2_init_xattr_tree_extent_tree(&et,
INODE_CACHE(args->reflink->new_inode),
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index c05324d3282..596bb2c9de4 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -94,75 +94,6 @@ xfs_buf_vmap_len(
}
/*
- * Page Region interfaces.
- *
- * For pages in filesystems where the blocksize is smaller than the
- * pagesize, we use the page->private field (long) to hold a bitmap
- * of uptodate regions within the page.
- *
- * Each such region is "bytes per page / bits per long" bytes long.
- *
- * NBPPR == number-of-bytes-per-page-region
- * BTOPR == bytes-to-page-region (rounded up)
- * BTOPRT == bytes-to-page-region-truncated (rounded down)
- */
-#if (BITS_PER_LONG == 32)
-#define PRSHIFT (PAGE_CACHE_SHIFT - 5) /* (32 == 1<<5) */
-#elif (BITS_PER_LONG == 64)
-#define PRSHIFT (PAGE_CACHE_SHIFT - 6) /* (64 == 1<<6) */
-#else
-#error BITS_PER_LONG must be 32 or 64
-#endif
-#define NBPPR (PAGE_CACHE_SIZE/BITS_PER_LONG)
-#define BTOPR(b) (((unsigned int)(b) + (NBPPR - 1)) >> PRSHIFT)
-#define BTOPRT(b) (((unsigned int)(b) >> PRSHIFT))
-
-STATIC unsigned long
-page_region_mask(
- size_t offset,
- size_t length)
-{
- unsigned long mask;
- int first, final;
-
- first = BTOPR(offset);
- final = BTOPRT(offset + length - 1);
- first = min(first, final);
-
- mask = ~0UL;
- mask <<= BITS_PER_LONG - (final - first);
- mask >>= BITS_PER_LONG - (final);
-
- ASSERT(offset + length <= PAGE_CACHE_SIZE);
- ASSERT((final - first) < BITS_PER_LONG && (final - first) >= 0);
-
- return mask;
-}
-
-STATIC void
-set_page_region(
- struct page *page,
- size_t offset,
- size_t length)
-{
- set_page_private(page,
- page_private(page) | page_region_mask(offset, length));
- if (page_private(page) == ~0UL)
- SetPageUptodate(page);
-}
-
-STATIC int
-test_page_region(
- struct page *page,
- size_t offset,
- size_t length)
-{
- unsigned long mask = page_region_mask(offset, length);
-
- return (mask && (page_private(page) & mask) == mask);
-}
-
-/*
* xfs_buf_lru_add - add a buffer to the LRU.
*
* The LRU takes a new reference to the buffer so that it will only be freed
@@ -332,7 +263,7 @@ xfs_buf_free(
ASSERT(list_empty(&bp->b_lru));
- if (bp->b_flags & (_XBF_PAGE_CACHE|_XBF_PAGES)) {
+ if (bp->b_flags & _XBF_PAGES) {
uint i;
if (xfs_buf_is_vmapped(bp))
@@ -342,25 +273,22 @@ xfs_buf_free(
for (i = 0; i < bp->b_page_count; i++) {
struct page *page = bp->b_pages[i];
- if (bp->b_flags & _XBF_PAGE_CACHE)
- ASSERT(!PagePrivate(page));
- page_cache_release(page);
+ __free_page(page);
}
- }
+ } else if (bp->b_flags & _XBF_KMEM)
+ kmem_free(bp->b_addr);
_xfs_buf_free_pages(bp);
xfs_buf_deallocate(bp);
}
/*
- * Finds all pages for buffer in question and builds it's page list.
+ * Allocates all the pages for buffer in question and builds it's page list.
*/
STATIC int
-_xfs_buf_lookup_pages(
+xfs_buf_allocate_memory(
xfs_buf_t *bp,
uint flags)
{
- struct address_space *mapping = bp->b_target->bt_mapping;
- size_t blocksize = bp->b_target->bt_bsize;
size_t size = bp->b_count_desired;
size_t nbytes, offset;
gfp_t gfp_mask = xb_to_gfp(flags);
@@ -369,29 +297,55 @@ _xfs_buf_lookup_pages(
xfs_off_t end;
int error;
+ /*
+ * for buffers that are contained within a single page, just allocate
+ * the memory from the heap - there's no need for the complexity of
+ * page arrays to keep allocation down to order 0.
+ */
+ if (bp->b_buffer_length < PAGE_SIZE) {
+ bp->b_addr = kmem_alloc(bp->b_buffer_length, xb_to_km(flags));
+ if (!bp->b_addr) {
+ /* low memory - use alloc_page loop instead */
+ goto use_alloc_page;
+ }
+
+ if (((unsigned long)(bp->b_addr + bp->b_buffer_length - 1) &
+ PAGE_MASK) !=
+ ((unsigned long)bp->b_addr & PAGE_MASK)) {
+ /* b_addr spans two pages - use alloc_page instead */
+ kmem_free(bp->b_addr);
+ bp->b_addr = NULL;
+ goto use_alloc_page;
+ }
+ bp->b_offset = offset_in_page(bp->b_addr);
+ bp->b_pages = bp->b_page_array;
+ bp->b_pages[0] = virt_to_page(bp->b_addr);
+ bp->b_page_count = 1;
+ bp->b_flags |= XBF_MAPPED | _XBF_KMEM;
+ return 0;
+ }
+
+use_alloc_page:
end = bp->b_file_offset + bp->b_buffer_length;
page_count = xfs_buf_btoc(end) - xfs_buf_btoct(bp->b_file_offset);
-
error = _xfs_buf_get_pages(bp, page_count, flags);
if (unlikely(error))
return error;
- bp->b_flags |= _XBF_PAGE_CACHE;
offset = bp->b_offset;
- first = bp->b_file_offset >> PAGE_CACHE_SHIFT;
+ first = bp->b_file_offset >> PAGE_SHIFT;
+ bp->b_flags |= _XBF_PAGES;
for (i = 0; i < bp->b_page_count; i++) {
struct page *page;
uint retries = 0;
-
- retry:
- page = find_or_create_page(mapping, first + i, gfp_mask);
+retry:
+ page = alloc_page(gfp_mask);
if (unlikely(page == NULL)) {
if (flags & XBF_READ_AHEAD) {
bp->b_page_count = i;
- for (i = 0; i < bp->b_page_count; i++)
- unlock_page(bp->b_pages[i]);
- return -ENOMEM;
+ error = ENOMEM;
+ goto out_free_pages;
}
/*
@@ -412,33 +366,16 @@ _xfs_buf_lookup_pages(
XFS_STATS_INC(xb_page_found);
- nbytes = min_t(size_t, size, PAGE_CACHE_SIZE - offset);
+ nbytes = min_t(size_t, size, PAGE_SIZE - offset);
size -= nbytes;
-
- ASSERT(!PagePrivate(page));
- if (!PageUptodate(page)) {
- page_count--;
- if (blocksize >= PAGE_CACHE_SIZE) {
- if (flags & XBF_READ)
- bp->b_flags |= _XBF_PAGE_LOCKED;
- } else if (!PagePrivate(page)) {
- if (test_page_region(page, offset, nbytes))
- page_count++;
- }
- }
-
bp->b_pages[i] = page;
offset = 0;
}
+ return 0;
- if (!(bp->b_flags & _XBF_PAGE_LOCKED)) {
- for (i = 0; i < bp->b_page_count; i++)
- unlock_page(bp->b_pages[i]);
- }
-
- if (page_count == bp->b_page_count)
- bp->b_flags |= XBF_DONE;
-
+out_free_pages:
+ for (i = 0; i < bp->b_page_count; i++)
+ __free_page(bp->b_pages[i]);
return error;
}
@@ -450,14 +387,23 @@ _xfs_buf_map_pages(
xfs_buf_t *bp,
uint flags)
{
- /* A single page buffer is always mappable */
+ ASSERT(bp->b_flags & _XBF_PAGES);
if (bp->b_page_count == 1) {
+ /* A single page buffer is always mappable */
bp->b_addr = page_address(bp->b_pages[0]) + bp->b_offset;
bp->b_flags |= XBF_MAPPED;
} else if (flags & XBF_MAPPED) {
- bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count,
- -1, PAGE_KERNEL);
- if (unlikely(bp->b_addr == NULL))
+ int retried = 0;
+
+ do {
+ bp->b_addr = vm_map_ram(bp->b_pages, bp->b_page_count,
+ -1, PAGE_KERNEL);
+ if (bp->b_addr)
+ break;
+ vm_unmap_aliases();
+ } while (retried++ <= 1);
+
+ if (!bp->b_addr)
return -ENOMEM;
bp->b_addr += bp->b_offset;
bp->b_flags |= XBF_MAPPED;
@@ -568,9 +514,14 @@ found:
}
}
+ /*
+ * if the buffer is stale, clear all the external state associated with
+ * it. We need to keep flags such as how we allocated the buffer memory
+ * intact here.
+ */
if (bp->b_flags & XBF_STALE) {
ASSERT((bp->b_flags & _XBF_DELWRI_Q) == 0);
- bp->b_flags &= XBF_MAPPED;
+ bp->b_flags &= XBF_MAPPED | _XBF_KMEM | _XBF_PAGES;
}
trace_xfs_buf_find(bp, flags, _RET_IP_);
@@ -591,7 +542,7 @@ xfs_buf_get(
xfs_buf_flags_t flags)
{
xfs_buf_t *bp, *new_bp;
- int error = 0, i;
+ int error = 0;
new_bp = xfs_buf_allocate(flags);
if (unlikely(!new_bp))
@@ -599,7 +550,7 @@ xfs_buf_get(
bp = _xfs_buf_find(target, ioff, isize, flags, new_bp);
if (bp == new_bp) {
- error = _xfs_buf_lookup_pages(bp, flags);
+ error = xfs_buf_allocate_memory(bp, flags);
if (error)
goto no_buffer;
} else {
@@ -608,9 +559,6 @@ xfs_buf_get(
return NULL;
}
- for (i = 0; i < bp->b_page_count; i++)
- mark_page_accessed(bp->b_pages[i]);
-
if (!(bp->b_flags & XBF_MAPPED)) {
error = _xfs_buf_map_pages(bp, flags);
if (unlikely(error)) {
@@ -711,8 +659,7 @@ xfs_buf_readahead(
{
struct backing_dev_info *bdi;
- bdi = target->bt_mapping->backing_dev_info;
- if (bdi_read_congested(bdi))
+ if (bdi_read_congested(target->bt_bdi))
return;
xfs_buf_read(target, ioff, isize,
@@ -790,10 +737,10 @@ xfs_buf_associate_memory(
size_t buflen;
int page_count;
- pageaddr = (unsigned long)mem & PAGE_CACHE_MASK;
+ pageaddr = (unsigned long)mem & PAGE_MASK;
offset = (unsigned long)mem - pageaddr;
- buflen = PAGE_CACHE_ALIGN(len + offset);
- page_count = buflen >> PAGE_CACHE_SHIFT;
+ buflen = PAGE_ALIGN(len + offset);
+ page_count = buflen >> PAGE_SHIFT;
/* Free any previous set of page pointers */
if (bp->b_pages)
@@ -810,13 +757,12 @@ xfs_buf_associate_memory(
for (i = 0; i < bp->b_page_count; i++) {
bp->b_pages[i] = mem_to_page((void *)pageaddr);
- pageaddr += PAGE_CACHE_SIZE;
+ pageaddr += PAGE_SIZE;
}
bp->b_count_desired = len;
bp->b_buffer_length = buflen;
bp->b_flags |= XBF_MAPPED;
- bp->b_flags &= ~_XBF_PAGE_LOCKED;
return 0;
}
@@ -923,20 +869,7 @@ xfs_buf_rele(
/*
- * Mutual exclusion on buffers. Locking model:
- *
- * Buffers associated with inodes for which buffer locking
- * is not enabled are not protected by semaphores, and are
- * assumed to be exclusively owned by the caller. There is a
- * spinlock in the buffer, used by the caller when concurrent
- * access is possible.
- */
-
-/*
- * Locks a buffer object, if it is not already locked. Note that this in
- * no way locks the underlying pages, so it is only useful for
- * synchronizing concurrent use of buffer objects, not for synchronizing
- * independent access to the underlying pages.
+ * Lock a buffer object, if it is not already locked.
*
* If we come across a stale, pinned, locked buffer, we know that we are
* being asked to lock a buffer that has been reallocated. Because it is
@@ -970,10 +903,7 @@ xfs_buf_lock_value(
}
/*
- * Locks a buffer object.
- * Note that this in no way locks the underlying pages, so it is only
- * useful for synchronizing concurrent use of buffer objects, not for
- * synchronizing independent access to the underlying pages.
+ * Lock a buffer object.
*
* If we come across a stale, pinned, locked buffer, we know that we
* are being asked to lock a buffer that has been reallocated. Because
@@ -1246,10 +1176,8 @@ _xfs_buf_ioend(
xfs_buf_t *bp,
int schedule)
{
- if (atomic_dec_and_test(&bp->b_io_remaining) == 1) {
- bp->b_flags &= ~_XBF_PAGE_LOCKED;
+ if (atomic_dec_and_test(&bp->b_io_remaining) == 1)
xfs_buf_ioend(bp, schedule);
- }
}
STATIC void
@@ -1258,35 +1186,12 @@ xfs_buf_bio_end_io(
int error)
{
xfs_buf_t *bp = (xfs_buf_t *)bio->bi_private;
- unsigned int blocksize = bp->b_target->bt_bsize;
- struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
xfs_buf_ioerror(bp, -error);
if (!error && xfs_buf_is_vmapped(bp) && (bp->b_flags & XBF_READ))
invalidate_kernel_vmap_range(bp->b_addr, xfs_buf_vmap_len(bp));
- do {
- struct page *page = bvec->bv_page;
-
- ASSERT(!PagePrivate(page));
- if (unlikely(bp->b_error)) {
- if (bp->b_flags & XBF_READ)
- ClearPageUptodate(page);
- } else if (blocksize >= PAGE_CACHE_SIZE) {
- SetPageUptodate(page);
- } else if (!PagePrivate(page) &&
- (bp->b_flags & _XBF_PAGE_CACHE)) {
- set_page_region(page, bvec->bv_offset, bvec->bv_len);
- }
-
- if (--bvec >= bio->bi_io_vec)
- prefetchw(&bvec->bv_page->flags);
-
- if (bp->b_flags & _XBF_PAGE_LOCKED)
- unlock_page(page);
- } while (bvec >= bio->bi_io_vec);
-
_xfs_buf_ioend(bp, 1);
bio_put(bio);
}
@@ -1300,7 +1205,6 @@ _xfs_buf_ioapply(
int offset = bp->b_offset;
int size = bp->b_count_desired;
sector_t sector = bp->b_bn;
- unsigned int blocksize = bp->b_target->bt_bsize;
total_nr_pages = bp->b_page_count;
map_i = 0;
@@ -1321,29 +1225,6 @@ _xfs_buf_ioapply(
(bp->b_flags & XBF_READ_AHEAD) ? READA : READ;
}
- /* Special code path for reading a sub page size buffer in --
- * we populate up the whole page, and hence the other metadata
- * in the same page. This optimization is only valid when the
- * filesystem block size is not smaller than the page size.
- */
- if ((bp->b_buffer_length < PAGE_CACHE_SIZE) &&
- ((bp->b_flags & (XBF_READ|_XBF_PAGE_LOCKED)) ==
- (XBF_READ|_XBF_PAGE_LOCKED)) &&
- (blocksize >= PAGE_CACHE_SIZE)) {
- bio = bio_alloc(GFP_NOIO, 1);
-
- bio->bi_bdev = bp->b_target->bt_bdev;
- bio->bi_sector = sector - (offset >> BBSHIFT);
- bio->bi_end_io = xfs_buf_bio_end_io;
- bio->bi_private = bp;
-
- bio_add_page(bio, bp->b_pages[0], PAGE_CACHE_SIZE, 0);
- size = 0;
-
- atomic_inc(&bp->b_io_remaining);
-
- goto submit_io;
- }
next_chunk:
atomic_inc(&bp->b_io_remaining);
@@ -1357,8 +1238,9 @@ next_chunk:
bio->bi_end_io = xfs_buf_bio_end_io;
bio->bi_private = bp;
+
for (; size && nr_pages; nr_pages--, map_i++) {
- int rbytes, nbytes = PAGE_CACHE_SIZE - offset;
+ int rbytes, nbytes = PAGE_SIZE - offset;
if (nbytes > size)
nbytes = size;
@@ -1373,7 +1255,6 @@ next_chunk:
total_nr_pages--;
}
-submit_io:
if (likely(bio->bi_size)) {
if (xfs_buf_is_vmapped(bp)) {
flush_kernel_vmap_range(bp->b_addr,
@@ -1383,18 +1264,7 @@ submit_io:
if (size)
goto next_chunk;
} else {
- /*
- * if we get here, no pages were added to the bio. However,
- * we can't just error out here - if the pages are locked then
- * we have to unlock them otherwise we can hang on a later
- * access to the page.
- */
xfs_buf_ioerror(bp, EIO);
- if (bp->b_flags & _XBF_PAGE_LOCKED) {
- int i;
- for (i = 0; i < bp->b_page_count; i++)
- unlock_page(bp->b_pages[i]);
- }
bio_put(bio);
}
}
@@ -1458,8 +1328,8 @@ xfs_buf_offset(
return XFS_BUF_PTR(bp) + offset;
offset += bp->b_offset;
- page = bp->b_pages[offset >> PAGE_CACHE_SHIFT];
- return (xfs_caddr_t)page_address(page) + (offset & (PAGE_CACHE_SIZE-1));
+ page = bp->b_pages[offset >> PAGE_SHIFT];
+ return (xfs_caddr_t)page_address(page) + (offset & (PAGE_SIZE-1));
}
/*
@@ -1481,9 +1351,9 @@ xfs_buf_iomove(
page = bp->b_pages[xfs_buf_btoct(boff + bp->b_offset)];
cpoff = xfs_buf_poff(boff + bp->b_offset);
csize = min_t(size_t,
- PAGE_CACHE_SIZE-cpoff, bp->b_count_desired-boff);
+ PAGE_SIZE-cpoff, bp->b_count_desired-boff);
- ASSERT(((csize + cpoff) <= PAGE_CACHE_SIZE));
+ ASSERT(((csize + cpoff) <= PAGE_SIZE));
switch (mode) {
case XBRW_ZERO:
@@ -1596,7 +1466,6 @@ xfs_free_buftarg(
xfs_flush_buftarg(btp, 1);
if (mp->m_flags & XFS_MOUNT_BARRIER)
xfs_blkdev_issue_flush(btp);
- iput(btp->bt_mapping->host);
kthread_stop(btp->bt_task);
kmem_free(btp);
@@ -1620,15 +1489,6 @@ xfs_setsize_buftarg_flags(
return EINVAL;
}
- if (verbose &&
- (PAGE_CACHE_SIZE / BITS_PER_LONG) > sectorsize) {
- printk(KERN_WARNING
- "XFS: %u byte sectors in use on device %s. "
- "This is suboptimal; %u or greater is ideal.\n",
- sectorsize, XFS_BUFTARG_NAME(btp),
- (unsigned int)PAGE_CACHE_SIZE / BITS_PER_LONG);
- }
-
return 0;
}
@@ -1643,7 +1503,7 @@ xfs_setsize_buftarg_early(
struct block_device *bdev)
{
return xfs_setsize_buftarg_flags(btp,
- PAGE_CACHE_SIZE, bdev_logical_block_size(bdev), 0);
+ PAGE_SIZE, bdev_logical_block_size(bdev), 0);
}
int
@@ -1656,40 +1516,6 @@ xfs_setsize_buftarg(
}
STATIC int
-xfs_mapping_buftarg(
- xfs_buftarg_t *btp,
- struct block_device *bdev)
-{
- struct backing_dev_info *bdi;
- struct inode *inode;
- struct address_space *mapping;
- static const struct address_space_operations mapping_aops = {
- .migratepage = fail_migrate_page,
- };
-
- inode = new_inode(bdev->bd_inode->i_sb);
- if (!inode) {
- printk(KERN_WARNING
- "XFS: Cannot allocate mapping inode for device %s\n",
- XFS_BUFTARG_NAME(btp));
- return ENOMEM;
- }
- inode->i_ino = get_next_ino();
- inode->i_mode = S_IFBLK;
- inode->i_bdev = bdev;
- inode->i_rdev = bdev->bd_dev;
- bdi = blk_get_backing_dev_info(bdev);
- if (!bdi)
- bdi = &default_backing_dev_info;
- mapping = &inode->i_data;
- mapping->a_ops = &mapping_aops;
- mapping->backing_dev_info = bdi;
- mapping_set_gfp_mask(mapping, GFP_NOFS);
- btp->bt_mapping = mapping;
- return 0;
-}
-
-STATIC int
xfs_alloc_delwrite_queue(
xfs_buftarg_t *btp,
const char *fsname)
@@ -1717,12 +1543,14 @@ xfs_alloc_buftarg(
btp->bt_mount = mp;
btp->bt_dev = bdev->bd_dev;
btp->bt_bdev = bdev;
+ btp->bt_bdi = blk_get_backing_dev_info(bdev);
+ if (!btp->bt_bdi)
+ goto error;
+
INIT_LIST_HEAD(&btp->bt_lru);
spin_lock_init(&btp->bt_lru_lock);
if (xfs_setsize_buftarg_early(btp, bdev))
goto error;
- if (xfs_mapping_buftarg(btp, bdev))
- goto error;
if (xfs_alloc_delwrite_queue(btp, fsname))
goto error;
btp->bt_shrinker.shrink = xfs_buftarg_shrink;
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index cbe65950e52..a9a1c451264 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -61,30 +61,11 @@ typedef enum {
#define XBF_DONT_BLOCK (1 << 16)/* do not block in current thread */
/* flags used only internally */
-#define _XBF_PAGE_CACHE (1 << 17)/* backed by pagecache */
#define _XBF_PAGES (1 << 18)/* backed by refcounted pages */
#define _XBF_RUN_QUEUES (1 << 19)/* run block device task queue */
+#define _XBF_KMEM (1 << 20)/* backed by heap memory */
#define _XBF_DELWRI_Q (1 << 21)/* buffer on delwri queue */
-/*
- * Special flag for supporting metadata blocks smaller than a FSB.
- *
- * In this case we can have multiple xfs_buf_t on a single page and
- * need to lock out concurrent xfs_buf_t readers as they only
- * serialise access to the buffer.
- *
- * If the FSB size >= PAGE_CACHE_SIZE case, we have no serialisation
- * between reads of the page. Hence we can have one thread read the
- * page and modify it, but then race with another thread that thinks
- * the page is not up-to-date and hence reads it again.
- *
- * The result is that the first modifcation to the page is lost.
- * This sort of AGF/AGI reading race can happen when unlinking inodes
- * that require truncation and results in the AGI unlinked list
- * modifications being lost.
- */
-#define _XBF_PAGE_LOCKED (1 << 22)
-
typedef unsigned int xfs_buf_flags_t;
#define XFS_BUF_FLAGS \
@@ -100,12 +81,10 @@ typedef unsigned int xfs_buf_flags_t;
{ XBF_LOCK, "LOCK" }, /* should never be set */\
{ XBF_TRYLOCK, "TRYLOCK" }, /* ditto */\
{ XBF_DONT_BLOCK, "DONT_BLOCK" }, /* ditto */\
- { _XBF_PAGE_CACHE, "PAGE_CACHE" }, \
{ _XBF_PAGES, "PAGES" }, \
{ _XBF_RUN_QUEUES, "RUN_QUEUES" }, \
- { _XBF_DELWRI_Q, "DELWRI_Q" }, \
- { _XBF_PAGE_LOCKED, "PAGE_LOCKED" }
-
+ { _XBF_KMEM, "KMEM" }, \
+ { _XBF_DELWRI_Q, "DELWRI_Q" }
typedef enum {
XBT_FORCE_SLEEP = 0,
@@ -120,7 +99,7 @@ typedef struct xfs_bufhash {
typedef struct xfs_buftarg {
dev_t bt_dev;
struct block_device *bt_bdev;
- struct address_space *bt_mapping;
+ struct backing_dev_info *bt_bdi;
struct xfs_mount *bt_mount;
unsigned int bt_bsize;
unsigned int bt_sshift;
@@ -139,17 +118,6 @@ typedef struct xfs_buftarg {
unsigned int bt_lru_nr;
} xfs_buftarg_t;
-/*
- * xfs_buf_t: Buffer structure for pagecache-based buffers
- *
- * This buffer structure is used by the pagecache buffer management routines
- * to refer to an assembly of pages forming a logical buffer.
- *
- * The buffer structure is used on a temporary basis only, and discarded when
- * released. The real data storage is recorded in the pagecache. Buffers are
- * hashed to the block device on which the file system resides.
- */
-
struct xfs_buf;
typedef void (*xfs_buf_iodone_t)(struct xfs_buf *);
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index a55c1b46b21..52aadfbed13 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -896,6 +896,7 @@ xfs_file_fallocate(
xfs_flock64_t bf;
xfs_inode_t *ip = XFS_I(inode);
int cmd = XFS_IOC_RESVSP;
+ int attr_flags = XFS_ATTR_NOLOCK;
if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
return -EOPNOTSUPP;
@@ -918,7 +919,10 @@ xfs_file_fallocate(
goto out_unlock;
}
- error = -xfs_change_file_space(ip, cmd, &bf, 0, XFS_ATTR_NOLOCK);
+ if (file->f_flags & O_DSYNC)
+ attr_flags |= XFS_ATTR_SYNC;
+
+ error = -xfs_change_file_space(ip, cmd, &bf, 0, attr_flags);
if (error)
goto out_unlock;
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 0ca0e3c024d..acca2c5ca3f 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -624,6 +624,10 @@ xfs_ioc_space(
if (filp->f_flags & (O_NDELAY|O_NONBLOCK))
attr_flags |= XFS_ATTR_NONBLOCK;
+
+ if (filp->f_flags & O_DSYNC)
+ attr_flags |= XFS_ATTR_SYNC;
+
if (ioflags & IO_INVIS)
attr_flags |= XFS_ATTR_DMI;
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 818c4cf2de8..1ba5c451da3 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -1078,7 +1078,7 @@ xfs_fs_write_inode(
error = 0;
goto out_unlock;
}
- error = xfs_iflush(ip, 0);
+ error = xfs_iflush(ip, SYNC_TRYLOCK);
}
out_unlock:
@@ -1539,10 +1539,14 @@ xfs_fs_fill_super(
if (error)
goto out_free_sb;
- error = xfs_mountfs(mp);
- if (error)
- goto out_filestream_unmount;
-
+ /*
+ * we must configure the block size in the superblock before we run the
+ * full mount process as the mount process can lookup and cache inodes.
+ * For the same reason we must also initialise the syncd and register
+ * the inode cache shrinker so that inodes can be reclaimed during
+ * operations like a quotacheck that iterate all inodes in the
+ * filesystem.
+ */
sb->s_magic = XFS_SB_MAGIC;
sb->s_blocksize = mp->m_sb.sb_blocksize;
sb->s_blocksize_bits = ffs(sb->s_blocksize) - 1;
@@ -1550,6 +1554,16 @@ xfs_fs_fill_super(
sb->s_time_gran = 1;
set_posix_acl_flag(sb);
+ error = xfs_syncd_init(mp);
+ if (error)
+ goto out_filestream_unmount;
+
+ xfs_inode_shrinker_register(mp);
+
+ error = xfs_mountfs(mp);
+ if (error)
+ goto out_syncd_stop;
+
root = igrab(VFS_I(mp->m_rootip));
if (!root) {
error = ENOENT;
@@ -1565,14 +1579,11 @@ xfs_fs_fill_super(
goto fail_vnrele;
}
- error = xfs_syncd_init(mp);
- if (error)
- goto fail_vnrele;
-
- xfs_inode_shrinker_register(mp);
-
return 0;
+ out_syncd_stop:
+ xfs_inode_shrinker_unregister(mp);
+ xfs_syncd_stop(mp);
out_filestream_unmount:
xfs_filestream_unmount(mp);
out_free_sb:
@@ -1596,6 +1607,9 @@ xfs_fs_fill_super(
}
fail_unmount:
+ xfs_inode_shrinker_unregister(mp);
+ xfs_syncd_stop(mp);
+
/*
* Blow away any referenced inode in the filestreams cache.
* This can and will cause log traffic as inodes go inactive
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c
index 6c10f1d2e3d..594cd822d84 100644
--- a/fs/xfs/linux-2.6/xfs_sync.c
+++ b/fs/xfs/linux-2.6/xfs_sync.c
@@ -761,8 +761,10 @@ xfs_reclaim_inode(
struct xfs_perag *pag,
int sync_mode)
{
- int error = 0;
+ int error;
+restart:
+ error = 0;
xfs_ilock(ip, XFS_ILOCK_EXCL);
if (!xfs_iflock_nowait(ip)) {
if (!(sync_mode & SYNC_WAIT))
@@ -788,9 +790,31 @@ xfs_reclaim_inode(
if (xfs_inode_clean(ip))
goto reclaim;
- /* Now we have an inode that needs flushing */
- error = xfs_iflush(ip, sync_mode);
+ /*
+ * Now we have an inode that needs flushing.
+ *
+ * We do a nonblocking flush here even if we are doing a SYNC_WAIT
+ * reclaim as we can deadlock with inode cluster removal.
+ * xfs_ifree_cluster() can lock the inode buffer before it locks the
+ * ip->i_lock, and we are doing the exact opposite here. As a result,
+ * doing a blocking xfs_itobp() to get the cluster buffer will result
+ * in an ABBA deadlock with xfs_ifree_cluster().
+ *
+ * As xfs_ifree_cluser() must gather all inodes that are active in the
+ * cache to mark them stale, if we hit this case we don't actually want
+ * to do IO here - we want the inode marked stale so we can simply
+ * reclaim it. Hence if we get an EAGAIN error on a SYNC_WAIT flush,
+ * just unlock the inode, back off and try again. Hopefully the next
+ * pass through will see the stale flag set on the inode.
+ */
+ error = xfs_iflush(ip, SYNC_TRYLOCK | sync_mode);
if (sync_mode & SYNC_WAIT) {
+ if (error == EAGAIN) {
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
+ /* backoff longer than in xfs_ifree_cluster */
+ delay(2);
+ goto restart;
+ }
xfs_iflock(ip);
goto reclaim;
}
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index da871f53223..742c8330994 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -2835,7 +2835,7 @@ xfs_iflush(
* Get the buffer containing the on-disk inode.
*/
error = xfs_itobp(mp, NULL, ip, &dip, &bp,
- (flags & SYNC_WAIT) ? XBF_LOCK : XBF_TRYLOCK);
+ (flags & SYNC_TRYLOCK) ? XBF_TRYLOCK : XBF_LOCK);
if (error || !bp) {
xfs_ifunlock(ip);
return error;
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c
index fd4f398bd6f..46cc40131d4 100644
--- a/fs/xfs/xfs_inode_item.c
+++ b/fs/xfs/xfs_inode_item.c
@@ -760,11 +760,11 @@ xfs_inode_item_push(
* Push the inode to it's backing buffer. This will not remove the
* inode from the AIL - a further push will be required to trigger a
* buffer push. However, this allows all the dirty inodes to be pushed
- * to the buffer before it is pushed to disk. THe buffer IO completion
- * will pull th einode from the AIL, mark it clean and unlock the flush
+ * to the buffer before it is pushed to disk. The buffer IO completion
+ * will pull the inode from the AIL, mark it clean and unlock the flush
* lock.
*/
- (void) xfs_iflush(ip, 0);
+ (void) xfs_iflush(ip, SYNC_TRYLOCK);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
}
diff --git a/fs/xfs/xfs_trans_buf.c b/fs/xfs/xfs_trans_buf.c
index 3bea6613233..03b3b7f85a3 100644
--- a/fs/xfs/xfs_trans_buf.c
+++ b/fs/xfs/xfs_trans_buf.c
@@ -383,7 +383,8 @@ xfs_trans_read_buf(
bp = xfs_buf_read(target, blkno, len, flags | XBF_DONT_BLOCK);
if (bp == NULL) {
*bpp = NULL;
- return 0;
+ return (flags & XBF_TRYLOCK) ?
+ 0 : XFS_ERROR(ENOMEM);
}
if (XFS_BUF_GETERROR(bp) != 0) {
XFS_BUF_SUPER_STALE(bp);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 37d8146ee15..c48b4217ec4 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -2831,7 +2831,8 @@ xfs_change_file_space(
ip->i_d.di_flags &= ~XFS_DIFLAG_PREALLOC;
xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
- xfs_trans_set_sync(tp);
+ if (attr_flags & XFS_ATTR_SYNC)
+ xfs_trans_set_sync(tp);
error = xfs_trans_commit(tp, 0);
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h
index f6702927eee..3bcd23353d6 100644
--- a/fs/xfs/xfs_vnodeops.h
+++ b/fs/xfs/xfs_vnodeops.h
@@ -18,6 +18,7 @@ int xfs_setattr(struct xfs_inode *ip, struct iattr *vap, int flags);
#define XFS_ATTR_NONBLOCK 0x02 /* return EAGAIN if operation would block */
#define XFS_ATTR_NOLOCK 0x04 /* Don't grab any conflicting locks */
#define XFS_ATTR_NOACL 0x08 /* Don't call xfs_acl_chmod */
+#define XFS_ATTR_SYNC 0x10 /* synchronous operation required */
int xfs_readlink(struct xfs_inode *ip, char *link);
int xfs_release(struct xfs_inode *ip);
diff --git a/include/keys/ceph-type.h b/include/keys/ceph-type.h
new file mode 100644
index 00000000000..f69c4ac197a
--- /dev/null
+++ b/include/keys/ceph-type.h
@@ -0,0 +1,8 @@
+#ifndef _KEYS_CEPH_TYPE_H
+#define _KEYS_CEPH_TYPE_H
+
+#include <linux/key.h>
+
+extern struct key_type key_type_ceph;
+
+#endif
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index 475f8c42c0e..381f4cec826 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -443,6 +443,7 @@ void atm_dev_signal_change(struct atm_dev *dev, char signal);
void vcc_insert_socket(struct sock *sk);
+void atm_dev_release_vccs(struct atm_dev *dev);
/*
* This is approximately the algorithm used by alloc_skb.
diff --git a/include/linux/can/core.h b/include/linux/can/core.h
index 6c507bea275..6f70a6d3a16 100644
--- a/include/linux/can/core.h
+++ b/include/linux/can/core.h
@@ -36,10 +36,10 @@
* @prot: pointer to struct proto structure.
*/
struct can_proto {
- int type;
- int protocol;
- struct proto_ops *ops;
- struct proto *prot;
+ int type;
+ int protocol;
+ const struct proto_ops *ops;
+ struct proto *prot;
};
/* function prototypes for the CAN networklayer core (af_can.c) */
@@ -58,5 +58,6 @@ extern void can_rx_unregister(struct net_device *dev, canid_t can_id,
void *data);
extern int can_send(struct sk_buff *skb, int loop);
+extern int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
#endif /* CAN_CORE_H */
diff --git a/include/linux/ceph/auth.h b/include/linux/ceph/auth.h
index 7fff521d7eb..aa13392a7ef 100644
--- a/include/linux/ceph/auth.h
+++ b/include/linux/ceph/auth.h
@@ -67,12 +67,12 @@ struct ceph_auth_client {
bool negotiating; /* true if negotiating protocol */
const char *name; /* entity name */
u64 global_id; /* our unique id in system */
- const char *secret; /* our secret key */
+ const struct ceph_crypto_key *key; /* our secret key */
unsigned want_keys; /* which services we want */
};
extern struct ceph_auth_client *ceph_auth_init(const char *name,
- const char *secret);
+ const struct ceph_crypto_key *key);
extern void ceph_auth_destroy(struct ceph_auth_client *ac);
extern void ceph_auth_reset(struct ceph_auth_client *ac);
diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h
index 0d2e0fffb47..6365f041745 100644
--- a/include/linux/ceph/libceph.h
+++ b/include/linux/ceph/libceph.h
@@ -61,7 +61,7 @@ struct ceph_options {
pointer type of args */
int num_mon;
char *name;
- char *secret;
+ struct ceph_crypto_key *key;
};
/*
diff --git a/include/linux/connector.h b/include/linux/connector.h
index bcafc942e5e..7c60d0942ad 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -88,8 +88,6 @@ struct cn_queue_dev {
atomic_t refcnt;
unsigned char name[CN_CBQ_NAMELEN];
- struct workqueue_struct *cn_queue;
-
struct list_head queue_list;
spinlock_t queue_lock;
@@ -101,20 +99,13 @@ struct cn_callback_id {
struct cb_id id;
};
-struct cn_callback_data {
- struct sk_buff *skb;
- void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
-
- void *free;
-};
-
struct cn_callback_entry {
struct list_head callback_entry;
- struct work_struct work;
+ atomic_t refcnt;
struct cn_queue_dev *pdev;
struct cn_callback_id id;
- struct cn_callback_data data;
+ void (*callback) (struct cn_msg *, struct netlink_skb_parms *);
u32 seq, group;
};
@@ -138,13 +129,12 @@ int cn_queue_add_callback(struct cn_queue_dev *dev, const char *name,
struct cb_id *id,
void (*callback)(struct cn_msg *, struct netlink_skb_parms *));
void cn_queue_del_callback(struct cn_queue_dev *dev, struct cb_id *id);
+void cn_queue_release_callback(struct cn_callback_entry *);
struct cn_queue_dev *cn_queue_alloc_dev(const char *name, struct sock *);
void cn_queue_free_dev(struct cn_queue_dev *dev);
int cn_cb_equal(struct cb_id *, struct cb_id *);
-void cn_queue_wrapper(struct work_struct *work);
-
#endif /* __KERNEL__ */
#endif /* __CONNECTOR_H */
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index ae757bcf128..c8fcbdd2b0e 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -680,6 +680,7 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data);
u32 ethtool_op_get_flags(struct net_device *dev);
int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported);
void ethtool_ntuple_flush(struct net_device *dev);
+bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported);
/**
* &ethtool_ops - Alter and report network device settings
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b677bd77f2d..52f283c1edb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -357,6 +357,8 @@ struct inodes_stat_t {
#define FS_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
#define FS_EXTENT_FL 0x00080000 /* Extents */
#define FS_DIRECTIO_FL 0x00100000 /* Use direct i/o */
+#define FS_NOCOW_FL 0x00800000 /* Do not cow file */
+#define FS_COW_FL 0x02000000 /* Cow file */
#define FS_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
#define FS_FL_USER_VISIBLE 0x0003DFFF /* User visible flags */
diff --git a/include/linux/input.h b/include/linux/input.h
index 056ae8a5bd9..f3a7794a18c 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -664,6 +664,13 @@ struct input_keymap_entry {
#define KEY_TOUCHPAD_ON 0x213
#define KEY_TOUCHPAD_OFF 0x214
+#define KEY_CAMERA_ZOOMIN 0x215
+#define KEY_CAMERA_ZOOMOUT 0x216
+#define KEY_CAMERA_UP 0x217
+#define KEY_CAMERA_DOWN 0x218
+#define KEY_CAMERA_LEFT 0x219
+#define KEY_CAMERA_RIGHT 0x21a
+
#define BTN_TRIGGER_HAPPY 0x2c0
#define BTN_TRIGGER_HAPPY1 0x2c0
#define BTN_TRIGGER_HAPPY2 0x2c1
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 59b72ca1c5d..943c9b53695 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -338,14 +338,6 @@ static inline void enable_irq_lockdep_irqrestore(unsigned int irq, unsigned long
/* IRQ wakeup (PM) control: */
extern int irq_set_irq_wake(unsigned int irq, unsigned int on);
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
-/* Please do not use: Use the replacement functions instead */
-static inline int set_irq_wake(unsigned int irq, unsigned int on)
-{
- return irq_set_irq_wake(irq, on);
-}
-#endif
-
static inline int enable_irq_wake(unsigned int irq)
{
return irq_set_irq_wake(irq, 1);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index 5d876c9b3a3..09a308072f5 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -64,13 +64,6 @@ typedef void (*irq_preflow_handler_t)(struct irq_data *data);
* IRQ_NO_BALANCING - Interrupt cannot be balanced (affinity set)
* IRQ_MOVE_PCNTXT - Interrupt can be migrated from process context
* IRQ_NESTED_TRHEAD - Interrupt nests into another thread
- *
- * Deprecated bits. They are kept updated as long as
- * CONFIG_GENERIC_HARDIRQS_NO_COMPAT is not set. Will go away soon. These bits
- * are internal state of the core code and if you really need to acces
- * them then talk to the genirq maintainer instead of hacking
- * something weird.
- *
*/
enum {
IRQ_TYPE_NONE = 0x00000000,
@@ -92,18 +85,6 @@ enum {
IRQ_NO_BALANCING = (1 << 13),
IRQ_MOVE_PCNTXT = (1 << 14),
IRQ_NESTED_THREAD = (1 << 15),
-
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
- IRQ_INPROGRESS = (1 << 16),
- IRQ_REPLAY = (1 << 17),
- IRQ_WAITING = (1 << 18),
- IRQ_DISABLED = (1 << 19),
- IRQ_PENDING = (1 << 20),
- IRQ_MASKED = (1 << 21),
- IRQ_MOVE_PENDING = (1 << 22),
- IRQ_AFFINITY_SET = (1 << 23),
- IRQ_WAKEUP = (1 << 24),
-#endif
};
#define IRQF_MODIFY_MASK \
@@ -135,7 +116,7 @@ struct msi_desc;
* struct irq_data - per irq and irq chip data passed down to chip functions
* @irq: interrupt number
* @node: node index useful for balancing
- * @state_use_accessor: status information for irq chip functions.
+ * @state_use_accessors: status information for irq chip functions.
* Use accessor functions to deal with it
* @chip: low level interrupt hardware access
* @handler_data: per-IRQ data for the irq_chip methods
@@ -174,6 +155,9 @@ struct irq_data {
* from suspend
* IRDQ_MOVE_PCNTXT - Interrupt can be moved in process
* context
+ * IRQD_IRQ_DISABLED - Disabled state of the interrupt
+ * IRQD_IRQ_MASKED - Masked state of the interrupt
+ * IRQD_IRQ_INPROGRESS - In progress state of the interrupt
*/
enum {
IRQD_TRIGGER_MASK = 0xf,
@@ -184,6 +168,9 @@ enum {
IRQD_LEVEL = (1 << 13),
IRQD_WAKEUP_STATE = (1 << 14),
IRQD_MOVE_PCNTXT = (1 << 15),
+ IRQD_IRQ_DISABLED = (1 << 16),
+ IRQD_IRQ_MASKED = (1 << 17),
+ IRQD_IRQ_INPROGRESS = (1 << 18),
};
static inline bool irqd_is_setaffinity_pending(struct irq_data *d)
@@ -206,6 +193,11 @@ static inline bool irqd_affinity_was_set(struct irq_data *d)
return d->state_use_accessors & IRQD_AFFINITY_SET;
}
+static inline void irqd_mark_affinity_was_set(struct irq_data *d)
+{
+ d->state_use_accessors |= IRQD_AFFINITY_SET;
+}
+
static inline u32 irqd_get_trigger_type(struct irq_data *d)
{
return d->state_use_accessors & IRQD_TRIGGER_MASK;
@@ -235,6 +227,36 @@ static inline bool irqd_can_move_in_process_context(struct irq_data *d)
return d->state_use_accessors & IRQD_MOVE_PCNTXT;
}
+static inline bool irqd_irq_disabled(struct irq_data *d)
+{
+ return d->state_use_accessors & IRQD_IRQ_DISABLED;
+}
+
+static inline bool irqd_irq_masked(struct irq_data *d)
+{
+ return d->state_use_accessors & IRQD_IRQ_MASKED;
+}
+
+static inline bool irqd_irq_inprogress(struct irq_data *d)
+{
+ return d->state_use_accessors & IRQD_IRQ_INPROGRESS;
+}
+
+/*
+ * Functions for chained handlers which can be enabled/disabled by the
+ * standard disable_irq/enable_irq calls. Must be called with
+ * irq_desc->lock held.
+ */
+static inline void irqd_set_chained_irq_inprogress(struct irq_data *d)
+{
+ d->state_use_accessors |= IRQD_IRQ_INPROGRESS;
+}
+
+static inline void irqd_clr_chained_irq_inprogress(struct irq_data *d)
+{
+ d->state_use_accessors &= ~IRQD_IRQ_INPROGRESS;
+}
+
/**
* struct irq_chip - hardware interrupt chip descriptor
*
@@ -271,6 +293,8 @@ static inline bool irqd_can_move_in_process_context(struct irq_data *d)
* @irq_set_wake: enable/disable power-management wake-on of an IRQ
* @irq_bus_lock: function to lock access to slow bus (i2c) chips
* @irq_bus_sync_unlock:function to sync and unlock slow bus (i2c) chips
+ * @irq_cpu_online: configure an interrupt source for a secondary CPU
+ * @irq_cpu_offline: un-configure an interrupt source for a secondary CPU
* @irq_print_chip: optional to print special chip info in show_interrupts
* @flags: chip specific flags
*
@@ -278,28 +302,6 @@ static inline bool irqd_can_move_in_process_context(struct irq_data *d)
*/
struct irq_chip {
const char *name;
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
- unsigned int (*startup)(unsigned int irq);
- void (*shutdown)(unsigned int irq);
- void (*enable)(unsigned int irq);
- void (*disable)(unsigned int irq);
-
- void (*ack)(unsigned int irq);
- void (*mask)(unsigned int irq);
- void (*mask_ack)(unsigned int irq);
- void (*unmask)(unsigned int irq);
- void (*eoi)(unsigned int irq);
-
- void (*end)(unsigned int irq);
- int (*set_affinity)(unsigned int irq,
- const struct cpumask *dest);
- int (*retrigger)(unsigned int irq);
- int (*set_type)(unsigned int irq, unsigned int flow_type);
- int (*set_wake)(unsigned int irq, unsigned int on);
-
- void (*bus_lock)(unsigned int irq);
- void (*bus_sync_unlock)(unsigned int irq);
-#endif
unsigned int (*irq_startup)(struct irq_data *data);
void (*irq_shutdown)(struct irq_data *data);
void (*irq_enable)(struct irq_data *data);
@@ -319,6 +321,9 @@ struct irq_chip {
void (*irq_bus_lock)(struct irq_data *data);
void (*irq_bus_sync_unlock)(struct irq_data *data);
+ void (*irq_cpu_online)(struct irq_data *data);
+ void (*irq_cpu_offline)(struct irq_data *data);
+
void (*irq_print_chip)(struct irq_data *data, struct seq_file *p);
unsigned long flags;
@@ -335,11 +340,14 @@ struct irq_chip {
* IRQCHIP_SET_TYPE_MASKED: Mask before calling chip.irq_set_type()
* IRQCHIP_EOI_IF_HANDLED: Only issue irq_eoi() when irq was handled
* IRQCHIP_MASK_ON_SUSPEND: Mask non wake irqs in the suspend path
+ * IRQCHIP_ONOFFLINE_ENABLED: Only call irq_on/off_line callbacks
+ * when irq enabled
*/
enum {
IRQCHIP_SET_TYPE_MASKED = (1 << 0),
IRQCHIP_EOI_IF_HANDLED = (1 << 1),
IRQCHIP_MASK_ON_SUSPEND = (1 << 2),
+ IRQCHIP_ONOFFLINE_ENABLED = (1 << 3),
};
/* This include will go away once we isolated irq_desc usage to core code */
@@ -364,25 +372,22 @@ struct irqaction;
extern int setup_irq(unsigned int irq, struct irqaction *new);
extern void remove_irq(unsigned int irq, struct irqaction *act);
+extern void irq_cpu_online(void);
+extern void irq_cpu_offline(void);
+extern int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *cpumask);
+
#ifdef CONFIG_GENERIC_HARDIRQS
#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_PENDING_IRQ)
-void move_native_irq(int irq);
-void move_masked_irq(int irq);
void irq_move_irq(struct irq_data *data);
void irq_move_masked_irq(struct irq_data *data);
#else
-static inline void move_native_irq(int irq) { }
-static inline void move_masked_irq(int irq) { }
static inline void irq_move_irq(struct irq_data *data) { }
static inline void irq_move_masked_irq(struct irq_data *data) { }
#endif
extern int no_irq_affinity;
-/* Handle irq action chains: */
-extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action);
-
/*
* Built-in IRQ handlers for various IRQ types,
* callable via desc->handle_irq()
@@ -390,6 +395,7 @@ extern irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action);
extern void handle_level_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_edge_irq(unsigned int irq, struct irq_desc *desc);
+extern void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_simple_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_percpu_irq(unsigned int irq, struct irq_desc *desc);
extern void handle_bad_irq(unsigned int irq, struct irq_desc *desc);
@@ -538,89 +544,6 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d)
return d->msi_desc;
}
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
-/* Please do not use: Use the replacement functions instead */
-static inline int set_irq_chip(unsigned int irq, struct irq_chip *chip)
-{
- return irq_set_chip(irq, chip);
-}
-static inline int set_irq_data(unsigned int irq, void *data)
-{
- return irq_set_handler_data(irq, data);
-}
-static inline int set_irq_chip_data(unsigned int irq, void *data)
-{
- return irq_set_chip_data(irq, data);
-}
-static inline int set_irq_type(unsigned int irq, unsigned int type)
-{
- return irq_set_irq_type(irq, type);
-}
-static inline int set_irq_msi(unsigned int irq, struct msi_desc *entry)
-{
- return irq_set_msi_desc(irq, entry);
-}
-static inline struct irq_chip *get_irq_chip(unsigned int irq)
-{
- return irq_get_chip(irq);
-}
-static inline void *get_irq_chip_data(unsigned int irq)
-{
- return irq_get_chip_data(irq);
-}
-static inline void *get_irq_data(unsigned int irq)
-{
- return irq_get_handler_data(irq);
-}
-static inline void *irq_data_get_irq_data(struct irq_data *d)
-{
- return irq_data_get_irq_handler_data(d);
-}
-static inline struct msi_desc *get_irq_msi(unsigned int irq)
-{
- return irq_get_msi_desc(irq);
-}
-static inline void set_irq_noprobe(unsigned int irq)
-{
- irq_set_noprobe(irq);
-}
-static inline void set_irq_probe(unsigned int irq)
-{
- irq_set_probe(irq);
-}
-static inline void set_irq_nested_thread(unsigned int irq, int nest)
-{
- irq_set_nested_thread(irq, nest);
-}
-static inline void
-set_irq_chip_and_handler_name(unsigned int irq, struct irq_chip *chip,
- irq_flow_handler_t handle, const char *name)
-{
- irq_set_chip_and_handler_name(irq, chip, handle, name);
-}
-static inline void
-set_irq_chip_and_handler(unsigned int irq, struct irq_chip *chip,
- irq_flow_handler_t handle)
-{
- irq_set_chip_and_handler(irq, chip, handle);
-}
-static inline void
-__set_irq_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
- const char *name)
-{
- __irq_set_handler(irq, handle, is_chained, name);
-}
-static inline void set_irq_handler(unsigned int irq, irq_flow_handler_t handle)
-{
- irq_set_handler(irq, handle);
-}
-static inline void
-set_irq_chained_handler(unsigned int irq, irq_flow_handler_t handle)
-{
- irq_set_chained_handler(irq, handle);
-}
-#endif
-
int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node);
void irq_free_descs(unsigned int irq, unsigned int cnt);
int irq_reserve_irqs(unsigned int from, unsigned int cnt);
diff --git a/include/linux/irqdesc.h b/include/linux/irqdesc.h
index 15e6c3905f4..a082905b5eb 100644
--- a/include/linux/irqdesc.h
+++ b/include/linux/irqdesc.h
@@ -35,32 +35,7 @@ struct timer_rand_state;
* @name: flow handler name for /proc/interrupts output
*/
struct irq_desc {
-
-#ifdef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
struct irq_data irq_data;
-#else
- /*
- * This union will go away, once we fixed the direct access to
- * irq_desc all over the place. The direct fields are a 1:1
- * overlay of irq_data.
- */
- union {
- struct irq_data irq_data;
- struct {
- unsigned int irq;
- unsigned int node;
- unsigned int pad_do_not_even_think_about_it;
- struct irq_chip *chip;
- void *handler_data;
- void *chip_data;
- struct msi_desc *msi_desc;
-#ifdef CONFIG_SMP
- cpumask_var_t affinity;
-#endif
- };
- };
-#endif
-
struct timer_rand_state *timer_rand_state;
unsigned int __percpu *kstat_irqs;
irq_flow_handler_t handle_irq;
@@ -68,11 +43,7 @@ struct irq_desc {
irq_preflow_handler_t preflow_handler;
#endif
struct irqaction *action; /* IRQ action list */
-#ifdef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
unsigned int status_use_accessors;
-#else
- unsigned int status; /* IRQ status */
-#endif
unsigned int core_internal_state__do_not_mess_with_it;
unsigned int depth; /* nested irq disables */
unsigned int wake_depth; /* nested wake enables */
@@ -127,27 +98,6 @@ static inline struct msi_desc *irq_desc_get_msi_desc(struct irq_desc *desc)
return desc->irq_data.msi_desc;
}
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
-static inline struct irq_chip *get_irq_desc_chip(struct irq_desc *desc)
-{
- return irq_desc_get_chip(desc);
-}
-static inline void *get_irq_desc_data(struct irq_desc *desc)
-{
- return irq_desc_get_handler_data(desc);
-}
-
-static inline void *get_irq_desc_chip_data(struct irq_desc *desc)
-{
- return irq_desc_get_chip_data(desc);
-}
-
-static inline struct msi_desc *get_irq_desc_msi(struct irq_desc *desc)
-{
- return irq_desc_get_msi_desc(desc);
-}
-#endif
-
/*
* Architectures call this to let the generic IRQ layer
* handle an interrupt. If the descriptor is attached to an
@@ -194,21 +144,13 @@ __irq_set_chip_handler_name_locked(unsigned int irq, struct irq_chip *chip,
desc->name = name;
}
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
-static inline void __set_irq_handler_unlocked(int irq,
- irq_flow_handler_t handler)
-{
- __irq_set_handler_locked(irq, handler);
-}
-
static inline int irq_balancing_disabled(unsigned int irq)
{
struct irq_desc *desc;
desc = irq_to_desc(irq);
- return desc->status & IRQ_NO_BALANCING_MASK;
+ return desc->status_use_accessors & IRQ_NO_BALANCING_MASK;
}
-#endif
static inline void
irq_set_lockdep_class(unsigned int irq, struct lock_class_key *class)
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 03e8e8dbc57..c2478a342cd 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -208,6 +208,7 @@ int __init parse_crashkernel(char *cmdline, unsigned long long system_ram,
unsigned long long *crash_size, unsigned long long *crash_base);
int crash_shrink_memory(unsigned long new_size);
size_t crash_get_memory_size(void);
+void crash_free_reserved_phys_range(unsigned long begin, unsigned long end);
#else /* !CONFIG_KEXEC */
struct pt_regs;
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h
index 56f8dea7215..b3184307519 100644
--- a/include/linux/mfd/ab8500.h
+++ b/include/linux/mfd/ab8500.h
@@ -74,6 +74,45 @@
#define AB8500_INT_ACC_DETECT_21DB_F 37
#define AB8500_INT_ACC_DETECT_21DB_R 38
#define AB8500_INT_GP_SW_ADC_CONV_END 39
+#define AB8500_INT_ACC_DETECT_1DB_F 33
+#define AB8500_INT_ACC_DETECT_1DB_R 34
+#define AB8500_INT_ACC_DETECT_22DB_F 35
+#define AB8500_INT_ACC_DETECT_22DB_R 36
+#define AB8500_INT_ACC_DETECT_21DB_F 37
+#define AB8500_INT_ACC_DETECT_21DB_R 38
+#define AB8500_INT_GP_SW_ADC_CONV_END 39
+#define AB8500_INT_GPIO6R 40
+#define AB8500_INT_GPIO7R 41
+#define AB8500_INT_GPIO8R 42
+#define AB8500_INT_GPIO9R 43
+#define AB8500_INT_GPIO10R 44
+#define AB8500_INT_GPIO11R 45
+#define AB8500_INT_GPIO12R 46
+#define AB8500_INT_GPIO13R 47
+#define AB8500_INT_GPIO24R 48
+#define AB8500_INT_GPIO25R 49
+#define AB8500_INT_GPIO36R 50
+#define AB8500_INT_GPIO37R 51
+#define AB8500_INT_GPIO38R 52
+#define AB8500_INT_GPIO39R 53
+#define AB8500_INT_GPIO40R 54
+#define AB8500_INT_GPIO41R 55
+#define AB8500_INT_GPIO6F 56
+#define AB8500_INT_GPIO7F 57
+#define AB8500_INT_GPIO8F 58
+#define AB8500_INT_GPIO9F 59
+#define AB8500_INT_GPIO10F 60
+#define AB8500_INT_GPIO11F 61
+#define AB8500_INT_GPIO12F 62
+#define AB8500_INT_GPIO13F 63
+#define AB8500_INT_GPIO24F 64
+#define AB8500_INT_GPIO25F 65
+#define AB8500_INT_GPIO36F 66
+#define AB8500_INT_GPIO37F 67
+#define AB8500_INT_GPIO38F 68
+#define AB8500_INT_GPIO39F 69
+#define AB8500_INT_GPIO40F 70
+#define AB8500_INT_GPIO41F 71
#define AB8500_INT_ADP_SOURCE_ERROR 72
#define AB8500_INT_ADP_SINK_ERROR 73
#define AB8500_INT_ADP_PROBE_PLUG 74
@@ -139,19 +178,27 @@ struct ab8500 {
u8 oldmask[AB8500_NUM_IRQ_REGS];
};
+struct regulator_reg_init;
struct regulator_init_data;
+struct ab8500_gpio_platform_data;
/**
* struct ab8500_platform_data - AB8500 platform data
* @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used
* @init: board-specific initialization after detection of ab8500
+ * @num_regulator_reg_init: number of regulator init registers
+ * @regulator_reg_init: regulator init registers
+ * @num_regulator: number of regulators
* @regulator: machine-specific constraints for regulators
*/
struct ab8500_platform_data {
int irq_base;
void (*init) (struct ab8500 *);
+ int num_regulator_reg_init;
+ struct ab8500_regulator_reg_init *regulator_reg_init;
int num_regulator;
struct regulator_init_data *regulator;
+ struct ab8500_gpio_platform_data *gpio;
};
extern int __devinit ab8500_init(struct ab8500 *ab8500);
diff --git a/include/linux/mfd/ab8500/gpio.h b/include/linux/mfd/ab8500/gpio.h
new file mode 100644
index 00000000000..488a8c920a2
--- /dev/null
+++ b/include/linux/mfd/ab8500/gpio.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright ST-Ericsson 2010.
+ *
+ * Author: Bibek Basu <bibek.basu@stericsson.com>
+ * Licensed under GPLv2.
+ */
+
+#ifndef _AB8500_GPIO_H
+#define _AB8500_GPIO_H
+
+/*
+ * Platform data to register a block: only the initial gpio/irq number.
+ */
+
+struct ab8500_gpio_platform_data {
+ int gpio_base;
+ u32 irq_base;
+ u8 config_reg[7];
+};
+
+#endif /* _AB8500_GPIO_H */
diff --git a/include/linux/mfd/sh_mobile_sdhi.h b/include/linux/mmc/sh_mobile_sdhi.h
index c981b959760..c981b959760 100644
--- a/include/linux/mfd/sh_mobile_sdhi.h
+++ b/include/linux/mmc/sh_mobile_sdhi.h
diff --git a/include/linux/mmc/tmio.h b/include/linux/mmc/tmio.h
new file mode 100644
index 00000000000..19490b942db
--- /dev/null
+++ b/include/linux/mmc/tmio.h
@@ -0,0 +1,63 @@
+/*
+ * include/linux/mmc/tmio.h
+ *
+ * Copyright (C) 2007 Ian Molton
+ * Copyright (C) 2004 Ian Molton
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Driver for the MMC / SD / SDIO cell found in:
+ *
+ * TC6393XB TC6391XB TC6387XB T7L66XB ASIC3
+ */
+#ifndef _LINUX_MMC_TMIO_H_
+#define _LINUX_MMC_TMIO_H_
+
+#define CTL_SD_CMD 0x00
+#define CTL_ARG_REG 0x04
+#define CTL_STOP_INTERNAL_ACTION 0x08
+#define CTL_XFER_BLK_COUNT 0xa
+#define CTL_RESPONSE 0x0c
+#define CTL_STATUS 0x1c
+#define CTL_IRQ_MASK 0x20
+#define CTL_SD_CARD_CLK_CTL 0x24
+#define CTL_SD_XFER_LEN 0x26
+#define CTL_SD_MEM_CARD_OPT 0x28
+#define CTL_SD_ERROR_DETAIL_STATUS 0x2c
+#define CTL_SD_DATA_PORT 0x30
+#define CTL_TRANSACTION_CTL 0x34
+#define CTL_SDIO_STATUS 0x36
+#define CTL_SDIO_IRQ_MASK 0x38
+#define CTL_RESET_SD 0xe0
+#define CTL_SDIO_REGS 0x100
+#define CTL_CLK_AND_WAIT_CTL 0x138
+#define CTL_RESET_SDIO 0x1e0
+
+/* Definitions for values the CTRL_STATUS register can take. */
+#define TMIO_STAT_CMDRESPEND 0x00000001
+#define TMIO_STAT_DATAEND 0x00000004
+#define TMIO_STAT_CARD_REMOVE 0x00000008
+#define TMIO_STAT_CARD_INSERT 0x00000010
+#define TMIO_STAT_SIGSTATE 0x00000020
+#define TMIO_STAT_WRPROTECT 0x00000080
+#define TMIO_STAT_CARD_REMOVE_A 0x00000100
+#define TMIO_STAT_CARD_INSERT_A 0x00000200
+#define TMIO_STAT_SIGSTATE_A 0x00000400
+#define TMIO_STAT_CMD_IDX_ERR 0x00010000
+#define TMIO_STAT_CRCFAIL 0x00020000
+#define TMIO_STAT_STOPBIT_ERR 0x00040000
+#define TMIO_STAT_DATATIMEOUT 0x00080000
+#define TMIO_STAT_RXOVERFLOW 0x00100000
+#define TMIO_STAT_TXUNDERRUN 0x00200000
+#define TMIO_STAT_CMDTIMEOUT 0x00400000
+#define TMIO_STAT_RXRDY 0x01000000
+#define TMIO_STAT_TXRQ 0x02000000
+#define TMIO_STAT_ILL_FUNC 0x20000000
+#define TMIO_STAT_CMD_BUSY 0x40000000
+#define TMIO_STAT_ILL_ACCESS 0x80000000
+
+#define TMIO_BBS 512 /* Boot block size */
+
+#endif /* _LINUX_MMC_TMIO_H_ */
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 8023e4e2513..91af2e49fa3 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -78,7 +78,6 @@ extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx,
struct page *page,
unsigned int offset,
unsigned int count);
-extern void nfs_clear_request(struct nfs_page *req);
extern void nfs_release_request(struct nfs_page *req);
diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h
index 6a210f1511f..76579f964a2 100644
--- a/include/linux/regulator/ab8500.h
+++ b/include/linux/regulator/ab8500.h
@@ -3,8 +3,8 @@
*
* License Terms: GNU General Public License v2
*
- * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
- *
+ * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
+ * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
*/
#ifndef __LINUX_MFD_AB8500_REGULATOR_H
@@ -17,6 +17,7 @@ enum ab8500_regulator_id {
AB8500_LDO_AUX3,
AB8500_LDO_INTCORE,
AB8500_LDO_TVOUT,
+ AB8500_LDO_USB,
AB8500_LDO_AUDIO,
AB8500_LDO_ANAMIC1,
AB8500_LDO_ANAMIC2,
@@ -24,4 +25,50 @@ enum ab8500_regulator_id {
AB8500_LDO_ANA,
AB8500_NUM_REGULATORS,
};
+
+/* AB8500 register initialization */
+struct ab8500_regulator_reg_init {
+ int id;
+ u8 value;
+};
+
+#define INIT_REGULATOR_REGISTER(_id, _value) \
+ { \
+ .id = _id, \
+ .value = _value, \
+ }
+
+/* AB8500 registers */
+enum ab8500_regulator_reg {
+ AB8500_REGUREQUESTCTRL2,
+ AB8500_REGUREQUESTCTRL3,
+ AB8500_REGUREQUESTCTRL4,
+ AB8500_REGUSYSCLKREQ1HPVALID1,
+ AB8500_REGUSYSCLKREQ1HPVALID2,
+ AB8500_REGUHWHPREQ1VALID1,
+ AB8500_REGUHWHPREQ1VALID2,
+ AB8500_REGUHWHPREQ2VALID1,
+ AB8500_REGUHWHPREQ2VALID2,
+ AB8500_REGUSWHPREQVALID1,
+ AB8500_REGUSWHPREQVALID2,
+ AB8500_REGUSYSCLKREQVALID1,
+ AB8500_REGUSYSCLKREQVALID2,
+ AB8500_REGUMISC1,
+ AB8500_VAUDIOSUPPLY,
+ AB8500_REGUCTRL1VAMIC,
+ AB8500_VPLLVANAREGU,
+ AB8500_VREFDDR,
+ AB8500_EXTSUPPLYREGU,
+ AB8500_VAUX12REGU,
+ AB8500_VRF1VAUX3REGU,
+ AB8500_VAUX1SEL,
+ AB8500_VAUX2SEL,
+ AB8500_VRF1VAUX3SEL,
+ AB8500_REGUCTRL2SPARE,
+ AB8500_REGUCTRLDISCH,
+ AB8500_REGUCTRLDISCH2,
+ AB8500_VSMPS1SEL1,
+ AB8500_NUM_REGULATOR_REGISTERS,
+};
+
#endif
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 7954f6bd7ed..9e87c1cb727 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -153,6 +153,8 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector);
int regulator_is_supported_voltage(struct regulator *regulator,
int min_uV, int max_uV);
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
+int regulator_set_voltage_time(struct regulator *regulator,
+ int old_uV, int new_uV);
int regulator_get_voltage(struct regulator *regulator);
int regulator_sync_voltage(struct regulator *regulator);
int regulator_set_current_limit(struct regulator *regulator,
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h
index b8ed16a33c4..6c433b89c80 100644
--- a/include/linux/regulator/driver.h
+++ b/include/linux/regulator/driver.h
@@ -63,7 +63,11 @@ enum regulator_status {
* when running with the specified parameters.
*
* @enable_time: Time taken for the regulator voltage output voltage to
- * stabalise after being enabled, in microseconds.
+ * stabilise after being enabled, in microseconds.
+ * @set_voltage_time_sel: Time taken for the regulator voltage output voltage
+ * to stabilise after being set to a new value, in microseconds.
+ * The function provides the from and to voltage selector, the
+ * function should return the worst case.
*
* @set_suspend_voltage: Set the voltage for the regulator when the system
* is suspended.
@@ -103,8 +107,11 @@ struct regulator_ops {
int (*set_mode) (struct regulator_dev *, unsigned int mode);
unsigned int (*get_mode) (struct regulator_dev *);
- /* Time taken to enable the regulator */
+ /* Time taken to enable or set voltage on the regulator */
int (*enable_time) (struct regulator_dev *);
+ int (*set_voltage_time_sel) (struct regulator_dev *,
+ unsigned int old_selector,
+ unsigned int new_selector);
/* report regulator status ... most other accessors report
* control inputs, this reports results of combining inputs
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h
index 761c745b9c2..c4c4fc45f85 100644
--- a/include/linux/regulator/machine.h
+++ b/include/linux/regulator/machine.h
@@ -186,6 +186,7 @@ struct regulator_init_data {
};
int regulator_suspend_prepare(suspend_state_t state);
+int regulator_suspend_finish(void);
#ifdef CONFIG_REGULATOR
void regulator_has_full_constraints(void);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 24cfa626931..d9e52fa2416 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -122,8 +122,14 @@ struct sk_buff_head {
struct sk_buff;
-/* To allow 64K frame to be packed as single skb without frag_list */
+/* To allow 64K frame to be packed as single skb without frag_list. Since
+ * GRO uses frags we allocate at least 16 regardless of page size.
+ */
+#if (65536/PAGE_SIZE + 2) < 16
+#define MAX_SKB_FRAGS 16UL
+#else
#define MAX_SKB_FRAGS (65536/PAGE_SIZE + 2)
+#endif
typedef struct skb_frag_struct skb_frag_t;
diff --git a/include/linux/sonypi.h b/include/linux/sonypi.h
index 0e6dc389194..c0f87da78f8 100644
--- a/include/linux/sonypi.h
+++ b/include/linux/sonypi.h
@@ -40,6 +40,7 @@
/* events the user application reading /dev/sonypi can use */
+#define SONYPI_EVENT_IGNORE 0
#define SONYPI_EVENT_JOGDIAL_DOWN 1
#define SONYPI_EVENT_JOGDIAL_UP 2
#define SONYPI_EVENT_JOGDIAL_DOWN_PRESSED 3
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 44842c8d38c..201f2228f73 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -102,6 +102,7 @@ struct driver_info {
* Affects statistic (counters) and short packet handling.
*/
#define FLAG_MULTI_PACKET 0x1000
+#define FLAG_RX_ASSEMBLE 0x2000 /* rx packets may span >1 frames */
/* init device ... can sleep, or cause probe() failure */
int (*bind)(struct usbnet *, struct usb_interface *);
@@ -172,7 +173,9 @@ struct cdc_state {
};
extern int usbnet_generic_cdc_bind(struct usbnet *, struct usb_interface *);
+extern int usbnet_cdc_bind(struct usbnet *, struct usb_interface *);
extern void usbnet_cdc_unbind(struct usbnet *, struct usb_interface *);
+extern void usbnet_cdc_status(struct usbnet *, struct urb *);
/* CDC and RNDIS support the same host-chosen packet filters for IN transfers */
#define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h
index 4ed6fcd6b72..9332e52ea8c 100644
--- a/include/linux/vmalloc.h
+++ b/include/linux/vmalloc.h
@@ -95,10 +95,27 @@ extern struct vm_struct *remove_vm_area(const void *addr);
extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
struct page ***pages);
+#ifdef CONFIG_MMU
extern int map_kernel_range_noflush(unsigned long start, unsigned long size,
pgprot_t prot, struct page **pages);
extern void unmap_kernel_range_noflush(unsigned long addr, unsigned long size);
extern void unmap_kernel_range(unsigned long addr, unsigned long size);
+#else
+static inline int
+map_kernel_range_noflush(unsigned long start, unsigned long size,
+ pgprot_t prot, struct page **pages)
+{
+ return size >> PAGE_SHIFT;
+}
+static inline void
+unmap_kernel_range_noflush(unsigned long addr, unsigned long size)
+{
+}
+static inline void
+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);
@@ -116,11 +133,26 @@ extern struct vm_struct *vmlist;
extern __init void vm_area_register_early(struct vm_struct *vm, size_t align);
#ifdef CONFIG_SMP
+# ifdef CONFIG_MMU
struct vm_struct **pcpu_get_vm_areas(const unsigned long *offsets,
const size_t *sizes, int nr_vms,
size_t align);
void pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms);
+# else
+static inline struct vm_struct **
+pcpu_get_vm_areas(const unsigned long *offsets,
+ const size_t *sizes, int nr_vms,
+ size_t align)
+{
+ return NULL;
+}
+
+static inline void
+pcpu_free_vm_areas(struct vm_struct **vms, int nr_vms)
+{
+}
+# endif
#endif
#endif /* _LINUX_VMALLOC_H */
diff --git a/include/net/dst.h b/include/net/dst.h
index 2a46cbaef92..75b95df4afe 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -345,7 +345,7 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev)
static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb)
{
- struct dst_entry *child = skb_dst(skb)->child;
+ struct dst_entry *child = dst_clone(skb_dst(skb)->child);
skb_dst_drop(skb);
return child;
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 04977eefb0e..fccc2180c61 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -286,5 +286,21 @@ static inline void ipv6_ib_mc_map(const struct in6_addr *addr,
buf[9] = broadcast[9];
memcpy(buf + 10, addr->s6_addr + 6, 10);
}
+
+static inline int ipv6_ipgre_mc_map(const struct in6_addr *addr,
+ const unsigned char *broadcast, char *buf)
+{
+ if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0) {
+ memcpy(buf, broadcast, 4);
+ } else {
+ /* v4mapped? */
+ if ((addr->s6_addr32[0] | addr->s6_addr32[1] |
+ (addr->s6_addr32[2] ^ htonl(0x0000ffff))) != 0)
+ return -EINVAL;
+ memcpy(buf, &addr->s6_addr32[3], 4);
+ }
+ return 0;
+}
+
#endif
#endif
diff --git a/include/net/ip.h b/include/net/ip.h
index a4f631108c5..7c416583b71 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -339,6 +339,14 @@ static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, ch
buf[16] = addr & 0x0f;
}
+static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
+{
+ if ((broadcast[0] | broadcast[1] | broadcast[2] | broadcast[3]) != 0)
+ memcpy(buf, broadcast, 4);
+ else
+ memcpy(buf, &naddr, sizeof(naddr));
+}
+
#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
#include <linux/ipv6.h>
#endif
diff --git a/include/net/rose.h b/include/net/rose.h
index 5ba9f02731e..555dd198aab 100644
--- a/include/net/rose.h
+++ b/include/net/rose.h
@@ -14,6 +14,12 @@
#define ROSE_MIN_LEN 3
+#define ROSE_CALL_REQ_ADDR_LEN_OFF 3
+#define ROSE_CALL_REQ_ADDR_LEN_VAL 0xAA /* each address is 10 digits */
+#define ROSE_CALL_REQ_DEST_ADDR_OFF 4
+#define ROSE_CALL_REQ_SRC_ADDR_OFF 9
+#define ROSE_CALL_REQ_FACILITIES_OFF 14
+
#define ROSE_GFI 0x10
#define ROSE_Q_BIT 0x80
#define ROSE_D_BIT 0x40
@@ -214,7 +220,7 @@ extern void rose_requeue_frames(struct sock *);
extern int rose_validate_nr(struct sock *, unsigned short);
extern void rose_write_internal(struct sock *, int);
extern int rose_decode(struct sk_buff *, int *, int *, int *, int *, int *);
-extern int rose_parse_facilities(unsigned char *, struct rose_facilities_struct *);
+extern int rose_parse_facilities(unsigned char *, unsigned int, struct rose_facilities_struct *);
extern void rose_disconnect(struct sock *, int, int, int);
/* rose_timer.c */
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index cffa5dc6644..6ae4bc5ce8a 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1601,6 +1601,28 @@ static inline int xfrm_replay_state_esn_len(struct xfrm_replay_state_esn *replay
}
#ifdef CONFIG_XFRM_MIGRATE
+static inline int xfrm_replay_clone(struct xfrm_state *x,
+ struct xfrm_state *orig)
+{
+ x->replay_esn = kzalloc(xfrm_replay_state_esn_len(orig->replay_esn),
+ GFP_KERNEL);
+ if (!x->replay_esn)
+ return -ENOMEM;
+
+ x->replay_esn->bmp_len = orig->replay_esn->bmp_len;
+ x->replay_esn->replay_window = orig->replay_esn->replay_window;
+
+ x->preplay_esn = kmemdup(x->replay_esn,
+ xfrm_replay_state_esn_len(x->replay_esn),
+ GFP_KERNEL);
+ if (!x->preplay_esn) {
+ kfree(x->replay_esn);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
static inline struct xfrm_algo *xfrm_algo_clone(struct xfrm_algo *orig)
{
return kmemdup(orig, xfrm_alg_len(orig), GFP_KERNEL);
diff --git a/include/trace/events/btrfs.h b/include/trace/events/btrfs.h
new file mode 100644
index 00000000000..f445cff66ab
--- /dev/null
+++ b/include/trace/events/btrfs.h
@@ -0,0 +1,667 @@
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM btrfs
+
+#if !defined(_TRACE_BTRFS_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_BTRFS_H
+
+#include <linux/writeback.h>
+#include <linux/tracepoint.h>
+
+struct btrfs_root;
+struct btrfs_fs_info;
+struct btrfs_inode;
+struct extent_map;
+struct btrfs_ordered_extent;
+struct btrfs_delayed_ref_node;
+struct btrfs_delayed_tree_ref;
+struct btrfs_delayed_data_ref;
+struct btrfs_delayed_ref_head;
+struct map_lookup;
+struct extent_buffer;
+
+#define show_ref_type(type) \
+ __print_symbolic(type, \
+ { BTRFS_TREE_BLOCK_REF_KEY, "TREE_BLOCK_REF" }, \
+ { BTRFS_EXTENT_DATA_REF_KEY, "EXTENT_DATA_REF" }, \
+ { BTRFS_EXTENT_REF_V0_KEY, "EXTENT_REF_V0" }, \
+ { BTRFS_SHARED_BLOCK_REF_KEY, "SHARED_BLOCK_REF" }, \
+ { BTRFS_SHARED_DATA_REF_KEY, "SHARED_DATA_REF" })
+
+#define __show_root_type(obj) \
+ __print_symbolic(obj, \
+ { BTRFS_ROOT_TREE_OBJECTID, "ROOT_TREE" }, \
+ { BTRFS_EXTENT_TREE_OBJECTID, "EXTENT_TREE" }, \
+ { BTRFS_CHUNK_TREE_OBJECTID, "CHUNK_TREE" }, \
+ { BTRFS_DEV_TREE_OBJECTID, "DEV_TREE" }, \
+ { BTRFS_FS_TREE_OBJECTID, "FS_TREE" }, \
+ { BTRFS_ROOT_TREE_DIR_OBJECTID, "ROOT_TREE_DIR" }, \
+ { BTRFS_CSUM_TREE_OBJECTID, "CSUM_TREE" }, \
+ { BTRFS_TREE_LOG_OBJECTID, "TREE_LOG" }, \
+ { BTRFS_TREE_RELOC_OBJECTID, "TREE_RELOC" }, \
+ { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" })
+
+#define show_root_type(obj) \
+ obj, ((obj >= BTRFS_DATA_RELOC_TREE_OBJECTID) || \
+ (obj <= BTRFS_CSUM_TREE_OBJECTID )) ? __show_root_type(obj) : "-"
+
+TRACE_EVENT(btrfs_transaction_commit,
+
+ TP_PROTO(struct btrfs_root *root),
+
+ TP_ARGS(root),
+
+ TP_STRUCT__entry(
+ __field( u64, generation )
+ __field( u64, root_objectid )
+ ),
+
+ TP_fast_assign(
+ __entry->generation = root->fs_info->generation;
+ __entry->root_objectid = root->root_key.objectid;
+ ),
+
+ TP_printk("root = %llu(%s), gen = %llu",
+ show_root_type(__entry->root_objectid),
+ (unsigned long long)__entry->generation)
+);
+
+DECLARE_EVENT_CLASS(btrfs__inode,
+
+ TP_PROTO(struct inode *inode),
+
+ TP_ARGS(inode),
+
+ TP_STRUCT__entry(
+ __field( ino_t, ino )
+ __field( blkcnt_t, blocks )
+ __field( u64, disk_i_size )
+ __field( u64, generation )
+ __field( u64, last_trans )
+ __field( u64, logged_trans )
+ __field( u64, root_objectid )
+ ),
+
+ TP_fast_assign(
+ __entry->ino = inode->i_ino;
+ __entry->blocks = inode->i_blocks;
+ __entry->disk_i_size = BTRFS_I(inode)->disk_i_size;
+ __entry->generation = BTRFS_I(inode)->generation;
+ __entry->last_trans = BTRFS_I(inode)->last_trans;
+ __entry->logged_trans = BTRFS_I(inode)->logged_trans;
+ __entry->root_objectid =
+ BTRFS_I(inode)->root->root_key.objectid;
+ ),
+
+ TP_printk("root = %llu(%s), gen = %llu, ino = %lu, blocks = %llu, "
+ "disk_i_size = %llu, last_trans = %llu, logged_trans = %llu",
+ show_root_type(__entry->root_objectid),
+ (unsigned long long)__entry->generation,
+ (unsigned long)__entry->ino,
+ (unsigned long long)__entry->blocks,
+ (unsigned long long)__entry->disk_i_size,
+ (unsigned long long)__entry->last_trans,
+ (unsigned long long)__entry->logged_trans)
+);
+
+DEFINE_EVENT(btrfs__inode, btrfs_inode_new,
+
+ TP_PROTO(struct inode *inode),
+
+ TP_ARGS(inode)
+);
+
+DEFINE_EVENT(btrfs__inode, btrfs_inode_request,
+
+ TP_PROTO(struct inode *inode),
+
+ TP_ARGS(inode)
+);
+
+DEFINE_EVENT(btrfs__inode, btrfs_inode_evict,
+
+ TP_PROTO(struct inode *inode),
+
+ TP_ARGS(inode)
+);
+
+#define __show_map_type(type) \
+ __print_symbolic(type, \
+ { EXTENT_MAP_LAST_BYTE, "LAST_BYTE" }, \
+ { EXTENT_MAP_HOLE, "HOLE" }, \
+ { EXTENT_MAP_INLINE, "INLINE" }, \
+ { EXTENT_MAP_DELALLOC, "DELALLOC" })
+
+#define show_map_type(type) \
+ type, (type >= EXTENT_MAP_LAST_BYTE) ? "-" : __show_map_type(type)
+
+#define show_map_flags(flag) \
+ __print_flags(flag, "|", \
+ { EXTENT_FLAG_PINNED, "PINNED" }, \
+ { EXTENT_FLAG_COMPRESSED, "COMPRESSED" }, \
+ { EXTENT_FLAG_VACANCY, "VACANCY" }, \
+ { EXTENT_FLAG_PREALLOC, "PREALLOC" })
+
+TRACE_EVENT(btrfs_get_extent,
+
+ TP_PROTO(struct btrfs_root *root, struct extent_map *map),
+
+ TP_ARGS(root, map),
+
+ TP_STRUCT__entry(
+ __field( u64, root_objectid )
+ __field( u64, start )
+ __field( u64, len )
+ __field( u64, orig_start )
+ __field( u64, block_start )
+ __field( u64, block_len )
+ __field( unsigned long, flags )
+ __field( int, refs )
+ __field( unsigned int, compress_type )
+ ),
+
+ TP_fast_assign(
+ __entry->root_objectid = root->root_key.objectid;
+ __entry->start = map->start;
+ __entry->len = map->len;
+ __entry->orig_start = map->orig_start;
+ __entry->block_start = map->block_start;
+ __entry->block_len = map->block_len;
+ __entry->flags = map->flags;
+ __entry->refs = atomic_read(&map->refs);
+ __entry->compress_type = map->compress_type;
+ ),
+
+ TP_printk("root = %llu(%s), start = %llu, len = %llu, "
+ "orig_start = %llu, block_start = %llu(%s), "
+ "block_len = %llu, flags = %s, refs = %u, "
+ "compress_type = %u",
+ show_root_type(__entry->root_objectid),
+ (unsigned long long)__entry->start,
+ (unsigned long long)__entry->len,
+ (unsigned long long)__entry->orig_start,
+ show_map_type(__entry->block_start),
+ (unsigned long long)__entry->block_len,
+ show_map_flags(__entry->flags),
+ __entry->refs, __entry->compress_type)
+);
+
+#define show_ordered_flags(flags) \
+ __print_symbolic(flags, \
+ { BTRFS_ORDERED_IO_DONE, "IO_DONE" }, \
+ { BTRFS_ORDERED_COMPLETE, "COMPLETE" }, \
+ { BTRFS_ORDERED_NOCOW, "NOCOW" }, \
+ { BTRFS_ORDERED_COMPRESSED, "COMPRESSED" }, \
+ { BTRFS_ORDERED_PREALLOC, "PREALLOC" }, \
+ { BTRFS_ORDERED_DIRECT, "DIRECT" })
+
+DECLARE_EVENT_CLASS(btrfs__ordered_extent,
+
+ TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered),
+
+ TP_ARGS(inode, ordered),
+
+ TP_STRUCT__entry(
+ __field( ino_t, ino )
+ __field( u64, file_offset )
+ __field( u64, start )
+ __field( u64, len )
+ __field( u64, disk_len )
+ __field( u64, bytes_left )
+ __field( unsigned long, flags )
+ __field( int, compress_type )
+ __field( int, refs )
+ __field( u64, root_objectid )
+ ),
+
+ TP_fast_assign(
+ __entry->ino = inode->i_ino;
+ __entry->file_offset = ordered->file_offset;
+ __entry->start = ordered->start;
+ __entry->len = ordered->len;
+ __entry->disk_len = ordered->disk_len;
+ __entry->bytes_left = ordered->bytes_left;
+ __entry->flags = ordered->flags;
+ __entry->compress_type = ordered->compress_type;
+ __entry->refs = atomic_read(&ordered->refs);
+ __entry->root_objectid =
+ BTRFS_I(inode)->root->root_key.objectid;
+ ),
+
+ TP_printk("root = %llu(%s), ino = %llu, file_offset = %llu, "
+ "start = %llu, len = %llu, disk_len = %llu, "
+ "bytes_left = %llu, flags = %s, compress_type = %d, "
+ "refs = %d",
+ show_root_type(__entry->root_objectid),
+ (unsigned long long)__entry->ino,
+ (unsigned long long)__entry->file_offset,
+ (unsigned long long)__entry->start,
+ (unsigned long long)__entry->len,
+ (unsigned long long)__entry->disk_len,
+ (unsigned long long)__entry->bytes_left,
+ show_ordered_flags(__entry->flags),
+ __entry->compress_type, __entry->refs)
+);
+
+DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_add,
+
+ TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered),
+
+ TP_ARGS(inode, ordered)
+);
+
+DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_remove,
+
+ TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered),
+
+ TP_ARGS(inode, ordered)
+);
+
+DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_start,
+
+ TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered),
+
+ TP_ARGS(inode, ordered)
+);
+
+DEFINE_EVENT(btrfs__ordered_extent, btrfs_ordered_extent_put,
+
+ TP_PROTO(struct inode *inode, struct btrfs_ordered_extent *ordered),
+
+ TP_ARGS(inode, ordered)
+);
+
+DECLARE_EVENT_CLASS(btrfs__writepage,
+
+ TP_PROTO(struct page *page, struct inode *inode,
+ struct writeback_control *wbc),
+
+ TP_ARGS(page, inode, wbc),
+
+ TP_STRUCT__entry(
+ __field( ino_t, ino )
+ __field( pgoff_t, index )
+ __field( long, nr_to_write )
+ __field( long, pages_skipped )
+ __field( loff_t, range_start )
+ __field( loff_t, range_end )
+ __field( char, nonblocking )
+ __field( char, for_kupdate )
+ __field( char, for_reclaim )
+ __field( char, range_cyclic )
+ __field( pgoff_t, writeback_index )
+ __field( u64, root_objectid )
+ ),
+
+ TP_fast_assign(
+ __entry->ino = inode->i_ino;
+ __entry->index = page->index;
+ __entry->nr_to_write = wbc->nr_to_write;
+ __entry->pages_skipped = wbc->pages_skipped;
+ __entry->range_start = wbc->range_start;
+ __entry->range_end = wbc->range_end;
+ __entry->nonblocking = wbc->nonblocking;
+ __entry->for_kupdate = wbc->for_kupdate;
+ __entry->for_reclaim = wbc->for_reclaim;
+ __entry->range_cyclic = wbc->range_cyclic;
+ __entry->writeback_index = inode->i_mapping->writeback_index;
+ __entry->root_objectid =
+ BTRFS_I(inode)->root->root_key.objectid;
+ ),
+
+ TP_printk("root = %llu(%s), ino = %lu, page_index = %lu, "
+ "nr_to_write = %ld, pages_skipped = %ld, range_start = %llu, "
+ "range_end = %llu, nonblocking = %d, for_kupdate = %d, "
+ "for_reclaim = %d, range_cyclic = %d, writeback_index = %lu",
+ show_root_type(__entry->root_objectid),
+ (unsigned long)__entry->ino, __entry->index,
+ __entry->nr_to_write, __entry->pages_skipped,
+ __entry->range_start, __entry->range_end,
+ __entry->nonblocking, __entry->for_kupdate,
+ __entry->for_reclaim, __entry->range_cyclic,
+ (unsigned long)__entry->writeback_index)
+);
+
+DEFINE_EVENT(btrfs__writepage, __extent_writepage,
+
+ TP_PROTO(struct page *page, struct inode *inode,
+ struct writeback_control *wbc),
+
+ TP_ARGS(page, inode, wbc)
+);
+
+TRACE_EVENT(btrfs_writepage_end_io_hook,
+
+ TP_PROTO(struct page *page, u64 start, u64 end, int uptodate),
+
+ TP_ARGS(page, start, end, uptodate),
+
+ TP_STRUCT__entry(
+ __field( ino_t, ino )
+ __field( pgoff_t, index )
+ __field( u64, start )
+ __field( u64, end )
+ __field( int, uptodate )
+ __field( u64, root_objectid )
+ ),
+
+ TP_fast_assign(
+ __entry->ino = page->mapping->host->i_ino;
+ __entry->index = page->index;
+ __entry->start = start;
+ __entry->end = end;
+ __entry->uptodate = uptodate;
+ __entry->root_objectid =
+ BTRFS_I(page->mapping->host)->root->root_key.objectid;
+ ),
+
+ TP_printk("root = %llu(%s), ino = %lu, page_index = %lu, start = %llu, "
+ "end = %llu, uptodate = %d",
+ show_root_type(__entry->root_objectid),
+ (unsigned long)__entry->ino, (unsigned long)__entry->index,
+ (unsigned long long)__entry->start,
+ (unsigned long long)__entry->end, __entry->uptodate)
+);
+
+TRACE_EVENT(btrfs_sync_file,
+
+ TP_PROTO(struct file *file, int datasync),
+
+ TP_ARGS(file, datasync),
+
+ TP_STRUCT__entry(
+ __field( ino_t, ino )
+ __field( ino_t, parent )
+ __field( int, datasync )
+ __field( u64, root_objectid )
+ ),
+
+ TP_fast_assign(
+ struct dentry *dentry = file->f_path.dentry;
+ struct inode *inode = dentry->d_inode;
+
+ __entry->ino = inode->i_ino;
+ __entry->parent = dentry->d_parent->d_inode->i_ino;
+ __entry->datasync = datasync;
+ __entry->root_objectid =
+ BTRFS_I(inode)->root->root_key.objectid;
+ ),
+
+ TP_printk("root = %llu(%s), ino = %ld, parent = %ld, datasync = %d",
+ show_root_type(__entry->root_objectid),
+ (unsigned long)__entry->ino, (unsigned long)__entry->parent,
+ __entry->datasync)
+);
+
+TRACE_EVENT(btrfs_sync_fs,
+
+ TP_PROTO(int wait),
+
+ TP_ARGS(wait),
+
+ TP_STRUCT__entry(
+ __field( int, wait )
+ ),
+
+ TP_fast_assign(
+ __entry->wait = wait;
+ ),
+
+ TP_printk("wait = %d", __entry->wait)
+);
+
+#define show_ref_action(action) \
+ __print_symbolic(action, \
+ { BTRFS_ADD_DELAYED_REF, "ADD_DELAYED_REF" }, \
+ { BTRFS_DROP_DELAYED_REF, "DROP_DELAYED_REF" }, \
+ { BTRFS_ADD_DELAYED_EXTENT, "ADD_DELAYED_EXTENT" }, \
+ { BTRFS_UPDATE_DELAYED_HEAD, "UPDATE_DELAYED_HEAD" })
+
+
+TRACE_EVENT(btrfs_delayed_tree_ref,
+
+ TP_PROTO(struct btrfs_delayed_ref_node *ref,
+ struct btrfs_delayed_tree_ref *full_ref,
+ int action),
+
+ TP_ARGS(ref, full_ref, action),
+
+ TP_STRUCT__entry(
+ __field( u64, bytenr )
+ __field( u64, num_bytes )
+ __field( int, action )
+ __field( u64, parent )
+ __field( u64, ref_root )
+ __field( int, level )
+ __field( int, type )
+ ),
+
+ TP_fast_assign(
+ __entry->bytenr = ref->bytenr;
+ __entry->num_bytes = ref->num_bytes;
+ __entry->action = action;
+ __entry->parent = full_ref->parent;
+ __entry->ref_root = full_ref->root;
+ __entry->level = full_ref->level;
+ __entry->type = ref->type;
+ ),
+
+ TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, "
+ "parent = %llu(%s), ref_root = %llu(%s), level = %d, "
+ "type = %s",
+ (unsigned long long)__entry->bytenr,
+ (unsigned long long)__entry->num_bytes,
+ show_ref_action(__entry->action),
+ show_root_type(__entry->parent),
+ show_root_type(__entry->ref_root),
+ __entry->level, show_ref_type(__entry->type))
+);
+
+TRACE_EVENT(btrfs_delayed_data_ref,
+
+ TP_PROTO(struct btrfs_delayed_ref_node *ref,
+ struct btrfs_delayed_data_ref *full_ref,
+ int action),
+
+ TP_ARGS(ref, full_ref, action),
+
+ TP_STRUCT__entry(
+ __field( u64, bytenr )
+ __field( u64, num_bytes )
+ __field( int, action )
+ __field( u64, parent )
+ __field( u64, ref_root )
+ __field( u64, owner )
+ __field( u64, offset )
+ __field( int, type )
+ ),
+
+ TP_fast_assign(
+ __entry->bytenr = ref->bytenr;
+ __entry->num_bytes = ref->num_bytes;
+ __entry->action = action;
+ __entry->parent = full_ref->parent;
+ __entry->ref_root = full_ref->root;
+ __entry->owner = full_ref->objectid;
+ __entry->offset = full_ref->offset;
+ __entry->type = ref->type;
+ ),
+
+ TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, "
+ "parent = %llu(%s), ref_root = %llu(%s), owner = %llu, "
+ "offset = %llu, type = %s",
+ (unsigned long long)__entry->bytenr,
+ (unsigned long long)__entry->num_bytes,
+ show_ref_action(__entry->action),
+ show_root_type(__entry->parent),
+ show_root_type(__entry->ref_root),
+ (unsigned long long)__entry->owner,
+ (unsigned long long)__entry->offset,
+ show_ref_type(__entry->type))
+);
+
+TRACE_EVENT(btrfs_delayed_ref_head,
+
+ TP_PROTO(struct btrfs_delayed_ref_node *ref,
+ struct btrfs_delayed_ref_head *head_ref,
+ int action),
+
+ TP_ARGS(ref, head_ref, action),
+
+ TP_STRUCT__entry(
+ __field( u64, bytenr )
+ __field( u64, num_bytes )
+ __field( int, action )
+ __field( int, is_data )
+ ),
+
+ TP_fast_assign(
+ __entry->bytenr = ref->bytenr;
+ __entry->num_bytes = ref->num_bytes;
+ __entry->action = action;
+ __entry->is_data = head_ref->is_data;
+ ),
+
+ TP_printk("bytenr = %llu, num_bytes = %llu, action = %s, is_data = %d",
+ (unsigned long long)__entry->bytenr,
+ (unsigned long long)__entry->num_bytes,
+ show_ref_action(__entry->action),
+ __entry->is_data)
+);
+
+#define show_chunk_type(type) \
+ __print_flags(type, "|", \
+ { BTRFS_BLOCK_GROUP_DATA, "DATA" }, \
+ { BTRFS_BLOCK_GROUP_SYSTEM, "SYSTEM"}, \
+ { BTRFS_BLOCK_GROUP_METADATA, "METADATA"}, \
+ { BTRFS_BLOCK_GROUP_RAID0, "RAID0" }, \
+ { BTRFS_BLOCK_GROUP_RAID1, "RAID1" }, \
+ { BTRFS_BLOCK_GROUP_DUP, "DUP" }, \
+ { BTRFS_BLOCK_GROUP_RAID10, "RAID10"})
+
+DECLARE_EVENT_CLASS(btrfs__chunk,
+
+ TP_PROTO(struct btrfs_root *root, struct map_lookup *map,
+ u64 offset, u64 size),
+
+ TP_ARGS(root, map, offset, size),
+
+ TP_STRUCT__entry(
+ __field( int, num_stripes )
+ __field( u64, type )
+ __field( int, sub_stripes )
+ __field( u64, offset )
+ __field( u64, size )
+ __field( u64, root_objectid )
+ ),
+
+ TP_fast_assign(
+ __entry->num_stripes = map->num_stripes;
+ __entry->type = map->type;
+ __entry->sub_stripes = map->sub_stripes;
+ __entry->offset = offset;
+ __entry->size = size;
+ __entry->root_objectid = root->root_key.objectid;
+ ),
+
+ TP_printk("root = %llu(%s), offset = %llu, size = %llu, "
+ "num_stripes = %d, sub_stripes = %d, type = %s",
+ show_root_type(__entry->root_objectid),
+ (unsigned long long)__entry->offset,
+ (unsigned long long)__entry->size,
+ __entry->num_stripes, __entry->sub_stripes,
+ show_chunk_type(__entry->type))
+);
+
+DEFINE_EVENT(btrfs__chunk, btrfs_chunk_alloc,
+
+ TP_PROTO(struct btrfs_root *root, struct map_lookup *map,
+ u64 offset, u64 size),
+
+ TP_ARGS(root, map, offset, size)
+);
+
+DEFINE_EVENT(btrfs__chunk, btrfs_chunk_free,
+
+ TP_PROTO(struct btrfs_root *root, struct map_lookup *map,
+ u64 offset, u64 size),
+
+ TP_ARGS(root, map, offset, size)
+);
+
+TRACE_EVENT(btrfs_cow_block,
+
+ TP_PROTO(struct btrfs_root *root, struct extent_buffer *buf,
+ struct extent_buffer *cow),
+
+ TP_ARGS(root, buf, cow),
+
+ TP_STRUCT__entry(
+ __field( u64, root_objectid )
+ __field( u64, buf_start )
+ __field( int, refs )
+ __field( u64, cow_start )
+ __field( int, buf_level )
+ __field( int, cow_level )
+ ),
+
+ TP_fast_assign(
+ __entry->root_objectid = root->root_key.objectid;
+ __entry->buf_start = buf->start;
+ __entry->refs = atomic_read(&buf->refs);
+ __entry->cow_start = cow->start;
+ __entry->buf_level = btrfs_header_level(buf);
+ __entry->cow_level = btrfs_header_level(cow);
+ ),
+
+ TP_printk("root = %llu(%s), refs = %d, orig_buf = %llu "
+ "(orig_level = %d), cow_buf = %llu (cow_level = %d)",
+ show_root_type(__entry->root_objectid),
+ __entry->refs,
+ (unsigned long long)__entry->buf_start,
+ __entry->buf_level,
+ (unsigned long long)__entry->cow_start,
+ __entry->cow_level)
+);
+
+DECLARE_EVENT_CLASS(btrfs__reserved_extent,
+
+ TP_PROTO(struct btrfs_root *root, u64 start, u64 len),
+
+ TP_ARGS(root, start, len),
+
+ TP_STRUCT__entry(
+ __field( u64, root_objectid )
+ __field( u64, start )
+ __field( u64, len )
+ ),
+
+ TP_fast_assign(
+ __entry->root_objectid = root->root_key.objectid;
+ __entry->start = start;
+ __entry->len = len;
+ ),
+
+ TP_printk("root = %llu(%s), start = %llu, len = %llu",
+ show_root_type(__entry->root_objectid),
+ (unsigned long long)__entry->start,
+ (unsigned long long)__entry->len)
+);
+
+DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_alloc,
+
+ TP_PROTO(struct btrfs_root *root, u64 start, u64 len),
+
+ TP_ARGS(root, start, len)
+);
+
+DEFINE_EVENT(btrfs__reserved_extent, btrfs_reserved_extent_free,
+
+ TP_PROTO(struct btrfs_root *root, u64 start, u64 len),
+
+ TP_ARGS(root, start, len)
+);
+
+#endif /* _TRACE_BTRFS_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 00f2c037267..c574f9a12c4 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -10,13 +10,6 @@ menu "IRQ subsystem"
config GENERIC_HARDIRQS
def_bool y
-# Select this to disable the deprecated stuff
-config GENERIC_HARDIRQS_NO_DEPRECATED
- bool
-
-config GENERIC_HARDIRQS_NO_COMPAT
- bool
-
# Options selectable by the architecture code
# Make sparse irq Kconfig switch below available
@@ -51,6 +44,10 @@ config HARDIRQS_SW_RESEND
config IRQ_PREFLOW_FASTEOI
bool
+# Edge style eoi based handler (cell)
+config IRQ_EDGE_EOI_HANDLER
+ bool
+
# Support forced irq threading
config IRQ_FORCED_THREADING
bool
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 394784c5706..342d8f44e40 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -70,10 +70,8 @@ unsigned long probe_irq_on(void)
raw_spin_lock_irq(&desc->lock);
if (!desc->action && irq_settings_can_probe(desc)) {
desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
- if (irq_startup(desc)) {
- irq_compat_set_pending(desc);
+ if (irq_startup(desc))
desc->istate |= IRQS_PENDING;
- }
}
raw_spin_unlock_irq(&desc->lock);
}
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index c9c0601f061..1dafc8652bd 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -34,9 +34,14 @@ int irq_set_chip(unsigned int irq, struct irq_chip *chip)
if (!chip)
chip = &no_irq_chip;
- irq_chip_set_defaults(chip);
desc->irq_data.chip = chip;
irq_put_desc_unlock(desc, flags);
+ /*
+ * For !CONFIG_SPARSE_IRQ make the irq show up in
+ * allocated_irqs. For the CONFIG_SPARSE_IRQ case, it is
+ * already marked, and this call is harmless.
+ */
+ irq_reserve_irq(irq);
return 0;
}
EXPORT_SYMBOL(irq_set_chip);
@@ -134,26 +139,22 @@ EXPORT_SYMBOL_GPL(irq_get_irq_data);
static void irq_state_clr_disabled(struct irq_desc *desc)
{
- desc->istate &= ~IRQS_DISABLED;
- irq_compat_clr_disabled(desc);
+ irqd_clear(&desc->irq_data, IRQD_IRQ_DISABLED);
}
static void irq_state_set_disabled(struct irq_desc *desc)
{
- desc->istate |= IRQS_DISABLED;
- irq_compat_set_disabled(desc);
+ irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
}
static void irq_state_clr_masked(struct irq_desc *desc)
{
- desc->istate &= ~IRQS_MASKED;
- irq_compat_clr_masked(desc);
+ irqd_clear(&desc->irq_data, IRQD_IRQ_MASKED);
}
static void irq_state_set_masked(struct irq_desc *desc)
{
- desc->istate |= IRQS_MASKED;
- irq_compat_set_masked(desc);
+ irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
}
int irq_startup(struct irq_desc *desc)
@@ -203,126 +204,6 @@ void irq_disable(struct irq_desc *desc)
}
}
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
-/* Temporary migration helpers */
-static void compat_irq_mask(struct irq_data *data)
-{
- data->chip->mask(data->irq);
-}
-
-static void compat_irq_unmask(struct irq_data *data)
-{
- data->chip->unmask(data->irq);
-}
-
-static void compat_irq_ack(struct irq_data *data)
-{
- data->chip->ack(data->irq);
-}
-
-static void compat_irq_mask_ack(struct irq_data *data)
-{
- data->chip->mask_ack(data->irq);
-}
-
-static void compat_irq_eoi(struct irq_data *data)
-{
- data->chip->eoi(data->irq);
-}
-
-static void compat_irq_enable(struct irq_data *data)
-{
- data->chip->enable(data->irq);
-}
-
-static void compat_irq_disable(struct irq_data *data)
-{
- data->chip->disable(data->irq);
-}
-
-static void compat_irq_shutdown(struct irq_data *data)
-{
- data->chip->shutdown(data->irq);
-}
-
-static unsigned int compat_irq_startup(struct irq_data *data)
-{
- return data->chip->startup(data->irq);
-}
-
-static int compat_irq_set_affinity(struct irq_data *data,
- const struct cpumask *dest, bool force)
-{
- return data->chip->set_affinity(data->irq, dest);
-}
-
-static int compat_irq_set_type(struct irq_data *data, unsigned int type)
-{
- return data->chip->set_type(data->irq, type);
-}
-
-static int compat_irq_set_wake(struct irq_data *data, unsigned int on)
-{
- return data->chip->set_wake(data->irq, on);
-}
-
-static int compat_irq_retrigger(struct irq_data *data)
-{
- return data->chip->retrigger(data->irq);
-}
-
-static void compat_bus_lock(struct irq_data *data)
-{
- data->chip->bus_lock(data->irq);
-}
-
-static void compat_bus_sync_unlock(struct irq_data *data)
-{
- data->chip->bus_sync_unlock(data->irq);
-}
-#endif
-
-/*
- * Fixup enable/disable function pointers
- */
-void irq_chip_set_defaults(struct irq_chip *chip)
-{
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
- if (chip->enable)
- chip->irq_enable = compat_irq_enable;
- if (chip->disable)
- chip->irq_disable = compat_irq_disable;
- if (chip->shutdown)
- chip->irq_shutdown = compat_irq_shutdown;
- if (chip->startup)
- chip->irq_startup = compat_irq_startup;
- if (!chip->end)
- chip->end = dummy_irq_chip.end;
- if (chip->bus_lock)
- chip->irq_bus_lock = compat_bus_lock;
- if (chip->bus_sync_unlock)
- chip->irq_bus_sync_unlock = compat_bus_sync_unlock;
- if (chip->mask)
- chip->irq_mask = compat_irq_mask;
- if (chip->unmask)
- chip->irq_unmask = compat_irq_unmask;
- if (chip->ack)
- chip->irq_ack = compat_irq_ack;
- if (chip->mask_ack)
- chip->irq_mask_ack = compat_irq_mask_ack;
- if (chip->eoi)
- chip->irq_eoi = compat_irq_eoi;
- if (chip->set_affinity)
- chip->irq_set_affinity = compat_irq_set_affinity;
- if (chip->set_type)
- chip->irq_set_type = compat_irq_set_type;
- if (chip->set_wake)
- chip->irq_set_wake = compat_irq_set_wake;
- if (chip->retrigger)
- chip->irq_retrigger = compat_irq_retrigger;
-#endif
-}
-
static inline void mask_ack_irq(struct irq_desc *desc)
{
if (desc->irq_data.chip->irq_mask_ack)
@@ -372,11 +253,10 @@ void handle_nested_irq(unsigned int irq)
kstat_incr_irqs_this_cpu(irq, desc);
action = desc->action;
- if (unlikely(!action || (desc->istate & IRQS_DISABLED)))
+ if (unlikely(!action || irqd_irq_disabled(&desc->irq_data)))
goto out_unlock;
- irq_compat_set_progress(desc);
- desc->istate |= IRQS_INPROGRESS;
+ irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
raw_spin_unlock_irq(&desc->lock);
action_ret = action->thread_fn(action->irq, action->dev_id);
@@ -384,8 +264,7 @@ void handle_nested_irq(unsigned int irq)
note_interrupt(irq, desc, action_ret);
raw_spin_lock_irq(&desc->lock);
- desc->istate &= ~IRQS_INPROGRESS;
- irq_compat_clr_progress(desc);
+ irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
out_unlock:
raw_spin_unlock_irq(&desc->lock);
@@ -416,14 +295,14 @@ handle_simple_irq(unsigned int irq, struct irq_desc *desc)
{
raw_spin_lock(&desc->lock);
- if (unlikely(desc->istate & IRQS_INPROGRESS))
+ if (unlikely(irqd_irq_inprogress(&desc->irq_data)))
if (!irq_check_poll(desc))
goto out_unlock;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
kstat_incr_irqs_this_cpu(irq, desc);
- if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED)))
+ if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data)))
goto out_unlock;
handle_irq_event(desc);
@@ -448,7 +327,7 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
raw_spin_lock(&desc->lock);
mask_ack_irq(desc);
- if (unlikely(desc->istate & IRQS_INPROGRESS))
+ if (unlikely(irqd_irq_inprogress(&desc->irq_data)))
if (!irq_check_poll(desc))
goto out_unlock;
@@ -459,12 +338,12 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
* If its disabled or no action available
* keep it masked and get out of here
*/
- if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED)))
+ if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data)))
goto out_unlock;
handle_irq_event(desc);
- if (!(desc->istate & (IRQS_DISABLED | IRQS_ONESHOT)))
+ if (!irqd_irq_disabled(&desc->irq_data) && !(desc->istate & IRQS_ONESHOT))
unmask_irq(desc);
out_unlock:
raw_spin_unlock(&desc->lock);
@@ -496,7 +375,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
{
raw_spin_lock(&desc->lock);
- if (unlikely(desc->istate & IRQS_INPROGRESS))
+ if (unlikely(irqd_irq_inprogress(&desc->irq_data)))
if (!irq_check_poll(desc))
goto out;
@@ -507,8 +386,7 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
* If its disabled or no action available
* then mask it and get out of here:
*/
- if (unlikely(!desc->action || (desc->istate & IRQS_DISABLED))) {
- irq_compat_set_pending(desc);
+ if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
desc->istate |= IRQS_PENDING;
mask_irq(desc);
goto out;
@@ -558,10 +436,9 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
* we shouldn't process the IRQ. Mark it pending, handle
* the necessary masking and go out
*/
- if (unlikely((desc->istate & (IRQS_DISABLED | IRQS_INPROGRESS) ||
- !desc->action))) {
+ if (unlikely(irqd_irq_disabled(&desc->irq_data) ||
+ irqd_irq_inprogress(&desc->irq_data) || !desc->action)) {
if (!irq_check_poll(desc)) {
- irq_compat_set_pending(desc);
desc->istate |= IRQS_PENDING;
mask_ack_irq(desc);
goto out_unlock;
@@ -584,20 +461,65 @@ handle_edge_irq(unsigned int irq, struct irq_desc *desc)
* Renable it, if it was not disabled in meantime.
*/
if (unlikely(desc->istate & IRQS_PENDING)) {
- if (!(desc->istate & IRQS_DISABLED) &&
- (desc->istate & IRQS_MASKED))
+ if (!irqd_irq_disabled(&desc->irq_data) &&
+ irqd_irq_masked(&desc->irq_data))
unmask_irq(desc);
}
handle_irq_event(desc);
} while ((desc->istate & IRQS_PENDING) &&
- !(desc->istate & IRQS_DISABLED));
+ !irqd_irq_disabled(&desc->irq_data));
out_unlock:
raw_spin_unlock(&desc->lock);
}
+#ifdef CONFIG_IRQ_EDGE_EOI_HANDLER
+/**
+ * handle_edge_eoi_irq - edge eoi type IRQ handler
+ * @irq: the interrupt number
+ * @desc: the interrupt description structure for this irq
+ *
+ * Similar as the above handle_edge_irq, but using eoi and w/o the
+ * mask/unmask logic.
+ */
+void handle_edge_eoi_irq(unsigned int irq, struct irq_desc *desc)
+{
+ struct irq_chip *chip = irq_desc_get_chip(desc);
+
+ raw_spin_lock(&desc->lock);
+
+ desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+ /*
+ * If we're currently running this IRQ, or its disabled,
+ * we shouldn't process the IRQ. Mark it pending, handle
+ * the necessary masking and go out
+ */
+ if (unlikely(irqd_irq_disabled(&desc->irq_data) ||
+ irqd_irq_inprogress(&desc->irq_data) || !desc->action)) {
+ if (!irq_check_poll(desc)) {
+ desc->istate |= IRQS_PENDING;
+ goto out_eoi;
+ }
+ }
+ kstat_incr_irqs_this_cpu(irq, desc);
+
+ do {
+ if (unlikely(!desc->action))
+ goto out_eoi;
+
+ handle_irq_event(desc);
+
+ } while ((desc->istate & IRQS_PENDING) &&
+ !irqd_irq_disabled(&desc->irq_data));
+
+out_eoi:
+ chip->irq_eoi(&desc->irq_data);
+ raw_spin_unlock(&desc->lock);
+}
+#endif
+
/**
* handle_percpu_irq - Per CPU local irq handler
* @irq: the interrupt number
@@ -642,8 +564,7 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
if (handle == handle_bad_irq) {
if (desc->irq_data.chip != &no_irq_chip)
mask_ack_irq(desc);
- irq_compat_set_disabled(desc);
- desc->istate |= IRQS_DISABLED;
+ irq_state_set_disabled(desc);
desc->depth = 1;
}
desc->handle_irq = handle;
@@ -684,8 +605,70 @@ void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
irqd_set(&desc->irq_data, IRQD_PER_CPU);
if (irq_settings_can_move_pcntxt(desc))
irqd_set(&desc->irq_data, IRQD_MOVE_PCNTXT);
+ if (irq_settings_is_level(desc))
+ irqd_set(&desc->irq_data, IRQD_LEVEL);
irqd_set(&desc->irq_data, irq_settings_get_trigger_mask(desc));
irq_put_desc_unlock(desc, flags);
}
+
+/**
+ * irq_cpu_online - Invoke all irq_cpu_online functions.
+ *
+ * Iterate through all irqs and invoke the chip.irq_cpu_online()
+ * for each.
+ */
+void irq_cpu_online(void)
+{
+ struct irq_desc *desc;
+ struct irq_chip *chip;
+ unsigned long flags;
+ unsigned int irq;
+
+ for_each_active_irq(irq) {
+ desc = irq_to_desc(irq);
+ if (!desc)
+ continue;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+
+ chip = irq_data_get_irq_chip(&desc->irq_data);
+ if (chip && chip->irq_cpu_online &&
+ (!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) ||
+ !irqd_irq_disabled(&desc->irq_data)))
+ chip->irq_cpu_online(&desc->irq_data);
+
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
+
+/**
+ * irq_cpu_offline - Invoke all irq_cpu_offline functions.
+ *
+ * Iterate through all irqs and invoke the chip.irq_cpu_offline()
+ * for each.
+ */
+void irq_cpu_offline(void)
+{
+ struct irq_desc *desc;
+ struct irq_chip *chip;
+ unsigned long flags;
+ unsigned int irq;
+
+ for_each_active_irq(irq) {
+ desc = irq_to_desc(irq);
+ if (!desc)
+ continue;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+
+ chip = irq_data_get_irq_chip(&desc->irq_data);
+ if (chip && chip->irq_cpu_offline &&
+ (!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) ||
+ !irqd_irq_disabled(&desc->irq_data)))
+ chip->irq_cpu_offline(&desc->irq_data);
+
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+}
diff --git a/kernel/irq/compat.h b/kernel/irq/compat.h
deleted file mode 100644
index 6bbaf66aca8..00000000000
--- a/kernel/irq/compat.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Compat layer for transition period
- */
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
-static inline void irq_compat_set_progress(struct irq_desc *desc)
-{
- desc->status |= IRQ_INPROGRESS;
-}
-
-static inline void irq_compat_clr_progress(struct irq_desc *desc)
-{
- desc->status &= ~IRQ_INPROGRESS;
-}
-static inline void irq_compat_set_disabled(struct irq_desc *desc)
-{
- desc->status |= IRQ_DISABLED;
-}
-static inline void irq_compat_clr_disabled(struct irq_desc *desc)
-{
- desc->status &= ~IRQ_DISABLED;
-}
-static inline void irq_compat_set_pending(struct irq_desc *desc)
-{
- desc->status |= IRQ_PENDING;
-}
-
-static inline void irq_compat_clr_pending(struct irq_desc *desc)
-{
- desc->status &= ~IRQ_PENDING;
-}
-static inline void irq_compat_set_masked(struct irq_desc *desc)
-{
- desc->status |= IRQ_MASKED;
-}
-
-static inline void irq_compat_clr_masked(struct irq_desc *desc)
-{
- desc->status &= ~IRQ_MASKED;
-}
-static inline void irq_compat_set_move_pending(struct irq_desc *desc)
-{
- desc->status |= IRQ_MOVE_PENDING;
-}
-
-static inline void irq_compat_clr_move_pending(struct irq_desc *desc)
-{
- desc->status &= ~IRQ_MOVE_PENDING;
-}
-static inline void irq_compat_set_affinity(struct irq_desc *desc)
-{
- desc->status |= IRQ_AFFINITY_SET;
-}
-
-static inline void irq_compat_clr_affinity(struct irq_desc *desc)
-{
- desc->status &= ~IRQ_AFFINITY_SET;
-}
-#else
-static inline void irq_compat_set_progress(struct irq_desc *desc) { }
-static inline void irq_compat_clr_progress(struct irq_desc *desc) { }
-static inline void irq_compat_set_disabled(struct irq_desc *desc) { }
-static inline void irq_compat_clr_disabled(struct irq_desc *desc) { }
-static inline void irq_compat_set_pending(struct irq_desc *desc) { }
-static inline void irq_compat_clr_pending(struct irq_desc *desc) { }
-static inline void irq_compat_set_masked(struct irq_desc *desc) { }
-static inline void irq_compat_clr_masked(struct irq_desc *desc) { }
-static inline void irq_compat_set_move_pending(struct irq_desc *desc) { }
-static inline void irq_compat_clr_move_pending(struct irq_desc *desc) { }
-static inline void irq_compat_set_affinity(struct irq_desc *desc) { }
-static inline void irq_compat_clr_affinity(struct irq_desc *desc) { }
-#endif
-
diff --git a/kernel/irq/debug.h b/kernel/irq/debug.h
index d1a33b7fa61..306cba37e9a 100644
--- a/kernel/irq/debug.h
+++ b/kernel/irq/debug.h
@@ -4,8 +4,10 @@
#include <linux/kallsyms.h>
-#define P(f) if (desc->status & f) printk("%14s set\n", #f)
+#define P(f) if (desc->status_use_accessors & f) printk("%14s set\n", #f)
#define PS(f) if (desc->istate & f) printk("%14s set\n", #f)
+/* FIXME */
+#define PD(f) do { } while (0)
static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
{
@@ -28,13 +30,15 @@ static inline void print_irq_desc(unsigned int irq, struct irq_desc *desc)
P(IRQ_NOAUTOEN);
PS(IRQS_AUTODETECT);
- PS(IRQS_INPROGRESS);
PS(IRQS_REPLAY);
PS(IRQS_WAITING);
- PS(IRQS_DISABLED);
PS(IRQS_PENDING);
- PS(IRQS_MASKED);
+
+ PD(IRQS_INPROGRESS);
+ PD(IRQS_DISABLED);
+ PD(IRQS_MASKED);
}
#undef P
#undef PS
+#undef PD
diff --git a/kernel/irq/dummychip.c b/kernel/irq/dummychip.c
index 20dc5474947..b5fcd96c710 100644
--- a/kernel/irq/dummychip.c
+++ b/kernel/irq/dummychip.c
@@ -31,13 +31,6 @@ static unsigned int noop_ret(struct irq_data *data)
return 0;
}
-#ifndef CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED
-static void compat_noop(unsigned int irq) { }
-#define END_INIT .end = compat_noop
-#else
-#define END_INIT
-#endif
-
/*
* Generic no controller implementation
*/
@@ -48,7 +41,6 @@ struct irq_chip no_irq_chip = {
.irq_enable = noop,
.irq_disable = noop,
.irq_ack = ack_bad,
- END_INIT
};
/*
@@ -64,5 +56,4 @@ struct irq_chip dummy_irq_chip = {
.irq_ack = noop,
.irq_mask = noop,
.irq_unmask = noop,
- END_INIT
};
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index 517561fc731..90cb55f6d7e 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -175,28 +175,13 @@ irqreturn_t handle_irq_event(struct irq_desc *desc)
struct irqaction *action = desc->action;
irqreturn_t ret;
- irq_compat_clr_pending(desc);
desc->istate &= ~IRQS_PENDING;
- irq_compat_set_progress(desc);
- desc->istate |= IRQS_INPROGRESS;
+ irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
raw_spin_unlock(&desc->lock);
ret = handle_irq_event_percpu(desc, action);
raw_spin_lock(&desc->lock);
- desc->istate &= ~IRQS_INPROGRESS;
- irq_compat_clr_progress(desc);
+ irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
return ret;
}
-
-/**
- * handle_IRQ_event - irq action chain handler
- * @irq: the interrupt number
- * @action: the interrupt action chain for this irq
- *
- * Handles the action chain of an irq event
- */
-irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
-{
- return handle_irq_event_percpu(irq_to_desc(irq), action);
-}
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 6c6ec9a4902..6546431447d 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -15,10 +15,6 @@
#define istate core_internal_state__do_not_mess_with_it
-#ifdef CONFIG_GENERIC_HARDIRQS_NO_COMPAT
-# define status status_use_accessors
-#endif
-
extern int noirqdebug;
/*
@@ -44,38 +40,28 @@ enum {
* IRQS_SPURIOUS_DISABLED - was disabled due to spurious interrupt
* detection
* IRQS_POLL_INPROGRESS - polling in progress
- * IRQS_INPROGRESS - Interrupt in progress
* IRQS_ONESHOT - irq is not unmasked in primary handler
* IRQS_REPLAY - irq is replayed
* IRQS_WAITING - irq is waiting
- * IRQS_DISABLED - irq is disabled
* IRQS_PENDING - irq is pending and replayed later
- * IRQS_MASKED - irq is masked
* IRQS_SUSPENDED - irq is suspended
*/
enum {
IRQS_AUTODETECT = 0x00000001,
IRQS_SPURIOUS_DISABLED = 0x00000002,
IRQS_POLL_INPROGRESS = 0x00000008,
- IRQS_INPROGRESS = 0x00000010,
IRQS_ONESHOT = 0x00000020,
IRQS_REPLAY = 0x00000040,
IRQS_WAITING = 0x00000080,
- IRQS_DISABLED = 0x00000100,
IRQS_PENDING = 0x00000200,
- IRQS_MASKED = 0x00000400,
IRQS_SUSPENDED = 0x00000800,
};
-#include "compat.h"
#include "debug.h"
#include "settings.h"
#define irq_data_to_desc(data) container_of(data, struct irq_desc, irq_data)
-/* Set default functions for irq_chip structures: */
-extern void irq_chip_set_defaults(struct irq_chip *chip);
-
extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
unsigned long flags);
extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
@@ -162,13 +148,11 @@ irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
static inline void irqd_set_move_pending(struct irq_data *d)
{
d->state_use_accessors |= IRQD_SETAFFINITY_PENDING;
- irq_compat_set_move_pending(irq_data_to_desc(d));
}
static inline void irqd_clr_move_pending(struct irq_data *d)
{
d->state_use_accessors &= ~IRQD_SETAFFINITY_PENDING;
- irq_compat_clr_move_pending(irq_data_to_desc(d));
}
static inline void irqd_clear(struct irq_data *d, unsigned int mask)
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 6fb014f172f..2c039c9b938 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -80,7 +80,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
desc->irq_data.handler_data = NULL;
desc->irq_data.msi_desc = NULL;
irq_settings_clr_and_set(desc, ~0, _IRQ_DEFAULT_INIT_FLAGS);
- desc->istate = IRQS_DISABLED;
+ irqd_set(&desc->irq_data, IRQD_IRQ_DISABLED);
desc->handle_irq = handle_bad_irq;
desc->depth = 1;
desc->irq_count = 0;
@@ -238,7 +238,6 @@ int __init early_irq_init(void)
struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS-1] = {
- .istate = IRQS_DISABLED,
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __RAW_SPIN_LOCK_UNLOCKED(irq_desc->lock),
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 0a2aa73e536..12a80fdae11 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -41,7 +41,7 @@ early_param("threadirqs", setup_forced_irqthreads);
void synchronize_irq(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
- unsigned int state;
+ bool inprogress;
if (!desc)
return;
@@ -53,16 +53,16 @@ void synchronize_irq(unsigned int irq)
* Wait until we're out of the critical section. This might
* give the wrong answer due to the lack of memory barriers.
*/
- while (desc->istate & IRQS_INPROGRESS)
+ while (irqd_irq_inprogress(&desc->irq_data))
cpu_relax();
/* Ok, that indicated we're done: double-check carefully. */
raw_spin_lock_irqsave(&desc->lock, flags);
- state = desc->istate;
+ inprogress = irqd_irq_inprogress(&desc->irq_data);
raw_spin_unlock_irqrestore(&desc->lock, flags);
/* Oops, that failed? */
- } while (state & IRQS_INPROGRESS);
+ } while (inprogress);
/*
* We made sure that no hardirq handler is running. Now verify
@@ -112,13 +112,13 @@ void irq_set_thread_affinity(struct irq_desc *desc)
}
#ifdef CONFIG_GENERIC_PENDING_IRQ
-static inline bool irq_can_move_pcntxt(struct irq_desc *desc)
+static inline bool irq_can_move_pcntxt(struct irq_data *data)
{
- return irq_settings_can_move_pcntxt(desc);
+ return irqd_can_move_in_process_context(data);
}
-static inline bool irq_move_pending(struct irq_desc *desc)
+static inline bool irq_move_pending(struct irq_data *data)
{
- return irqd_is_setaffinity_pending(&desc->irq_data);
+ return irqd_is_setaffinity_pending(data);
}
static inline void
irq_copy_pending(struct irq_desc *desc, const struct cpumask *mask)
@@ -131,43 +131,34 @@ irq_get_pending(struct cpumask *mask, struct irq_desc *desc)
cpumask_copy(mask, desc->pending_mask);
}
#else
-static inline bool irq_can_move_pcntxt(struct irq_desc *desc) { return true; }
-static inline bool irq_move_pending(struct irq_desc *desc) { return false; }
+static inline bool irq_can_move_pcntxt(struct irq_data *data) { return true; }
+static inline bool irq_move_pending(struct irq_data *data) { return false; }
static inline void
irq_copy_pending(struct irq_desc *desc, const struct cpumask *mask) { }
static inline void
irq_get_pending(struct cpumask *mask, struct irq_desc *desc) { }
#endif
-/**
- * irq_set_affinity - Set the irq affinity of a given irq
- * @irq: Interrupt to set affinity
- * @cpumask: cpumask
- *
- */
-int irq_set_affinity(unsigned int irq, const struct cpumask *mask)
+int __irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask)
{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irq_chip *chip = desc->irq_data.chip;
- unsigned long flags;
+ struct irq_chip *chip = irq_data_get_irq_chip(data);
+ struct irq_desc *desc = irq_data_to_desc(data);
int ret = 0;
- if (!chip->irq_set_affinity)
+ if (!chip || !chip->irq_set_affinity)
return -EINVAL;
- raw_spin_lock_irqsave(&desc->lock, flags);
-
- if (irq_can_move_pcntxt(desc)) {
- ret = chip->irq_set_affinity(&desc->irq_data, mask, false);
+ if (irq_can_move_pcntxt(data)) {
+ ret = chip->irq_set_affinity(data, mask, false);
switch (ret) {
case IRQ_SET_MASK_OK:
- cpumask_copy(desc->irq_data.affinity, mask);
+ cpumask_copy(data->affinity, mask);
case IRQ_SET_MASK_OK_NOCOPY:
irq_set_thread_affinity(desc);
ret = 0;
}
} else {
- irqd_set_move_pending(&desc->irq_data);
+ irqd_set_move_pending(data);
irq_copy_pending(desc, mask);
}
@@ -175,8 +166,28 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *mask)
kref_get(&desc->affinity_notify->kref);
schedule_work(&desc->affinity_notify->work);
}
- irq_compat_set_affinity(desc);
- irqd_set(&desc->irq_data, IRQD_AFFINITY_SET);
+ irqd_set(data, IRQD_AFFINITY_SET);
+
+ return ret;
+}
+
+/**
+ * irq_set_affinity - Set the irq affinity of a given irq
+ * @irq: Interrupt to set affinity
+ * @mask: cpumask
+ *
+ */
+int irq_set_affinity(unsigned int irq, const struct cpumask *mask)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ unsigned long flags;
+ int ret;
+
+ if (!desc)
+ return -EINVAL;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+ ret = __irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask);
raw_spin_unlock_irqrestore(&desc->lock, flags);
return ret;
}
@@ -206,7 +217,7 @@ static void irq_affinity_notify(struct work_struct *work)
goto out;
raw_spin_lock_irqsave(&desc->lock, flags);
- if (irq_move_pending(desc))
+ if (irq_move_pending(&desc->irq_data))
irq_get_pending(cpumask, desc);
else
cpumask_copy(cpumask, desc->irq_data.affinity);
@@ -285,10 +296,8 @@ setup_affinity(unsigned int irq, struct irq_desc *desc, struct cpumask *mask)
if (cpumask_intersects(desc->irq_data.affinity,
cpu_online_mask))
set = desc->irq_data.affinity;
- else {
- irq_compat_clr_affinity(desc);
+ else
irqd_clear(&desc->irq_data, IRQD_AFFINITY_SET);
- }
}
cpumask_and(mask, cpu_online_mask, set);
@@ -551,9 +560,9 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
flags &= IRQ_TYPE_SENSE_MASK;
if (chip->flags & IRQCHIP_SET_TYPE_MASKED) {
- if (!(desc->istate & IRQS_MASKED))
+ if (!irqd_irq_masked(&desc->irq_data))
mask_irq(desc);
- if (!(desc->istate & IRQS_DISABLED))
+ if (!irqd_irq_disabled(&desc->irq_data))
unmask = 1;
}
@@ -575,8 +584,6 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
irqd_set(&desc->irq_data, IRQD_LEVEL);
}
- if (chip != desc->irq_data.chip)
- irq_chip_set_defaults(desc->irq_data.chip);
ret = 0;
break;
default:
@@ -651,7 +658,7 @@ again:
* irq_wake_thread(). See the comment there which explains the
* serialization.
*/
- if (unlikely(desc->istate & IRQS_INPROGRESS)) {
+ if (unlikely(irqd_irq_inprogress(&desc->irq_data))) {
raw_spin_unlock_irq(&desc->lock);
chip_bus_sync_unlock(desc);
cpu_relax();
@@ -668,12 +675,10 @@ again:
desc->threads_oneshot &= ~action->thread_mask;
- if (!desc->threads_oneshot && !(desc->istate & IRQS_DISABLED) &&
- (desc->istate & IRQS_MASKED)) {
- irq_compat_clr_masked(desc);
- desc->istate &= ~IRQS_MASKED;
- desc->irq_data.chip->irq_unmask(&desc->irq_data);
- }
+ if (!desc->threads_oneshot && !irqd_irq_disabled(&desc->irq_data) &&
+ irqd_irq_masked(&desc->irq_data))
+ unmask_irq(desc);
+
out_unlock:
raw_spin_unlock_irq(&desc->lock);
chip_bus_sync_unlock(desc);
@@ -767,7 +772,7 @@ static int irq_thread(void *data)
atomic_inc(&desc->threads_active);
raw_spin_lock_irq(&desc->lock);
- if (unlikely(desc->istate & IRQS_DISABLED)) {
+ if (unlikely(irqd_irq_disabled(&desc->irq_data))) {
/*
* CHECKME: We might need a dedicated
* IRQ_THREAD_PENDING flag here, which
@@ -775,7 +780,6 @@ static int irq_thread(void *data)
* but AFAICT IRQS_PENDING should be fine as it
* retriggers the interrupt itself --- tglx
*/
- irq_compat_set_pending(desc);
desc->istate |= IRQS_PENDING;
raw_spin_unlock_irq(&desc->lock);
} else {
@@ -971,8 +975,6 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
new->thread_mask = 1 << ffz(thread_mask);
if (!shared) {
- irq_chip_set_defaults(desc->irq_data.chip);
-
init_waitqueue_head(&desc->wait_for_threads);
/* Setup the type (level, edge polarity) if configured: */
@@ -985,8 +987,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
}
desc->istate &= ~(IRQS_AUTODETECT | IRQS_SPURIOUS_DISABLED | \
- IRQS_INPROGRESS | IRQS_ONESHOT | \
- IRQS_WAITING);
+ IRQS_ONESHOT | IRQS_WAITING);
+ irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
if (new->flags & IRQF_PERCPU) {
irqd_set(&desc->irq_data, IRQD_PER_CPU);
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index ec4806d4778..bc6194698df 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -53,20 +53,14 @@ void irq_move_masked_irq(struct irq_data *idata)
cpumask_clear(desc->pending_mask);
}
-void move_masked_irq(int irq)
-{
- irq_move_masked_irq(irq_get_irq_data(irq));
-}
-
void irq_move_irq(struct irq_data *idata)
{
- struct irq_desc *desc = irq_data_to_desc(idata);
bool masked;
if (likely(!irqd_is_setaffinity_pending(idata)))
return;
- if (unlikely(desc->istate & IRQS_DISABLED))
+ if (unlikely(irqd_irq_disabled(idata)))
return;
/*
@@ -74,15 +68,10 @@ void irq_move_irq(struct irq_data *idata)
* threaded interrupt with ONESHOT set, we can end up with an
* interrupt storm.
*/
- masked = desc->istate & IRQS_MASKED;
+ masked = irqd_irq_masked(idata);
if (!masked)
idata->chip->irq_mask(idata);
irq_move_masked_irq(idata);
if (!masked)
idata->chip->irq_unmask(idata);
}
-
-void move_native_irq(int irq)
-{
- irq_move_irq(irq_get_irq_data(irq));
-}
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 626d092eed9..dd201bd3510 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -364,6 +364,10 @@ int __weak arch_show_interrupts(struct seq_file *p, int prec)
return 0;
}
+#ifndef ACTUAL_NR_IRQS
+# define ACTUAL_NR_IRQS nr_irqs
+#endif
+
int show_interrupts(struct seq_file *p, void *v)
{
static int prec;
@@ -373,10 +377,10 @@ int show_interrupts(struct seq_file *p, void *v)
struct irqaction *action;
struct irq_desc *desc;
- if (i > nr_irqs)
+ if (i > ACTUAL_NR_IRQS)
return 0;
- if (i == nr_irqs)
+ if (i == ACTUAL_NR_IRQS)
return arch_show_interrupts(p, prec);
/* print header and calculate the width of the first column */
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index ad683a99b1e..14dd5761e8c 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -65,7 +65,6 @@ void check_irq_resend(struct irq_desc *desc, unsigned int irq)
if (desc->istate & IRQS_REPLAY)
return;
if (desc->istate & IRQS_PENDING) {
- irq_compat_clr_pending(desc);
desc->istate &= ~IRQS_PENDING;
desc->istate |= IRQS_REPLAY;
diff --git a/kernel/irq/settings.h b/kernel/irq/settings.h
index 0227ad35827..0d91730b633 100644
--- a/kernel/irq/settings.h
+++ b/kernel/irq/settings.h
@@ -15,17 +15,8 @@ enum {
_IRQF_MODIFY_MASK = IRQF_MODIFY_MASK,
};
-#define IRQ_INPROGRESS GOT_YOU_MORON
-#define IRQ_REPLAY GOT_YOU_MORON
-#define IRQ_WAITING GOT_YOU_MORON
-#define IRQ_DISABLED GOT_YOU_MORON
-#define IRQ_PENDING GOT_YOU_MORON
-#define IRQ_MASKED GOT_YOU_MORON
-#define IRQ_WAKEUP GOT_YOU_MORON
-#define IRQ_MOVE_PENDING GOT_YOU_MORON
#define IRQ_PER_CPU GOT_YOU_MORON
#define IRQ_NO_BALANCING GOT_YOU_MORON
-#define IRQ_AFFINITY_SET GOT_YOU_MORON
#define IRQ_LEVEL GOT_YOU_MORON
#define IRQ_NOPROBE GOT_YOU_MORON
#define IRQ_NOREQUEST GOT_YOU_MORON
@@ -37,102 +28,98 @@ enum {
static inline void
irq_settings_clr_and_set(struct irq_desc *desc, u32 clr, u32 set)
{
- desc->status &= ~(clr & _IRQF_MODIFY_MASK);
- desc->status |= (set & _IRQF_MODIFY_MASK);
+ desc->status_use_accessors &= ~(clr & _IRQF_MODIFY_MASK);
+ desc->status_use_accessors |= (set & _IRQF_MODIFY_MASK);
}
static inline bool irq_settings_is_per_cpu(struct irq_desc *desc)
{
- return desc->status & _IRQ_PER_CPU;
+ return desc->status_use_accessors & _IRQ_PER_CPU;
}
static inline void irq_settings_set_per_cpu(struct irq_desc *desc)
{
- desc->status |= _IRQ_PER_CPU;
+ desc->status_use_accessors |= _IRQ_PER_CPU;
}
static inline void irq_settings_set_no_balancing(struct irq_desc *desc)
{
- desc->status |= _IRQ_NO_BALANCING;
+ desc->status_use_accessors |= _IRQ_NO_BALANCING;
}
static inline bool irq_settings_has_no_balance_set(struct irq_desc *desc)
{
- return desc->status & _IRQ_NO_BALANCING;
+ return desc->status_use_accessors & _IRQ_NO_BALANCING;
}
static inline u32 irq_settings_get_trigger_mask(struct irq_desc *desc)
{
- return desc->status & IRQ_TYPE_SENSE_MASK;
+ return desc->status_use_accessors & IRQ_TYPE_SENSE_MASK;
}
static inline void
irq_settings_set_trigger_mask(struct irq_desc *desc, u32 mask)
{
- desc->status &= ~IRQ_TYPE_SENSE_MASK;
- desc->status |= mask & IRQ_TYPE_SENSE_MASK;
+ desc->status_use_accessors &= ~IRQ_TYPE_SENSE_MASK;
+ desc->status_use_accessors |= mask & IRQ_TYPE_SENSE_MASK;
}
static inline bool irq_settings_is_level(struct irq_desc *desc)
{
- return desc->status & _IRQ_LEVEL;
+ return desc->status_use_accessors & _IRQ_LEVEL;
}
static inline void irq_settings_clr_level(struct irq_desc *desc)
{
- desc->status &= ~_IRQ_LEVEL;
+ desc->status_use_accessors &= ~_IRQ_LEVEL;
}
static inline void irq_settings_set_level(struct irq_desc *desc)
{
- desc->status |= _IRQ_LEVEL;
+ desc->status_use_accessors |= _IRQ_LEVEL;
}
static inline bool irq_settings_can_request(struct irq_desc *desc)
{
- return !(desc->status & _IRQ_NOREQUEST);
+ return !(desc->status_use_accessors & _IRQ_NOREQUEST);
}
static inline void irq_settings_clr_norequest(struct irq_desc *desc)
{
- desc->status &= ~_IRQ_NOREQUEST;
+ desc->status_use_accessors &= ~_IRQ_NOREQUEST;
}
static inline void irq_settings_set_norequest(struct irq_desc *desc)
{
- desc->status |= _IRQ_NOREQUEST;
+ desc->status_use_accessors |= _IRQ_NOREQUEST;
}
static inline bool irq_settings_can_probe(struct irq_desc *desc)
{
- return !(desc->status & _IRQ_NOPROBE);
+ return !(desc->status_use_accessors & _IRQ_NOPROBE);
}
static inline void irq_settings_clr_noprobe(struct irq_desc *desc)
{
- desc->status &= ~_IRQ_NOPROBE;
+ desc->status_use_accessors &= ~_IRQ_NOPROBE;
}
static inline void irq_settings_set_noprobe(struct irq_desc *desc)
{
- desc->status |= _IRQ_NOPROBE;
+ desc->status_use_accessors |= _IRQ_NOPROBE;
}
static inline bool irq_settings_can_move_pcntxt(struct irq_desc *desc)
{
- return desc->status & _IRQ_MOVE_PCNTXT;
+ return desc->status_use_accessors & _IRQ_MOVE_PCNTXT;
}
static inline bool irq_settings_can_autoenable(struct irq_desc *desc)
{
- return !(desc->status & _IRQ_NOAUTOEN);
+ return !(desc->status_use_accessors & _IRQ_NOAUTOEN);
}
static inline bool irq_settings_is_nested_thread(struct irq_desc *desc)
{
- return desc->status & _IRQ_NESTED_THREAD;
+ return desc->status_use_accessors & _IRQ_NESTED_THREAD;
}
-
-/* Nothing should touch desc->status from now on */
-#undef status
-#define status USE_THE_PROPER_WRAPPERS_YOU_MORON
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index dd586ebf9c8..dfbd550401b 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -45,12 +45,12 @@ bool irq_wait_for_poll(struct irq_desc *desc)
#ifdef CONFIG_SMP
do {
raw_spin_unlock(&desc->lock);
- while (desc->istate & IRQS_INPROGRESS)
+ while (irqd_irq_inprogress(&desc->irq_data))
cpu_relax();
raw_spin_lock(&desc->lock);
- } while (desc->istate & IRQS_INPROGRESS);
+ } while (irqd_irq_inprogress(&desc->irq_data));
/* Might have been disabled in meantime */
- return !(desc->istate & IRQS_DISABLED) && desc->action;
+ return !irqd_irq_disabled(&desc->irq_data) && desc->action;
#else
return false;
#endif
@@ -75,7 +75,7 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force)
* Do not poll disabled interrupts unless the spurious
* disabled poller asks explicitely.
*/
- if ((desc->istate & IRQS_DISABLED) && !force)
+ if (irqd_irq_disabled(&desc->irq_data) && !force)
goto out;
/*
@@ -88,12 +88,11 @@ static int try_one_irq(int irq, struct irq_desc *desc, bool force)
goto out;
/* Already running on another processor */
- if (desc->istate & IRQS_INPROGRESS) {
+ if (irqd_irq_inprogress(&desc->irq_data)) {
/*
* Already running: If it is shared get the other
* CPU to go looking for our mystery interrupt too
*/
- irq_compat_set_pending(desc);
desc->istate |= IRQS_PENDING;
goto out;
}
diff --git a/kernel/kexec.c b/kernel/kexec.c
index ec19b92c7eb..4e240a378df 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -1099,7 +1099,8 @@ size_t crash_get_memory_size(void)
return size;
}
-static void free_reserved_phys_range(unsigned long begin, unsigned long end)
+void __weak crash_free_reserved_phys_range(unsigned long begin,
+ unsigned long end)
{
unsigned long addr;
@@ -1135,7 +1136,7 @@ int crash_shrink_memory(unsigned long new_size)
start = roundup(start, PAGE_SIZE);
end = roundup(start + new_size, PAGE_SIZE);
- free_reserved_phys_range(end, crashk_res.end);
+ crash_free_reserved_phys_range(end, crashk_res.end);
if ((start == end) && (crashk_res.parent != NULL))
release_resource(&crashk_res);
diff --git a/kernel/signal.c b/kernel/signal.c
index 324eff5468a..1186cf7fac7 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2437,7 +2437,7 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
/* Not even root can pretend to send signals from the kernel.
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
- if (info.si_code != SI_QUEUE) {
+ if (info.si_code >= 0 || info.si_code == SI_TKILL) {
/* We used to allow any < 0 si_code */
WARN_ON_ONCE(info.si_code < 0);
return -EPERM;
@@ -2457,7 +2457,7 @@ long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
/* Not even root can pretend to send signals from the kernel.
* Nor can they impersonate a kill()/tgkill(), which adds source info.
*/
- if (info->si_code != SI_QUEUE) {
+ if (info->si_code >= 0 || info->si_code == SI_TKILL) {
/* We used to allow any < 0 si_code */
WARN_ON_ONCE(info->si_code < 0);
return -EPERM;
diff --git a/mm/nommu.c b/mm/nommu.c
index cb86e7d5e7f..c4c542c736a 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -1971,21 +1971,10 @@ int filemap_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
}
EXPORT_SYMBOL(filemap_fault);
-/*
- * Access another process' address space.
- * - source/target buffer must be kernel space
- */
-int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
+ unsigned long addr, void *buf, int len, int write)
{
struct vm_area_struct *vma;
- struct mm_struct *mm;
-
- if (addr + len < addr)
- return 0;
-
- mm = get_task_mm(tsk);
- if (!mm)
- return 0;
down_read(&mm->mmap_sem);
@@ -2010,6 +1999,43 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
}
up_read(&mm->mmap_sem);
+
+ return len;
+}
+
+/**
+ * @access_remote_vm - access another process' address space
+ * @mm: the mm_struct of the target address space
+ * @addr: start address to access
+ * @buf: source or destination buffer
+ * @len: number of bytes to transfer
+ * @write: whether the access is a write
+ *
+ * The caller must hold a reference on @mm.
+ */
+int access_remote_vm(struct mm_struct *mm, unsigned long addr,
+ void *buf, int len, int write)
+{
+ return __access_remote_vm(NULL, mm, addr, buf, len, write);
+}
+
+/*
+ * Access another process' address space.
+ * - source/target buffer must be kernel space
+ */
+int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+{
+ struct mm_struct *mm;
+
+ if (addr + len < addr)
+ return 0;
+
+ mm = get_task_mm(tsk);
+ if (!mm)
+ return 0;
+
+ len = __access_remote_vm(tsk, mm, addr, buf, len, write);
+
mmput(mm);
return len;
}
diff --git a/mm/percpu.c b/mm/percpu.c
index 3f930018aa6..55d4d113fbd 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -1008,8 +1008,7 @@ phys_addr_t per_cpu_ptr_to_phys(void *addr)
}
if (in_first_chunk) {
- if ((unsigned long)addr < VMALLOC_START ||
- (unsigned long)addr >= VMALLOC_END)
+ if (!is_vmalloc_addr(addr))
return __pa(addr);
else
return page_to_phys(vmalloc_to_page(addr));
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 206e771e82d..956a5302002 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1051,16 +1051,17 @@ static int atalk_release(struct socket *sock)
{
struct sock *sk = sock->sk;
- sock_hold(sk);
- lock_sock(sk);
if (sk) {
+ sock_hold(sk);
+ lock_sock(sk);
+
sock_orphan(sk);
sock->sk = NULL;
atalk_destroy_socket(sk);
- }
- release_sock(sk);
- sock_put(sk);
+ release_sock(sk);
+ sock_put(sk);
+ }
return 0;
}
diff --git a/net/atm/common.c b/net/atm/common.c
index 1b9c52a02cd..22b963d06a1 100644
--- a/net/atm/common.c
+++ b/net/atm/common.c
@@ -252,6 +252,7 @@ void atm_dev_release_vccs(struct atm_dev *dev)
}
write_unlock_irq(&vcc_sklist_lock);
}
+EXPORT_SYMBOL(atm_dev_release_vccs);
static int adjust_tp(struct atm_trafprm *tp, unsigned char aal)
{
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index dce8f0009a1..718b60366df 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -389,6 +389,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
{
struct net_bridge_port *p;
int err = 0;
+ bool changed_addr;
/* Don't allow bridging non-ethernet like devices */
if ((dev->flags & IFF_LOOPBACK) ||
@@ -446,7 +447,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
list_add_rcu(&p->list, &br->port_list);
spin_lock_bh(&br->lock);
- br_stp_recalculate_bridge_id(br);
+ changed_addr = br_stp_recalculate_bridge_id(br);
br_features_recompute(br);
if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) &&
@@ -456,6 +457,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
br_ifinfo_notify(RTM_NEWLINK, p);
+ if (changed_addr)
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+
dev_set_mtu(br->dev, br_min_mtu(br));
kobject_uevent(&p->kobj, KOBJ_ADD);
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index f61eb2eff3f..59660c909a7 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1475,7 +1475,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
ip6h->payload_len == 0)
return 0;
- len = ntohs(ip6h->payload_len);
+ len = ntohs(ip6h->payload_len) + sizeof(*ip6h);
if (skb->len < len)
return -EINVAL;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 19e2f46ed08..387013d3374 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -497,7 +497,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br);
extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val);
extern void br_stp_enable_port(struct net_bridge_port *p);
extern void br_stp_disable_port(struct net_bridge_port *p);
-extern void br_stp_recalculate_bridge_id(struct net_bridge *br);
+extern bool br_stp_recalculate_bridge_id(struct net_bridge *br);
extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
extern void br_stp_set_bridge_priority(struct net_bridge *br,
u16 newprio);
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index 79372d4a405..9b61d09de9b 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -204,7 +204,7 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1];
/* called under bridge lock */
-void br_stp_recalculate_bridge_id(struct net_bridge *br)
+bool br_stp_recalculate_bridge_id(struct net_bridge *br)
{
const unsigned char *br_mac_zero =
(const unsigned char *)br_mac_zero_aligned;
@@ -213,7 +213,7 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
/* user has chosen a value so keep it */
if (br->flags & BR_SET_MAC_ADDR)
- return;
+ return false;
list_for_each_entry(p, &br->port_list, list) {
if (addr == br_mac_zero ||
@@ -222,8 +222,11 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br)
}
- if (compare_ether_addr(br->bridge_id.addr, addr))
- br_stp_change_bridge_id(br, addr);
+ if (compare_ether_addr(br->bridge_id.addr, addr) == 0)
+ return false; /* no change */
+
+ br_stp_change_bridge_id(br, addr);
+ return true;
}
/* called under bridge lock */
diff --git a/net/can/af_can.c b/net/can/af_can.c
index 702be5a2c95..733d66f1b05 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -95,7 +95,7 @@ struct s_pstats can_pstats; /* receive list statistics */
* af_can socket functions
*/
-static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct sock *sk = sock->sk;
@@ -108,6 +108,7 @@ static int can_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
return -ENOIOCTLCMD;
}
}
+EXPORT_SYMBOL(can_ioctl);
static void can_sock_destruct(struct sock *sk)
{
@@ -698,13 +699,9 @@ int can_proto_register(struct can_proto *cp)
printk(KERN_ERR "can: protocol %d already registered\n",
proto);
err = -EBUSY;
- } else {
+ } else
proto_tab[proto] = cp;
- /* use generic ioctl function if not defined by module */
- if (!cp->ops->ioctl)
- cp->ops->ioctl = can_ioctl;
- }
spin_unlock(&proto_tab_lock);
if (err < 0)
diff --git a/net/can/bcm.c b/net/can/bcm.c
index 092dc88a7c6..871a0ad5102 100644
--- a/net/can/bcm.c
+++ b/net/can/bcm.c
@@ -1569,7 +1569,7 @@ static int bcm_recvmsg(struct kiocb *iocb, struct socket *sock,
return size;
}
-static struct proto_ops bcm_ops __read_mostly = {
+static const struct proto_ops bcm_ops = {
.family = PF_CAN,
.release = bcm_release,
.bind = sock_no_bind,
@@ -1578,7 +1578,7 @@ static struct proto_ops bcm_ops __read_mostly = {
.accept = sock_no_accept,
.getname = sock_no_getname,
.poll = datagram_poll,
- .ioctl = NULL, /* use can_ioctl() from af_can.c */
+ .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = sock_no_setsockopt,
diff --git a/net/can/raw.c b/net/can/raw.c
index 883e9d74fdd..649acfa7c70 100644
--- a/net/can/raw.c
+++ b/net/can/raw.c
@@ -742,7 +742,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock,
return size;
}
-static struct proto_ops raw_ops __read_mostly = {
+static const struct proto_ops raw_ops = {
.family = PF_CAN,
.release = raw_release,
.bind = raw_bind,
@@ -751,7 +751,7 @@ static struct proto_ops raw_ops __read_mostly = {
.accept = sock_no_accept,
.getname = raw_getname,
.poll = datagram_poll,
- .ioctl = NULL, /* use can_ioctl() from af_can.c */
+ .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = raw_setsockopt,
diff --git a/net/ceph/Kconfig b/net/ceph/Kconfig
index ad424049b0c..be683f2d401 100644
--- a/net/ceph/Kconfig
+++ b/net/ceph/Kconfig
@@ -4,6 +4,7 @@ config CEPH_LIB
select LIBCRC32C
select CRYPTO_AES
select CRYPTO
+ select KEYS
default n
help
Choose Y or M here to include cephlib, which provides the
diff --git a/net/ceph/auth.c b/net/ceph/auth.c
index 549c1f43e1d..b4bf4ac090f 100644
--- a/net/ceph/auth.c
+++ b/net/ceph/auth.c
@@ -35,12 +35,12 @@ static int ceph_auth_init_protocol(struct ceph_auth_client *ac, int protocol)
/*
* setup, teardown.
*/
-struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
+struct ceph_auth_client *ceph_auth_init(const char *name, const struct ceph_crypto_key *key)
{
struct ceph_auth_client *ac;
int ret;
- dout("auth_init name '%s' secret '%s'\n", name, secret);
+ dout("auth_init name '%s'\n", name);
ret = -ENOMEM;
ac = kzalloc(sizeof(*ac), GFP_NOFS);
@@ -52,8 +52,8 @@ struct ceph_auth_client *ceph_auth_init(const char *name, const char *secret)
ac->name = name;
else
ac->name = CEPH_AUTH_NAME_DEFAULT;
- dout("auth_init name %s secret %s\n", ac->name, secret);
- ac->secret = secret;
+ dout("auth_init name %s\n", ac->name);
+ ac->key = key;
return ac;
out:
diff --git a/net/ceph/auth_x.c b/net/ceph/auth_x.c
index 7fd5dfcf6e1..1587dc6010c 100644
--- a/net/ceph/auth_x.c
+++ b/net/ceph/auth_x.c
@@ -662,14 +662,16 @@ int ceph_x_init(struct ceph_auth_client *ac)
goto out;
ret = -EINVAL;
- if (!ac->secret) {
+ if (!ac->key) {
pr_err("no secret set (for auth_x protocol)\n");
goto out_nomem;
}
- ret = ceph_crypto_key_unarmor(&xi->secret, ac->secret);
- if (ret)
+ ret = ceph_crypto_key_clone(&xi->secret, ac->key);
+ if (ret < 0) {
+ pr_err("cannot clone key: %d\n", ret);
goto out_nomem;
+ }
xi->starting = true;
xi->ticket_handlers = RB_ROOT;
diff --git a/net/ceph/ceph_common.c b/net/ceph/ceph_common.c
index 95f96ab94bb..132963abc26 100644
--- a/net/ceph/ceph_common.c
+++ b/net/ceph/ceph_common.c
@@ -5,6 +5,8 @@
#include <linux/fs.h>
#include <linux/inet.h>
#include <linux/in6.h>
+#include <linux/key.h>
+#include <keys/ceph-type.h>
#include <linux/module.h>
#include <linux/mount.h>
#include <linux/parser.h>
@@ -20,6 +22,7 @@
#include <linux/ceph/decode.h>
#include <linux/ceph/mon_client.h>
#include <linux/ceph/auth.h>
+#include "crypto.h"
@@ -117,9 +120,29 @@ int ceph_compare_options(struct ceph_options *new_opt,
if (ret)
return ret;
- ret = strcmp_null(opt1->secret, opt2->secret);
- if (ret)
- return ret;
+ if (opt1->key && !opt2->key)
+ return -1;
+ if (!opt1->key && opt2->key)
+ return 1;
+ if (opt1->key && opt2->key) {
+ if (opt1->key->type != opt2->key->type)
+ return -1;
+ if (opt1->key->created.tv_sec != opt2->key->created.tv_sec)
+ return -1;
+ if (opt1->key->created.tv_nsec != opt2->key->created.tv_nsec)
+ return -1;
+ if (opt1->key->len != opt2->key->len)
+ return -1;
+ if (opt1->key->key && !opt2->key->key)
+ return -1;
+ if (!opt1->key->key && opt2->key->key)
+ return 1;
+ if (opt1->key->key && opt2->key->key) {
+ ret = memcmp(opt1->key->key, opt2->key->key, opt1->key->len);
+ if (ret)
+ return ret;
+ }
+ }
/* any matching mon ip implies a match */
for (i = 0; i < opt1->num_mon; i++) {
@@ -176,6 +199,7 @@ enum {
Opt_fsid,
Opt_name,
Opt_secret,
+ Opt_key,
Opt_ip,
Opt_last_string,
/* string args above */
@@ -192,6 +216,7 @@ static match_table_t opt_tokens = {
{Opt_fsid, "fsid=%s"},
{Opt_name, "name=%s"},
{Opt_secret, "secret=%s"},
+ {Opt_key, "key=%s"},
{Opt_ip, "ip=%s"},
/* string args above */
{Opt_noshare, "noshare"},
@@ -203,11 +228,56 @@ void ceph_destroy_options(struct ceph_options *opt)
{
dout("destroy_options %p\n", opt);
kfree(opt->name);
- kfree(opt->secret);
+ if (opt->key) {
+ ceph_crypto_key_destroy(opt->key);
+ kfree(opt->key);
+ }
kfree(opt);
}
EXPORT_SYMBOL(ceph_destroy_options);
+/* get secret from key store */
+static int get_secret(struct ceph_crypto_key *dst, const char *name) {
+ struct key *ukey;
+ int key_err;
+ int err = 0;
+ struct ceph_crypto_key *ckey;
+
+ ukey = request_key(&key_type_ceph, name, NULL);
+ if (!ukey || IS_ERR(ukey)) {
+ /* request_key errors don't map nicely to mount(2)
+ errors; don't even try, but still printk */
+ key_err = PTR_ERR(ukey);
+ switch (key_err) {
+ case -ENOKEY:
+ pr_warning("ceph: Mount failed due to key not found: %s\n", name);
+ break;
+ case -EKEYEXPIRED:
+ pr_warning("ceph: Mount failed due to expired key: %s\n", name);
+ break;
+ case -EKEYREVOKED:
+ pr_warning("ceph: Mount failed due to revoked key: %s\n", name);
+ break;
+ default:
+ pr_warning("ceph: Mount failed due to unknown key error"
+ " %d: %s\n", key_err, name);
+ }
+ err = -EPERM;
+ goto out;
+ }
+
+ ckey = ukey->payload.data;
+ err = ceph_crypto_key_clone(dst, ckey);
+ if (err)
+ goto out_key;
+ /* pass through, err is 0 */
+
+out_key:
+ key_put(ukey);
+out:
+ return err;
+}
+
int ceph_parse_options(struct ceph_options **popt, char *options,
const char *dev_name, const char *dev_name_end,
int (*parse_extra_token)(char *c, void *private),
@@ -295,9 +365,24 @@ int ceph_parse_options(struct ceph_options **popt, char *options,
GFP_KERNEL);
break;
case Opt_secret:
- opt->secret = kstrndup(argstr[0].from,
- argstr[0].to-argstr[0].from,
- GFP_KERNEL);
+ opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
+ if (!opt->key) {
+ err = -ENOMEM;
+ goto out;
+ }
+ err = ceph_crypto_key_unarmor(opt->key, argstr[0].from);
+ if (err < 0)
+ goto out;
+ break;
+ case Opt_key:
+ opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
+ if (!opt->key) {
+ err = -ENOMEM;
+ goto out;
+ }
+ err = get_secret(opt->key, argstr[0].from);
+ if (err < 0)
+ goto out;
break;
/* misc */
@@ -394,8 +479,8 @@ void ceph_destroy_client(struct ceph_client *client)
ceph_osdc_stop(&client->osdc);
/*
- * make sure mds and osd connections close out before destroying
- * the auth module, which is needed to free those connections'
+ * make sure osd connections close out before destroying the
+ * auth module, which is needed to free those connections'
* ceph_authorizers.
*/
ceph_msgr_flush();
@@ -496,10 +581,14 @@ static int __init init_ceph_lib(void)
if (ret < 0)
goto out;
- ret = ceph_msgr_init();
+ ret = ceph_crypto_init();
if (ret < 0)
goto out_debugfs;
+ ret = ceph_msgr_init();
+ if (ret < 0)
+ goto out_crypto;
+
pr_info("loaded (mon/osd proto %d/%d, osdmap %d/%d %d/%d)\n",
CEPH_MONC_PROTOCOL, CEPH_OSDC_PROTOCOL,
CEPH_OSDMAP_VERSION, CEPH_OSDMAP_VERSION_EXT,
@@ -507,6 +596,8 @@ static int __init init_ceph_lib(void)
return 0;
+out_crypto:
+ ceph_crypto_shutdown();
out_debugfs:
ceph_debugfs_cleanup();
out:
@@ -517,6 +608,7 @@ static void __exit exit_ceph_lib(void)
{
dout("exit_ceph_lib\n");
ceph_msgr_exit();
+ ceph_crypto_shutdown();
ceph_debugfs_cleanup();
}
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 7b505b0c983..5a8009c9e0c 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -5,10 +5,23 @@
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <crypto/hash.h>
+#include <linux/key-type.h>
+#include <keys/ceph-type.h>
#include <linux/ceph/decode.h>
#include "crypto.h"
+int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
+ const struct ceph_crypto_key *src)
+{
+ memcpy(dst, src, sizeof(struct ceph_crypto_key));
+ dst->key = kmalloc(src->len, GFP_NOFS);
+ if (!dst->key)
+ return -ENOMEM;
+ memcpy(dst->key, src->key, src->len);
+ return 0;
+}
+
int ceph_crypto_key_encode(struct ceph_crypto_key *key, void **p, void *end)
{
if (*p + sizeof(u16) + sizeof(key->created) +
@@ -410,3 +423,63 @@ int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
return -EINVAL;
}
}
+
+int ceph_key_instantiate(struct key *key, const void *data, size_t datalen)
+{
+ struct ceph_crypto_key *ckey;
+ int ret;
+ void *p;
+
+ ret = -EINVAL;
+ if (datalen <= 0 || datalen > 32767 || !data)
+ goto err;
+
+ ret = key_payload_reserve(key, datalen);
+ if (ret < 0)
+ goto err;
+
+ ret = -ENOMEM;
+ ckey = kmalloc(sizeof(*ckey), GFP_KERNEL);
+ if (!ckey)
+ goto err;
+
+ /* TODO ceph_crypto_key_decode should really take const input */
+ p = (void*)data;
+ ret = ceph_crypto_key_decode(ckey, &p, (char*)data+datalen);
+ if (ret < 0)
+ goto err_ckey;
+
+ key->payload.data = ckey;
+ return 0;
+
+err_ckey:
+ kfree(ckey);
+err:
+ return ret;
+}
+
+int ceph_key_match(const struct key *key, const void *description)
+{
+ return strcmp(key->description, description) == 0;
+}
+
+void ceph_key_destroy(struct key *key) {
+ struct ceph_crypto_key *ckey = key->payload.data;
+
+ ceph_crypto_key_destroy(ckey);
+}
+
+struct key_type key_type_ceph = {
+ .name = "ceph",
+ .instantiate = ceph_key_instantiate,
+ .match = ceph_key_match,
+ .destroy = ceph_key_destroy,
+};
+
+int ceph_crypto_init(void) {
+ return register_key_type(&key_type_ceph);
+}
+
+void ceph_crypto_shutdown(void) {
+ unregister_key_type(&key_type_ceph);
+}
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index f9eccace592..1919d1550d7 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -19,6 +19,8 @@ static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key)
kfree(key->key);
}
+extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst,
+ const struct ceph_crypto_key *src);
extern int ceph_crypto_key_encode(struct ceph_crypto_key *key,
void **p, void *end);
extern int ceph_crypto_key_decode(struct ceph_crypto_key *key,
@@ -40,6 +42,8 @@ extern int ceph_encrypt2(struct ceph_crypto_key *secret,
void *dst, size_t *dst_len,
const void *src1, size_t src1_len,
const void *src2, size_t src2_len);
+extern int ceph_crypto_init(void);
+extern void ceph_crypto_shutdown(void);
/* armor.c */
extern int ceph_armor(char *dst, const char *src, const char *end);
diff --git a/net/ceph/mon_client.c b/net/ceph/mon_client.c
index 8a079399174..cbe31fa4550 100644
--- a/net/ceph/mon_client.c
+++ b/net/ceph/mon_client.c
@@ -759,7 +759,7 @@ int ceph_monc_init(struct ceph_mon_client *monc, struct ceph_client *cl)
/* authentication */
monc->auth = ceph_auth_init(cl->options->name,
- cl->options->secret);
+ cl->options->key);
if (IS_ERR(monc->auth))
return PTR_ERR(monc->auth);
monc->auth->want_keys =
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c
index 02212ed5085..3b91d651fe0 100644
--- a/net/ceph/osd_client.c
+++ b/net/ceph/osd_client.c
@@ -837,8 +837,7 @@ static void __unregister_request(struct ceph_osd_client *osdc,
dout("moving osd to %p lru\n", req->r_osd);
__move_osd_to_lru(osdc, req->r_osd);
}
- if (list_empty(&req->r_osd_item) &&
- list_empty(&req->r_linger_item))
+ if (list_empty(&req->r_linger_item))
req->r_osd = NULL;
}
@@ -883,7 +882,8 @@ static void __unregister_linger_request(struct ceph_osd_client *osdc,
dout("moving osd to %p lru\n", req->r_osd);
__move_osd_to_lru(osdc, req->r_osd);
}
- req->r_osd = NULL;
+ if (list_empty(&req->r_osd_item))
+ req->r_osd = NULL;
}
}
@@ -1602,11 +1602,11 @@ void handle_watch_notify(struct ceph_osd_client *osdc, struct ceph_msg *msg)
cookie, ver, event);
if (event) {
event_work = kmalloc(sizeof(*event_work), GFP_NOIO);
- INIT_WORK(&event_work->work, do_event_work);
if (!event_work) {
dout("ERROR: could not allocate event_work\n");
goto done_err;
}
+ INIT_WORK(&event_work->work, do_event_work);
event_work->event = event;
event_work->ver = ver;
event_work->notify_id = notify_id;
@@ -1672,7 +1672,7 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
if (req->r_sent == 0) {
rc = __map_request(osdc, req);
if (rc < 0)
- return rc;
+ goto out_unlock;
if (req->r_osd == NULL) {
dout("send_request %p no up osds in pg\n", req);
ceph_monc_request_next_osdmap(&osdc->client->monc);
@@ -1689,6 +1689,8 @@ int ceph_osdc_start_request(struct ceph_osd_client *osdc,
}
}
}
+
+out_unlock:
mutex_unlock(&osdc->request_mutex);
up_read(&osdc->map_sem);
return rc;
diff --git a/net/core/dev.c b/net/core/dev.c
index f453370131a..3da9fb06d47 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1140,9 +1140,6 @@ static int __dev_open(struct net_device *dev)
ASSERT_RTNL();
- /*
- * Is it even present?
- */
if (!netif_device_present(dev))
return -ENODEV;
@@ -1151,9 +1148,6 @@ static int __dev_open(struct net_device *dev)
if (ret)
return ret;
- /*
- * Call device private open method
- */
set_bit(__LINK_STATE_START, &dev->state);
if (ops->ndo_validate_addr)
@@ -1162,31 +1156,12 @@ static int __dev_open(struct net_device *dev)
if (!ret && ops->ndo_open)
ret = ops->ndo_open(dev);
- /*
- * If it went open OK then:
- */
-
if (ret)
clear_bit(__LINK_STATE_START, &dev->state);
else {
- /*
- * Set the flags.
- */
dev->flags |= IFF_UP;
-
- /*
- * Enable NET_DMA
- */
net_dmaengine_get();
-
- /*
- * Initialize multicasting status
- */
dev_set_rx_mode(dev);
-
- /*
- * Wakeup transmit queue engine
- */
dev_activate(dev);
}
@@ -1209,22 +1184,13 @@ int dev_open(struct net_device *dev)
{
int ret;
- /*
- * Is it already up?
- */
if (dev->flags & IFF_UP)
return 0;
- /*
- * Open device
- */
ret = __dev_open(dev);
if (ret < 0)
return ret;
- /*
- * ... and announce new interface.
- */
rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
call_netdevice_notifiers(NETDEV_UP, dev);
@@ -1240,10 +1206,6 @@ static int __dev_close_many(struct list_head *head)
might_sleep();
list_for_each_entry(dev, head, unreg_list) {
- /*
- * Tell people we are going down, so that they can
- * prepare to death, when device is still operating.
- */
call_netdevice_notifiers(NETDEV_GOING_DOWN, dev);
clear_bit(__LINK_STATE_START, &dev->state);
@@ -1272,15 +1234,7 @@ static int __dev_close_many(struct list_head *head)
if (ops->ndo_stop)
ops->ndo_stop(dev);
- /*
- * Device is now down.
- */
-
dev->flags &= ~IFF_UP;
-
- /*
- * Shutdown NET_DMA
- */
net_dmaengine_put();
}
@@ -1309,9 +1263,6 @@ static int dev_close_many(struct list_head *head)
__dev_close_many(head);
- /*
- * Tell people we are down
- */
list_for_each_entry(dev, head, unreg_list) {
rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
call_netdevice_notifiers(NETDEV_DOWN, dev);
@@ -1371,11 +1322,6 @@ EXPORT_SYMBOL(dev_disable_lro);
static int dev_boot_phase = 1;
-/*
- * Device change register/unregister. These are not inline or static
- * as we export them to the world.
- */
-
/**
* register_netdevice_notifier - register a network notifier block
* @nb: notifier
@@ -1477,6 +1423,7 @@ int call_netdevice_notifiers(unsigned long val, struct net_device *dev)
ASSERT_RTNL();
return raw_notifier_call_chain(&netdev_chain, val, dev);
}
+EXPORT_SYMBOL(call_netdevice_notifiers);
/* When > 0 there are consumers of rx skb time stamps */
static atomic_t netstamp_needed = ATOMIC_INIT(0);
@@ -1507,6 +1454,27 @@ static inline void net_timestamp_check(struct sk_buff *skb)
__net_timestamp(skb);
}
+static inline bool is_skb_forwardable(struct net_device *dev,
+ struct sk_buff *skb)
+{
+ unsigned int len;
+
+ if (!(dev->flags & IFF_UP))
+ return false;
+
+ len = dev->mtu + dev->hard_header_len + VLAN_HLEN;
+ if (skb->len <= len)
+ return true;
+
+ /* if TSO is enabled, we don't care about the length as the packet
+ * could be forwarded without being segmented before
+ */
+ if (skb_is_gso(skb))
+ return true;
+
+ return false;
+}
+
/**
* dev_forward_skb - loopback an skb to another netif
*
@@ -1530,8 +1498,7 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
skb_orphan(skb);
nf_reset(skb);
- if (unlikely(!(dev->flags & IFF_UP) ||
- (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN)))) {
+ if (unlikely(!is_skb_forwardable(dev, skb))) {
atomic_long_inc(&dev->rx_dropped);
kfree_skb(skb);
return NET_RX_DROP;
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 24bd57493c0..74ead9eca12 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -141,9 +141,24 @@ u32 ethtool_op_get_flags(struct net_device *dev)
}
EXPORT_SYMBOL(ethtool_op_get_flags);
+/* Check if device can enable (or disable) particular feature coded in "data"
+ * argument. Flags "supported" describe features that can be toggled by device.
+ * If feature can not be toggled, it state (enabled or disabled) must match
+ * hardcoded device features state, otherwise flags are marked as invalid.
+ */
+bool ethtool_invalid_flags(struct net_device *dev, u32 data, u32 supported)
+{
+ u32 features = dev->features & flags_dup_features;
+ /* "data" can contain only flags_dup_features bits,
+ * see __ethtool_set_flags */
+
+ return (features & ~supported) != (data & ~supported);
+}
+EXPORT_SYMBOL(ethtool_invalid_flags);
+
int ethtool_op_set_flags(struct net_device *dev, u32 data, u32 supported)
{
- if (data & ~supported)
+ if (ethtool_invalid_flags(dev, data, supported))
return -EINVAL;
dev->features = ((dev->features & ~flags_dup_features) |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 090d273d786..1b74d3b6437 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -215,6 +215,9 @@ int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir)
case ARPHRD_INFINIBAND:
ip_ib_mc_map(addr, dev->broadcast, haddr);
return 0;
+ case ARPHRD_IPGRE:
+ ip_ipgre_mc_map(addr, dev->broadcast, haddr);
+ return 0;
default:
if (dir) {
memcpy(haddr, dev->broadcast, dev->addr_len);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index f116ce8f1b4..451088330bb 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -1068,6 +1068,7 @@ static void ip_fib_net_exit(struct net *net)
fib4_rules_exit(net);
#endif
+ rtnl_lock();
for (i = 0; i < FIB_TABLE_HASHSZ; i++) {
struct fib_table *tb;
struct hlist_head *head;
@@ -1080,6 +1081,7 @@ static void ip_fib_net_exit(struct net *net)
fib_free_table(tb);
}
}
+ rtnl_unlock();
kfree(net->ipv4.fib_table_hash);
}
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 90a3ff60559..b92c86f6e9b 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1365,9 +1365,9 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
err = fib_props[fa->fa_type].error;
if (err) {
#ifdef CONFIG_IP_FIB_TRIE_STATS
- t->stats.semantic_match_miss++;
+ t->stats.semantic_match_passed++;
#endif
- return 1;
+ return err;
}
if (fi->fib_flags & RTNH_F_DEAD)
continue;
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index 1906fa35860..28a736f3442 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -140,11 +140,11 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
} else {
dopt->ts_needtime = 0;
- if (soffset + 8 <= optlen) {
+ if (soffset + 7 <= optlen) {
__be32 addr;
- memcpy(&addr, sptr+soffset-1, 4);
- if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) {
+ memcpy(&addr, dptr+soffset-1, 4);
+ if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_UNICAST) {
dopt->ts_needtime = 1;
soffset += 8;
}
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index e837ffd3edc..2d3c72e5bbb 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -569,6 +569,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
rt = ip_route_output_flow(sock_net(sk), &fl4, sk);
if (IS_ERR(rt)) {
err = PTR_ERR(rt);
+ rt = NULL;
goto done;
}
}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index 7ff0343e05c..29e48593bf2 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -663,7 +663,7 @@ static int pim6_rcv(struct sk_buff *skb)
skb_pull(skb, (u8 *)encap - skb->data);
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IPV6);
- skb->ip_summed = 0;
+ skb->ip_summed = CHECKSUM_NONE;
skb->pkt_type = PACKET_HOST;
skb_tunnel_rx(skb, reg_dev);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 0e49c9db3c9..92f952d093d 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -341,6 +341,8 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
case ARPHRD_INFINIBAND:
ipv6_ib_mc_map(addr, dev->broadcast, buf);
return 0;
+ case ARPHRD_IPGRE:
+ return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
default:
if (dir) {
memcpy(buf, dev->broadcast, dev->addr_len);
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 5b743bdd89b..36477538cea 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -656,10 +656,16 @@ static void iriap_getvaluebyclass_indication(struct iriap_cb *self,
n = 1;
name_len = fp[n++];
+
+ IRDA_ASSERT(name_len < IAS_MAX_CLASSNAME + 1, return;);
+
memcpy(name, fp+n, name_len); n+=name_len;
name[name_len] = '\0';
attr_len = fp[n++];
+
+ IRDA_ASSERT(attr_len < IAS_MAX_ATTRIBNAME + 1, return;);
+
memcpy(attr, fp+n, attr_len); n+=attr_len;
attr[attr_len] = '\0';
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c
index 7c567b8aa89..2bb2beb6a37 100644
--- a/net/irda/irnet/irnet_ppp.c
+++ b/net/irda/irnet/irnet_ppp.c
@@ -105,6 +105,9 @@ irnet_ctrl_write(irnet_socket * ap,
while(isspace(start[length - 1]))
length--;
+ DABORT(length < 5 || length > NICKNAME_MAX_LEN + 5,
+ -EINVAL, CTRL_ERROR, "Invalid nickname.\n");
+
/* Copy the name for later reuse */
memcpy(ap->rname, start + 5, length - 5);
ap->rname[length - 5] = '\0';
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 5ee0c62046a..a80aef6e3d1 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -978,7 +978,7 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
struct sock *make;
struct rose_sock *make_rose;
struct rose_facilities_struct facilities;
- int n, len;
+ int n;
skb->sk = NULL; /* Initially we don't know who it's for */
@@ -987,9 +987,9 @@ int rose_rx_call_request(struct sk_buff *skb, struct net_device *dev, struct ros
*/
memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
- len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1;
- len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1;
- if (!rose_parse_facilities(skb->data + len + 4, &facilities)) {
+ if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
+ skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
+ &facilities)) {
rose_transmit_clear_request(neigh, lci, ROSE_INVALID_FACILITY, 76);
return 0;
}
diff --git a/net/rose/rose_loopback.c b/net/rose/rose_loopback.c
index ae4a9d99aec..344456206b7 100644
--- a/net/rose/rose_loopback.c
+++ b/net/rose/rose_loopback.c
@@ -73,9 +73,20 @@ static void rose_loopback_timer(unsigned long param)
unsigned int lci_i, lci_o;
while ((skb = skb_dequeue(&loopback_queue)) != NULL) {
+ if (skb->len < ROSE_MIN_LEN) {
+ kfree_skb(skb);
+ continue;
+ }
lci_i = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
frametype = skb->data[2];
- dest = (rose_address *)(skb->data + 4);
+ if (frametype == ROSE_CALL_REQUEST &&
+ (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
+ skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
+ ROSE_CALL_REQ_ADDR_LEN_VAL)) {
+ kfree_skb(skb);
+ continue;
+ }
+ dest = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
lci_o = ROSE_DEFAULT_MAXVC + 1 - lci_i;
skb_reset_transport_header(skb);
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c
index 88a77e90e7e..08dcd2f29cd 100644
--- a/net/rose/rose_route.c
+++ b/net/rose/rose_route.c
@@ -861,7 +861,7 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
unsigned int lci, new_lci;
unsigned char cause, diagnostic;
struct net_device *dev;
- int len, res = 0;
+ int res = 0;
char buf[11];
#if 0
@@ -869,10 +869,17 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
return res;
#endif
+ if (skb->len < ROSE_MIN_LEN)
+ return res;
frametype = skb->data[2];
lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF);
- src_addr = (rose_address *)(skb->data + 9);
- dest_addr = (rose_address *)(skb->data + 4);
+ if (frametype == ROSE_CALL_REQUEST &&
+ (skb->len <= ROSE_CALL_REQ_FACILITIES_OFF ||
+ skb->data[ROSE_CALL_REQ_ADDR_LEN_OFF] !=
+ ROSE_CALL_REQ_ADDR_LEN_VAL))
+ return res;
+ src_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_SRC_ADDR_OFF);
+ dest_addr = (rose_address *)(skb->data + ROSE_CALL_REQ_DEST_ADDR_OFF);
spin_lock_bh(&rose_neigh_list_lock);
spin_lock_bh(&rose_route_list_lock);
@@ -1010,12 +1017,11 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25)
goto out;
}
- len = (((skb->data[3] >> 4) & 0x0F) + 1) >> 1;
- len += (((skb->data[3] >> 0) & 0x0F) + 1) >> 1;
-
memset(&facilities, 0x00, sizeof(struct rose_facilities_struct));
- if (!rose_parse_facilities(skb->data + len + 4, &facilities)) {
+ if (!rose_parse_facilities(skb->data + ROSE_CALL_REQ_FACILITIES_OFF,
+ skb->len - ROSE_CALL_REQ_FACILITIES_OFF,
+ &facilities)) {
rose_transmit_clear_request(rose_neigh, lci, ROSE_INVALID_FACILITY, 76);
goto out;
}
diff --git a/net/rose/rose_subr.c b/net/rose/rose_subr.c
index 1734abba26a..f6c71caa94b 100644
--- a/net/rose/rose_subr.c
+++ b/net/rose/rose_subr.c
@@ -142,7 +142,7 @@ void rose_write_internal(struct sock *sk, int frametype)
*dptr++ = ROSE_GFI | lci1;
*dptr++ = lci2;
*dptr++ = frametype;
- *dptr++ = 0xAA;
+ *dptr++ = ROSE_CALL_REQ_ADDR_LEN_VAL;
memcpy(dptr, &rose->dest_addr, ROSE_ADDR_LEN);
dptr += ROSE_ADDR_LEN;
memcpy(dptr, &rose->source_addr, ROSE_ADDR_LEN);
@@ -246,12 +246,16 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct *
do {
switch (*p & 0xC0) {
case 0x00:
+ if (len < 2)
+ return -1;
p += 2;
n += 2;
len -= 2;
break;
case 0x40:
+ if (len < 3)
+ return -1;
if (*p == FAC_NATIONAL_RAND)
facilities->rand = ((p[1] << 8) & 0xFF00) + ((p[2] << 0) & 0x00FF);
p += 3;
@@ -260,40 +264,61 @@ static int rose_parse_national(unsigned char *p, struct rose_facilities_struct *
break;
case 0x80:
+ if (len < 4)
+ return -1;
p += 4;
n += 4;
len -= 4;
break;
case 0xC0:
+ if (len < 2)
+ return -1;
l = p[1];
+ if (len < 2 + l)
+ return -1;
if (*p == FAC_NATIONAL_DEST_DIGI) {
if (!fac_national_digis_received) {
+ if (l < AX25_ADDR_LEN)
+ return -1;
memcpy(&facilities->source_digis[0], p + 2, AX25_ADDR_LEN);
facilities->source_ndigis = 1;
}
}
else if (*p == FAC_NATIONAL_SRC_DIGI) {
if (!fac_national_digis_received) {
+ if (l < AX25_ADDR_LEN)
+ return -1;
memcpy(&facilities->dest_digis[0], p + 2, AX25_ADDR_LEN);
facilities->dest_ndigis = 1;
}
}
else if (*p == FAC_NATIONAL_FAIL_CALL) {
+ if (l < AX25_ADDR_LEN)
+ return -1;
memcpy(&facilities->fail_call, p + 2, AX25_ADDR_LEN);
}
else if (*p == FAC_NATIONAL_FAIL_ADD) {
+ if (l < 1 + ROSE_ADDR_LEN)
+ return -1;
memcpy(&facilities->fail_addr, p + 3, ROSE_ADDR_LEN);
}
else if (*p == FAC_NATIONAL_DIGIS) {
+ if (l % AX25_ADDR_LEN)
+ return -1;
fac_national_digis_received = 1;
facilities->source_ndigis = 0;
facilities->dest_ndigis = 0;
for (pt = p + 2, lg = 0 ; lg < l ; pt += AX25_ADDR_LEN, lg += AX25_ADDR_LEN) {
- if (pt[6] & AX25_HBIT)
+ if (pt[6] & AX25_HBIT) {
+ if (facilities->dest_ndigis >= ROSE_MAX_DIGIS)
+ return -1;
memcpy(&facilities->dest_digis[facilities->dest_ndigis++], pt, AX25_ADDR_LEN);
- else
+ } else {
+ if (facilities->source_ndigis >= ROSE_MAX_DIGIS)
+ return -1;
memcpy(&facilities->source_digis[facilities->source_ndigis++], pt, AX25_ADDR_LEN);
+ }
}
}
p += l + 2;
@@ -314,25 +339,38 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
do {
switch (*p & 0xC0) {
case 0x00:
+ if (len < 2)
+ return -1;
p += 2;
n += 2;
len -= 2;
break;
case 0x40:
+ if (len < 3)
+ return -1;
p += 3;
n += 3;
len -= 3;
break;
case 0x80:
+ if (len < 4)
+ return -1;
p += 4;
n += 4;
len -= 4;
break;
case 0xC0:
+ if (len < 2)
+ return -1;
l = p[1];
+
+ /* Prevent overflows*/
+ if (l < 10 || l > 20)
+ return -1;
+
if (*p == FAC_CCITT_DEST_NSAP) {
memcpy(&facilities->source_addr, p + 7, ROSE_ADDR_LEN);
memcpy(callsign, p + 12, l - 10);
@@ -355,45 +393,44 @@ static int rose_parse_ccitt(unsigned char *p, struct rose_facilities_struct *fac
return n;
}
-int rose_parse_facilities(unsigned char *p,
+int rose_parse_facilities(unsigned char *p, unsigned packet_len,
struct rose_facilities_struct *facilities)
{
int facilities_len, len;
facilities_len = *p++;
- if (facilities_len == 0)
+ if (facilities_len == 0 || (unsigned)facilities_len > packet_len)
return 0;
- while (facilities_len > 0) {
- if (*p == 0x00) {
- facilities_len--;
- p++;
-
- switch (*p) {
- case FAC_NATIONAL: /* National */
- len = rose_parse_national(p + 1, facilities, facilities_len - 1);
- facilities_len -= len + 1;
- p += len + 1;
- break;
-
- case FAC_CCITT: /* CCITT */
- len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1);
- facilities_len -= len + 1;
- p += len + 1;
- break;
-
- default:
- printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p);
- facilities_len--;
- p++;
- break;
- }
- } else
- break; /* Error in facilities format */
+ while (facilities_len >= 3 && *p == 0x00) {
+ facilities_len--;
+ p++;
+
+ switch (*p) {
+ case FAC_NATIONAL: /* National */
+ len = rose_parse_national(p + 1, facilities, facilities_len - 1);
+ break;
+
+ case FAC_CCITT: /* CCITT */
+ len = rose_parse_ccitt(p + 1, facilities, facilities_len - 1);
+ break;
+
+ default:
+ printk(KERN_DEBUG "ROSE: rose_parse_facilities - unknown facilities family %02X\n", *p);
+ len = 1;
+ break;
+ }
+
+ if (len < 0)
+ return 0;
+ if (WARN_ON(len >= facilities_len))
+ return 0;
+ facilities_len -= len + 1;
+ p += len + 1;
}
- return 1;
+ return facilities_len == 0;
}
static int rose_create_facilities(unsigned char *buffer, struct rose_sock *rose)
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
index 152976ec0b7..d5bf91d04f6 100644
--- a/net/sctp/protocol.c
+++ b/net/sctp/protocol.c
@@ -1205,7 +1205,7 @@ SCTP_STATIC __init int sctp_init(void)
if ((sctp_assoc_hashsize > (64 * 1024)) && order > 0)
continue;
sctp_assoc_hashtable = (struct sctp_hashbucket *)
- __get_free_pages(GFP_ATOMIC, order);
+ __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
} while (!sctp_assoc_hashtable && --order > 0);
if (!sctp_assoc_hashtable) {
pr_err("Failed association hash alloc\n");
@@ -1238,7 +1238,7 @@ SCTP_STATIC __init int sctp_init(void)
if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
continue;
sctp_port_hashtable = (struct sctp_bind_hashbucket *)
- __get_free_pages(GFP_ATOMIC, order);
+ __get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
} while (!sctp_port_hashtable && --order > 0);
if (!sctp_port_hashtable) {
pr_err("Failed bind hash alloc\n");
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
index ffb687671da..6b43ee7221d 100644
--- a/net/sunrpc/sched.c
+++ b/net/sunrpc/sched.c
@@ -860,8 +860,10 @@ static void rpc_release_resources_task(struct rpc_task *task)
{
if (task->tk_rqstp)
xprt_release(task);
- if (task->tk_msg.rpc_cred)
+ if (task->tk_msg.rpc_cred) {
put_rpccred(task->tk_msg.rpc_cred);
+ task->tk_msg.rpc_cred = NULL;
+ }
rpc_task_release_client(task);
}
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 872065ca7f8..a026b0ef244 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -173,7 +173,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
goto drop_unlock;
}
- if (x->props.replay_window && x->repl->check(x, skb, seq)) {
+ if (x->repl->check(x, skb, seq)) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMINSTATESEQERROR);
goto drop_unlock;
}
@@ -190,6 +190,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
XFRM_SKB_CB(skb)->seq.input.low = seq;
XFRM_SKB_CB(skb)->seq.input.hi = seq_hi;
+ skb_dst_force(skb);
+
nexthdr = x->type->input(x, skb);
if (nexthdr == -EINPROGRESS)
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 1aba03f449c..47bacd8c025 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -78,6 +78,8 @@ static int xfrm_output_one(struct sk_buff *skb, int err)
spin_unlock_bh(&x->lock);
+ skb_dst_force(skb);
+
err = x->type->output(x, skb);
if (err == -EINPROGRESS)
goto out_exit;
@@ -94,7 +96,7 @@ resume:
err = -EHOSTUNREACH;
goto error_nolock;
}
- skb_dst_set(skb, dst_clone(dst));
+ skb_dst_set(skb, dst);
x = dst->xfrm;
} while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 2f5be5b1574..f218385950c 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -118,6 +118,9 @@ static int xfrm_replay_check(struct xfrm_state *x,
u32 diff;
u32 seq = ntohl(net_seq);
+ if (!x->props.replay_window)
+ return 0;
+
if (unlikely(seq == 0))
goto err;
@@ -193,9 +196,14 @@ static int xfrm_replay_check_bmp(struct xfrm_state *x,
{
unsigned int bitnr, nr;
struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
+ u32 pos;
u32 seq = ntohl(net_seq);
u32 diff = replay_esn->seq - seq;
- u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
+
+ if (!replay_esn->replay_window)
+ return 0;
+
+ pos = (replay_esn->seq - 1) % replay_esn->replay_window;
if (unlikely(seq == 0))
goto err;
@@ -373,12 +381,17 @@ static int xfrm_replay_check_esn(struct xfrm_state *x,
unsigned int bitnr, nr;
u32 diff;
struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
+ u32 pos;
u32 seq = ntohl(net_seq);
- u32 pos = (replay_esn->seq - 1) % replay_esn->replay_window;
u32 wsize = replay_esn->replay_window;
u32 top = replay_esn->seq;
u32 bottom = top - wsize + 1;
+ if (!wsize)
+ return 0;
+
+ pos = (replay_esn->seq - 1) % replay_esn->replay_window;
+
if (unlikely(seq == 0 && replay_esn->seq_hi == 0 &&
(replay_esn->seq < replay_esn->replay_window - 1)))
goto err;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f83a3d1da81..dd78536d40d 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1181,6 +1181,12 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp)
goto error;
}
+ if (orig->replay_esn) {
+ err = xfrm_replay_clone(x, orig);
+ if (err)
+ goto error;
+ }
+
memcpy(&x->mark, &orig->mark, sizeof(x->mark));
err = xfrm_init_state(x);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fc152d28753..3d15d3e1b2c 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -127,6 +127,9 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
if (!rt)
return 0;
+ if (p->id.proto != IPPROTO_ESP)
+ return -EINVAL;
+
if (p->replay_window != 0)
return -EINVAL;
@@ -360,6 +363,23 @@ static int attach_aead(struct xfrm_algo_aead **algpp, u8 *props,
return 0;
}
+static inline int xfrm_replay_verify_len(struct xfrm_replay_state_esn *replay_esn,
+ struct nlattr *rp)
+{
+ struct xfrm_replay_state_esn *up;
+
+ if (!replay_esn || !rp)
+ return 0;
+
+ up = nla_data(rp);
+
+ if (xfrm_replay_state_esn_len(replay_esn) !=
+ xfrm_replay_state_esn_len(up))
+ return -EINVAL;
+
+ return 0;
+}
+
static int xfrm_alloc_replay_state_esn(struct xfrm_replay_state_esn **replay_esn,
struct xfrm_replay_state_esn **preplay_esn,
struct nlattr *rta)
@@ -1766,6 +1786,10 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
if (x->km.state != XFRM_STATE_VALID)
goto out;
+ err = xfrm_replay_verify_len(x->replay_esn, rp);
+ if (err)
+ goto out;
+
spin_lock_bh(&x->lock);
xfrm_update_ae_params(x, attrs);
spin_unlock_bh(&x->lock);
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 3e7544d2a07..ea7c01f4a2b 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -213,7 +213,7 @@ static u16 map_class(u16 pol_value)
return i;
}
- return pol_value;
+ return SECCLASS_NULL;
}
static void map_decision(u16 tclass, struct av_decision *avd,
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index fcab80b36a3..fc017c0a7b5 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -331,7 +331,7 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count,
goto err;
if (gpios[i].wake) {
- ret = set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
+ ret = irq_set_irq_wake(gpio_to_irq(gpios[i].gpio), 1);
if (ret != 0)
printk(KERN_ERR
"Failed to mark GPIO %d as wake source: %d\n",