summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/IRQ-domain.txt117
-rw-r--r--Documentation/devicetree/bindings/arm/tegra/emc.txt100
-rw-r--r--Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt19
-rw-r--r--Documentation/devicetree/bindings/dma/tegra20-apbdma.txt30
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio_nvidia.txt36
-rw-r--r--Documentation/feature-removal-schedule.txt14
-rw-r--r--MAINTAINERS24
-rw-r--r--Makefile2
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/Kconfig.debug164
-rw-r--r--arch/arm/boot/dts/tegra-harmony.dts45
-rw-r--r--arch/arm/boot/dts/tegra-paz00.dts30
-rw-r--r--arch/arm/boot/dts/tegra-seaboard.dts78
-rw-r--r--arch/arm/boot/dts/tegra-trimslice.dts12
-rw-r--r--arch/arm/boot/dts/tegra-ventana.dts42
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi43
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi53
-rw-r--r--arch/arm/common/gic.c95
-rw-r--r--arch/arm/common/it8152.c7
-rw-r--r--arch/arm/common/pl330.c3
-rw-r--r--arch/arm/common/vic.c16
-rw-r--r--arch/arm/configs/at91cap9_defconfig108
-rw-r--r--arch/arm/configs/imx_v4_v5_defconfig18
-rw-r--r--arch/arm/configs/imx_v6_v7_defconfig36
-rw-r--r--arch/arm/configs/magician_defconfig2
-rw-r--r--arch/arm/include/asm/assembler.h5
-rw-r--r--arch/arm/include/asm/hardware/gic.h4
-rw-r--r--arch/arm/include/asm/hardware/pl330.h2
-rw-r--r--arch/arm/include/asm/hardware/vic.h2
-rw-r--r--arch/arm/include/asm/processor.h1
-rw-r--r--arch/arm/include/asm/system.h1
-rw-r--r--arch/arm/kernel/process.c27
-rw-r--r--arch/arm/kernel/ptrace.c9
-rw-r--r--arch/arm/kernel/smp_twd.c2
-rw-r--r--arch/arm/mach-at91/Kconfig26
-rw-r--r--arch/arm/mach-at91/Makefile4
-rw-r--r--arch/arm/mach-at91/Makefile.boot6
-rw-r--r--arch/arm/mach-at91/at91cap9.c396
-rw-r--r--arch/arm/mach-at91/at91cap9_devices.c1273
-rw-r--r--arch/arm/mach-at91/at91rm9200.c10
-rw-r--r--arch/arm/mach-at91/at91sam9260.c8
-rw-r--r--arch/arm/mach-at91/at91sam9261.c8
-rw-r--r--arch/arm/mach-at91/at91sam9263.c8
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c13
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c7
-rw-r--r--arch/arm/mach-at91/at91sam9g45_devices.c113
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c8
-rw-r--r--arch/arm/mach-at91/at91sam9rl_devices.c8
-rw-r--r--arch/arm/mach-at91/at91x40.c12
-rw-r--r--arch/arm/mach-at91/board-cap9adk.c396
-rw-r--r--arch/arm/mach-at91/board-flexibity.c12
-rw-r--r--arch/arm/mach-at91/board-sam9m10g45ek.c80
-rw-r--r--arch/arm/mach-at91/clock.c5
-rw-r--r--arch/arm/mach-at91/generic.h1
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pmc.h14
-rw-r--r--arch/arm/mach-at91/include/mach/at91cap9.h122
-rw-r--r--arch/arm/mach-at91/include/mach/at91cap9_matrix.h137
-rw-r--r--arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h10
-rw-r--r--arch/arm/mach-at91/include/mach/board.h6
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h21
-rw-r--r--arch/arm/mach-at91/include/mach/hardware.h4
-rw-r--r--arch/arm/mach-at91/include/mach/system.h50
-rw-r--r--arch/arm/mach-at91/pm.c5
-rw-r--r--arch/arm/mach-at91/pm.h18
-rw-r--r--arch/arm/mach-at91/pm_slowclock.S12
-rw-r--r--arch/arm/mach-at91/setup.c17
-rw-r--r--arch/arm/mach-at91/soc.h5
-rw-r--r--arch/arm/mach-bcmring/core.c23
-rw-r--r--arch/arm/mach-bcmring/include/mach/system.h28
-rw-r--r--arch/arm/mach-clps711x/common.c16
-rw-r--r--arch/arm/mach-clps711x/include/mach/system.h35
-rw-r--r--arch/arm/mach-cns3xxx/include/mach/system.h25
-rw-r--r--arch/arm/mach-davinci/include/mach/system.h21
-rw-r--r--arch/arm/mach-dove/include/mach/system.h17
-rw-r--r--arch/arm/mach-ebsa110/core.c25
-rw-r--r--arch/arm/mach-ebsa110/include/mach/system.h37
-rw-r--r--arch/arm/mach-ep93xx/core.c46
-rw-r--r--arch/arm/mach-ep93xx/include/mach/system.h7
-rw-r--r--arch/arm/mach-exynos/common.c14
-rw-r--r--arch/arm/mach-exynos/dma.c38
-rw-r--r--arch/arm/mach-exynos/include/mach/system.h20
-rw-r--r--arch/arm/mach-footbridge/include/mach/system.h13
-rw-r--r--arch/arm/mach-gemini/Makefile2
-rw-r--r--arch/arm/mach-gemini/idle.c29
-rw-r--r--arch/arm/mach-gemini/include/mach/system.h14
-rw-r--r--arch/arm/mach-gemini/irq.c4
-rw-r--r--arch/arm/mach-h720x/common.c18
-rw-r--r--arch/arm/mach-h720x/include/mach/system.h27
-rw-r--r--arch/arm/mach-imx/Kconfig1
-rw-r--r--arch/arm/mach-imx/clock-imx6q.c74
-rw-r--r--arch/arm/mach-imx/imx51-dt.c4
-rw-r--r--arch/arm/mach-imx/imx53-dt.c4
-rw-r--r--arch/arm/mach-imx/lluart.c2
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c3
-rw-r--r--arch/arm/mach-imx/mach-mx21ads.c16
-rw-r--r--arch/arm/mach-imx/mach-mx27_3ds.c108
-rw-r--r--arch/arm/mach-imx/mach-mx31ads.c35
-rw-r--r--arch/arm/mach-imx/mach-mx31moboard.c2
-rw-r--r--arch/arm/mach-imx/mm-imx3.c52
-rw-r--r--arch/arm/mach-imx/mm-imx5.c28
-rw-r--r--arch/arm/mach-imx/pm-imx27.c3
-rw-r--r--arch/arm/mach-imx/pm-imx5.c4
-rw-r--r--arch/arm/mach-integrator/core.c70
-rw-r--r--arch/arm/mach-integrator/impd1.c9
-rw-r--r--arch/arm/mach-integrator/include/mach/system.h33
-rw-r--r--arch/arm/mach-integrator/integrator_cp.c49
-rw-r--r--arch/arm/mach-iop13xx/include/mach/system.h13
-rw-r--r--arch/arm/mach-iop32x/include/mach/system.h13
-rw-r--r--arch/arm/mach-iop33x/include/mach/system.h13
-rw-r--r--arch/arm/mach-ixp2000/include/mach/system.h14
-rw-r--r--arch/arm/mach-ixp23xx/core.c3
-rw-r--r--arch/arm/mach-ixp23xx/include/mach/system.h16
-rw-r--r--arch/arm/mach-ixp4xx/common.c6
-rw-r--r--arch/arm/mach-ixp4xx/include/mach/system.h19
-rw-r--r--arch/arm/mach-kirkwood/include/mach/system.h17
-rw-r--r--arch/arm/mach-ks8695/include/mach/system.h27
-rw-r--r--arch/arm/mach-lpc32xx/clock.c36
-rw-r--r--arch/arm/mach-lpc32xx/common.c22
-rw-r--r--arch/arm/mach-lpc32xx/common.h1
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/irqs.h2
-rw-r--r--arch/arm/mach-lpc32xx/include/mach/system.h27
-rw-r--r--arch/arm/mach-lpc32xx/irq.c25
-rw-r--r--arch/arm/mach-lpc32xx/phy3250.c33
-rw-r--r--arch/arm/mach-lpc32xx/serial.c20
-rw-r--r--arch/arm/mach-mmp/aspenite.c1
-rw-r--r--arch/arm/mach-mmp/include/mach/pxa910.h1
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-apbc.h1
-rw-r--r--arch/arm/mach-mmp/include/mach/regs-rtc.h23
-rw-r--r--arch/arm/mach-mmp/include/mach/system.h16
-rw-r--r--arch/arm/mach-mmp/pxa168.c1
-rw-r--r--arch/arm/mach-mmp/pxa910.c27
-rw-r--r--arch/arm/mach-mmp/tavorevb.c1
-rw-r--r--arch/arm/mach-mmp/ttc_dkb.c1
-rw-r--r--arch/arm/mach-msm/board-msm8x60.c8
-rw-r--r--arch/arm/mach-msm/idle.S36
-rw-r--r--arch/arm/mach-msm/idle.c49
-rw-r--r--arch/arm/mach-msm/include/mach/system.h1
-rw-r--r--arch/arm/mach-mv78xx0/include/mach/system.h17
-rw-r--r--arch/arm/mach-mxs/clock-mx23.c1
-rw-r--r--arch/arm/mach-mxs/clock-mx28.c1
-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.c8
-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/amba-duart.c2
-rw-r--r--arch/arm/mach-mxs/devices/platform-gpmi-nand.c81
-rw-r--r--arch/arm/mach-mxs/include/mach/devices-common.h10
-rw-r--r--arch/arm/mach-mxs/include/mach/system.h25
-rw-r--r--arch/arm/mach-mxs/pm.c3
-rw-r--r--arch/arm/mach-netx/fb.c13
-rw-r--r--arch/arm/mach-netx/include/mach/system.h28
-rw-r--r--arch/arm/mach-nomadik/board-nhk8815.c17
-rw-r--r--arch/arm/mach-nomadik/cpu-8815.c9
-rw-r--r--arch/arm/mach-nomadik/include/mach/system.h32
-rw-r--r--arch/arm/mach-omap1/board-innovator.c4
-rw-r--r--arch/arm/mach-omap1/include/mach/system.h5
-rw-r--r--arch/arm/mach-omap1/pm.c19
-rw-r--r--arch/arm/mach-omap2/Kconfig4
-rw-r--r--arch/arm/mach-omap2/board-generic.c2
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c4
-rw-r--r--arch/arm/mach-omap2/board-omap3evm.c2
-rw-r--r--arch/arm/mach-omap2/common.h1
-rw-r--r--arch/arm/mach-omap2/cpuidle44xx.c5
-rw-r--r--arch/arm/mach-omap2/emu.c26
-rw-r--r--arch/arm/mach-omap2/gpmc-smsc911x.c52
-rw-r--r--arch/arm/mach-omap2/hsmmc.c6
-rw-r--r--arch/arm/mach-omap2/include/mach/system.h5
-rw-r--r--arch/arm/mach-omap2/io.c1
-rw-r--r--arch/arm/mach-omap2/mailbox.c13
-rw-r--r--arch/arm/mach-omap2/mux.c2
-rw-r--r--arch/arm/mach-omap2/omap4-common.c25
-rw-r--r--arch/arm/mach-omap2/pm.c3
-rw-r--r--arch/arm/mach-omap2/pm24xx.c4
-rw-r--r--arch/arm/mach-omap2/pm34xx.c6
-rw-r--r--arch/arm/mach-omap2/pm44xx.c8
-rw-r--r--arch/arm/mach-omap2/prm_common.c1
-rw-r--r--arch/arm/mach-omap2/usb-host.c6
-rw-r--r--arch/arm/mach-omap2/voltagedomains3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/voltagedomains44xx_data.c2
-rw-r--r--arch/arm/mach-orion5x/include/mach/system.h19
-rw-r--r--arch/arm/mach-picoxcell/include/mach/system.h26
-rw-r--r--arch/arm/mach-pnx4008/include/mach/system.h29
-rw-r--r--arch/arm/mach-prima2/include/mach/system.h17
-rw-r--r--arch/arm/mach-prima2/irq.c2
-rw-r--r--arch/arm/mach-pxa/devices.c28
-rw-r--r--arch/arm/mach-pxa/hx4700.c58
-rw-r--r--arch/arm/mach-pxa/include/mach/system.h15
-rw-r--r--arch/arm/mach-pxa/magician.c33
-rw-r--r--arch/arm/mach-pxa/pxa25x.c2
-rw-r--r--arch/arm/mach-pxa/pxa27x.c2
-rw-r--r--arch/arm/mach-pxa/pxa3xx.c1
-rw-r--r--arch/arm/mach-pxa/pxa95x.c1
-rw-r--r--arch/arm/mach-pxa/saarb.c1
-rw-r--r--arch/arm/mach-pxa/sharpsl_pm.c3
-rw-r--r--arch/arm/mach-pxa/spitz_pm.c5
-rw-r--r--arch/arm/mach-realview/core.h20
-rw-r--r--arch/arm/mach-realview/include/mach/irqs-pb1176.h2
-rw-r--r--arch/arm/mach-realview/include/mach/system.h33
-rw-r--r--arch/arm/mach-realview/realview_eb.c78
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c78
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c78
-rw-r--r--arch/arm/mach-realview/realview_pba8.c78
-rw-r--r--arch/arm/mach-realview/realview_pbx.c78
-rw-r--r--arch/arm/mach-rpc/include/mach/system.h13
-rw-r--r--arch/arm/mach-s3c2410/include/mach/system.h54
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c4
-rw-r--r--arch/arm/mach-s3c2416/s3c2416.c5
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c2
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/system.h19
-rw-r--r--arch/arm/mach-s5p64x0/common.c15
-rw-r--r--arch/arm/mach-s5p64x0/dma.c22
-rw-r--r--arch/arm/mach-s5p64x0/include/mach/system.h21
-rw-r--r--arch/arm/mach-s5pc100/common.c12
-rw-r--r--arch/arm/mach-s5pc100/dma.c38
-rw-r--r--arch/arm/mach-s5pc100/include/mach/system.h19
-rw-r--r--arch/arm/mach-s5pv210/common.c12
-rw-r--r--arch/arm/mach-s5pv210/dma.c38
-rw-r--r--arch/arm/mach-s5pv210/include/mach/system.h21
-rw-r--r--arch/arm/mach-sa1100/clock.c82
-rw-r--r--arch/arm/mach-sa1100/generic.c8
-rw-r--r--arch/arm/mach-sa1100/include/mach/system.h9
-rw-r--r--arch/arm/mach-shark/core.c6
-rw-r--r--arch/arm/mach-shark/include/mach/system.h13
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c29
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c12
-rw-r--r--arch/arm/mach-shmobile/board-kota2.c3
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c95
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c113
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh73a0.h6
-rw-r--r--arch/arm/mach-shmobile/include/mach/system.h5
-rw-r--r--arch/arm/mach-shmobile/intc-sh73a0.c2
-rw-r--r--arch/arm/mach-shmobile/pfc-r8a7779.c2
-rw-r--r--arch/arm/mach-shmobile/pfc-sh7372.c41
-rw-r--r--arch/arm/mach-shmobile/smp-sh73a0.c2
-rw-r--r--arch/arm/mach-spear3xx/include/mach/system.h19
-rw-r--r--arch/arm/mach-spear3xx/spear300.c14
-rw-r--r--arch/arm/mach-spear3xx/spear3xx.c27
-rw-r--r--arch/arm/mach-spear6xx/include/mach/system.h19
-rw-r--r--arch/arm/mach-spear6xx/spear6xx.c10
-rw-r--r--arch/arm/mach-tegra/Makefile3
-rw-r--r--arch/arm/mach-tegra/apbio.c145
-rw-r--r--arch/arm/mach-tegra/apbio.h39
-rw-r--r--arch/arm/mach-tegra/board-harmony-power.c15
-rw-r--r--arch/arm/mach-tegra/board-harmony.c2
-rw-r--r--arch/arm/mach-tegra/board-seaboard.c5
-rw-r--r--arch/arm/mach-tegra/common.c23
-rw-r--r--arch/arm/mach-tegra/dma.c128
-rw-r--r--arch/arm/mach-tegra/fuse.c107
-rw-r--r--arch/arm/mach-tegra/fuse.h34
-rw-r--r--arch/arm/mach-tegra/include/mach/debug-macro.S88
-rw-r--r--arch/arm/mach-tegra/include/mach/gpio-tegra.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/irammap.h35
-rw-r--r--arch/arm/mach-tegra/include/mach/uncompress.h120
-rw-r--r--arch/arm/mach-tegra/pmc.c76
-rw-r--r--arch/arm/mach-tegra/pmc.h (renamed from arch/arm/mach-highbank/include/mach/system.h)17
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c2
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.c224
-rw-r--r--arch/arm/mach-tegra/tegra2_emc.h11
-rw-r--r--arch/arm/mach-u300/core.c85
-rw-r--r--arch/arm/mach-u300/include/mach/system.h14
-rw-r--r--arch/arm/mach-ux500/devices-common.c13
-rw-r--r--arch/arm/mach-ux500/include/mach/system.h20
-rw-r--r--arch/arm/mach-versatile/core.c77
-rw-r--r--arch/arm/mach-versatile/core.h20
-rw-r--r--arch/arm/mach-versatile/include/mach/system.h33
-rw-r--r--arch/arm/mach-versatile/versatile_pb.c18
-rw-r--r--arch/arm/mach-vexpress/core.h17
-rw-r--r--arch/arm/mach-vexpress/ct-ca9x4.c8
-rw-r--r--arch/arm/mach-vexpress/include/mach/ct-ca9x4.h2
-rw-r--r--arch/arm/mach-vexpress/include/mach/system.h33
-rw-r--r--arch/arm/mach-vexpress/v2m.c20
-rw-r--r--arch/arm/mach-vt8500/include/mach/system.h5
-rw-r--r--arch/arm/mach-w90x900/dev.c1
-rw-r--r--arch/arm/mach-w90x900/include/mach/system.h19
-rw-r--r--arch/arm/mach-zynq/include/mach/system.h23
-rw-r--r--arch/arm/mm/Kconfig3
-rw-r--r--arch/arm/mm/cache-v7.S2
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c8
-rw-r--r--arch/arm/plat-mxc/devices/platform-ahci-imx.c16
-rw-r--r--arch/arm/plat-mxc/epit.c2
-rw-r--r--arch/arm/plat-mxc/include/mach/board-mx31ads.h33
-rw-r--r--arch/arm/plat-mxc/include/mach/debug-macro.S2
-rw-r--r--arch/arm/plat-mxc/include/mach/dma.h3
-rw-r--r--arch/arm/plat-mxc/include/mach/system.h25
-rw-r--r--arch/arm/plat-mxc/pwm.c4
-rw-r--r--arch/arm/plat-mxc/system.c2
-rw-r--r--arch/arm/plat-mxc/time.c2
-rw-r--r--arch/arm/plat-omap/common.c1
-rw-r--r--arch/arm/plat-omap/include/plat/omap-secure.h6
-rw-r--r--arch/arm/plat-omap/include/plat/system.h15
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c27
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-rtc.h81
-rw-r--r--arch/arm/plat-samsung/include/plat/rtc-core.h27
-rw-r--r--arch/arm/plat-spear/include/plat/system.h26
-rw-r--r--arch/avr32/mach-at32ap/include/mach/cpu.h3
-rw-r--r--arch/c6x/Kconfig1
-rw-r--r--arch/c6x/boot/Makefile2
-rw-r--r--arch/c6x/include/asm/irq.h245
-rw-r--r--arch/c6x/kernel/irq.c612
-rw-r--r--arch/c6x/platforms/megamod-pic.c25
-rw-r--r--arch/m68k/include/asm/mcf_pgtable.h3
-rw-r--r--arch/m68k/mm/mcfmmu.c9
-rw-r--r--arch/m68k/platform/coldfire/entry.S4
-rw-r--r--arch/microblaze/Kconfig1
-rw-r--r--arch/microblaze/include/asm/hardirq.h16
-rw-r--r--arch/microblaze/include/asm/irq.h42
-rw-r--r--arch/microblaze/kernel/intc.c61
-rw-r--r--arch/microblaze/kernel/irq.c24
-rw-r--r--arch/microblaze/kernel/setup.c2
-rw-r--r--arch/mips/Kconfig1
-rw-r--r--arch/mips/include/asm/irq.h5
-rw-r--r--arch/mips/kernel/prom.c14
-rw-r--r--arch/openrisc/include/asm/prom.h10
-rw-r--r--arch/openrisc/include/asm/ptrace.h8
-rw-r--r--arch/openrisc/kernel/init_task.c1
-rw-r--r--arch/openrisc/kernel/irq.c1
-rw-r--r--arch/openrisc/kernel/ptrace.c12
-rw-r--r--arch/parisc/Makefile4
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/include/asm/ehv_pic.h2
-rw-r--r--arch/powerpc/include/asm/i8259.h2
-rw-r--r--arch/powerpc/include/asm/irq.h247
-rw-r--r--arch/powerpc/include/asm/mpic.h2
-rw-r--r--arch/powerpc/include/asm/xics.h2
-rw-r--r--arch/powerpc/kernel/entry_32.S2
-rw-r--r--arch/powerpc/kernel/entry_64.S6
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S2
-rw-r--r--arch/powerpc/kernel/irq.c617
-rw-r--r--arch/powerpc/kernel/signal.c12
-rw-r--r--arch/powerpc/kernel/signal.h2
-rw-r--r--arch/powerpc/platforms/512x/mpc5121_ads_cpld.c12
-rw-r--r--arch/powerpc/platforms/52xx/media5200.c15
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_gpt.c16
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c12
-rw-r--r--arch/powerpc/platforms/82xx/pq2ads-pci-pic.c14
-rw-r--r--arch/powerpc/platforms/85xx/socrates_fpga_pic.c15
-rw-r--r--arch/powerpc/platforms/86xx/gef_pic.c15
-rw-r--r--arch/powerpc/platforms/cell/axon_msi.c29
-rw-r--r--arch/powerpc/platforms/cell/beat_interrupt.c16
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c16
-rw-r--r--arch/powerpc/platforms/cell/spider-pic.c14
-rw-r--r--arch/powerpc/platforms/embedded6xx/flipper-pic.c24
-rw-r--r--arch/powerpc/platforms/embedded6xx/hlwd-pic.c29
-rw-r--r--arch/powerpc/platforms/iseries/irq.c11
-rw-r--r--arch/powerpc/platforms/powermac/pic.c26
-rw-r--r--arch/powerpc/platforms/powermac/smp.c9
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c11
-rw-r--r--arch/powerpc/platforms/wsp/opb_pic.c26
-rw-r--r--arch/powerpc/platforms/wsp/smp.c2
-rw-r--r--arch/powerpc/sysdev/cpm1.c9
-rw-r--r--arch/powerpc/sysdev/cpm2_pic.c23
-rw-r--r--arch/powerpc/sysdev/ehv_pic.c14
-rw-r--r--arch/powerpc/sysdev/fsl_msi.c10
-rw-r--r--arch/powerpc/sysdev/fsl_msi.h2
-rw-r--r--arch/powerpc/sysdev/i8259.c15
-rw-r--r--arch/powerpc/sysdev/ipic.c31
-rw-r--r--arch/powerpc/sysdev/ipic.h2
-rw-r--r--arch/powerpc/sysdev/mpc8xx_pic.c11
-rw-r--r--arch/powerpc/sysdev/mpic.c17
-rw-r--r--arch/powerpc/sysdev/mpic_msi.c2
-rw-r--r--arch/powerpc/sysdev/mv64x60_pic.c11
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.c26
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe_ic.h2
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c13
-rw-r--r--arch/powerpc/sysdev/uic.c26
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c25
-rw-r--r--arch/powerpc/sysdev/xilinx_intc.c19
-rw-r--r--arch/s390/Kconfig3
-rw-r--r--arch/s390/include/asm/compat.h7
-rw-r--r--arch/s390/kernel/compat_wrapper.S2
-rw-r--r--arch/s390/kernel/crash_dump.c1
-rw-r--r--arch/s390/kernel/process.c6
-rw-r--r--arch/s390/kernel/ptrace.c2
-rw-r--r--arch/s390/kernel/setup.c2
-rw-r--r--arch/s390/kernel/signal.c1
-rw-r--r--arch/s390/kernel/time.c7
-rw-r--r--arch/s390/mm/fault.c1
-rw-r--r--arch/s390/mm/init.c30
-rw-r--r--arch/s390/mm/mmap.c2
-rw-r--r--arch/s390/mm/pgtable.c2
-rw-r--r--arch/sh/boards/board-sh7757lcr.c20
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c1
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c2
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c1
-rw-r--r--arch/sh/boards/mach-migor/setup.c2
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c1
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c2
-rw-r--r--arch/sh/include/asm/device.h8
-rw-r--r--arch/sh/kernel/cpu/sh4a/clock-sh7724.c2
-rw-r--r--arch/sh/kernel/cpu/sh4a/setup-sh7757.c22
-rw-r--r--arch/sh/kernel/smp.c2
-rw-r--r--arch/sh/kernel/topology.c2
-rw-r--r--arch/sh/mm/cache-sh2a.c2
-rw-r--r--arch/sparc/include/asm/prom.h10
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/i387.h53
-rw-r--r--arch/x86/include/asm/irq_controller.h12
-rw-r--r--arch/x86/include/asm/perf_event.h8
-rw-r--r--arch/x86/include/asm/processor.h3
-rw-r--r--arch/x86/include/asm/prom.h10
-rw-r--r--arch/x86/kernel/cpu/common.c5
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c44
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd.c2
-rw-r--r--arch/x86/kernel/cpu/perf_event.h8
-rw-r--r--arch/x86/kernel/cpu/perf_event_amd.c37
-rw-r--r--arch/x86/kernel/devicetree.c101
-rw-r--r--arch/x86/kernel/entry_64.S9
-rw-r--r--arch/x86/kernel/microcode_amd.c1
-rw-r--r--arch/x86/kernel/process_32.c3
-rw-r--r--arch/x86/kernel/process_64.c3
-rw-r--r--arch/x86/kernel/traps.c40
-rw-r--r--arch/x86/kvm/svm.c5
-rw-r--r--arch/x86/xen/enlighten.c6
-rw-r--r--arch/x86/xen/mmu.c8
-rw-r--r--block/partitions/ldm.c11
-rw-r--r--drivers/amba/bus.c105
-rw-r--r--drivers/atm/solos-pci.c4
-rw-r--r--drivers/block/nvme.c2
-rw-r--r--drivers/bluetooth/btusb.c4
-rw-r--r--drivers/cpuidle/Kconfig2
-rw-r--r--drivers/crypto/mv_cesa.c1
-rw-r--r--drivers/edac/i3200_edac.c15
-rw-r--r--drivers/gpio/gpio-mpc8xxx.c30
-rw-r--r--drivers/gpio/gpio-tegra.c59
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_connector.c16
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_core.c3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c6
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c26
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h4
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c34
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.h1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c70
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c34
-rw-r--r--drivers/gpu/drm/exynos/exynos_mixer.c19
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h15
-rw-r--r--drivers/gpu/drm/i915/intel_display.c37
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c14
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c1
-rw-r--r--drivers/gpu/drm/radeon/ni.c1
-rw-r--r--drivers/gpu/drm/radeon/r100.c8
-rw-r--r--drivers/gpu/drm/radeon/r300.c8
-rw-r--r--drivers/gpu/drm/radeon/r420.c8
-rw-r--r--drivers/gpu/drm/radeon/r520.c8
-rw-r--r--drivers/gpu/drm/radeon/r600.c1
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_atombios.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c25
-rw-r--r--drivers/gpu/drm/radeon/radeon_cs.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_gart.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_ring.c7
-rw-r--r--drivers/gpu/drm/radeon/rs400.c8
-rw-r--r--drivers/gpu/drm/radeon/rs600.c8
-rw-r--r--drivers/gpu/drm/radeon/rs690.c8
-rw-r--r--drivers/gpu/drm/radeon/rv515.c8
-rw-r--r--drivers/gpu/drm/radeon/rv770.c1
-rw-r--r--drivers/hwmon/ads1015.c3
-rw-r--r--drivers/hwmon/f75375s.c92
-rw-r--r--drivers/hwmon/max6639.c22
-rw-r--r--drivers/hwmon/pmbus/max34440.c2
-rw-r--r--drivers/i2c/busses/i2c-imx.c4
-rw-r--r--drivers/i2c/busses/i2c-mxs.c13
-rw-r--r--drivers/iommu/omap-iommu-debug.c59
-rw-r--r--drivers/iommu/omap-iommu.c3
-rw-r--r--drivers/media/radio/wl128x/Kconfig4
-rw-r--r--drivers/media/rc/imon.c26
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c18
-rw-r--r--drivers/media/video/hdpvr/hdpvr-video.c46
-rw-r--r--drivers/media/video/hdpvr/hdpvr.h1
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c2
-rw-r--r--drivers/mfd/Kconfig1
-rw-r--r--drivers/mfd/twl-core.c21
-rw-r--r--drivers/mmc/host/at91_mci.c1
-rw-r--r--drivers/mmc/host/mmci.c2
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c6
-rw-r--r--drivers/net/Space.c2
-rw-r--r--drivers/net/can/sja1000/sja1000.c13
-rw-r--r--drivers/net/ethernet/atheros/atl1c/atl1c_main.c4
-rw-r--r--drivers/net/ethernet/broadcom/b44.c2
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c6
-rw-r--r--drivers/net/ethernet/cirrus/Kconfig19
-rw-r--r--drivers/net/ethernet/cirrus/cs89x0.c148
-rw-r--r--drivers/net/ethernet/cisco/enic/cq_enet_desc.h2
-rw-r--r--drivers/net/ethernet/cisco/enic/enic_pp.c2
-rw-r--r--drivers/net/ethernet/jme.c10
-rw-r--r--drivers/net/ethernet/jme.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/eq.c8
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/fw.c2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/main.c10
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mlx4.h2
-rw-r--r--drivers/net/ethernet/mellanox/mlx4/mr.c12
-rw-r--r--drivers/net/ethernet/micrel/ks8851_mll.c2
-rw-r--r--drivers/net/ethernet/sfc/rx.c4
-rw-r--r--drivers/net/ethernet/ti/davinci_emac.c6
-rw-r--r--drivers/net/phy/icplus.c55
-rw-r--r--drivers/net/phy/mdio-gpio.c4
-rw-r--r--drivers/net/ppp/ppp_generic.c23
-rw-r--r--drivers/net/usb/cdc_ether.c7
-rw-r--r--drivers/net/usb/hso.c2
-rw-r--r--drivers/net/usb/zaurus.c12
-rw-r--r--drivers/net/vmxnet3/vmxnet3_drv.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c2
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c8
-rw-r--r--drivers/of/platform.c10
-rw-r--r--drivers/parisc/iommu-helpers.h2
-rw-r--r--drivers/pcmcia/pxa2xx_base.c12
-rw-r--r--drivers/platform/x86/ibm_rtl.c15
-rw-r--r--drivers/platform/x86/intel_ips.c15
-rw-r--r--drivers/regulator/88pm8607.c6
-rw-r--r--drivers/regulator/Kconfig8
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/bq24022.c162
-rw-r--r--drivers/rtc/Kconfig4
-rw-r--r--drivers/rtc/rtc-s3c.c71
-rw-r--r--drivers/rtc/rtc-sa1100.c207
-rw-r--r--drivers/s390/block/dasd_eckd.c2
-rw-r--r--drivers/s390/block/dasd_ioctl.c1
-rw-r--r--drivers/s390/char/con3215.c22
-rw-r--r--drivers/s390/char/fs3270.c1
-rw-r--r--drivers/s390/char/vmcp.c1
-rw-r--r--drivers/s390/cio/chsc_sch.c1
-rw-r--r--drivers/s390/scsi/zfcp_cfdc.c1
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c25
-rw-r--r--drivers/scsi/ipr.c24
-rw-r--r--drivers/scsi/isci/host.c4
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.c3
-rw-r--r--drivers/scsi/osd/osd_uld.c4
-rw-r--r--drivers/scsi/qla2xxx/qla_attr.c13
-rw-r--r--drivers/scsi/qla2xxx/qla_bsg.c50
-rw-r--r--drivers/scsi/qla2xxx/qla_dbg.c3
-rw-r--r--drivers/scsi/qla2xxx/qla_def.h1
-rw-r--r--drivers/scsi/qla2xxx/qla_inline.h13
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c1
-rw-r--r--drivers/scsi/qla2xxx/qla_mbx.c7
-rw-r--r--drivers/scsi/qla2xxx/qla_nx.c15
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c19
-rw-r--r--drivers/scsi/qla2xxx/qla_version.h2
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c23
-rw-r--r--drivers/scsi/scsi_pm.c16
-rw-r--r--drivers/scsi/scsi_priv.h1
-rw-r--r--drivers/scsi/scsi_scan.c4
-rw-r--r--drivers/sh/clk/cpg.c2
-rw-r--r--drivers/tty/serial/imx.c7
-rw-r--r--drivers/usb/core/hcd-pci.c5
-rw-r--r--drivers/usb/core/hcd.c6
-rw-r--r--drivers/usb/core/hub.c30
-rw-r--r--drivers/usb/gadget/Kconfig4
-rw-r--r--drivers/usb/host/pci-quirks.c11
-rw-r--r--drivers/usb/host/xhci-hub.c2
-rw-r--r--drivers/usb/host/xhci-mem.c32
-rw-r--r--drivers/usb/host/xhci.c5
-rw-r--r--drivers/usb/serial/cp210x.c2
-rw-r--r--drivers/usb/serial/option.c143
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c6
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.h4
-rw-r--r--drivers/usb/storage/usb.c90
-rw-r--r--drivers/usb/storage/usb.h7
-rw-r--r--drivers/video/omap2/displays/Kconfig2
-rw-r--r--drivers/video/omap2/dss/apply.c6
-rw-r--r--drivers/video/omap2/dss/hdmi.c24
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c9
-rw-r--r--drivers/video/pvr2fb.c2
-rw-r--r--drivers/video/via/hw.c4
-rw-r--r--drivers/virtio/virtio_balloon.c33
-rw-r--r--drivers/watchdog/Kconfig2
-rw-r--r--drivers/watchdog/booke_wdt.c6
-rw-r--r--drivers/watchdog/hpwdt.c5
-rw-r--r--drivers/watchdog/pnx4008_wdt.c2
-rw-r--r--drivers/watchdog/s3c2410_wdt.c57
-rw-r--r--fs/autofs4/autofs_i.h1
-rw-r--r--fs/autofs4/dev-ioctl.c1
-rw-r--r--fs/autofs4/expire.c2
-rw-r--r--fs/autofs4/inode.c2
-rw-r--r--fs/autofs4/waitq.c22
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/btrfs/backref.c2
-rw-r--r--fs/btrfs/check-integrity.c2
-rw-r--r--fs/btrfs/compression.c2
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/disk-io.c12
-rw-r--r--fs/btrfs/extent-tree.c51
-rw-r--r--fs/btrfs/extent_io.c113
-rw-r--r--fs/btrfs/extent_io.h1
-rw-r--r--fs/btrfs/extent_map.h4
-rw-r--r--fs/btrfs/file.c29
-rw-r--r--fs/btrfs/free-space-cache.c1
-rw-r--r--fs/btrfs/inode-map.c6
-rw-r--r--fs/btrfs/inode.c40
-rw-r--r--fs/btrfs/ioctl.c59
-rw-r--r--fs/btrfs/scrub.c8
-rw-r--r--fs/btrfs/transaction.c16
-rw-r--r--fs/btrfs/volumes.c33
-rw-r--r--fs/compat.c56
-rw-r--r--fs/dcache.c21
-rw-r--r--fs/direct-io.c4
-rw-r--r--fs/ecryptfs/miscdev.c2
-rw-r--r--fs/eventpoll.c30
-rw-r--r--fs/gfs2/glock.c14
-rw-r--r--fs/gfs2/inode.c5
-rw-r--r--fs/gfs2/ops_fstype.c5
-rw-r--r--fs/gfs2/rgrp.c13
-rw-r--r--fs/inode.c8
-rw-r--r--fs/namei.c70
-rw-r--r--fs/nfs/nfs4proc.c130
-rw-r--r--fs/nfs/nfs4state.c2
-rw-r--r--fs/nfs/nfs4xdr.c5
-rw-r--r--fs/ntfs/attrib.c6
-rw-r--r--fs/ntfs/mft.c6
-rw-r--r--fs/ntfs/super.c4
-rw-r--r--fs/ocfs2/namei.c2
-rw-r--r--fs/quota/quota.c24
-rw-r--r--fs/select.c2
-rw-r--r--fs/signalfd.c15
-rw-r--r--fs/super.c22
-rw-r--r--fs/xfs/xfs_dquot.c24
-rw-r--r--fs/xfs/xfs_log_recover.c6
-rw-r--r--fs/xfs/xfs_qm_syscalls.c4
-rw-r--r--fs/xfs/xfs_trans.c4
-rw-r--r--fs/xfs/xfs_trans_dquot.c10
-rw-r--r--include/asm-generic/io-64-nonatomic-hi-lo.h28
-rw-r--r--include/asm-generic/io-64-nonatomic-lo-hi.h28
-rw-r--r--include/asm-generic/iomap.h2
-rw-r--r--include/asm-generic/pci_iomap.h2
-rw-r--r--include/asm-generic/poll.h2
-rw-r--r--include/drm/Kbuild1
-rw-r--r--include/drm/exynos_drm.h22
-rw-r--r--include/linux/amba/bus.h36
-rw-r--r--include/linux/compat.h4
-rw-r--r--include/linux/dcache.h21
-rw-r--r--include/linux/digsig.h4
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/if_link.h1
-rw-r--r--include/linux/irqdomain.h191
-rw-r--r--include/linux/netfilter_bridge/ebtables.h4
-rw-r--r--include/linux/nfs_xdr.h2
-rw-r--r--include/linux/of_address.h33
-rw-r--r--include/linux/of_irq.h4
-rw-r--r--include/linux/of_platform.h12
-rw-r--r--include/linux/platform_data/tegra_emc.h (renamed from arch/arm/mach-tegra/include/mach/system.h)26
-rw-r--r--include/linux/regset.h10
-rw-r--r--include/linux/regulator/bq24022.h24
-rw-r--r--include/linux/rtnetlink.h3
-rw-r--r--include/linux/signalfd.h5
-rw-r--r--include/linux/skbuff.h10
-rw-r--r--include/linux/syscalls.h2
-rw-r--r--include/linux/usb/ch11.h10
-rw-r--r--include/net/bluetooth/bluetooth.h2
-rw-r--r--include/net/bluetooth/hci_core.h6
-rw-r--r--include/net/bluetooth/l2cap.h12
-rw-r--r--include/net/netfilter/nf_conntrack.h2
-rw-r--r--include/net/rtnetlink.h2
-rw-r--r--include/trace/events/sched.h50
-rw-r--r--kernel/events/hw_breakpoint.c4
-rw-r--r--kernel/fork.c5
-rw-r--r--kernel/irq/autoprobe.c4
-rw-r--r--kernel/irq/chip.c42
-rw-r--r--kernel/irq/internals.h2
-rw-r--r--kernel/irq/irqdomain.c828
-rw-r--r--kernel/irq/manage.c2
-rw-r--r--kernel/pid.c4
-rw-r--r--kernel/sched/core.c5
-rw-r--r--kernel/sched/fair.c2
-rw-r--r--mm/memblock.c6
-rw-r--r--mm/memcontrol.c5
-rw-r--r--mm/nommu.c9
-rw-r--r--mm/page_alloc.c1
-rw-r--r--net/atm/clip.c10
-rw-r--r--net/bluetooth/af_bluetooth.c12
-rw-r--r--net/bluetooth/hci_conn.c4
-rw-r--r--net/bluetooth/hci_core.c3
-rw-r--r--net/bluetooth/l2cap_core.c24
-rw-r--r--net/bluetooth/l2cap_sock.c4
-rw-r--r--net/bluetooth/rfcomm/core.c18
-rw-r--r--net/bluetooth/rfcomm/sock.c2
-rw-r--r--net/core/neighbour.c2
-rw-r--r--net/core/rtnetlink.c78
-rw-r--r--net/ipv4/ip_gre.c10
-rw-r--r--net/ipv4/ping.c1
-rw-r--r--net/ipv4/tcp.c5
-rw-r--r--net/ipv4/xfrm4_mode_beet.c5
-rw-r--r--net/ipv4/xfrm4_mode_tunnel.c6
-rw-r--r--net/ipv6/ip6mr.c4
-rw-r--r--net/ipv6/ndisc.c5
-rw-r--r--net/ipv6/xfrm6_mode_beet.c6
-rw-r--r--net/ipv6/xfrm6_mode_tunnel.c6
-rw-r--r--net/mac80211/debugfs_sta.c4
-rw-r--r--net/mac80211/rate.c2
-rw-r--r--net/mac80211/rate.h3
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c2
-rw-r--r--net/netfilter/nf_conntrack_core.c38
-rw-r--r--net/netfilter/nf_conntrack_netlink.c46
-rw-r--r--net/netfilter/nf_queue.c40
-rw-r--r--net/netfilter/xt_TEE.c5
-rw-r--r--net/sched/sch_netem.c6
-rwxr-xr-xscripts/coccicheck13
-rwxr-xr-xscripts/depmod.sh6
-rw-r--r--scripts/mod/file2alias.c35
-rw-r--r--scripts/mod/modpost.c9
-rw-r--r--scripts/package/builddeb12
-rw-r--r--sound/pci/azt3328.c3
-rw-r--r--sound/pci/hda/hda_codec.c12
-rw-r--r--sound/pci/hda/hda_codec.h3
-rw-r--r--sound/pci/hda/patch_cirrus.c4
-rw-r--r--sound/pci/hda/patch_conexant.c24
-rw-r--r--sound/pci/hda/patch_realtek.c27
-rw-r--r--sound/pci/hda/patch_sigmatel.c2
-rw-r--r--sound/soc/codecs/ak4642.c31
-rw-r--r--sound/soc/codecs/wm8962.c2
-rw-r--r--sound/soc/imx/imx-ssi.c2
-rw-r--r--sound/soc/soc-dapm.c12
-rw-r--r--sound/usb/caiaq/audio.c5
-rw-r--r--sound/usb/card.h1
-rw-r--r--sound/usb/format.c4
-rw-r--r--sound/usb/quirks.c6
-rw-r--r--tools/perf/util/event.c1
-rw-r--r--tools/perf/util/evlist.c4
-rw-r--r--tools/perf/util/probe-event.c6
-rw-r--r--tools/perf/util/probe-finder.c12
-rwxr-xr-xtools/testing/ktest/ktest.pl8
720 files changed, 7882 insertions, 9906 deletions
diff --git a/Documentation/IRQ-domain.txt b/Documentation/IRQ-domain.txt
new file mode 100644
index 00000000000..27dcaabfb4d
--- /dev/null
+++ b/Documentation/IRQ-domain.txt
@@ -0,0 +1,117 @@
+irq_domain interrupt number mapping library
+
+The current design of the Linux kernel uses a single large number
+space where each separate IRQ source is assigned a different number.
+This is simple when there is only one interrupt controller, but in
+systems with multiple interrupt controllers the kernel must ensure
+that each one gets assigned non-overlapping allocations of Linux
+IRQ numbers.
+
+The irq_alloc_desc*() and irq_free_desc*() APIs provide allocation of
+irq numbers, but they don't provide any support for reverse mapping of
+the controller-local IRQ (hwirq) number into the Linux IRQ number
+space.
+
+The irq_domain library adds mapping between hwirq and IRQ numbers on
+top of the irq_alloc_desc*() API. An irq_domain to manage mapping is
+preferred over interrupt controller drivers open coding their own
+reverse mapping scheme.
+
+irq_domain also implements translation from Device Tree interrupt
+specifiers to hwirq numbers, and can be easily extended to support
+other IRQ topology data sources.
+
+=== irq_domain usage ===
+An interrupt controller driver creates and registers an irq_domain by
+calling one of the irq_domain_add_*() functions (each mapping method
+has a different allocator function, more on that later). The function
+will return a pointer to the irq_domain on success. The caller must
+provide the allocator function with an irq_domain_ops structure with
+the .map callback populated as a minimum.
+
+In most cases, the irq_domain will begin empty without any mappings
+between hwirq and IRQ numbers. Mappings are added to the irq_domain
+by calling irq_create_mapping() which accepts the irq_domain and a
+hwirq number as arguments. If a mapping for the hwirq doesn't already
+exist then it will allocate a new Linux irq_desc, associate it with
+the hwirq, and call the .map() callback so the driver can perform any
+required hardware setup.
+
+When an interrupt is received, irq_find_mapping() function should
+be used to find the Linux IRQ number from the hwirq number.
+
+If the driver has the Linux IRQ number or the irq_data pointer, and
+needs to know the associated hwirq number (such as in the irq_chip
+callbacks) then it can be directly obtained from irq_data->hwirq.
+
+=== Types of irq_domain mappings ===
+There are several mechanisms available for reverse mapping from hwirq
+to Linux irq, and each mechanism uses a different allocation function.
+Which reverse map type should be used depends on the use case. Each
+of the reverse map types are described below:
+
+==== Linear ====
+irq_domain_add_linear()
+
+The linear reverse map maintains a fixed size table indexed by the
+hwirq number. When a hwirq is mapped, an irq_desc is allocated for
+the hwirq, and the IRQ number is stored in the table.
+
+The Linear map is a good choice when the maximum number of hwirqs is
+fixed and a relatively small number (~ < 256). The advantages of this
+map are fixed time lookup for IRQ numbers, and irq_descs are only
+allocated for in-use IRQs. The disadvantage is that the table must be
+as large as the largest possible hwirq number.
+
+The majority of drivers should use the linear map.
+
+==== Tree ====
+irq_domain_add_tree()
+
+The irq_domain maintains a radix tree map from hwirq numbers to Linux
+IRQs. When an hwirq is mapped, an irq_desc is allocated and the
+hwirq is used as the lookup key for the radix tree.
+
+The tree map is a good choice if the hwirq number can be very large
+since it doesn't need to allocate a table as large as the largest
+hwirq number. The disadvantage is that hwirq to IRQ number lookup is
+dependent on how many entries are in the table.
+
+Very few drivers should need this mapping. At the moment, powerpc
+iseries is the only user.
+
+==== No Map ===-
+irq_domain_add_nomap()
+
+The No Map mapping is to be used when the hwirq number is
+programmable in the hardware. In this case it is best to program the
+Linux IRQ number into the hardware itself so that no mapping is
+required. Calling irq_create_direct_mapping() will allocate a Linux
+IRQ number and call the .map() callback so that driver can program the
+Linux IRQ number into the hardware.
+
+Most drivers cannot use this mapping.
+
+==== Legacy ====
+irq_domain_add_legacy()
+irq_domain_add_legacy_isa()
+
+The Legacy mapping is a special case for drivers that already have a
+range of irq_descs allocated for the hwirqs. It is used when the
+driver cannot be immediately converted to use the linear mapping. For
+example, many embedded system board support files use a set of #defines
+for IRQ numbers that are passed to struct device registrations. In that
+case the Linux IRQ numbers cannot be dynamically assigned and the legacy
+mapping should be used.
+
+The legacy map assumes a contiguous range of IRQ numbers has already
+been allocated for the controller and that the IRQ number can be
+calculated by adding a fixed offset to the hwirq number, and
+visa-versa. The disadvantage is that it requires the interrupt
+controller to manage IRQ allocations and it requires an irq_desc to be
+allocated for every hwirq, even if it is unused.
+
+The legacy map should only be used if fixed IRQ mappings must be
+supported. For example, ISA controllers would use the legacy map for
+mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ
+numbers.
diff --git a/Documentation/devicetree/bindings/arm/tegra/emc.txt b/Documentation/devicetree/bindings/arm/tegra/emc.txt
new file mode 100644
index 00000000000..09335f8eee0
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/emc.txt
@@ -0,0 +1,100 @@
+Embedded Memory Controller
+
+Properties:
+- name : Should be emc
+- #address-cells : Should be 1
+- #size-cells : Should be 0
+- compatible : Should contain "nvidia,tegra20-emc".
+- reg : Offset and length of the register set for the device
+- nvidia,use-ram-code : If present, the sub-nodes will be addressed
+ and chosen using the ramcode board selector. If omitted, only one
+ set of tables can be present and said tables will be used
+ irrespective of ram-code configuration.
+
+Child device nodes describe the memory settings for different configurations and clock rates.
+
+Example:
+
+ emc@7000f400 {
+ #address-cells = < 1 >;
+ #size-cells = < 0 >;
+ compatible = "nvidia,tegra20-emc";
+ reg = <0x7000f4000 0x200>;
+ }
+
+
+Embedded Memory Controller ram-code table
+
+If the emc node has the nvidia,use-ram-code property present, then the
+next level of nodes below the emc table are used to specify which settings
+apply for which ram-code settings.
+
+If the emc node lacks the nvidia,use-ram-code property, this level is omitted
+and the tables are stored directly under the emc node (see below).
+
+Properties:
+
+- name : Should be emc-tables
+- nvidia,ram-code : the binary representation of the ram-code board strappings
+ for which this node (and children) are valid.
+
+
+
+Embedded Memory Controller configuration table
+
+This is a table containing the EMC register settings for the various
+operating speeds of the memory controller. They are always located as
+subnodes of the emc controller node.
+
+There are two ways of specifying which tables to use:
+
+* The simplest is if there is just one set of tables in the device tree,
+ and they will always be used (based on which frequency is used).
+ This is the preferred method, especially when firmware can fill in
+ this information based on the specific system information and just
+ pass it on to the kernel.
+
+* The slightly more complex one is when more than one memory configuration
+ might exist on the system. The Tegra20 platform handles this during
+ early boot by selecting one out of possible 4 memory settings based
+ on a 2-pin "ram code" bootstrap setting on the board. The values of
+ these strappings can be read through a register in the SoC, and thus
+ used to select which tables to use.
+
+Properties:
+- name : Should be emc-table
+- compatible : Should contain "nvidia,tegra20-emc-table".
+- reg : either an opaque enumerator to tell different tables apart, or
+ the valid frequency for which the table should be used (in kHz).
+- clock-frequency : the clock frequency for the EMC at which this
+ table should be used (in kHz).
+- nvidia,emc-registers : a 46 word array of EMC registers to be programmed
+ for operation at the 'clock-frequency' setting.
+ The order and contents of the registers are:
+ RC, RFC, RAS, RP, R2W, W2R, R2P, W2P, RD_RCD, WR_RCD, RRD, REXT,
+ WDV, QUSE, QRST, QSAFE, RDV, REFRESH, BURST_REFRESH_NUM, PDEX2WR,
+ PDEX2RD, PCHG2PDEN, ACT2PDEN, AR2PDEN, RW2PDEN, TXSR, TCKE, TFAW,
+ TRPAB, TCLKSTABLE, TCLKSTOP, TREFBW, QUSE_EXTRA, FBIO_CFG6, ODT_WRITE,
+ ODT_READ, FBIO_CFG5, CFG_DIG_DLL, DLL_XFORM_DQS, DLL_XFORM_QUSE,
+ ZCAL_REF_CNT, ZCAL_WAIT_CNT, AUTO_CAL_INTERVAL, CFG_CLKTRIM_0,
+ CFG_CLKTRIM_1, CFG_CLKTRIM_2
+
+ emc-table@166000 {
+ reg = <166000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = < 166000 >;
+ nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 >;
+ };
+
+ emc-table@333000 {
+ reg = <333000>;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = < 333000 >;
+ nvidia,emc-registers = < 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+ 0 0 0 0 >;
+ };
diff --git a/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
new file mode 100644
index 00000000000..b5846e21cc2
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/tegra/nvidia,tegra20-pmc.txt
@@ -0,0 +1,19 @@
+NVIDIA Tegra Power Management Controller (PMC)
+
+Properties:
+- name : Should be pmc
+- compatible : Should contain "nvidia,tegra<chip>-pmc".
+- reg : Offset and length of the register set for the device
+- nvidia,invert-interrupt : If present, inverts the PMU interrupt signal.
+ The PMU is an external Power Management Unit, whose interrupt output
+ signal is fed into the PMC. This signal is optionally inverted, and then
+ fed into the ARM GIC. The PMC is not involved in the detection or
+ handling of this interrupt signal, merely its inversion.
+
+Example:
+
+pmc@7000f400 {
+ compatible = "nvidia,tegra20-pmc";
+ reg = <0x7000e400 0x400>;
+ nvidia,invert-interrupt;
+};
diff --git a/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt
new file mode 100644
index 00000000000..90fa7da525b
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/tegra20-apbdma.txt
@@ -0,0 +1,30 @@
+* NVIDIA Tegra APB DMA controller
+
+Required properties:
+- compatible: Should be "nvidia,<chip>-apbdma"
+- reg: Should contain DMA registers location and length. This shuld include
+ all of the per-channel registers.
+- interrupts: Should contain all of the per-channel DMA interrupts.
+
+Examples:
+
+apbdma: dma@6000a000 {
+ compatible = "nvidia,tegra20-apbdma";
+ reg = <0x6000a000 0x1200>;
+ interrupts = < 0 136 0x04
+ 0 137 0x04
+ 0 138 0x04
+ 0 139 0x04
+ 0 140 0x04
+ 0 141 0x04
+ 0 142 0x04
+ 0 143 0x04
+ 0 144 0x04
+ 0 145 0x04
+ 0 146 0x04
+ 0 147 0x04
+ 0 148 0x04
+ 0 149 0x04
+ 0 150 0x04
+ 0 151 0x04 >;
+};
diff --git a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
index eb4b530d64e..023c9526e5f 100644
--- a/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
+++ b/Documentation/devicetree/bindings/gpio/gpio_nvidia.txt
@@ -1,8 +1,40 @@
-NVIDIA Tegra 2 GPIO controller
+NVIDIA Tegra GPIO controller
Required properties:
-- compatible : "nvidia,tegra20-gpio"
+- compatible : "nvidia,tegra<chip>-gpio"
+- reg : Physical base address and length of the controller's registers.
+- interrupts : The interrupt outputs from the controller. For Tegra20,
+ there should be 7 interrupts specified, and for Tegra30, there should
+ be 8 interrupts specified.
- #gpio-cells : Should be two. The first cell is the pin number and the
second cell is used to specify optional parameters:
- bit 0 specifies polarity (0 for normal, 1 for inverted)
- gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+ The first cell is the GPIO number.
+ The second cell is used to specify flags:
+ bits[3:0] trigger type and level flags:
+ 1 = low-to-high edge triggered.
+ 2 = high-to-low edge triggered.
+ 4 = active high level-sensitive.
+ 8 = active low level-sensitive.
+ Valid combinations are 1, 2, 3, 4, 8.
+- interrupt-controller : Marks the device node as an interrupt controller.
+
+Example:
+
+gpio: gpio@6000d000 {
+ compatible = "nvidia,tegra20-gpio";
+ reg = < 0x6000d000 0x1000 >;
+ interrupts = < 0 32 0x04
+ 0 33 0x04
+ 0 34 0x04
+ 0 35 0x04
+ 0 55 0x04
+ 0 87 0x04
+ 0 89 0x04 >;
+ #gpio-cells = <2>;
+ gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
+};
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index a0ffac029a0..1bea46a54b1 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -510,17 +510,3 @@ Why: The pci_scan_bus_parented() interface creates a new root bus. The
convert to using pci_scan_root_bus() so they can supply a list of
bus resources when the bus is created.
Who: Bjorn Helgaas <bhelgaas@google.com>
-
-----------------------------
-
-What: The CAP9 SoC family will be removed
-When: 3.4
-Files: arch/arm/mach-at91/at91cap9.c
- arch/arm/mach-at91/at91cap9_devices.c
- arch/arm/mach-at91/include/mach/at91cap9.h
- arch/arm/mach-at91/include/mach/at91cap9_matrix.h
- arch/arm/mach-at91/include/mach/at91cap9_ddrsdr.h
- arch/arm/mach-at91/board-cap9adk.c
-Why: The code is not actively maintained and platforms are now hard to find.
-Who: Nicolas Ferre <nicolas.ferre@atmel.com>
- Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
diff --git a/MAINTAINERS b/MAINTAINERS
index 9a648eb8e21..f096b0d8e97 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -269,7 +269,6 @@ S: Orphan
F: drivers/platform/x86/wmi.c
AD1889 ALSA SOUND DRIVER
-M: Kyle McMartin <kyle@mcmartin.ca>
M: Thibaut Varene <T-Bone@parisc-linux.org>
W: http://wiki.parisc-linux.org/AD1889
L: linux-parisc@vger.kernel.org
@@ -3047,7 +3046,6 @@ F: drivers/hwspinlock/hwspinlock_*
F: include/linux/hwspinlock.h
HARMONY SOUND DRIVER
-M: Kyle McMartin <kyle@mcmartin.ca>
L: linux-parisc@vger.kernel.org
S: Maintained
F: sound/parisc/harmony.*
@@ -3640,6 +3638,15 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
F: kernel/irq/
+IRQ DOMAINS (IRQ NUMBER MAPPING LIBRARY)
+M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
+M: Grant Likely <grant.likely@secretlab.ca>
+T: git git://git.secretlab.ca/git/linux-2.6.git irqdomain/next
+S: Maintained
+F: Documentation/IRQ-domain.txt
+F: include/linux/irqdomain.h
+F: kernel/irq/irqdomain.c
+
ISAPNP
M: Jaroslav Kysela <perex@perex.cz>
S: Maintained
@@ -3782,7 +3789,7 @@ F: Documentation/kdump/
KERNEL AUTOMOUNTER v4 (AUTOFS4)
M: Ian Kent <raven@themaw.net>
-L: autofs@linux.kernel.org
+L: autofs@vger.kernel.org
S: Maintained
F: fs/autofs4/
@@ -4687,7 +4694,7 @@ NTFS FILESYSTEM
M: Anton Altaparmakov <anton@tuxera.com>
L: linux-ntfs-dev@lists.sourceforge.net
W: http://www.tuxera.com/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs-2.6.git
+T: git git://git.kernel.org/pub/scm/linux/kernel/git/aia21/ntfs.git
S: Supported
F: Documentation/filesystems/ntfs.txt
F: fs/ntfs/
@@ -5000,9 +5007,8 @@ F: Documentation/blockdev/paride.txt
F: drivers/block/paride/
PARISC ARCHITECTURE
-M: Kyle McMartin <kyle@mcmartin.ca>
-M: Helge Deller <deller@gmx.de>
M: "James E.J. Bottomley" <jejb@parisc-linux.org>
+M: Helge Deller <deller@gmx.de>
L: linux-parisc@vger.kernel.org
W: http://www.parisc-linux.org/
Q: http://patchwork.kernel.org/project/linux-parisc/list/
@@ -5861,7 +5867,7 @@ S: Maintained
F: drivers/mmc/host/sdhci-spear.c
SECURITY SUBSYSTEM
-M: James Morris <jmorris@namei.org>
+M: James Morris <james.l.morris@oracle.com>
L: linux-security-module@vger.kernel.org (suggested Cc:)
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security.git
W: http://security.wiki.kernel.org/
@@ -5874,7 +5880,7 @@ S: Supported
SELINUX SECURITY MODULE
M: Stephen Smalley <sds@tycho.nsa.gov>
-M: James Morris <jmorris@namei.org>
+M: James Morris <james.l.morris@oracle.com>
M: Eric Paris <eparis@parisplace.org>
L: selinux@tycho.nsa.gov (subscribers-only, general discussion)
W: http://selinuxproject.org
@@ -7274,7 +7280,7 @@ WATCHDOG DEVICE DRIVERS
M: Wim Van Sebroeck <wim@iguana.be>
L: linux-watchdog@vger.kernel.org
W: http://www.linux-watchdog.org/
-T: git git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog.git
+T: git git://www.linux-watchdog.org/linux-watchdog.git
S: Maintained
F: Documentation/watchdog/
F: drivers/watchdog/
diff --git a/Makefile b/Makefile
index 4ddd641ab61..66d13c917bc 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
VERSION = 3
PATCHLEVEL = 3
SUBLEVEL = 0
-EXTRAVERSION = -rc4
+EXTRAVERSION = -rc6
NAME = Saber-toothed Squirrel
# *DOCUMENTATION*
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a48aecc17ea..baf6dc6e9a1 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -324,7 +324,7 @@ config ARCH_AT91
select CLKDEV_LOOKUP
help
This enables support for systems based on the Atmel AT91RM9200,
- AT91SAM9 and AT91CAP9 processors.
+ AT91SAM9 processors.
config ARCH_BCMRING
bool "Broadcom BCMRING"
@@ -754,7 +754,7 @@ config ARCH_SA1100
select ARCH_HAS_CPUFREQ
select CPU_FREQ
select GENERIC_CLOCKEVENTS
- select HAVE_CLK
+ select CLKDEV_LOOKUP
select HAVE_SCHED_CLOCK
select TICK_ONESHOT
select ARCH_REQUIRE_GPIOLIB
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index e0d236d7ff7..66ca8014ff3 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -81,47 +81,14 @@ choice
prompt "Kernel low-level debugging port"
depends on DEBUG_LL
- config DEBUG_LL_UART_NONE
- bool "No low-level debugging UART"
- help
- Say Y here if your platform doesn't provide a UART option
- below. This relies on your platform choosing the right UART
- definition internally in order for low-level debugging to
- work.
-
- config DEBUG_ICEDCC
- bool "Kernel low-level debugging via EmbeddedICE DCC channel"
- help
- Say Y here if you want the debug print routines to direct
- their output to the EmbeddedICE macrocell's DCC channel using
- co-processor 14. This is known to work on the ARM9 style ICE
- channel and on the XScale with the PEEDI.
-
- Note that the system will appear to hang during boot if there
- is nothing connected to read from the DCC.
-
config AT91_DEBUG_LL_DBGU0
bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
depends on HAVE_AT91_DBGU0
config AT91_DEBUG_LL_DBGU1
- bool "Kernel low-level debugging on 9263, 9g45 and cap9"
+ bool "Kernel low-level debugging on 9263 and 9g45"
depends on HAVE_AT91_DBGU1
- config DEBUG_FOOTBRIDGE_COM1
- bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
- depends on FOOTBRIDGE
- help
- Say Y here if you want the debug print routines to direct
- their output to the 8250 at PCI COM1.
-
- config DEBUG_DC21285_PORT
- bool "Kernel low-level debugging messages via footbridge serial port"
- depends on FOOTBRIDGE
- help
- Say Y here if you want the debug print routines to direct
- their output to the serial port in the DC21285 (Footbridge).
-
config DEBUG_CLPS711X_UART1
bool "Kernel low-level debugging messages via UART1"
depends on ARCH_CLPS711X
@@ -136,6 +103,20 @@ choice
Say Y here if you want the debug print routines to direct
their output to the second serial port on these devices.
+ config DEBUG_DC21285_PORT
+ bool "Kernel low-level debugging messages via footbridge serial port"
+ depends on FOOTBRIDGE
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port in the DC21285 (Footbridge).
+
+ config DEBUG_FOOTBRIDGE_COM1
+ bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
+ depends on FOOTBRIDGE
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the 8250 at PCI COM1.
+
config DEBUG_HIGHBANK_UART
bool "Kernel low-level debugging messages via Highbank UART"
depends on ARCH_HIGHBANK
@@ -199,45 +180,49 @@ choice
Say Y here if you want kernel low-level debugging support
on i.MX50 or i.MX53.
- config DEBUG_IMX6Q_UART
- bool "i.MX6Q Debug UART"
+ config DEBUG_IMX6Q_UART4
+ bool "i.MX6Q Debug UART4"
depends on SOC_IMX6Q
help
Say Y here if you want kernel low-level debugging support
- on i.MX6Q.
+ on i.MX6Q UART4.
- config DEBUG_S3C_UART0
- depends on PLAT_SAMSUNG
- bool "Use S3C UART 0 for low-level debug"
+ config DEBUG_MSM_UART1
+ bool "Kernel low-level debugging messages via MSM UART1"
+ depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
help
Say Y here if you want the debug print routines to direct
- their output to UART 0. The port must have been initialised
- by the boot-loader before use.
-
- The uncompressor code port configuration is now handled
- by CONFIG_S3C_LOWLEVEL_UART_PORT.
+ their output to the first serial port on MSM devices.
- config DEBUG_S3C_UART1
- depends on PLAT_SAMSUNG
- bool "Use S3C UART 1 for low-level debug"
+ config DEBUG_MSM_UART2
+ bool "Kernel low-level debugging messages via MSM UART2"
+ depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
help
Say Y here if you want the debug print routines to direct
- their output to UART 1. The port must have been initialised
- by the boot-loader before use.
+ their output to the second serial port on MSM devices.
- The uncompressor code port configuration is now handled
- by CONFIG_S3C_LOWLEVEL_UART_PORT.
+ config DEBUG_MSM_UART3
+ bool "Kernel low-level debugging messages via MSM UART3"
+ depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the third serial port on MSM devices.
- config DEBUG_S3C_UART2
- depends on PLAT_SAMSUNG
- bool "Use S3C UART 2 for low-level debug"
+ config DEBUG_MSM8660_UART
+ bool "Kernel low-level debugging messages via MSM 8660 UART"
+ depends on ARCH_MSM8X60
+ select MSM_HAS_DEBUG_UART_HS
help
Say Y here if you want the debug print routines to direct
- their output to UART 2. The port must have been initialised
- by the boot-loader before use.
+ their output to the serial port on MSM 8660 devices.
- The uncompressor code port configuration is now handled
- by CONFIG_S3C_LOWLEVEL_UART_PORT.
+ config DEBUG_MSM8960_UART
+ bool "Kernel low-level debugging messages via MSM 8960 UART"
+ depends on ARCH_MSM8960
+ select MSM_HAS_DEBUG_UART_HS
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the serial port on MSM 8960 devices.
config DEBUG_REALVIEW_STD_PORT
bool "RealView Default UART"
@@ -255,42 +240,57 @@ choice
their output to the standard serial port on the RealView
PB1176 platform.
- config DEBUG_MSM_UART1
- bool "Kernel low-level debugging messages via MSM UART1"
- depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+ config DEBUG_S3C_UART0
+ depends on PLAT_SAMSUNG
+ bool "Use S3C UART 0 for low-level debug"
help
Say Y here if you want the debug print routines to direct
- their output to the first serial port on MSM devices.
+ their output to UART 0. The port must have been initialised
+ by the boot-loader before use.
- config DEBUG_MSM_UART2
- bool "Kernel low-level debugging messages via MSM UART2"
- depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+ The uncompressor code port configuration is now handled
+ by CONFIG_S3C_LOWLEVEL_UART_PORT.
+
+ config DEBUG_S3C_UART1
+ depends on PLAT_SAMSUNG
+ bool "Use S3C UART 1 for low-level debug"
help
Say Y here if you want the debug print routines to direct
- their output to the second serial port on MSM devices.
+ their output to UART 1. The port must have been initialised
+ by the boot-loader before use.
- config DEBUG_MSM_UART3
- bool "Kernel low-level debugging messages via MSM UART3"
- depends on ARCH_MSM7X00A || ARCH_MSM7X30 || ARCH_QSD8X50
+ The uncompressor code port configuration is now handled
+ by CONFIG_S3C_LOWLEVEL_UART_PORT.
+
+ config DEBUG_S3C_UART2
+ depends on PLAT_SAMSUNG
+ bool "Use S3C UART 2 for low-level debug"
help
Say Y here if you want the debug print routines to direct
- their output to the third serial port on MSM devices.
+ their output to UART 2. The port must have been initialised
+ by the boot-loader before use.
- config DEBUG_MSM8660_UART
- bool "Kernel low-level debugging messages via MSM 8660 UART"
- depends on ARCH_MSM8X60
- select MSM_HAS_DEBUG_UART_HS
+ The uncompressor code port configuration is now handled
+ by CONFIG_S3C_LOWLEVEL_UART_PORT.
+
+ config DEBUG_LL_UART_NONE
+ bool "No low-level debugging UART"
help
- Say Y here if you want the debug print routines to direct
- their output to the serial port on MSM 8660 devices.
+ Say Y here if your platform doesn't provide a UART option
+ below. This relies on your platform choosing the right UART
+ definition internally in order for low-level debugging to
+ work.
- config DEBUG_MSM8960_UART
- bool "Kernel low-level debugging messages via MSM 8960 UART"
- depends on ARCH_MSM8960
- select MSM_HAS_DEBUG_UART_HS
+ config DEBUG_ICEDCC
+ bool "Kernel low-level debugging via EmbeddedICE DCC channel"
help
Say Y here if you want the debug print routines to direct
- their output to the serial port on MSM 8960 devices.
+ their output to the EmbeddedICE macrocell's DCC channel using
+ co-processor 14. This is known to work on the ARM9 style ICE
+ channel and on the XScale with the PEEDI.
+
+ Note that the system will appear to hang during boot if there
+ is nothing connected to read from the DCC.
endchoice
diff --git a/arch/arm/boot/dts/tegra-harmony.dts b/arch/arm/boot/dts/tegra-harmony.dts
index 80afa1b70b8..6e8447dc020 100644
--- a/arch/arm/boot/dts/tegra-harmony.dts
+++ b/arch/arm/boot/dts/tegra-harmony.dts
@@ -10,19 +10,25 @@
reg = < 0x00000000 0x40000000 >;
};
+ pmc@7000f400 {
+ nvidia,invert-interrupt;
+ };
+
i2c@7000c000 {
clock-frequency = <400000>;
- codec: wm8903@1a {
+ wm8903: wm8903@1a {
compatible = "wlf,wm8903";
reg = <0x1a>;
- interrupts = < 347 >;
+ interrupt-parent = <&gpio>;
+ interrupts = < 187 0x04 >;
gpio-controller;
#gpio-cells = <2>;
- /* 0x8000 = Not configured */
- gpio-cfg = < 0x8000 0x8000 0 0x8000 0x8000 >;
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
};
};
@@ -38,13 +44,32 @@
clock-frequency = <400000>;
};
- sound {
- compatible = "nvidia,harmony-sound", "nvidia,tegra-wm8903";
+ i2s@70002a00 {
+ status = "disable";
+ };
- spkr-en-gpios = <&codec 2 0>;
- hp-det-gpios = <&gpio 178 0>;
- int-mic-en-gpios = <&gpio 184 0>;
- ext-mic-en-gpios = <&gpio 185 0>;
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-harmony",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Harmony";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 0>;
+ nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+ nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
+ nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
};
serial@70006000 {
diff --git a/arch/arm/boot/dts/tegra-paz00.dts b/arch/arm/boot/dts/tegra-paz00.dts
index 825d2957da0..e4b552b46fe 100644
--- a/arch/arm/boot/dts/tegra-paz00.dts
+++ b/arch/arm/boot/dts/tegra-paz00.dts
@@ -12,6 +12,13 @@
i2c@7000c000 {
clock-frequency = <400000>;
+
+ alc5632: alc5632@1e {
+ compatible = "realtek,alc5632";
+ reg = <0x1e>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
};
i2c@7000c400 {
@@ -37,6 +44,29 @@
clock-frequency = <400000>;
};
+ i2s@70002a00 {
+ status = "disable";
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-alc5632-paz00",
+ "nvidia,tegra-audio-alc5632";
+
+ nvidia,model = "Compal PAZ00";
+
+ nvidia,audio-routing =
+ "Int Spk", "SPKOUT",
+ "Int Spk", "SPKOUTN",
+ "Headset Mic", "MICBIAS1",
+ "MIC1", "Headset Mic",
+ "Headset Stereophone", "HPR",
+ "Headset Stereophone", "HPL";
+
+ nvidia,audio-codec = <&alc5632>;
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+ };
+
serial@70006000 {
clock-frequency = <216000000>;
};
diff --git a/arch/arm/boot/dts/tegra-seaboard.dts b/arch/arm/boot/dts/tegra-seaboard.dts
index b55a02e34ba..876d5c92ce3 100644
--- a/arch/arm/boot/dts/tegra-seaboard.dts
+++ b/arch/arm/boot/dts/tegra-seaboard.dts
@@ -13,6 +13,20 @@
i2c@7000c000 {
clock-frequency = <400000>;
+
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = < 187 0x04 >;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+ };
};
i2c@7000c400 {
@@ -32,6 +46,32 @@
};
};
+ i2s@70002a00 {
+ status = "disable";
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-seaboard",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Seaboard";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1R", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 0>;
+ nvidia,hp-det-gpios = <&gpio 185 0>; /* gpio PX1 */
+ };
+
serial@70006000 {
status = "disable";
};
@@ -93,4 +133,42 @@
gpio-key,wakeup;
};
};
+
+ emc@7000f400 {
+ emc-table@190000 {
+ reg = < 190000 >;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = < 190000 >;
+ nvidia,emc-registers = < 0x0000000c 0x00000026
+ 0x00000009 0x00000003 0x00000004 0x00000004
+ 0x00000002 0x0000000c 0x00000003 0x00000003
+ 0x00000002 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x0000059f
+ 0x00000000 0x00000003 0x00000003 0x00000003
+ 0x00000003 0x00000001 0x0000000b 0x000000c8
+ 0x00000003 0x00000007 0x00000004 0x0000000f
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xa06204ae
+ 0x007dc010 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000 >;
+ };
+
+ emc-table@380000 {
+ reg = < 380000 >;
+ compatible = "nvidia,tegra20-emc-table";
+ clock-frequency = < 380000 >;
+ nvidia,emc-registers = < 0x00000017 0x0000004b
+ 0x00000012 0x00000006 0x00000004 0x00000005
+ 0x00000003 0x0000000c 0x00000006 0x00000006
+ 0x00000003 0x00000001 0x00000004 0x00000005
+ 0x00000004 0x00000009 0x0000000d 0x00000b5f
+ 0x00000000 0x00000003 0x00000003 0x00000006
+ 0x00000006 0x00000001 0x00000011 0x000000c8
+ 0x00000003 0x0000000e 0x00000007 0x0000000f
+ 0x00000002 0x00000000 0x00000000 0x00000002
+ 0x00000000 0x00000000 0x00000083 0xe044048b
+ 0x007d8010 0x00000000 0x00000000 0x00000000
+ 0x00000000 0x00000000 0x00000000 0x00000000 >;
+ };
+ };
};
diff --git a/arch/arm/boot/dts/tegra-trimslice.dts b/arch/arm/boot/dts/tegra-trimslice.dts
index 3b3ee7db99f..252476867b5 100644
--- a/arch/arm/boot/dts/tegra-trimslice.dts
+++ b/arch/arm/boot/dts/tegra-trimslice.dts
@@ -26,6 +26,18 @@
status = "disable";
};
+ i2s@70002800 {
+ status = "disable";
+ };
+
+ i2s@70002a00 {
+ status = "disable";
+ };
+
+ das@70000c00 {
+ status = "disable";
+ };
+
serial@70006000 {
clock-frequency = < 216000000 >;
};
diff --git a/arch/arm/boot/dts/tegra-ventana.dts b/arch/arm/boot/dts/tegra-ventana.dts
index c7d3b87f29d..2dcff8728e9 100644
--- a/arch/arm/boot/dts/tegra-ventana.dts
+++ b/arch/arm/boot/dts/tegra-ventana.dts
@@ -12,6 +12,20 @@
i2c@7000c000 {
clock-frequency = <400000>;
+
+ wm8903: wm8903@1a {
+ compatible = "wlf,wm8903";
+ reg = <0x1a>;
+ interrupt-parent = <&gpio>;
+ interrupts = < 187 0x04 >;
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ micdet-cfg = <0>;
+ micdet-delay = <100>;
+ gpio-cfg = < 0xffffffff 0xffffffff 0 0xffffffff 0xffffffff >;
+ };
};
i2c@7000c400 {
@@ -26,6 +40,34 @@
clock-frequency = <400000>;
};
+ i2s@70002a00 {
+ status = "disable";
+ };
+
+ sound {
+ compatible = "nvidia,tegra-audio-wm8903-ventana",
+ "nvidia,tegra-audio-wm8903";
+ nvidia,model = "NVIDIA Tegra Ventana";
+
+ nvidia,audio-routing =
+ "Headphone Jack", "HPOUTR",
+ "Headphone Jack", "HPOUTL",
+ "Int Spk", "ROP",
+ "Int Spk", "RON",
+ "Int Spk", "LOP",
+ "Int Spk", "LON",
+ "Mic Jack", "MICBIAS",
+ "IN1L", "Mic Jack";
+
+ nvidia,i2s-controller = <&tegra_i2s1>;
+ nvidia,audio-codec = <&wm8903>;
+
+ nvidia,spkr-en-gpios = <&wm8903 2 0>;
+ nvidia,hp-det-gpios = <&gpio 178 0>; /* gpio PW2 */
+ nvidia,int-mic-en-gpios = <&gpio 184 0>; /*gpio PX0 */
+ nvidia,ext-mic-en-gpios = <&gpio 185 0>; /* gpio PX1 */
+ };
+
serial@70006000 {
status = "disable";
};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 3da7afd4532..ec1f0101c79 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -4,6 +4,11 @@
compatible = "nvidia,tegra20";
interrupt-parent = <&intc>;
+ pmc@7000f400 {
+ compatible = "nvidia,tegra20-pmc";
+ reg = <0x7000e400 0x400>;
+ };
+
intc: interrupt-controller@50041000 {
compatible = "arm,cortex-a9-gic";
interrupt-controller;
@@ -12,6 +17,27 @@
< 0x50040100 0x0100 >;
};
+ apbdma: dma@6000a000 {
+ compatible = "nvidia,tegra20-apbdma";
+ reg = <0x6000a000 0x1200>;
+ interrupts = < 0 104 0x04
+ 0 105 0x04
+ 0 106 0x04
+ 0 107 0x04
+ 0 108 0x04
+ 0 109 0x04
+ 0 110 0x04
+ 0 111 0x04
+ 0 112 0x04
+ 0 113 0x04
+ 0 114 0x04
+ 0 115 0x04
+ 0 116 0x04
+ 0 117 0x04
+ 0 118 0x04
+ 0 119 0x04 >;
+ };
+
i2c@7000c000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -44,18 +70,18 @@
interrupts = < 0 53 0x04 >;
};
- i2s@70002800 {
+ tegra_i2s1: i2s@70002800 {
compatible = "nvidia,tegra20-i2s";
reg = <0x70002800 0x200>;
interrupts = < 0 13 0x04 >;
- dma-channel = < 2 >;
+ nvidia,dma-request-selector = < &apbdma 2 >;
};
- i2s@70002a00 {
+ tegra_i2s2: i2s@70002a00 {
compatible = "nvidia,tegra20-i2s";
reg = <0x70002a00 0x200>;
interrupts = < 0 3 0x04 >;
- dma-channel = < 1 >;
+ nvidia,dma-request-selector = < &apbdma 1 >;
};
das@70000c00 {
@@ -75,6 +101,8 @@
0 89 0x04 >;
#gpio-cells = <2>;
gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
};
pinmux: pinmux@70000000 {
@@ -120,6 +148,13 @@
interrupts = < 0 91 0x04 >;
};
+ emc@7000f400 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "nvidia,tegra20-emc";
+ reg = <0x7000f400 0x200>;
+ };
+
sdhci@c8000000 {
compatible = "nvidia,tegra20-sdhci";
reg = <0xc8000000 0x200>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index ee7db9892e0..ac4b75cb26c 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -4,6 +4,11 @@
compatible = "nvidia,tegra30";
interrupt-parent = <&intc>;
+ pmc@7000f400 {
+ compatible = "nvidia,tegra20-pmc", "nvidia,tegra30-pmc";
+ reg = <0x7000e400 0x400>;
+ };
+
intc: interrupt-controller@50041000 {
compatible = "arm,cortex-a9-gic";
interrupt-controller;
@@ -12,6 +17,43 @@
< 0x50040100 0x0100 >;
};
+ apbdma: dma@6000a000 {
+ compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
+ reg = <0x6000a000 0x1400>;
+ interrupts = < 0 104 0x04
+ 0 105 0x04
+ 0 106 0x04
+ 0 107 0x04
+ 0 108 0x04
+ 0 109 0x04
+ 0 110 0x04
+ 0 111 0x04
+ 0 112 0x04
+ 0 113 0x04
+ 0 114 0x04
+ 0 115 0x04
+ 0 116 0x04
+ 0 117 0x04
+ 0 118 0x04
+ 0 119 0x04
+ 0 128 0x04
+ 0 129 0x04
+ 0 130 0x04
+ 0 131 0x04
+ 0 132 0x04
+ 0 133 0x04
+ 0 134 0x04
+ 0 135 0x04
+ 0 136 0x04
+ 0 137 0x04
+ 0 138 0x04
+ 0 139 0x04
+ 0 140 0x04
+ 0 141 0x04
+ 0 142 0x04
+ 0 143 0x04 >;
+ };
+
i2c@7000c000 {
#address-cells = <1>;
#size-cells = <0>;
@@ -55,9 +97,18 @@
gpio: gpio@6000d000 {
compatible = "nvidia,tegra30-gpio", "nvidia,tegra20-gpio";
reg = < 0x6000d000 0x1000 >;
- interrupts = < 0 32 0x04 0 33 0x04 0 34 0x04 0 35 0x04 0 55 0x04 0 87 0x04 0 89 0x04 >;
+ interrupts = < 0 32 0x04
+ 0 33 0x04
+ 0 34 0x04
+ 0 35 0x04
+ 0 55 0x04
+ 0 87 0x04
+ 0 89 0x04
+ 0 125 0x04 >;
#gpio-cells = <2>;
gpio-controller;
+ #interrupt-cells = <2>;
+ interrupt-controller;
};
serial@70006000 {
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index c47d6199b78..f0783be1735 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -51,7 +51,6 @@ union gic_base {
};
struct gic_chip_data {
- unsigned int irq_offset;
union gic_base dist_base;
union gic_base cpu_base;
#ifdef CONFIG_CPU_PM
@@ -61,9 +60,7 @@ struct gic_chip_data {
u32 __percpu *saved_ppi_enable;
u32 __percpu *saved_ppi_conf;
#endif
-#ifdef CONFIG_IRQ_DOMAIN
- struct irq_domain domain;
-#endif
+ struct irq_domain *domain;
unsigned int gic_irqs;
#ifdef CONFIG_GIC_NON_BANKED
void __iomem *(*get_base)(union gic_base *);
@@ -282,7 +279,7 @@ asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
irqnr = irqstat & ~0x1c00;
if (likely(irqnr > 15 && irqnr < 1021)) {
- irqnr = irq_domain_to_irq(&gic->domain, irqnr);
+ irqnr = irq_find_mapping(gic->domain, irqnr);
handle_IRQ(irqnr, regs);
continue;
}
@@ -314,8 +311,8 @@ static void gic_handle_cascade_irq(unsigned int irq, struct irq_desc *desc)
if (gic_irq == 1023)
goto out;
- cascade_irq = irq_domain_to_irq(&chip_data->domain, gic_irq);
- if (unlikely(gic_irq < 32 || gic_irq > 1020 || cascade_irq >= NR_IRQS))
+ cascade_irq = irq_find_mapping(chip_data->domain, gic_irq);
+ if (unlikely(gic_irq < 32 || gic_irq > 1020))
do_bad_IRQ(cascade_irq, desc);
else
generic_handle_irq(cascade_irq);
@@ -348,10 +345,9 @@ void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
static void __init gic_dist_init(struct gic_chip_data *gic)
{
- unsigned int i, irq;
+ unsigned int i;
u32 cpumask;
unsigned int gic_irqs = gic->gic_irqs;
- struct irq_domain *domain = &gic->domain;
void __iomem *base = gic_data_dist_base(gic);
u32 cpu = cpu_logical_map(smp_processor_id());
@@ -386,23 +382,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic)
for (i = 32; i < gic_irqs; i += 32)
writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32);
- /*
- * Setup the Linux IRQ subsystem.
- */
- irq_domain_for_each_irq(domain, i, irq) {
- if (i < 32) {
- irq_set_percpu_devid(irq);
- irq_set_chip_and_handler(irq, &gic_chip,
- handle_percpu_devid_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
- } else {
- irq_set_chip_and_handler(irq, &gic_chip,
- handle_fasteoi_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
- }
- irq_set_chip_data(irq, gic);
- }
-
writel_relaxed(1, base + GIC_DIST_CTRL);
}
@@ -618,11 +597,27 @@ static void __init gic_pm_init(struct gic_chip_data *gic)
}
#endif
-#ifdef CONFIG_OF
-static int gic_irq_domain_dt_translate(struct irq_domain *d,
- struct device_node *controller,
- const u32 *intspec, unsigned int intsize,
- unsigned long *out_hwirq, unsigned int *out_type)
+static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hw)
+{
+ if (hw < 32) {
+ irq_set_percpu_devid(irq);
+ irq_set_chip_and_handler(irq, &gic_chip,
+ handle_percpu_devid_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN);
+ } else {
+ irq_set_chip_and_handler(irq, &gic_chip,
+ handle_fasteoi_irq);
+ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
+ }
+ irq_set_chip_data(irq, d->host_data);
+ return 0;
+}
+
+static int gic_irq_domain_xlate(struct irq_domain *d,
+ struct device_node *controller,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq, unsigned int *out_type)
{
if (d->of_node != controller)
return -EINVAL;
@@ -639,26 +634,23 @@ static int gic_irq_domain_dt_translate(struct irq_domain *d,
*out_type = intspec[2] & IRQ_TYPE_SENSE_MASK;
return 0;
}
-#endif
const struct irq_domain_ops gic_irq_domain_ops = {
-#ifdef CONFIG_OF
- .dt_translate = gic_irq_domain_dt_translate,
-#endif
+ .map = gic_irq_domain_map,
+ .xlate = gic_irq_domain_xlate,
};
void __init gic_init_bases(unsigned int gic_nr, int irq_start,
void __iomem *dist_base, void __iomem *cpu_base,
- u32 percpu_offset)
+ u32 percpu_offset, struct device_node *node)
{
+ irq_hw_number_t hwirq_base;
struct gic_chip_data *gic;
- struct irq_domain *domain;
- int gic_irqs;
+ int gic_irqs, irq_base;
BUG_ON(gic_nr >= MAX_GIC_NR);
gic = &gic_data[gic_nr];
- domain = &gic->domain;
#ifdef CONFIG_GIC_NON_BANKED
if (percpu_offset) { /* Frankein-GIC without banked registers... */
unsigned int cpu;
@@ -694,10 +686,10 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
* For primary GICs, skip over SGIs.
* For secondary GICs, skip over PPIs, too.
*/
- domain->hwirq_base = 32;
+ hwirq_base = 32;
if (gic_nr == 0) {
if ((irq_start & 31) > 0) {
- domain->hwirq_base = 16;
+ hwirq_base = 16;
if (irq_start != -1)
irq_start = (irq_start & ~31) + 16;
}
@@ -713,17 +705,17 @@ void __init gic_init_bases(unsigned int gic_nr, int irq_start,
gic_irqs = 1020;
gic->gic_irqs = gic_irqs;
- domain->nr_irq = gic_irqs - domain->hwirq_base;
- domain->irq_base = irq_alloc_descs(irq_start, 16, domain->nr_irq,
- numa_node_id());
- if (IS_ERR_VALUE(domain->irq_base)) {
+ gic_irqs -= hwirq_base; /* calculate # of irqs to allocate */
+ irq_base = irq_alloc_descs(irq_start, 16, gic_irqs, numa_node_id());
+ if (IS_ERR_VALUE(irq_base)) {
WARN(1, "Cannot allocate irq_descs @ IRQ%d, assuming pre-allocated\n",
irq_start);
- domain->irq_base = irq_start;
+ irq_base = irq_start;
}
- domain->priv = gic;
- domain->ops = &gic_irq_domain_ops;
- irq_domain_add(domain);
+ gic->domain = irq_domain_add_legacy(node, gic_irqs, irq_base,
+ hwirq_base, &gic_irq_domain_ops, gic);
+ if (WARN_ON(!gic->domain))
+ return;
gic_chip.flags |= gic_arch_extn.flags;
gic_dist_init(gic);
@@ -768,7 +760,6 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
void __iomem *dist_base;
u32 percpu_offset;
int irq;
- struct irq_domain *domain = &gic_data[gic_cnt].domain;
if (WARN_ON(!node))
return -ENODEV;
@@ -782,9 +773,7 @@ int __init gic_of_init(struct device_node *node, struct device_node *parent)
if (of_property_read_u32(node, "cpu-offset", &percpu_offset))
percpu_offset = 0;
- domain->of_node = of_node_get(node);
-
- gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset);
+ gic_init_bases(gic_cnt, -1, dist_base, cpu_base, percpu_offset, node);
if (parent) {
irq = irq_of_parse_and_map(node, 0);
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c
index d1bcd7b13eb..fb1f1cfce60 100644
--- a/arch/arm/common/it8152.c
+++ b/arch/arm/common/it8152.c
@@ -320,13 +320,6 @@ err0:
return -EBUSY;
}
-/*
- * If we set up a device for bus mastering, we need to check the latency
- * timer as we don't have even crappy BIOSes to set it properly.
- * The implementation is from arch/i386/pci/i386.c
- */
-unsigned int pcibios_max_latency = 255;
-
/* ITE bridge requires setting latency timer to avoid early bus access
termination by PCI bus master devices
*/
diff --git a/arch/arm/common/pl330.c b/arch/arm/common/pl330.c
index d8e44a43047..ff3ad224482 100644
--- a/arch/arm/common/pl330.c
+++ b/arch/arm/common/pl330.c
@@ -1502,12 +1502,13 @@ int pl330_chan_ctrl(void *ch_id, enum pl330_chan_op op)
struct pl330_thread *thrd = ch_id;
struct pl330_dmac *pl330;
unsigned long flags;
- int ret = 0, active = thrd->req_running;
+ int ret = 0, active;
if (!thrd || thrd->free || thrd->dmac->state == DYING)
return -EINVAL;
pl330 = thrd->dmac;
+ active = thrd->req_running;
spin_lock_irqsave(&pl330->lock, flags);
diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c
index dcb004a804c..7a66311f306 100644
--- a/arch/arm/common/vic.c
+++ b/arch/arm/common/vic.c
@@ -56,7 +56,7 @@ struct vic_device {
u32 int_enable;
u32 soft_int;
u32 protect;
- struct irq_domain domain;
+ struct irq_domain *domain;
};
/* we cannot allocate memory when VICs are initially registered */
@@ -192,14 +192,8 @@ static void __init vic_register(void __iomem *base, unsigned int irq,
v->resume_sources = resume_sources;
v->irq = irq;
vic_id++;
-
- v->domain.irq_base = irq;
- v->domain.nr_irq = 32;
-#ifdef CONFIG_OF_IRQ
- v->domain.of_node = of_node_get(node);
-#endif /* CONFIG_OF */
- v->domain.ops = &irq_domain_simple_ops;
- irq_domain_add(&v->domain);
+ v->domain = irq_domain_add_legacy(node, 32, irq, 0,
+ &irq_domain_simple_ops, v);
}
static void vic_ack_irq(struct irq_data *d)
@@ -348,7 +342,7 @@ static void __init vic_init_st(void __iomem *base, unsigned int irq_start,
vic_register(base, irq_start, 0, node);
}
-static void __init __vic_init(void __iomem *base, unsigned int irq_start,
+void __init __vic_init(void __iomem *base, unsigned int irq_start,
u32 vic_sources, u32 resume_sources,
struct device_node *node)
{
@@ -444,7 +438,7 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
stat = readl_relaxed(vic->base + VIC_IRQ_STATUS);
while (stat) {
irq = ffs(stat) - 1;
- handle_IRQ(irq_domain_to_irq(&vic->domain, irq), regs);
+ handle_IRQ(irq_find_mapping(vic->domain, irq), regs);
stat &= ~(1 << irq);
handled = 1;
}
diff --git a/arch/arm/configs/at91cap9_defconfig b/arch/arm/configs/at91cap9_defconfig
deleted file mode 100644
index 8826eb218e7..00000000000
--- a/arch/arm/configs/at91cap9_defconfig
+++ /dev/null
@@ -1,108 +0,0 @@
-CONFIG_EXPERIMENTAL=y
-# CONFIG_LOCALVERSION_AUTO is not set
-# CONFIG_SWAP is not set
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_AT91=y
-CONFIG_ARCH_AT91CAP9=y
-CONFIG_MACH_AT91CAP9ADK=y
-CONFIG_MTD_AT91_DATAFLASH_CARD=y
-CONFIG_AT91_PROGRAMMABLE_CLOCKS=y
-# CONFIG_ARM_THUMB is not set
-CONFIG_AEABI=y
-CONFIG_LEDS=y
-CONFIG_LEDS_CPU=y
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE="console=ttyS0,115200 root=/dev/ram0 rw"
-CONFIG_FPE_NWFPE=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
-# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
-# CONFIG_IPV6 is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_JEDECPROBE=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_DATAFLASH=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_ATMEL=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=8192
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_SCSI_MULTI_LUN=y
-CONFIG_NETDEVICES=y
-CONFIG_MII=y
-CONFIG_MACB=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ADS7846=y
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_ATMEL=y
-CONFIG_SERIAL_ATMEL_CONSOLE=y
-CONFIG_HW_RANDOM=y
-CONFIG_I2C=y
-CONFIG_I2C_CHARDEV=y
-CONFIG_SPI=y
-CONFIG_SPI_ATMEL=y
-# CONFIG_HWMON is not set
-CONFIG_WATCHDOG=y
-CONFIG_WATCHDOG_NOWAYOUT=y
-CONFIG_FB=y
-CONFIG_FB_ATMEL=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-# CONFIG_USB_HID is not set
-CONFIG_USB=y
-CONFIG_USB_DEVICEFS=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_ETH=m
-CONFIG_USB_FILE_STORAGE=m
-CONFIG_MMC=y
-CONFIG_MMC_AT91=m
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AT91SAM9=y
-CONFIG_EXT2_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_CRAMFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_DEBUG_FS=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_USER=y
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig
index a22e9307906..d9eddfd7742 100644
--- a/arch/arm/configs/imx_v4_v5_defconfig
+++ b/arch/arm/configs/imx_v4_v5_defconfig
@@ -45,6 +45,7 @@ CONFIG_FPE_NWFPE=y
CONFIG_FPE_NWFPE_XP=y
CONFIG_PM_DEBUG=y
CONFIG_NET=y
+CONFIG_SMSC911X=y
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
@@ -78,6 +79,8 @@ CONFIG_MISC_DEVICES=y
CONFIG_EEPROM_AT24=y
CONFIG_EEPROM_AT25=y
CONFIG_NETDEVICES=y
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
CONFIG_DM9000=y
CONFIG_SMC91X=y
CONFIG_SMC911X=y
@@ -115,6 +118,21 @@ CONFIG_FB_IMX=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_MEDIA=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF_DMA_CONTIG=y
+CONFIG_VIDEOBUF2_CORE=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_VIDEO_MX2_HOSTSUPPORT=y
+CONFIG_VIDEO_MX2=y
CONFIG_BACKLIGHT_PWM=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FONTS=y
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig
index 3a4fb2e5fc6..6ae457aeea4 100644
--- a/arch/arm/configs/imx_v6_v7_defconfig
+++ b/arch/arm/configs/imx_v6_v7_defconfig
@@ -26,7 +26,6 @@ CONFIG_MACH_ARMADILLO5X0=y
CONFIG_MACH_KZM_ARM11_01=y
CONFIG_MACH_PCM043=y
CONFIG_MACH_MX35_3DS=y
-CONFIG_MACH_EUKREA_CPUIMX35=y
CONFIG_MACH_VPR200=y
CONFIG_MACH_IMX51_DT=y
CONFIG_MACH_MX51_3DS=y
@@ -82,8 +81,9 @@ CONFIG_PATA_IMX=y
CONFIG_NETDEVICES=y
# CONFIG_NET_VENDOR_BROADCOM is not set
# CONFIG_NET_VENDOR_CHELSIO is not set
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
# CONFIG_NET_VENDOR_FARADAY is not set
-CONFIG_FEC=y
# CONFIG_NET_VENDOR_INTEL is not set
# CONFIG_NET_VENDOR_MARVELL is not set
# CONFIG_NET_VENDOR_MICREL is not set
@@ -126,7 +126,39 @@ CONFIG_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_MFD_MC13XXX=y
CONFIG_REGULATOR=y
+CONFIG_REGULATOR_MC13783=y
CONFIG_REGULATOR_MC13892=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEOBUF_GEN=y
+CONFIG_VIDEOBUF2_CORE=y
+CONFIG_VIDEOBUF2_MEMOPS=y
+CONFIG_VIDEOBUF2_DMA_CONTIG=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_OV2640=y
+CONFIG_MX3_VIDEO=y
+CONFIG_VIDEO_MX3=y
+CONFIG_FB=y
+CONFIG_FB_MX3=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_MONO=y
+CONFIG_LOGO_LINUX_VGA16=y
+CONFIG_LOGO_LINUX_CLUT224=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_MXC=y
diff --git a/arch/arm/configs/magician_defconfig b/arch/arm/configs/magician_defconfig
index 443675d317e..a691ef4c600 100644
--- a/arch/arm/configs/magician_defconfig
+++ b/arch/arm/configs/magician_defconfig
@@ -101,7 +101,7 @@ CONFIG_MFD_ASIC3=y
CONFIG_HTC_EGPIO=y
CONFIG_HTC_PASIC3=y
CONFIG_REGULATOR=y
-CONFIG_REGULATOR_BQ24022=y
+CONFIG_REGULATOR_GPIO=y
CONFIG_FB=y
CONFIG_FB_PXA=y
CONFIG_FB_PXA_OVERLAY=y
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
index 62f8095d46d..23371b17b23 100644
--- a/arch/arm/include/asm/assembler.h
+++ b/arch/arm/include/asm/assembler.h
@@ -137,6 +137,11 @@
disable_irq
.endm
+ .macro save_and_disable_irqs_notrace, oldcpsr
+ mrs \oldcpsr, cpsr
+ disable_irq_notrace
+ .endm
+
/*
* Restore interrupt state previously stored in a register. We don't
* guarantee that this will preserve the flags.
diff --git a/arch/arm/include/asm/hardware/gic.h b/arch/arm/include/asm/hardware/gic.h
index 4bdfe001869..4b1ce6cd477 100644
--- a/arch/arm/include/asm/hardware/gic.h
+++ b/arch/arm/include/asm/hardware/gic.h
@@ -39,7 +39,7 @@ struct device_node;
extern struct irq_chip gic_arch_extn;
void gic_init_bases(unsigned int, int, void __iomem *, void __iomem *,
- u32 offset);
+ u32 offset, struct device_node *);
int gic_of_init(struct device_node *node, struct device_node *parent);
void gic_secondary_init(unsigned int);
void gic_handle_irq(struct pt_regs *regs);
@@ -49,7 +49,7 @@ void gic_raise_softirq(const struct cpumask *mask, unsigned int irq);
static inline void gic_init(unsigned int nr, int start,
void __iomem *dist , void __iomem *cpu)
{
- gic_init_bases(nr, start, dist, cpu, 0);
+ gic_init_bases(nr, start, dist, cpu, 0, NULL);
}
#endif
diff --git a/arch/arm/include/asm/hardware/pl330.h b/arch/arm/include/asm/hardware/pl330.h
index 575fa8186ca..c1821385abf 100644
--- a/arch/arm/include/asm/hardware/pl330.h
+++ b/arch/arm/include/asm/hardware/pl330.h
@@ -41,7 +41,7 @@ enum pl330_dstcachectrl {
DCCTRL1, /* Bufferable only */
DCCTRL2, /* Cacheable, but do not allocate */
DCCTRL3, /* Cacheable and bufferable, but do not allocate */
- DINVALID1 = 8,
+ DINVALID1, /* AWCACHE = 0x1000 */
DINVALID2,
DCCTRL6, /* Cacheable write-through, allocate on writes only */
DCCTRL7, /* Cacheable write-back, allocate on writes only */
diff --git a/arch/arm/include/asm/hardware/vic.h b/arch/arm/include/asm/hardware/vic.h
index f42ebd61959..e14af1a1a32 100644
--- a/arch/arm/include/asm/hardware/vic.h
+++ b/arch/arm/include/asm/hardware/vic.h
@@ -47,6 +47,8 @@
struct device_node;
struct pt_regs;
+void __vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources,
+ u32 resume_sources, struct device_node *node);
void vic_init(void __iomem *base, unsigned int irq_start, u32 vic_sources, u32 resume_sources);
int vic_of_init(struct device_node *node, struct device_node *parent);
void vic_handle_irq(struct pt_regs *regs);
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index ce280b8d613..cb8d638924f 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -22,6 +22,7 @@
#include <asm/hw_breakpoint.h>
#include <asm/ptrace.h>
#include <asm/types.h>
+#include <asm/system.h>
#ifdef __KERNEL__
#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index e4c96cc6ec0..424aa458c48 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -110,6 +110,7 @@ extern void cpu_init(void);
void soft_restart(unsigned long);
extern void (*arm_pm_restart)(char str, const char *cmd);
+extern void (*arm_pm_idle)(void);
#define UDBG_UNDEFINED (1 << 0)
#define UDBG_SYSCALL (1 << 1)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 971d65c253a..008e7ce766a 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -61,8 +61,6 @@ extern void setup_mm_for_reboot(void);
static volatile int hlt_counter;
-#include <mach/system.h>
-
void disable_hlt(void)
{
hlt_counter++;
@@ -181,13 +179,17 @@ void cpu_idle_wait(void)
EXPORT_SYMBOL_GPL(cpu_idle_wait);
/*
- * This is our default idle handler. We need to disable
- * interrupts here to ensure we don't miss a wakeup call.
+ * This is our default idle handler.
*/
+
+void (*arm_pm_idle)(void);
+
static void default_idle(void)
{
- if (!need_resched())
- arch_idle();
+ if (arm_pm_idle)
+ arm_pm_idle();
+ else
+ cpu_do_idle();
local_irq_enable();
}
@@ -215,6 +217,10 @@ void cpu_idle(void)
cpu_die();
#endif
+ /*
+ * We need to disable interrupts here
+ * to ensure we don't miss a wakeup call.
+ */
local_irq_disable();
#ifdef CONFIG_PL310_ERRATA_769419
wmb();
@@ -222,19 +228,18 @@ void cpu_idle(void)
if (hlt_counter) {
local_irq_enable();
cpu_relax();
- } else {
+ } else if (!need_resched()) {
stop_critical_timings();
if (cpuidle_idle_call())
pm_idle();
start_critical_timings();
/*
- * This will eventually be removed - pm_idle
- * functions should always return with IRQs
- * enabled.
+ * pm_idle functions must always
+ * return with IRQs enabled.
*/
WARN_ON(irqs_disabled());
+ } else
local_irq_enable();
- }
}
leds_event(led_idle_end);
rcu_idle_exit();
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index e33870ff0ac..ede6443c34d 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -23,6 +23,7 @@
#include <linux/perf_event.h>
#include <linux/hw_breakpoint.h>
#include <linux/regset.h>
+#include <linux/audit.h>
#include <asm/pgtable.h>
#include <asm/system.h>
@@ -904,6 +905,12 @@ long arch_ptrace(struct task_struct *child, long request,
return ret;
}
+#ifdef __ARMEB__
+#define AUDIT_ARCH_NR AUDIT_ARCH_ARMEB
+#else
+#define AUDIT_ARCH_NR AUDIT_ARCH_ARM
+#endif
+
asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
{
unsigned long ip;
@@ -918,7 +925,7 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
if (!ip)
audit_syscall_exit(regs);
else
- audit_syscall_entry(AUDIT_ARCH_ARMEB, scno, regs->ARM_r0,
+ audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0,
regs->ARM_r1, regs->ARM_r2, regs->ARM_r3);
if (!test_thread_flag(TIF_SYSCALL_TRACE))
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c
index 4285daa077b..7a79b24597b 100644
--- a/arch/arm/kernel/smp_twd.c
+++ b/arch/arm/kernel/smp_twd.c
@@ -129,7 +129,7 @@ static struct notifier_block twd_cpufreq_nb = {
static int twd_cpufreq_init(void)
{
- if (!IS_ERR(twd_clk))
+ if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
return cpufreq_register_notifier(&twd_cpufreq_nb,
CPUFREQ_TRANSITION_NOTIFIER);
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 71feb00a1e9..0284e66c47f 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -102,15 +102,6 @@ config ARCH_AT91SAM9G45
select HAVE_AT91_DBGU1
select AT91_SAM9G45_RESET
-config ARCH_AT91CAP9
- bool "AT91CAP9"
- select CPU_ARM926T
- select GENERIC_CLOCKEVENTS
- select HAVE_FB_ATMEL
- select HAVE_NET_MACB
- select HAVE_AT91_DBGU1
- select AT91_SAM9G45_RESET
-
config ARCH_AT91X40
bool "AT91x40"
select ARCH_USES_GETTIMEOFFSET
@@ -447,21 +438,6 @@ endif
# ----------------------------------------------------------
-if ARCH_AT91CAP9
-
-comment "AT91CAP9 Board Type"
-
-config MACH_AT91CAP9ADK
- bool "Atmel AT91CAP9A-DK Evaluation Kit"
- select HAVE_AT91_DATAFLASH_CARD
- help
- Select this if you are using Atmel's AT91CAP9A-DK Evaluation Kit.
- <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4138>
-
-endif
-
-# ----------------------------------------------------------
-
if ARCH_AT91X40
comment "AT91X40 Board Type"
@@ -544,7 +520,7 @@ config AT91_EARLY_DBGU0
depends on HAVE_AT91_DBGU0
config AT91_EARLY_DBGU1
- bool "DBGU on 9263, 9g45 and cap9"
+ bool "DBGU on 9263 and 9g45"
depends on HAVE_AT91_DBGU1
config AT91_EARLY_USART0
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 705e1fbded3..aeb76f1690d 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -20,7 +20,6 @@ obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_d
obj-$(CONFIG_ARCH_AT91SAM9RL) += at91sam9rl.o at91sam926x_time.o at91sam9rl_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam926x_time.o at91sam9g45_devices.o sam9_smc.o
-obj-$(CONFIG_ARCH_AT91CAP9) += at91cap9.o at91sam926x_time.o at91cap9_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91X40) += at91x40.o at91x40_time.o
# AT91RM9200 board-specific support
@@ -81,9 +80,6 @@ obj-$(CONFIG_MACH_AT91SAM9M10G45EK) += board-sam9m10g45ek.o
# AT91SAM board with device-tree
obj-$(CONFIG_MACH_AT91SAM_DT) += board-dt.o
-# AT91CAP9 board-specific support
-obj-$(CONFIG_MACH_AT91CAP9ADK) += board-cap9adk.o
-
# AT91X40 board-specific support
obj-$(CONFIG_MACH_AT91EB01) += board-eb01.o
diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index 8ddafadfdc7..2fd051eb244 100644
--- a/arch/arm/mach-at91/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
@@ -3,11 +3,7 @@
# PARAMS_PHYS must be within 4MB of ZRELADDR
# INITRD_PHYS must be in RAM
-ifeq ($(CONFIG_ARCH_AT91CAP9),y)
- zreladdr-y += 0x70008000
-params_phys-y := 0x70000100
-initrd_phys-y := 0x70410000
-else ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
+ifeq ($(CONFIG_ARCH_AT91SAM9G45),y)
zreladdr-y += 0x70008000
params_phys-y := 0x70000100
initrd_phys-y := 0x70410000
diff --git a/arch/arm/mach-at91/at91cap9.c b/arch/arm/mach-at91/at91cap9.c
deleted file mode 100644
index a42edc25a87..00000000000
--- a/arch/arm/mach-at91/at91cap9.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * arch/arm/mach-at91/at91cap9.c
- *
- * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- * Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <linux/module.h>
-
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/cpu.h>
-#include <mach/at91cap9.h>
-#include <mach/at91_pmc.h>
-
-#include "soc.h"
-#include "generic.h"
-#include "clock.h"
-#include "sam9_smc.h"
-
-/* --------------------------------------------------------------------
- * Clocks
- * -------------------------------------------------------------------- */
-
-/*
- * The peripheral clocks.
- */
-static struct clk pioABCD_clk = {
- .name = "pioABCD_clk",
- .pmc_mask = 1 << AT91CAP9_ID_PIOABCD,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb0_clk = {
- .name = "mpb0_clk",
- .pmc_mask = 1 << AT91CAP9_ID_MPB0,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb1_clk = {
- .name = "mpb1_clk",
- .pmc_mask = 1 << AT91CAP9_ID_MPB1,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb2_clk = {
- .name = "mpb2_clk",
- .pmc_mask = 1 << AT91CAP9_ID_MPB2,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb3_clk = {
- .name = "mpb3_clk",
- .pmc_mask = 1 << AT91CAP9_ID_MPB3,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mpb4_clk = {
- .name = "mpb4_clk",
- .pmc_mask = 1 << AT91CAP9_ID_MPB4,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart0_clk = {
- .name = "usart0_clk",
- .pmc_mask = 1 << AT91CAP9_ID_US0,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart1_clk = {
- .name = "usart1_clk",
- .pmc_mask = 1 << AT91CAP9_ID_US1,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk usart2_clk = {
- .name = "usart2_clk",
- .pmc_mask = 1 << AT91CAP9_ID_US2,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mmc0_clk = {
- .name = "mci0_clk",
- .pmc_mask = 1 << AT91CAP9_ID_MCI0,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk mmc1_clk = {
- .name = "mci1_clk",
- .pmc_mask = 1 << AT91CAP9_ID_MCI1,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk can_clk = {
- .name = "can_clk",
- .pmc_mask = 1 << AT91CAP9_ID_CAN,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk twi_clk = {
- .name = "twi_clk",
- .pmc_mask = 1 << AT91CAP9_ID_TWI,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk spi0_clk = {
- .name = "spi0_clk",
- .pmc_mask = 1 << AT91CAP9_ID_SPI0,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk spi1_clk = {
- .name = "spi1_clk",
- .pmc_mask = 1 << AT91CAP9_ID_SPI1,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk ssc0_clk = {
- .name = "ssc0_clk",
- .pmc_mask = 1 << AT91CAP9_ID_SSC0,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk ssc1_clk = {
- .name = "ssc1_clk",
- .pmc_mask = 1 << AT91CAP9_ID_SSC1,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk ac97_clk = {
- .name = "ac97_clk",
- .pmc_mask = 1 << AT91CAP9_ID_AC97C,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk tcb_clk = {
- .name = "tcb_clk",
- .pmc_mask = 1 << AT91CAP9_ID_TCB,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk pwm_clk = {
- .name = "pwm_clk",
- .pmc_mask = 1 << AT91CAP9_ID_PWMC,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk macb_clk = {
- .name = "pclk",
- .pmc_mask = 1 << AT91CAP9_ID_EMAC,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk aestdes_clk = {
- .name = "aestdes_clk",
- .pmc_mask = 1 << AT91CAP9_ID_AESTDES,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk adc_clk = {
- .name = "adc_clk",
- .pmc_mask = 1 << AT91CAP9_ID_ADC,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk isi_clk = {
- .name = "isi_clk",
- .pmc_mask = 1 << AT91CAP9_ID_ISI,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk lcdc_clk = {
- .name = "lcdc_clk",
- .pmc_mask = 1 << AT91CAP9_ID_LCDC,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk dma_clk = {
- .name = "dma_clk",
- .pmc_mask = 1 << AT91CAP9_ID_DMA,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk udphs_clk = {
- .name = "udphs_clk",
- .pmc_mask = 1 << AT91CAP9_ID_UDPHS,
- .type = CLK_TYPE_PERIPHERAL,
-};
-static struct clk ohci_clk = {
- .name = "ohci_clk",
- .pmc_mask = 1 << AT91CAP9_ID_UHP,
- .type = CLK_TYPE_PERIPHERAL,
-};
-
-static struct clk *periph_clocks[] __initdata = {
- &pioABCD_clk,
- &mpb0_clk,
- &mpb1_clk,
- &mpb2_clk,
- &mpb3_clk,
- &mpb4_clk,
- &usart0_clk,
- &usart1_clk,
- &usart2_clk,
- &mmc0_clk,
- &mmc1_clk,
- &can_clk,
- &twi_clk,
- &spi0_clk,
- &spi1_clk,
- &ssc0_clk,
- &ssc1_clk,
- &ac97_clk,
- &tcb_clk,
- &pwm_clk,
- &macb_clk,
- &aestdes_clk,
- &adc_clk,
- &isi_clk,
- &lcdc_clk,
- &dma_clk,
- &udphs_clk,
- &ohci_clk,
- // irq0 .. irq1
-};
-
-static struct clk_lookup periph_clocks_lookups[] = {
- /* One additional fake clock for macb_hclk */
- CLKDEV_CON_ID("hclk", &macb_clk),
- CLKDEV_CON_DEV_ID("hclk", "atmel_usba_udc", &utmi_clk),
- CLKDEV_CON_DEV_ID("pclk", "atmel_usba_udc", &udphs_clk),
- CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.0", &mmc0_clk),
- CLKDEV_CON_DEV_ID("mci_clk", "at91_mci.1", &mmc1_clk),
- CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.0", &spi0_clk),
- CLKDEV_CON_DEV_ID("spi_clk", "atmel_spi.1", &spi1_clk),
- CLKDEV_CON_DEV_ID("t0_clk", "atmel_tcb.0", &tcb_clk),
- CLKDEV_CON_DEV_ID("pclk", "ssc.0", &ssc0_clk),
- CLKDEV_CON_DEV_ID("pclk", "ssc.1", &ssc1_clk),
- /* fake hclk clock */
- CLKDEV_CON_DEV_ID("hclk", "at91_ohci", &ohci_clk),
- CLKDEV_CON_ID("pioA", &pioABCD_clk),
- CLKDEV_CON_ID("pioB", &pioABCD_clk),
- CLKDEV_CON_ID("pioC", &pioABCD_clk),
- CLKDEV_CON_ID("pioD", &pioABCD_clk),
-};
-
-static struct clk_lookup usart_clocks_lookups[] = {
- CLKDEV_CON_DEV_ID("usart", "atmel_usart.0", &mck),
- CLKDEV_CON_DEV_ID("usart", "atmel_usart.1", &usart0_clk),
- CLKDEV_CON_DEV_ID("usart", "atmel_usart.2", &usart1_clk),
- CLKDEV_CON_DEV_ID("usart", "atmel_usart.3", &usart2_clk),
-};
-
-/*
- * The four programmable clocks.
- * You must configure pin multiplexing to bring these signals out.
- */
-static struct clk pck0 = {
- .name = "pck0",
- .pmc_mask = AT91_PMC_PCK0,
- .type = CLK_TYPE_PROGRAMMABLE,
- .id = 0,
-};
-static struct clk pck1 = {
- .name = "pck1",
- .pmc_mask = AT91_PMC_PCK1,
- .type = CLK_TYPE_PROGRAMMABLE,
- .id = 1,
-};
-static struct clk pck2 = {
- .name = "pck2",
- .pmc_mask = AT91_PMC_PCK2,
- .type = CLK_TYPE_PROGRAMMABLE,
- .id = 2,
-};
-static struct clk pck3 = {
- .name = "pck3",
- .pmc_mask = AT91_PMC_PCK3,
- .type = CLK_TYPE_PROGRAMMABLE,
- .id = 3,
-};
-
-static void __init at91cap9_register_clocks(void)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
- clk_register(periph_clocks[i]);
-
- clkdev_add_table(periph_clocks_lookups,
- ARRAY_SIZE(periph_clocks_lookups));
- clkdev_add_table(usart_clocks_lookups,
- ARRAY_SIZE(usart_clocks_lookups));
-
- clk_register(&pck0);
- clk_register(&pck1);
- clk_register(&pck2);
- clk_register(&pck3);
-}
-
-static struct clk_lookup console_clock_lookup;
-
-void __init at91cap9_set_console_clock(int id)
-{
- if (id >= ARRAY_SIZE(usart_clocks_lookups))
- return;
-
- console_clock_lookup.con_id = "usart";
- console_clock_lookup.clk = usart_clocks_lookups[id].clk;
- clkdev_add(&console_clock_lookup);
-}
-
-/* --------------------------------------------------------------------
- * GPIO
- * -------------------------------------------------------------------- */
-
-static struct at91_gpio_bank at91cap9_gpio[] __initdata = {
- {
- .id = AT91CAP9_ID_PIOABCD,
- .regbase = AT91CAP9_BASE_PIOA,
- }, {
- .id = AT91CAP9_ID_PIOABCD,
- .regbase = AT91CAP9_BASE_PIOB,
- }, {
- .id = AT91CAP9_ID_PIOABCD,
- .regbase = AT91CAP9_BASE_PIOC,
- }, {
- .id = AT91CAP9_ID_PIOABCD,
- .regbase = AT91CAP9_BASE_PIOD,
- }
-};
-
-/* --------------------------------------------------------------------
- * AT91CAP9 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91cap9_map_io(void)
-{
- at91_init_sram(0, AT91CAP9_SRAM_BASE, AT91CAP9_SRAM_SIZE);
-}
-
-static void __init at91cap9_ioremap_registers(void)
-{
- at91_ioremap_shdwc(AT91CAP9_BASE_SHDWC);
- at91_ioremap_rstc(AT91CAP9_BASE_RSTC);
- at91sam926x_ioremap_pit(AT91CAP9_BASE_PIT);
- at91sam9_ioremap_smc(0, AT91CAP9_BASE_SMC);
-}
-
-static void __init at91cap9_initialize(void)
-{
- arm_pm_restart = at91sam9g45_restart;
- at91_extern_irq = (1 << AT91CAP9_ID_IRQ0) | (1 << AT91CAP9_ID_IRQ1);
-
- /* Register GPIO subsystem */
- at91_gpio_init(at91cap9_gpio, 4);
-
- /* Remember the silicon revision */
- if (cpu_is_at91cap9_revB())
- system_rev = 0xB;
- else if (cpu_is_at91cap9_revC())
- system_rev = 0xC;
-}
-
-/* --------------------------------------------------------------------
- * Interrupt initialization
- * -------------------------------------------------------------------- */
-
-/*
- * The default interrupt priority levels (0 = lowest, 7 = highest).
- */
-static unsigned int at91cap9_default_irq_priority[NR_AIC_IRQS] __initdata = {
- 7, /* Advanced Interrupt Controller (FIQ) */
- 7, /* System Peripherals */
- 1, /* Parallel IO Controller A, B, C and D */
- 0, /* MP Block Peripheral 0 */
- 0, /* MP Block Peripheral 1 */
- 0, /* MP Block Peripheral 2 */
- 0, /* MP Block Peripheral 3 */
- 0, /* MP Block Peripheral 4 */
- 5, /* USART 0 */
- 5, /* USART 1 */
- 5, /* USART 2 */
- 0, /* Multimedia Card Interface 0 */
- 0, /* Multimedia Card Interface 1 */
- 3, /* CAN */
- 6, /* Two-Wire Interface */
- 5, /* Serial Peripheral Interface 0 */
- 5, /* Serial Peripheral Interface 1 */
- 4, /* Serial Synchronous Controller 0 */
- 4, /* Serial Synchronous Controller 1 */
- 5, /* AC97 Controller */
- 0, /* Timer Counter 0, 1 and 2 */
- 0, /* Pulse Width Modulation Controller */
- 3, /* Ethernet */
- 0, /* Advanced Encryption Standard, Triple DES*/
- 0, /* Analog-to-Digital Converter */
- 0, /* Image Sensor Interface */
- 3, /* LCD Controller */
- 0, /* DMA Controller */
- 2, /* USB Device Port */
- 2, /* USB Host port */
- 0, /* Advanced Interrupt Controller (IRQ0) */
- 0, /* Advanced Interrupt Controller (IRQ1) */
-};
-
-struct at91_init_soc __initdata at91cap9_soc = {
- .map_io = at91cap9_map_io,
- .default_irq_priority = at91cap9_default_irq_priority,
- .ioremap_registers = at91cap9_ioremap_registers,
- .register_clocks = at91cap9_register_clocks,
- .init = at91cap9_initialize,
-};
diff --git a/arch/arm/mach-at91/at91cap9_devices.c b/arch/arm/mach-at91/at91cap9_devices.c
deleted file mode 100644
index d298fb7cb21..00000000000
--- a/arch/arm/mach-at91/at91cap9_devices.c
+++ /dev/null
@@ -1,1273 +0,0 @@
-/*
- * arch/arm/mach-at91/at91cap9_devices.c
- *
- * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- * Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include <linux/dma-mapping.h>
-#include <linux/gpio.h>
-#include <linux/platform_device.h>
-#include <linux/i2c-gpio.h>
-
-#include <video/atmel_lcdc.h>
-
-#include <mach/board.h>
-#include <mach/cpu.h>
-#include <mach/at91cap9.h>
-#include <mach/at91cap9_matrix.h>
-#include <mach/at91sam9_smc.h>
-
-#include "generic.h"
-
-
-/* --------------------------------------------------------------------
- * USB Host
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
-static u64 ohci_dmamask = DMA_BIT_MASK(32);
-static struct at91_usbh_data usbh_data;
-
-static struct resource usbh_resources[] = {
- [0] = {
- .start = AT91CAP9_UHP_BASE,
- .end = AT91CAP9_UHP_BASE + SZ_1M - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_UHP,
- .end = AT91CAP9_ID_UHP,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91_usbh_device = {
- .name = "at91_ohci",
- .id = -1,
- .dev = {
- .dma_mask = &ohci_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &usbh_data,
- },
- .resource = usbh_resources,
- .num_resources = ARRAY_SIZE(usbh_resources),
-};
-
-void __init at91_add_device_usbh(struct at91_usbh_data *data)
-{
- int i;
-
- if (!data)
- return;
-
- if (cpu_is_at91cap9_revB())
- irq_set_irq_type(AT91CAP9_ID_UHP, IRQ_TYPE_LEVEL_HIGH);
-
- /* Enable VBus control for UHP ports */
- for (i = 0; i < data->ports; i++) {
- if (gpio_is_valid(data->vbus_pin[i]))
- at91_set_gpio_output(data->vbus_pin[i], 0);
- }
-
- /* Enable overcurrent notification */
- for (i = 0; i < data->ports; i++) {
- if (data->overcurrent_pin[i])
- at91_set_gpio_input(data->overcurrent_pin[i], 1);
- }
-
- usbh_data = *data;
- platform_device_register(&at91_usbh_device);
-}
-#else
-void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * USB HS Device (Gadget)
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_USB_ATMEL_USBA) || defined(CONFIG_USB_ATMEL_USBA_MODULE)
-
-static struct resource usba_udc_resources[] = {
- [0] = {
- .start = AT91CAP9_UDPHS_FIFO,
- .end = AT91CAP9_UDPHS_FIFO + SZ_512K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_BASE_UDPHS,
- .end = AT91CAP9_BASE_UDPHS + SZ_1K - 1,
- .flags = IORESOURCE_MEM,
- },
- [2] = {
- .start = AT91CAP9_ID_UDPHS,
- .end = AT91CAP9_ID_UDPHS,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-#define EP(nam, idx, maxpkt, maxbk, dma, isoc) \
- [idx] = { \
- .name = nam, \
- .index = idx, \
- .fifo_size = maxpkt, \
- .nr_banks = maxbk, \
- .can_dma = dma, \
- .can_isoc = isoc, \
- }
-
-static struct usba_ep_data usba_udc_ep[] = {
- EP("ep0", 0, 64, 1, 0, 0),
- EP("ep1", 1, 1024, 3, 1, 1),
- EP("ep2", 2, 1024, 3, 1, 1),
- EP("ep3", 3, 1024, 2, 1, 1),
- EP("ep4", 4, 1024, 2, 1, 1),
- EP("ep5", 5, 1024, 2, 1, 0),
- EP("ep6", 6, 1024, 2, 1, 0),
- EP("ep7", 7, 1024, 2, 0, 0),
-};
-
-#undef EP
-
-/*
- * pdata doesn't have room for any endpoints, so we need to
- * append room for the ones we need right after it.
- */
-static struct {
- struct usba_platform_data pdata;
- struct usba_ep_data ep[8];
-} usba_udc_data;
-
-static struct platform_device at91_usba_udc_device = {
- .name = "atmel_usba_udc",
- .id = -1,
- .dev = {
- .platform_data = &usba_udc_data.pdata,
- },
- .resource = usba_udc_resources,
- .num_resources = ARRAY_SIZE(usba_udc_resources),
-};
-
-void __init at91_add_device_usba(struct usba_platform_data *data)
-{
- if (cpu_is_at91cap9_revB()) {
- 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);
- }
- else
- at91_sys_write(AT91_MATRIX_UDPHS, AT91_MATRIX_SELECT_UDPHS);
-
- /*
- * Invalid pins are 0 on AT91, but the usba driver is shared
- * with AVR32, which use negative values instead. Once/if
- * gpio_is_valid() is ported to AT91, revisit this code.
- */
- usba_udc_data.pdata.vbus_pin = -EINVAL;
- usba_udc_data.pdata.num_ep = ARRAY_SIZE(usba_udc_ep);
- memcpy(usba_udc_data.ep, usba_udc_ep, sizeof(usba_udc_ep));
-
- if (data && gpio_is_valid(data->vbus_pin)) {
- at91_set_gpio_input(data->vbus_pin, 0);
- at91_set_deglitch(data->vbus_pin, 1);
- usba_udc_data.pdata.vbus_pin = data->vbus_pin;
- }
-
- /* Pullup pin is handled internally by USB device peripheral */
-
- platform_device_register(&at91_usba_udc_device);
-}
-#else
-void __init at91_add_device_usba(struct usba_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * Ethernet
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
-static u64 eth_dmamask = DMA_BIT_MASK(32);
-static struct macb_platform_data eth_data;
-
-static struct resource eth_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_EMAC,
- .end = AT91CAP9_BASE_EMAC + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_EMAC,
- .end = AT91CAP9_ID_EMAC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_eth_device = {
- .name = "macb",
- .id = -1,
- .dev = {
- .dma_mask = &eth_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &eth_data,
- },
- .resource = eth_resources,
- .num_resources = ARRAY_SIZE(eth_resources),
-};
-
-void __init at91_add_device_eth(struct macb_platform_data *data)
-{
- if (!data)
- return;
-
- if (gpio_is_valid(data->phy_irq_pin)) {
- at91_set_gpio_input(data->phy_irq_pin, 0);
- at91_set_deglitch(data->phy_irq_pin, 1);
- }
-
- /* Pins used for MII and RMII */
- at91_set_A_periph(AT91_PIN_PB21, 0); /* ETXCK_EREFCK */
- at91_set_A_periph(AT91_PIN_PB22, 0); /* ERXDV */
- at91_set_A_periph(AT91_PIN_PB25, 0); /* ERX0 */
- at91_set_A_periph(AT91_PIN_PB26, 0); /* ERX1 */
- at91_set_A_periph(AT91_PIN_PB27, 0); /* ERXER */
- at91_set_A_periph(AT91_PIN_PB28, 0); /* ETXEN */
- at91_set_A_periph(AT91_PIN_PB23, 0); /* ETX0 */
- at91_set_A_periph(AT91_PIN_PB24, 0); /* ETX1 */
- at91_set_A_periph(AT91_PIN_PB30, 0); /* EMDIO */
- at91_set_A_periph(AT91_PIN_PB29, 0); /* EMDC */
-
- if (!data->is_rmii) {
- at91_set_B_periph(AT91_PIN_PC25, 0); /* ECRS */
- at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */
- at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */
- at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */
- at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */
- at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */
- at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */
- at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */
- }
-
- eth_data = *data;
- platform_device_register(&at91cap9_eth_device);
-}
-#else
-void __init at91_add_device_eth(struct macb_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * MMC / SD
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
-static u64 mmc_dmamask = DMA_BIT_MASK(32);
-static struct at91_mmc_data mmc0_data, mmc1_data;
-
-static struct resource mmc0_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_MCI0,
- .end = AT91CAP9_BASE_MCI0 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_MCI0,
- .end = AT91CAP9_ID_MCI0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_mmc0_device = {
- .name = "at91_mci",
- .id = 0,
- .dev = {
- .dma_mask = &mmc_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &mmc0_data,
- },
- .resource = mmc0_resources,
- .num_resources = ARRAY_SIZE(mmc0_resources),
-};
-
-static struct resource mmc1_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_MCI1,
- .end = AT91CAP9_BASE_MCI1 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_MCI1,
- .end = AT91CAP9_ID_MCI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_mmc1_device = {
- .name = "at91_mci",
- .id = 1,
- .dev = {
- .dma_mask = &mmc_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &mmc1_data,
- },
- .resource = mmc1_resources,
- .num_resources = ARRAY_SIZE(mmc1_resources),
-};
-
-void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
-{
- if (!data)
- return;
-
- /* input/irq */
- if (gpio_is_valid(data->det_pin)) {
- at91_set_gpio_input(data->det_pin, 1);
- at91_set_deglitch(data->det_pin, 1);
- }
- if (gpio_is_valid(data->wp_pin))
- at91_set_gpio_input(data->wp_pin, 1);
- if (gpio_is_valid(data->vcc_pin))
- at91_set_gpio_output(data->vcc_pin, 0);
-
- if (mmc_id == 0) { /* MCI0 */
- /* CLK */
- at91_set_A_periph(AT91_PIN_PA2, 0);
-
- /* CMD */
- at91_set_A_periph(AT91_PIN_PA1, 1);
-
- /* DAT0, maybe DAT1..DAT3 */
- at91_set_A_periph(AT91_PIN_PA0, 1);
- if (data->wire4) {
- at91_set_A_periph(AT91_PIN_PA3, 1);
- at91_set_A_periph(AT91_PIN_PA4, 1);
- at91_set_A_periph(AT91_PIN_PA5, 1);
- }
-
- mmc0_data = *data;
- platform_device_register(&at91cap9_mmc0_device);
- } else { /* MCI1 */
- /* CLK */
- at91_set_A_periph(AT91_PIN_PA16, 0);
-
- /* CMD */
- at91_set_A_periph(AT91_PIN_PA17, 1);
-
- /* DAT0, maybe DAT1..DAT3 */
- at91_set_A_periph(AT91_PIN_PA18, 1);
- if (data->wire4) {
- at91_set_A_periph(AT91_PIN_PA19, 1);
- at91_set_A_periph(AT91_PIN_PA20, 1);
- at91_set_A_periph(AT91_PIN_PA21, 1);
- }
-
- mmc1_data = *data;
- platform_device_register(&at91cap9_mmc1_device);
- }
-}
-#else
-void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * NAND / SmartMedia
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_MTD_NAND_ATMEL) || defined(CONFIG_MTD_NAND_ATMEL_MODULE)
-static struct atmel_nand_data nand_data;
-
-#define NAND_BASE AT91_CHIPSELECT_3
-
-static struct resource nand_resources[] = {
- [0] = {
- .start = NAND_BASE,
- .end = NAND_BASE + SZ_256M - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_BASE_ECC,
- .end = AT91CAP9_BASE_ECC + SZ_512 - 1,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device at91cap9_nand_device = {
- .name = "atmel_nand",
- .id = -1,
- .dev = {
- .platform_data = &nand_data,
- },
- .resource = nand_resources,
- .num_resources = ARRAY_SIZE(nand_resources),
-};
-
-void __init at91_add_device_nand(struct atmel_nand_data *data)
-{
- unsigned long csa;
-
- if (!data)
- return;
-
- csa = at91_sys_read(AT91_MATRIX_EBICSA);
- at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA);
-
- /* enable pin */
- if (gpio_is_valid(data->enable_pin))
- at91_set_gpio_output(data->enable_pin, 1);
-
- /* ready/busy pin */
- if (gpio_is_valid(data->rdy_pin))
- at91_set_gpio_input(data->rdy_pin, 1);
-
- /* card detect pin */
- if (gpio_is_valid(data->det_pin))
- at91_set_gpio_input(data->det_pin, 1);
-
- nand_data = *data;
- platform_device_register(&at91cap9_nand_device);
-}
-#else
-void __init at91_add_device_nand(struct atmel_nand_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * TWI (i2c)
- * -------------------------------------------------------------------- */
-
-/*
- * Prefer the GPIO code since the TWI controller isn't robust
- * (gets overruns and underruns under load) and can only issue
- * repeated STARTs in one scenario (the driver doesn't yet handle them).
- */
-#if defined(CONFIG_I2C_GPIO) || defined(CONFIG_I2C_GPIO_MODULE)
-
-static struct i2c_gpio_platform_data pdata = {
- .sda_pin = AT91_PIN_PB4,
- .sda_is_open_drain = 1,
- .scl_pin = AT91_PIN_PB5,
- .scl_is_open_drain = 1,
- .udelay = 2, /* ~100 kHz */
-};
-
-static struct platform_device at91cap9_twi_device = {
- .name = "i2c-gpio",
- .id = -1,
- .dev.platform_data = &pdata,
-};
-
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
-{
- at91_set_GPIO_periph(AT91_PIN_PB4, 1); /* TWD (SDA) */
- at91_set_multi_drive(AT91_PIN_PB4, 1);
-
- at91_set_GPIO_periph(AT91_PIN_PB5, 1); /* TWCK (SCL) */
- at91_set_multi_drive(AT91_PIN_PB5, 1);
-
- i2c_register_board_info(0, devices, nr_devices);
- platform_device_register(&at91cap9_twi_device);
-}
-
-#elif defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
-
-static struct resource twi_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_TWI,
- .end = AT91CAP9_BASE_TWI + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_TWI,
- .end = AT91CAP9_ID_TWI,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_twi_device = {
- .name = "at91_i2c",
- .id = -1,
- .resource = twi_resources,
- .num_resources = ARRAY_SIZE(twi_resources),
-};
-
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices)
-{
- /* pins used for TWI interface */
- at91_set_B_periph(AT91_PIN_PB4, 0); /* TWD */
- at91_set_multi_drive(AT91_PIN_PB4, 1);
-
- at91_set_B_periph(AT91_PIN_PB5, 0); /* TWCK */
- at91_set_multi_drive(AT91_PIN_PB5, 1);
-
- i2c_register_board_info(0, devices, nr_devices);
- platform_device_register(&at91cap9_twi_device);
-}
-#else
-void __init at91_add_device_i2c(struct i2c_board_info *devices, int nr_devices) {}
-#endif
-
-/* --------------------------------------------------------------------
- * SPI
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
-static u64 spi_dmamask = DMA_BIT_MASK(32);
-
-static struct resource spi0_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_SPI0,
- .end = AT91CAP9_BASE_SPI0 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_SPI0,
- .end = AT91CAP9_ID_SPI0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_spi0_device = {
- .name = "atmel_spi",
- .id = 0,
- .dev = {
- .dma_mask = &spi_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = spi0_resources,
- .num_resources = ARRAY_SIZE(spi0_resources),
-};
-
-static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PD0, AT91_PIN_PD1 };
-
-static struct resource spi1_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_SPI1,
- .end = AT91CAP9_BASE_SPI1 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_SPI1,
- .end = AT91CAP9_ID_SPI1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_spi1_device = {
- .name = "atmel_spi",
- .id = 1,
- .dev = {
- .dma_mask = &spi_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = spi1_resources,
- .num_resources = ARRAY_SIZE(spi1_resources),
-};
-
-static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
-
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
-{
- int i;
- unsigned long cs_pin;
- short enable_spi0 = 0;
- short enable_spi1 = 0;
-
- /* Choose SPI chip-selects */
- for (i = 0; i < nr_devices; i++) {
- if (devices[i].controller_data)
- cs_pin = (unsigned long) devices[i].controller_data;
- else if (devices[i].bus_num == 0)
- cs_pin = spi0_standard_cs[devices[i].chip_select];
- else
- cs_pin = spi1_standard_cs[devices[i].chip_select];
-
- if (devices[i].bus_num == 0)
- enable_spi0 = 1;
- else
- enable_spi1 = 1;
-
- /* enable chip-select pin */
- at91_set_gpio_output(cs_pin, 1);
-
- /* pass chip-select pin to driver */
- devices[i].controller_data = (void *) cs_pin;
- }
-
- spi_register_board_info(devices, nr_devices);
-
- /* Configure SPI bus(es) */
- if (enable_spi0) {
- at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
- at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
- at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI0_SPCK */
-
- platform_device_register(&at91cap9_spi0_device);
- }
- if (enable_spi1) {
- at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */
- at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */
- at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */
-
- platform_device_register(&at91cap9_spi1_device);
- }
-}
-#else
-void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * Timer/Counter block
- * -------------------------------------------------------------------- */
-
-#ifdef CONFIG_ATMEL_TCLIB
-
-static struct resource tcb_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_TCB0,
- .end = AT91CAP9_BASE_TCB0 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_TCB,
- .end = AT91CAP9_ID_TCB,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_tcb_device = {
- .name = "atmel_tcb",
- .id = 0,
- .resource = tcb_resources,
- .num_resources = ARRAY_SIZE(tcb_resources),
-};
-
-static void __init at91_add_device_tc(void)
-{
- platform_device_register(&at91cap9_tcb_device);
-}
-#else
-static void __init at91_add_device_tc(void) { }
-#endif
-
-
-/* --------------------------------------------------------------------
- * RTT
- * -------------------------------------------------------------------- */
-
-static struct resource rtt_resources[] = {
- {
- .start = AT91CAP9_BASE_RTT,
- .end = AT91CAP9_BASE_RTT + SZ_16 - 1,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device at91cap9_rtt_device = {
- .name = "at91_rtt",
- .id = 0,
- .resource = rtt_resources,
- .num_resources = ARRAY_SIZE(rtt_resources),
-};
-
-static void __init at91_add_device_rtt(void)
-{
- platform_device_register(&at91cap9_rtt_device);
-}
-
-
-/* --------------------------------------------------------------------
- * Watchdog
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_AT91SAM9X_WATCHDOG) || defined(CONFIG_AT91SAM9X_WATCHDOG_MODULE)
-static struct resource wdt_resources[] = {
- {
- .start = AT91CAP9_BASE_WDT,
- .end = AT91CAP9_BASE_WDT + SZ_16 - 1,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device at91cap9_wdt_device = {
- .name = "at91_wdt",
- .id = -1,
- .resource = wdt_resources,
- .num_resources = ARRAY_SIZE(wdt_resources),
-};
-
-static void __init at91_add_device_watchdog(void)
-{
- platform_device_register(&at91cap9_wdt_device);
-}
-#else
-static void __init at91_add_device_watchdog(void) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * PWM
- * --------------------------------------------------------------------*/
-
-#if defined(CONFIG_ATMEL_PWM)
-static u32 pwm_mask;
-
-static struct resource pwm_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_PWMC,
- .end = AT91CAP9_BASE_PWMC + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_PWMC,
- .end = AT91CAP9_ID_PWMC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_pwm0_device = {
- .name = "atmel_pwm",
- .id = -1,
- .dev = {
- .platform_data = &pwm_mask,
- },
- .resource = pwm_resources,
- .num_resources = ARRAY_SIZE(pwm_resources),
-};
-
-void __init at91_add_device_pwm(u32 mask)
-{
- if (mask & (1 << AT91_PWM0))
- at91_set_A_periph(AT91_PIN_PB19, 1); /* enable PWM0 */
-
- if (mask & (1 << AT91_PWM1))
- at91_set_B_periph(AT91_PIN_PB8, 1); /* enable PWM1 */
-
- if (mask & (1 << AT91_PWM2))
- at91_set_B_periph(AT91_PIN_PC29, 1); /* enable PWM2 */
-
- if (mask & (1 << AT91_PWM3))
- at91_set_B_periph(AT91_PIN_PA11, 1); /* enable PWM3 */
-
- pwm_mask = mask;
-
- platform_device_register(&at91cap9_pwm0_device);
-}
-#else
-void __init at91_add_device_pwm(u32 mask) {}
-#endif
-
-
-
-/* --------------------------------------------------------------------
- * AC97
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SND_ATMEL_AC97C) || defined(CONFIG_SND_ATMEL_AC97C_MODULE)
-static u64 ac97_dmamask = DMA_BIT_MASK(32);
-static struct ac97c_platform_data ac97_data;
-
-static struct resource ac97_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_AC97C,
- .end = AT91CAP9_BASE_AC97C + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_AC97C,
- .end = AT91CAP9_ID_AC97C,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_ac97_device = {
- .name = "atmel_ac97c",
- .id = 1,
- .dev = {
- .dma_mask = &ac97_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &ac97_data,
- },
- .resource = ac97_resources,
- .num_resources = ARRAY_SIZE(ac97_resources),
-};
-
-void __init at91_add_device_ac97(struct ac97c_platform_data *data)
-{
- if (!data)
- return;
-
- at91_set_A_periph(AT91_PIN_PA6, 0); /* AC97FS */
- at91_set_A_periph(AT91_PIN_PA7, 0); /* AC97CK */
- at91_set_A_periph(AT91_PIN_PA8, 0); /* AC97TX */
- at91_set_A_periph(AT91_PIN_PA9, 0); /* AC97RX */
-
- /* reset */
- if (gpio_is_valid(data->reset_pin))
- at91_set_gpio_output(data->reset_pin, 0);
-
- ac97_data = *data;
- platform_device_register(&at91cap9_ac97_device);
-}
-#else
-void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * LCD Controller
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static u64 lcdc_dmamask = DMA_BIT_MASK(32);
-static struct atmel_lcdfb_info lcdc_data;
-
-static struct resource lcdc_resources[] = {
- [0] = {
- .start = AT91CAP9_LCDC_BASE,
- .end = AT91CAP9_LCDC_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_LCDC,
- .end = AT91CAP9_ID_LCDC,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91_lcdc_device = {
- .name = "atmel_lcdfb",
- .id = 0,
- .dev = {
- .dma_mask = &lcdc_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &lcdc_data,
- },
- .resource = lcdc_resources,
- .num_resources = ARRAY_SIZE(lcdc_resources),
-};
-
-void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data)
-{
- if (!data)
- return;
-
- if (cpu_is_at91cap9_revB())
- 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 */
- at91_set_A_periph(AT91_PIN_PC3, 0); /* LCDDEN */
- at91_set_B_periph(AT91_PIN_PB9, 0); /* LCDCC */
- at91_set_A_periph(AT91_PIN_PC6, 0); /* LCDD2 */
- at91_set_A_periph(AT91_PIN_PC7, 0); /* LCDD3 */
- at91_set_A_periph(AT91_PIN_PC8, 0); /* LCDD4 */
- at91_set_A_periph(AT91_PIN_PC9, 0); /* LCDD5 */
- at91_set_A_periph(AT91_PIN_PC10, 0); /* LCDD6 */
- at91_set_A_periph(AT91_PIN_PC11, 0); /* LCDD7 */
- at91_set_A_periph(AT91_PIN_PC14, 0); /* LCDD10 */
- at91_set_A_periph(AT91_PIN_PC15, 0); /* LCDD11 */
- at91_set_A_periph(AT91_PIN_PC16, 0); /* LCDD12 */
- at91_set_A_periph(AT91_PIN_PC17, 0); /* LCDD13 */
- at91_set_A_periph(AT91_PIN_PC18, 0); /* LCDD14 */
- at91_set_A_periph(AT91_PIN_PC19, 0); /* LCDD15 */
- at91_set_A_periph(AT91_PIN_PC22, 0); /* LCDD18 */
- at91_set_A_periph(AT91_PIN_PC23, 0); /* LCDD19 */
- at91_set_A_periph(AT91_PIN_PC24, 0); /* LCDD20 */
- at91_set_A_periph(AT91_PIN_PC25, 0); /* LCDD21 */
- at91_set_A_periph(AT91_PIN_PC26, 0); /* LCDD22 */
- at91_set_A_periph(AT91_PIN_PC27, 0); /* LCDD23 */
-
- lcdc_data = *data;
- platform_device_register(&at91_lcdc_device);
-}
-#else
-void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * SSC -- Synchronous Serial Controller
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_ATMEL_SSC) || defined(CONFIG_ATMEL_SSC_MODULE)
-static u64 ssc0_dmamask = DMA_BIT_MASK(32);
-
-static struct resource ssc0_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_SSC0,
- .end = AT91CAP9_BASE_SSC0 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_SSC0,
- .end = AT91CAP9_ID_SSC0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_ssc0_device = {
- .name = "ssc",
- .id = 0,
- .dev = {
- .dma_mask = &ssc0_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = ssc0_resources,
- .num_resources = ARRAY_SIZE(ssc0_resources),
-};
-
-static inline void configure_ssc0_pins(unsigned pins)
-{
- if (pins & ATMEL_SSC_TF)
- at91_set_A_periph(AT91_PIN_PB0, 1);
- if (pins & ATMEL_SSC_TK)
- at91_set_A_periph(AT91_PIN_PB1, 1);
- if (pins & ATMEL_SSC_TD)
- at91_set_A_periph(AT91_PIN_PB2, 1);
- if (pins & ATMEL_SSC_RD)
- at91_set_A_periph(AT91_PIN_PB3, 1);
- if (pins & ATMEL_SSC_RK)
- at91_set_A_periph(AT91_PIN_PB4, 1);
- if (pins & ATMEL_SSC_RF)
- at91_set_A_periph(AT91_PIN_PB5, 1);
-}
-
-static u64 ssc1_dmamask = DMA_BIT_MASK(32);
-
-static struct resource ssc1_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_SSC1,
- .end = AT91CAP9_BASE_SSC1 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_SSC1,
- .end = AT91CAP9_ID_SSC1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device at91cap9_ssc1_device = {
- .name = "ssc",
- .id = 1,
- .dev = {
- .dma_mask = &ssc1_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .resource = ssc1_resources,
- .num_resources = ARRAY_SIZE(ssc1_resources),
-};
-
-static inline void configure_ssc1_pins(unsigned pins)
-{
- if (pins & ATMEL_SSC_TF)
- at91_set_A_periph(AT91_PIN_PB6, 1);
- if (pins & ATMEL_SSC_TK)
- at91_set_A_periph(AT91_PIN_PB7, 1);
- if (pins & ATMEL_SSC_TD)
- at91_set_A_periph(AT91_PIN_PB8, 1);
- if (pins & ATMEL_SSC_RD)
- at91_set_A_periph(AT91_PIN_PB9, 1);
- if (pins & ATMEL_SSC_RK)
- at91_set_A_periph(AT91_PIN_PB10, 1);
- if (pins & ATMEL_SSC_RF)
- at91_set_A_periph(AT91_PIN_PB11, 1);
-}
-
-/*
- * SSC controllers are accessed through library code, instead of any
- * kind of all-singing/all-dancing driver. For example one could be
- * used by a particular I2S audio codec's driver, while another one
- * on the same system might be used by a custom data capture driver.
- */
-void __init at91_add_device_ssc(unsigned id, unsigned pins)
-{
- struct platform_device *pdev;
-
- /*
- * NOTE: caller is responsible for passing information matching
- * "pins" to whatever will be using each particular controller.
- */
- switch (id) {
- case AT91CAP9_ID_SSC0:
- pdev = &at91cap9_ssc0_device;
- configure_ssc0_pins(pins);
- break;
- case AT91CAP9_ID_SSC1:
- pdev = &at91cap9_ssc1_device;
- configure_ssc1_pins(pins);
- break;
- default:
- return;
- }
-
- platform_device_register(pdev);
-}
-
-#else
-void __init at91_add_device_ssc(unsigned id, unsigned pins) {}
-#endif
-
-
-/* --------------------------------------------------------------------
- * UART
- * -------------------------------------------------------------------- */
-
-#if defined(CONFIG_SERIAL_ATMEL)
-static struct resource dbgu_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_DBGU,
- .end = AT91CAP9_BASE_DBGU + SZ_512 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91_ID_SYS,
- .end = AT91_ID_SYS,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct atmel_uart_data dbgu_data = {
- .use_dma_tx = 0,
- .use_dma_rx = 0, /* DBGU not capable of receive DMA */
-};
-
-static u64 dbgu_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_dbgu_device = {
- .name = "atmel_usart",
- .id = 0,
- .dev = {
- .dma_mask = &dbgu_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &dbgu_data,
- },
- .resource = dbgu_resources,
- .num_resources = ARRAY_SIZE(dbgu_resources),
-};
-
-static inline void configure_dbgu_pins(void)
-{
- at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
- at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
-}
-
-static struct resource uart0_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_US0,
- .end = AT91CAP9_BASE_US0 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_US0,
- .end = AT91CAP9_ID_US0,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct atmel_uart_data uart0_data = {
- .use_dma_tx = 1,
- .use_dma_rx = 1,
-};
-
-static u64 uart0_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart0_device = {
- .name = "atmel_usart",
- .id = 1,
- .dev = {
- .dma_mask = &uart0_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &uart0_data,
- },
- .resource = uart0_resources,
- .num_resources = ARRAY_SIZE(uart0_resources),
-};
-
-static inline void configure_usart0_pins(unsigned pins)
-{
- at91_set_A_periph(AT91_PIN_PA22, 1); /* TXD0 */
- at91_set_A_periph(AT91_PIN_PA23, 0); /* RXD0 */
-
- if (pins & ATMEL_UART_RTS)
- at91_set_A_periph(AT91_PIN_PA24, 0); /* RTS0 */
- if (pins & ATMEL_UART_CTS)
- at91_set_A_periph(AT91_PIN_PA25, 0); /* CTS0 */
-}
-
-static struct resource uart1_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_US1,
- .end = AT91CAP9_BASE_US1 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_US1,
- .end = AT91CAP9_ID_US1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct atmel_uart_data uart1_data = {
- .use_dma_tx = 1,
- .use_dma_rx = 1,
-};
-
-static u64 uart1_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart1_device = {
- .name = "atmel_usart",
- .id = 2,
- .dev = {
- .dma_mask = &uart1_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &uart1_data,
- },
- .resource = uart1_resources,
- .num_resources = ARRAY_SIZE(uart1_resources),
-};
-
-static inline void configure_usart1_pins(unsigned pins)
-{
- at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
- at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
-
- if (pins & ATMEL_UART_RTS)
- at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
- if (pins & ATMEL_UART_CTS)
- at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
-}
-
-static struct resource uart2_resources[] = {
- [0] = {
- .start = AT91CAP9_BASE_US2,
- .end = AT91CAP9_BASE_US2 + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AT91CAP9_ID_US2,
- .end = AT91CAP9_ID_US2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct atmel_uart_data uart2_data = {
- .use_dma_tx = 1,
- .use_dma_rx = 1,
-};
-
-static u64 uart2_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device at91cap9_uart2_device = {
- .name = "atmel_usart",
- .id = 3,
- .dev = {
- .dma_mask = &uart2_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &uart2_data,
- },
- .resource = uart2_resources,
- .num_resources = ARRAY_SIZE(uart2_resources),
-};
-
-static inline void configure_usart2_pins(unsigned pins)
-{
- at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
- at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
-
- if (pins & ATMEL_UART_RTS)
- at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
- if (pins & ATMEL_UART_CTS)
- at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
-}
-
-static struct platform_device *__initdata at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
-struct platform_device *atmel_default_console_device; /* the serial console device */
-
-void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins)
-{
- struct platform_device *pdev;
- struct atmel_uart_data *pdata;
-
- switch (id) {
- case 0: /* DBGU */
- pdev = &at91cap9_dbgu_device;
- configure_dbgu_pins();
- break;
- case AT91CAP9_ID_US0:
- pdev = &at91cap9_uart0_device;
- configure_usart0_pins(pins);
- break;
- case AT91CAP9_ID_US1:
- pdev = &at91cap9_uart1_device;
- configure_usart1_pins(pins);
- break;
- case AT91CAP9_ID_US2:
- pdev = &at91cap9_uart2_device;
- configure_usart2_pins(pins);
- break;
- default:
- return;
- }
- pdata = pdev->dev.platform_data;
- pdata->num = portnr; /* update to mapped ID */
-
- if (portnr < ATMEL_MAX_UART)
- at91_uarts[portnr] = pdev;
-}
-
-void __init at91_set_serial_console(unsigned portnr)
-{
- if (portnr < ATMEL_MAX_UART) {
- atmel_default_console_device = at91_uarts[portnr];
- at91cap9_set_console_clock(at91_uarts[portnr]->id);
- }
-}
-
-void __init at91_add_device_serial(void)
-{
- int i;
-
- for (i = 0; i < ATMEL_MAX_UART; i++) {
- if (at91_uarts[i])
- platform_device_register(at91_uarts[i]);
- }
-
- if (!atmel_default_console_device)
- printk(KERN_INFO "AT91: No default serial console defined.\n");
-}
-#else
-void __init at91_register_uart(unsigned id, unsigned portnr, unsigned pins) {}
-void __init at91_set_serial_console(unsigned portnr) {}
-void __init at91_add_device_serial(void) {}
-#endif
-
-
-/* -------------------------------------------------------------------- */
-/*
- * These devices are always present and don't need any board-specific
- * setup.
- */
-static int __init at91_add_standard_devices(void)
-{
- at91_add_device_rtt();
- at91_add_device_watchdog();
- at91_add_device_tc();
- return 0;
-}
-
-arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index 99c3174e24a..dd6e2de1342 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -289,6 +289,15 @@ static struct at91_gpio_bank at91rm9200_gpio[] __initdata = {
}
};
+static void at91rm9200_idle(void)
+{
+ /*
+ * Disable the processor clock. The processor will be automatically
+ * re-enabled by an interrupt or by a reset.
+ */
+ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+}
+
static void at91rm9200_restart(char mode, const char *cmd)
{
/*
@@ -314,6 +323,7 @@ static void __init at91rm9200_ioremap_registers(void)
static void __init at91rm9200_initialize(void)
{
+ arm_pm_idle = at91rm9200_idle;
arm_pm_restart = at91rm9200_restart;
at91_extern_irq = (1 << AT91RM9200_ID_IRQ0) | (1 << AT91RM9200_ID_IRQ1)
| (1 << AT91RM9200_ID_IRQ2) | (1 << AT91RM9200_ID_IRQ3)
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index d4036ba4361..9ac8c6fe336 100644
--- a/arch/arm/mach-at91/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
+#include <asm/proc-fns.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -328,8 +329,15 @@ static void __init at91sam9260_ioremap_registers(void)
at91sam9_ioremap_smc(0, AT91SAM9260_BASE_SMC);
}
+static void at91sam9260_idle(void)
+{
+ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+ cpu_do_idle();
+}
+
static void __init at91sam9260_initialize(void)
{
+ arm_pm_idle = at91sam9260_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
| (1 << AT91SAM9260_ID_IRQ2);
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index 023c2ff138d..ab76868f01f 100644
--- a/arch/arm/mach-at91/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
+#include <asm/proc-fns.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -286,8 +287,15 @@ static void __init at91sam9261_ioremap_registers(void)
at91sam9_ioremap_smc(0, AT91SAM9261_BASE_SMC);
}
+static void at91sam9261_idle(void)
+{
+ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+ cpu_do_idle();
+}
+
static void __init at91sam9261_initialize(void)
{
+ arm_pm_idle = at91sam9261_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_extern_irq = (1 << AT91SAM9261_ID_IRQ0) | (1 << AT91SAM9261_ID_IRQ1)
| (1 << AT91SAM9261_ID_IRQ2);
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
index 75e876c258a..247ab633abc 100644
--- a/arch/arm/mach-at91/at91sam9263.c
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -12,6 +12,7 @@
#include <linux/module.h>
+#include <asm/proc-fns.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -307,8 +308,15 @@ static void __init at91sam9263_ioremap_registers(void)
at91sam9_ioremap_smc(1, AT91SAM9263_BASE_SMC1);
}
+static void at91sam9263_idle(void)
+{
+ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+ cpu_do_idle();
+}
+
static void __init at91sam9263_initialize(void)
{
+ arm_pm_idle = at91sam9263_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
index 366a7765635..70709ab0102 100644
--- a/arch/arm/mach-at91/at91sam9263_devices.c
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -891,7 +891,8 @@ static struct platform_device at91sam9263_isi_device = {
.num_resources = ARRAY_SIZE(isi_resources),
};
-void __init at91_add_device_isi(void)
+void __init at91_add_device_isi(struct isi_platform_data *data,
+ bool use_pck_as_mck)
{
at91_set_A_periph(AT91_PIN_PE0, 0); /* ISI_D0 */
at91_set_A_periph(AT91_PIN_PE1, 0); /* ISI_D1 */
@@ -904,14 +905,20 @@ void __init at91_add_device_isi(void)
at91_set_A_periph(AT91_PIN_PE8, 0); /* ISI_PCK */
at91_set_A_periph(AT91_PIN_PE9, 0); /* ISI_HSYNC */
at91_set_A_periph(AT91_PIN_PE10, 0); /* ISI_VSYNC */
- at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */
at91_set_B_periph(AT91_PIN_PE12, 0); /* ISI_PD8 */
at91_set_B_periph(AT91_PIN_PE13, 0); /* ISI_PD9 */
at91_set_B_periph(AT91_PIN_PE14, 0); /* ISI_PD10 */
at91_set_B_periph(AT91_PIN_PE15, 0); /* ISI_PD11 */
+
+ if (use_pck_as_mck) {
+ at91_set_B_periph(AT91_PIN_PE11, 0); /* ISI_MCK (PCK3) */
+
+ /* TODO: register the PCK for ISI_MCK and set its parent */
+ }
}
#else
-void __init at91_add_device_isi(void) {}
+void __init at91_add_device_isi(struct isi_platform_data *data,
+ bool use_pck_as_mck) {}
#endif
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
index 1cb6a96b1c1..5b12192e52e 100644
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ b/arch/arm/mach-at91/at91sam9g45.c
@@ -317,6 +317,12 @@ static struct at91_gpio_bank at91sam9g45_gpio[] __initdata = {
}
};
+static void at91sam9g45_idle(void)
+{
+ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+ cpu_do_idle();
+}
+
/* --------------------------------------------------------------------
* AT91SAM9G45 processor initialization
* -------------------------------------------------------------------- */
@@ -337,6 +343,7 @@ static void __init at91sam9g45_ioremap_registers(void)
static void __init at91sam9g45_initialize(void)
{
+ arm_pm_idle = at91sam9g45_idle;
arm_pm_restart = at91sam9g45_restart;
at91_extern_irq = (1 << AT91SAM9G45_ID_IRQ0);
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c
index b7582dd10dc..bd4e68cd3e2 100644
--- a/arch/arm/mach-at91/at91sam9g45_devices.c
+++ b/arch/arm/mach-at91/at91sam9g45_devices.c
@@ -14,6 +14,7 @@
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
+#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/i2c-gpio.h>
#include <linux/atmel-mci.h>
@@ -28,7 +29,10 @@
#include <mach/at_hdmac.h>
#include <mach/atmel-mci.h>
+#include <media/atmel-isi.h>
+
#include "generic.h"
+#include "clock.h"
/* --------------------------------------------------------------------
@@ -38,10 +42,6 @@
#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
static u64 hdmac_dmamask = DMA_BIT_MASK(32);
-static struct at_dma_platform_data atdma_pdata = {
- .nr_channels = 8,
-};
-
static struct resource hdmac_resources[] = {
[0] = {
.start = AT91SAM9G45_BASE_DMA,
@@ -56,12 +56,11 @@ static struct resource hdmac_resources[] = {
};
static struct platform_device at_hdmac_device = {
- .name = "at_hdmac",
+ .name = "at91sam9g45_dma",
.id = -1,
.dev = {
.dma_mask = &hdmac_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &atdma_pdata,
},
.resource = hdmac_resources,
.num_resources = ARRAY_SIZE(hdmac_resources),
@@ -69,9 +68,15 @@ static struct platform_device at_hdmac_device = {
void __init at91_add_device_hdmac(void)
{
- dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
- dma_cap_set(DMA_SLAVE, atdma_pdata.cap_mask);
- platform_device_register(&at_hdmac_device);
+#if defined(CONFIG_OF)
+ struct device_node *of_node =
+ of_find_node_by_name(NULL, "dma-controller");
+
+ if (of_node)
+ of_node_put(of_node);
+ else
+#endif
+ platform_device_register(&at_hdmac_device);
}
#else
void __init at91_add_device_hdmac(void) {}
@@ -869,6 +874,96 @@ void __init at91_add_device_ac97(struct ac97c_platform_data *data)
void __init at91_add_device_ac97(struct ac97c_platform_data *data) {}
#endif
+/* --------------------------------------------------------------------
+ * Image Sensor Interface
+ * -------------------------------------------------------------------- */
+#if defined(CONFIG_VIDEO_ATMEL_ISI) || defined(CONFIG_VIDEO_ATMEL_ISI_MODULE)
+static u64 isi_dmamask = DMA_BIT_MASK(32);
+static struct isi_platform_data isi_data;
+
+struct resource isi_resources[] = {
+ [0] = {
+ .start = AT91SAM9G45_BASE_ISI,
+ .end = AT91SAM9G45_BASE_ISI + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AT91SAM9G45_ID_ISI,
+ .end = AT91SAM9G45_ID_ISI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device at91sam9g45_isi_device = {
+ .name = "atmel_isi",
+ .id = 0,
+ .dev = {
+ .dma_mask = &isi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &isi_data,
+ },
+ .resource = isi_resources,
+ .num_resources = ARRAY_SIZE(isi_resources),
+};
+
+static struct clk_lookup isi_mck_lookups[] = {
+ CLKDEV_CON_DEV_ID("isi_mck", "atmel_isi.0", NULL),
+};
+
+void __init at91_add_device_isi(struct isi_platform_data *data,
+ bool use_pck_as_mck)
+{
+ struct clk *pck;
+ struct clk *parent;
+
+ if (!data)
+ return;
+ isi_data = *data;
+
+ at91_set_A_periph(AT91_PIN_PB20, 0); /* ISI_D0 */
+ at91_set_A_periph(AT91_PIN_PB21, 0); /* ISI_D1 */
+ at91_set_A_periph(AT91_PIN_PB22, 0); /* ISI_D2 */
+ at91_set_A_periph(AT91_PIN_PB23, 0); /* ISI_D3 */
+ at91_set_A_periph(AT91_PIN_PB24, 0); /* ISI_D4 */
+ at91_set_A_periph(AT91_PIN_PB25, 0); /* ISI_D5 */
+ at91_set_A_periph(AT91_PIN_PB26, 0); /* ISI_D6 */
+ at91_set_A_periph(AT91_PIN_PB27, 0); /* ISI_D7 */
+ at91_set_A_periph(AT91_PIN_PB28, 0); /* ISI_PCK */
+ at91_set_A_periph(AT91_PIN_PB30, 0); /* ISI_HSYNC */
+ at91_set_A_periph(AT91_PIN_PB29, 0); /* ISI_VSYNC */
+ at91_set_B_periph(AT91_PIN_PB8, 0); /* ISI_PD8 */
+ at91_set_B_periph(AT91_PIN_PB9, 0); /* ISI_PD9 */
+ at91_set_B_periph(AT91_PIN_PB10, 0); /* ISI_PD10 */
+ at91_set_B_periph(AT91_PIN_PB11, 0); /* ISI_PD11 */
+
+ platform_device_register(&at91sam9g45_isi_device);
+
+ if (use_pck_as_mck) {
+ at91_set_B_periph(AT91_PIN_PB31, 0); /* ISI_MCK (PCK1) */
+
+ pck = clk_get(NULL, "pck1");
+ parent = clk_get(NULL, "plla");
+
+ BUG_ON(IS_ERR(pck) || IS_ERR(parent));
+
+ if (clk_set_parent(pck, parent)) {
+ pr_err("Failed to set PCK's parent\n");
+ } else {
+ /* Register PCK as ISI_MCK */
+ isi_mck_lookups[0].clk = pck;
+ clkdev_add_table(isi_mck_lookups,
+ ARRAY_SIZE(isi_mck_lookups));
+ }
+
+ clk_put(pck);
+ clk_put(parent);
+ }
+}
+#else
+void __init at91_add_device_isi(struct isi_platform_data *data,
+ bool use_pck_as_mck) {}
+#endif
+
/* --------------------------------------------------------------------
* LCD Controller
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
index d2c91a841cb..fd60e226a98 100644
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ b/arch/arm/mach-at91/at91sam9rl.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
+#include <asm/proc-fns.h>
#include <asm/irq.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -291,8 +292,15 @@ static void __init at91sam9rl_ioremap_registers(void)
at91sam9_ioremap_smc(0, AT91SAM9RL_BASE_SMC);
}
+static void at91sam9rl_idle(void)
+{
+ at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
+ cpu_do_idle();
+}
+
static void __init at91sam9rl_initialize(void)
{
+ arm_pm_idle = at91sam9rl_idle;
arm_pm_restart = at91sam9_alt_restart;
at91_extern_irq = (1 << AT91SAM9RL_ID_IRQ0);
diff --git a/arch/arm/mach-at91/at91sam9rl_devices.c b/arch/arm/mach-at91/at91sam9rl_devices.c
index 61908dce978..9be71c11d0f 100644
--- a/arch/arm/mach-at91/at91sam9rl_devices.c
+++ b/arch/arm/mach-at91/at91sam9rl_devices.c
@@ -33,10 +33,6 @@
#if defined(CONFIG_AT_HDMAC) || defined(CONFIG_AT_HDMAC_MODULE)
static u64 hdmac_dmamask = DMA_BIT_MASK(32);
-static struct at_dma_platform_data atdma_pdata = {
- .nr_channels = 2,
-};
-
static struct resource hdmac_resources[] = {
[0] = {
.start = AT91SAM9RL_BASE_DMA,
@@ -51,12 +47,11 @@ static struct resource hdmac_resources[] = {
};
static struct platform_device at_hdmac_device = {
- .name = "at_hdmac",
+ .name = "at91sam9rl_dma",
.id = -1,
.dev = {
.dma_mask = &hdmac_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &atdma_pdata,
},
.resource = hdmac_resources,
.num_resources = ARRAY_SIZE(hdmac_resources),
@@ -64,7 +59,6 @@ static struct platform_device at_hdmac_device = {
void __init at91_add_device_hdmac(void)
{
- dma_cap_set(DMA_MEMCPY, atdma_pdata.cap_mask);
platform_device_register(&at_hdmac_device);
}
#else
diff --git a/arch/arm/mach-at91/at91x40.c b/arch/arm/mach-at91/at91x40.c
index 56ba3bd035a..0154b7f44ff 100644
--- a/arch/arm/mach-at91/at91x40.c
+++ b/arch/arm/mach-at91/at91x40.c
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <asm/proc-fns.h>
#include <asm/mach/arch.h>
#include <mach/at91x40.h>
#include <mach/at91_st.h>
@@ -37,8 +38,19 @@ unsigned long clk_get_rate(struct clk *clk)
return AT91X40_MASTER_CLOCK;
}
+static void at91x40_idle(void)
+{
+ /*
+ * Disable the processor clock. The processor will be automatically
+ * re-enabled by an interrupt or by a reset.
+ */
+ at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
+ cpu_do_idle();
+}
+
void __init at91x40_initialize(unsigned long main_clock)
{
+ arm_pm_idle = at91x40_idle;
at91_extern_irq = (1 << AT91X40_ID_IRQ0) | (1 << AT91X40_ID_IRQ1)
| (1 << AT91X40_ID_IRQ2);
}
diff --git a/arch/arm/mach-at91/board-cap9adk.c b/arch/arm/mach-at91/board-cap9adk.c
deleted file mode 100644
index ac3de4f7c31..00000000000
--- a/arch/arm/mach-at91/board-cap9adk.c
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * linux/arch/arm/mach-at91/board-cap9adk.c
- *
- * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include <linux/types.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/mm.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/ads7846.h>
-#include <linux/fb.h>
-#include <linux/mtd/physmap.h>
-
-#include <video/atmel_lcdc.h>
-
-#include <mach/hardware.h>
-#include <asm/setup.h>
-#include <asm/mach-types.h>
-
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include <mach/board.h>
-#include <mach/at91cap9_matrix.h>
-#include <mach/at91sam9_smc.h>
-#include <mach/system_rev.h>
-
-#include "sam9_smc.h"
-#include "generic.h"
-
-
-static void __init cap9adk_init_early(void)
-{
- /* Initialize processor: 12 MHz crystal */
- at91_initialize(12000000);
-
- /* Setup the LEDs: USER1 and USER2 LED for cpu/timer... */
- at91_init_leds(AT91_PIN_PA10, AT91_PIN_PA11);
- /* ... POWER LED always on */
- at91_set_gpio_output(AT91_PIN_PC29, 1);
-
- /* Setup the serial ports and console */
- at91_register_uart(0, 0, 0); /* DBGU = ttyS0 */
- at91_set_serial_console(0);
-}
-
-/*
- * USB Host port
- */
-static struct at91_usbh_data __initdata cap9adk_usbh_data = {
- .ports = 2,
- .vbus_pin = {-EINVAL, -EINVAL},
- .overcurrent_pin= {-EINVAL, -EINVAL},
-};
-
-/*
- * USB HS Device port
- */
-static struct usba_platform_data __initdata cap9adk_usba_udc_data = {
- .vbus_pin = AT91_PIN_PB31,
-};
-
-/*
- * ADS7846 Touchscreen
- */
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
-static int ads7843_pendown_state(void)
-{
- return !at91_get_gpio_value(AT91_PIN_PC4); /* Touchscreen PENIRQ */
-}
-
-static struct ads7846_platform_data ads_info = {
- .model = 7843,
- .x_min = 150,
- .x_max = 3830,
- .y_min = 190,
- .y_max = 3830,
- .vref_delay_usecs = 100,
- .x_plate_ohms = 450,
- .y_plate_ohms = 250,
- .pressure_max = 15000,
- .debounce_max = 1,
- .debounce_rep = 0,
- .debounce_tol = (~0),
- .get_pendown_state = ads7843_pendown_state,
-};
-
-static void __init cap9adk_add_device_ts(void)
-{
- at91_set_gpio_input(AT91_PIN_PC4, 1); /* Touchscreen PENIRQ */
- at91_set_gpio_input(AT91_PIN_PC5, 1); /* Touchscreen BUSY */
-}
-#else
-static void __init cap9adk_add_device_ts(void) {}
-#endif
-
-
-/*
- * SPI devices.
- */
-static struct spi_board_info cap9adk_spi_devices[] = {
-#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
- { /* DataFlash card */
- .modalias = "mtd_dataflash",
- .chip_select = 0,
- .max_speed_hz = 15 * 1000 * 1000,
- .bus_num = 0,
- },
-#endif
-#if defined(CONFIG_TOUCHSCREEN_ADS7846) || defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
- {
- .modalias = "ads7846",
- .chip_select = 3, /* can be 2 or 3, depending on J2 jumper */
- .max_speed_hz = 125000 * 26, /* (max sample rate @ 3V) * (cmd + data + overhead) */
- .bus_num = 0,
- .platform_data = &ads_info,
- .irq = AT91_PIN_PC4,
- },
-#endif
-};
-
-
-/*
- * MCI (SD/MMC)
- */
-static struct at91_mmc_data __initdata cap9adk_mmc_data = {
- .wire4 = 1,
- .det_pin = -EINVAL,
- .wp_pin = -EINVAL,
- .vcc_pin = -EINVAL,
-};
-
-
-/*
- * MACB Ethernet device
- */
-static struct macb_platform_data __initdata cap9adk_macb_data = {
- .phy_irq_pin = -EINVAL,
- .is_rmii = 1,
-};
-
-
-/*
- * NAND flash
- */
-static struct mtd_partition __initdata cap9adk_nand_partitions[] = {
- {
- .name = "NAND partition",
- .offset = 0,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct atmel_nand_data __initdata cap9adk_nand_data = {
- .ale = 21,
- .cle = 22,
- .det_pin = -EINVAL,
- .rdy_pin = -EINVAL,
- .enable_pin = AT91_PIN_PD15,
- .parts = cap9adk_nand_partitions,
- .num_parts = ARRAY_SIZE(cap9adk_nand_partitions),
-};
-
-static struct sam9_smc_config __initdata cap9adk_nand_smc_config = {
- .ncs_read_setup = 1,
- .nrd_setup = 2,
- .ncs_write_setup = 1,
- .nwe_setup = 2,
-
- .ncs_read_pulse = 6,
- .nrd_pulse = 4,
- .ncs_write_pulse = 6,
- .nwe_pulse = 4,
-
- .read_cycle = 8,
- .write_cycle = 8,
-
- .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE,
- .tdf_cycles = 1,
-};
-
-static void __init cap9adk_add_device_nand(void)
-{
- unsigned long csa;
-
- csa = at91_sys_read(AT91_MATRIX_EBICSA);
- at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
-
- cap9adk_nand_data.bus_width_16 = board_have_nand_16bit();
- /* setup bus-width (8 or 16) */
- if (cap9adk_nand_data.bus_width_16)
- cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_16;
- else
- cap9adk_nand_smc_config.mode |= AT91_SMC_DBW_8;
-
- /* configure chip-select 3 (NAND) */
- sam9_smc_configure(0, 3, &cap9adk_nand_smc_config);
-
- at91_add_device_nand(&cap9adk_nand_data);
-}
-
-
-/*
- * NOR flash
- */
-static struct mtd_partition cap9adk_nor_partitions[] = {
- {
- .name = "NOR partition",
- .offset = 0,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct physmap_flash_data cap9adk_nor_data = {
- .width = 2,
- .parts = cap9adk_nor_partitions,
- .nr_parts = ARRAY_SIZE(cap9adk_nor_partitions),
-};
-
-#define NOR_BASE AT91_CHIPSELECT_0
-#define NOR_SIZE SZ_8M
-
-static struct resource nor_flash_resources[] = {
- {
- .start = NOR_BASE,
- .end = NOR_BASE + NOR_SIZE - 1,
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device cap9adk_nor_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = {
- .platform_data = &cap9adk_nor_data,
- },
- .resource = nor_flash_resources,
- .num_resources = ARRAY_SIZE(nor_flash_resources),
-};
-
-static struct sam9_smc_config __initdata cap9adk_nor_smc_config = {
- .ncs_read_setup = 2,
- .nrd_setup = 4,
- .ncs_write_setup = 2,
- .nwe_setup = 4,
-
- .ncs_read_pulse = 10,
- .nrd_pulse = 8,
- .ncs_write_pulse = 10,
- .nwe_pulse = 8,
-
- .read_cycle = 16,
- .write_cycle = 16,
-
- .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_BAT_WRITE | AT91_SMC_DBW_16,
- .tdf_cycles = 1,
-};
-
-static __init void cap9adk_add_device_nor(void)
-{
- unsigned long csa;
-
- csa = at91_sys_read(AT91_MATRIX_EBICSA);
- at91_sys_write(AT91_MATRIX_EBICSA, csa | AT91_MATRIX_EBI_VDDIOMSEL_3_3V);
-
- /* configure chip-select 0 (NOR) */
- sam9_smc_configure(0, 0, &cap9adk_nor_smc_config);
-
- platform_device_register(&cap9adk_nor_flash);
-}
-
-
-/*
- * LCD Controller
- */
-#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
-static struct fb_videomode at91_tft_vga_modes[] = {
- {
- .name = "TX09D50VM1CCA @ 60",
- .refresh = 60,
- .xres = 240, .yres = 320,
- .pixclock = KHZ2PICOS(4965),
-
- .left_margin = 1, .right_margin = 33,
- .upper_margin = 1, .lower_margin = 0,
- .hsync_len = 5, .vsync_len = 1,
-
- .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- .vmode = FB_VMODE_NONINTERLACED,
- },
-};
-
-static struct fb_monspecs at91fb_default_monspecs = {
- .manufacturer = "HIT",
- .monitor = "TX09D70VM1CCA",
-
- .modedb = at91_tft_vga_modes,
- .modedb_len = ARRAY_SIZE(at91_tft_vga_modes),
- .hfmin = 15000,
- .hfmax = 64000,
- .vfmin = 50,
- .vfmax = 150,
-};
-
-#define AT91CAP9_DEFAULT_LCDCON2 (ATMEL_LCDC_MEMOR_LITTLE \
- | ATMEL_LCDC_DISTYPE_TFT \
- | ATMEL_LCDC_CLKMOD_ALWAYSACTIVE)
-
-static void at91_lcdc_power_control(int on)
-{
- if (on)
- at91_set_gpio_value(AT91_PIN_PC0, 0); /* power up */
- else
- at91_set_gpio_value(AT91_PIN_PC0, 1); /* power down */
-}
-
-/* Driver datas */
-static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data = {
- .default_bpp = 16,
- .default_dmacon = ATMEL_LCDC_DMAEN,
- .default_lcdcon2 = AT91CAP9_DEFAULT_LCDCON2,
- .default_monspecs = &at91fb_default_monspecs,
- .atmel_lcdfb_power_control = at91_lcdc_power_control,
- .guard_time = 1,
-};
-
-#else
-static struct atmel_lcdfb_info __initdata cap9adk_lcdc_data;
-#endif
-
-
-/*
- * AC97
- */
-static struct ac97c_platform_data cap9adk_ac97_data = {
- .reset_pin = -EINVAL,
-};
-
-
-static void __init cap9adk_board_init(void)
-{
- /* Serial */
- at91_add_device_serial();
- /* USB Host */
- at91_add_device_usbh(&cap9adk_usbh_data);
- /* USB HS */
- at91_add_device_usba(&cap9adk_usba_udc_data);
- /* SPI */
- at91_add_device_spi(cap9adk_spi_devices, ARRAY_SIZE(cap9adk_spi_devices));
- /* Touchscreen */
- cap9adk_add_device_ts();
- /* MMC */
- at91_add_device_mmc(1, &cap9adk_mmc_data);
- /* Ethernet */
- at91_add_device_eth(&cap9adk_macb_data);
- /* NAND */
- cap9adk_add_device_nand();
- /* NOR Flash */
- cap9adk_add_device_nor();
- /* I2C */
- at91_add_device_i2c(NULL, 0);
- /* LCD Controller */
- at91_add_device_lcdc(&cap9adk_lcdc_data);
- /* AC97 */
- at91_add_device_ac97(&cap9adk_ac97_data);
-}
-
-MACHINE_START(AT91CAP9ADK, "Atmel AT91CAP9A-DK")
- /* Maintainer: Stelian Pop <stelian.pop@leadtechdesign.com> */
- .timer = &at91sam926x_timer,
- .map_io = at91_map_io,
- .init_early = cap9adk_init_early,
- .init_irq = at91_init_irq_default,
- .init_machine = cap9adk_board_init,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-flexibity.c b/arch/arm/mach-at91/board-flexibity.c
index eec02cd57ce..1815152001f 100644
--- a/arch/arm/mach-at91/board-flexibity.c
+++ b/arch/arm/mach-at91/board-flexibity.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mach-at91/board-flexibity.c
*
- * Copyright (C) 2010 Flexibity
+ * Copyright (C) 2010-2011 Flexibity
* Copyright (C) 2005 SAN People
* Copyright (C) 2006 Atmel
*
@@ -62,6 +62,13 @@ static struct at91_udc_data __initdata flexibity_udc_data = {
.pullup_pin = -EINVAL, /* pull-up driven by UDC */
};
+/* I2C devices */
+static struct i2c_board_info __initdata flexibity_i2c_devices[] = {
+ {
+ I2C_BOARD_INFO("ds1307", 0x68),
+ },
+};
+
/* SPI devices */
static struct spi_board_info flexibity_spi_devices[] = {
{ /* DataFlash chip */
@@ -141,6 +148,9 @@ static void __init flexibity_board_init(void)
at91_add_device_usbh(&flexibity_usbh_data);
/* USB Device */
at91_add_device_udc(&flexibity_udc_data);
+ /* I2C */
+ at91_add_device_i2c(flexibity_i2c_devices,
+ ARRAY_SIZE(flexibity_i2c_devices));
/* SPI */
at91_add_device_spi(flexibity_spi_devices,
ARRAY_SIZE(flexibity_spi_devices));
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c
index ea0d1b9c2b7..57497e2b887 100644
--- a/arch/arm/mach-at91/board-sam9m10g45ek.c
+++ b/arch/arm/mach-at91/board-sam9m10g45ek.c
@@ -24,11 +24,13 @@
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/leds.h>
-#include <linux/clk.h>
#include <linux/atmel-mci.h>
+#include <linux/delay.h>
#include <mach/hardware.h>
#include <video/atmel_lcdc.h>
+#include <media/soc_camera.h>
+#include <media/atmel-isi.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@@ -185,6 +187,71 @@ static void __init ek_add_device_nand(void)
/*
+ * ISI
+ */
+static struct isi_platform_data __initdata isi_data = {
+ .frate = ISI_CFG1_FRATE_CAPTURE_ALL,
+ /* to use codec and preview path simultaneously */
+ .full_mode = 1,
+ .data_width_flags = ISI_DATAWIDTH_8 | ISI_DATAWIDTH_10,
+ /* ISI_MCK is provided by programmable clock or external clock */
+ .mck_hz = 25000000,
+};
+
+
+/*
+ * soc-camera OV2640
+ */
+#if defined(CONFIG_SOC_CAMERA_OV2640) || \
+ defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
+static unsigned long isi_camera_query_bus_param(struct soc_camera_link *link)
+{
+ /* ISI board for ek using default 8-bits connection */
+ return SOCAM_DATAWIDTH_8;
+}
+
+static int i2c_camera_power(struct device *dev, int on)
+{
+ /* enable or disable the camera */
+ pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
+ at91_set_gpio_output(AT91_PIN_PD13, !on);
+
+ if (!on)
+ goto out;
+
+ /* If enabled, give a reset impulse */
+ at91_set_gpio_output(AT91_PIN_PD12, 0);
+ msleep(20);
+ at91_set_gpio_output(AT91_PIN_PD12, 1);
+ msleep(100);
+
+out:
+ return 0;
+}
+
+static struct i2c_board_info i2c_camera = {
+ I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+ .bus_id = 0,
+ .board_info = &i2c_camera,
+ .i2c_adapter_id = 0,
+ .power = i2c_camera_power,
+ .query_bus_param = isi_camera_query_bus_param,
+};
+
+static struct platform_device isi_ov2640 = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &iclink_ov2640,
+ },
+};
+#endif
+
+
+/*
* LCD Controller
*/
#if defined(CONFIG_FB_ATMEL) || defined(CONFIG_FB_ATMEL_MODULE)
@@ -377,7 +444,12 @@ static struct gpio_led ek_pwm_led[] = {
#endif
};
-
+static struct platform_device *devices[] __initdata = {
+#if defined(CONFIG_SOC_CAMERA_OV2640) || \
+ defined(CONFIG_SOC_CAMERA_OV2640_MODULE)
+ &isi_ov2640,
+#endif
+};
static void __init ek_board_init(void)
{
@@ -399,6 +471,8 @@ static void __init ek_board_init(void)
ek_add_device_nand();
/* I2C */
at91_add_device_i2c(0, NULL, 0);
+ /* ISI, using programmable clock as ISI_MCK */
+ at91_add_device_isi(&isi_data, true);
/* LCD Controller */
at91_add_device_lcdc(&ek_lcdc_data);
/* Touch Screen */
@@ -410,6 +484,8 @@ static void __init ek_board_init(void)
/* LEDs */
at91_gpio_leds(ek_leds, ARRAY_SIZE(ek_leds));
at91_pwm_leds(ek_pwm_led, ARRAY_SIZE(ek_pwm_led));
+ /* Other platform devices */
+ platform_add_devices(devices, ARRAY_SIZE(devices));
}
MACHINE_START(AT91SAM9M10G45EK, "Atmel AT91SAM9M10G45-EK")
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c
index 61873f3aa92..aa04e22a9da 100644
--- a/arch/arm/mach-at91/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -47,8 +47,7 @@
/*
* Chips have some kind of clocks : group them by functionality
*/
-#define cpu_has_utmi() ( cpu_is_at91cap9() \
- || cpu_is_at91sam9rl() \
+#define cpu_has_utmi() ( cpu_is_at91sam9rl() \
|| cpu_is_at91sam9g45())
#define cpu_has_800M_plla() ( cpu_is_at91sam9g20() \
@@ -602,8 +601,6 @@ static void __init at91_pllb_usbfs_clock_init(unsigned long main_clock)
cpu_is_at91sam9g10()) {
uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
udpck.pmc_mask = AT91SAM926x_PMC_UDP;
- } else if (cpu_is_at91cap9()) {
- uhpck.pmc_mask = AT91CAP9_PMC_UHP;
}
at91_sys_write(AT91_CKGR_PLLBR, 0);
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index 594133451c0..7e8280e798c 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -45,7 +45,6 @@ extern void __init at91sam9261_set_console_clock(int id);
extern void __init at91sam9263_set_console_clock(int id);
extern void __init at91sam9rl_set_console_clock(int id);
extern void __init at91sam9g45_set_console_clock(int id);
-extern void __init at91cap9_set_console_clock(int id);
#ifdef CONFIG_AT91_PMC_UNIT
extern int __init at91_clock_init(unsigned long main_clock);
#else
diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h
index e46f93e34aa..dbdd6ae473d 100644
--- a/arch/arm/mach-at91/include/mach/at91_pmc.h
+++ b/arch/arm/mach-at91/include/mach/at91_pmc.h
@@ -23,10 +23,8 @@
#define AT91_PMC_PCK (1 << 0) /* Processor Clock */
#define AT91RM9200_PMC_UDP (1 << 1) /* USB Devcice Port Clock [AT91RM9200 only] */
#define AT91RM9200_PMC_MCKUDP (1 << 2) /* USB Device Port Master Clock Automatic Disable on Suspend [AT91RM9200 only] */
-#define AT91CAP9_PMC_DDR (1 << 2) /* DDR Clock [CAP9 revC & some SAM9 only] */
#define AT91RM9200_PMC_UHP (1 << 4) /* USB Host Port Clock [AT91RM9200 only] */
#define AT91SAM926x_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91SAM926x only] */
-#define AT91CAP9_PMC_UHP (1 << 6) /* USB Host Port Clock [AT91CAP9 only] */
#define AT91SAM926x_PMC_UDP (1 << 7) /* USB Devcice Port Clock [AT91SAM926x only] */
#define AT91_PMC_PCK0 (1 << 8) /* Programmable Clock 0 */
#define AT91_PMC_PCK1 (1 << 9) /* Programmable Clock 1 */
@@ -40,7 +38,7 @@
#define AT91_PMC_PCDR (AT91_PMC + 0x14) /* Peripheral Clock Disable Register */
#define AT91_PMC_PCSR (AT91_PMC + 0x18) /* Peripheral Clock Status Register */
-#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [some SAM9, CAP9] */
+#define AT91_CKGR_UCKR (AT91_PMC + 0x1C) /* UTMI Clock Register [some SAM9] */
#define AT91_PMC_UPLLEN (1 << 16) /* UTMI PLL Enable */
#define AT91_PMC_UPLLCOUNT (0xf << 20) /* UTMI PLL Start-up Time */
#define AT91_PMC_BIASEN (1 << 24) /* UTMI BIAS Enable */
@@ -48,7 +46,7 @@
#define AT91_CKGR_MOR (AT91_PMC + 0x20) /* Main Oscillator Register [not on SAM9RL] */
#define AT91_PMC_MOSCEN (1 << 0) /* Main Oscillator Enable */
-#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x, CAP9] */
+#define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass [SAM9x] */
#define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */
#define AT91_CKGR_MCFR (AT91_PMC + 0x24) /* Main Clock Frequency Register */
@@ -87,7 +85,7 @@
#define AT91RM9200_PMC_MDIV_2 (1 << 8)
#define AT91RM9200_PMC_MDIV_3 (2 << 8)
#define AT91RM9200_PMC_MDIV_4 (3 << 8)
-#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9,CAP9 only] */
+#define AT91SAM9_PMC_MDIV_1 (0 << 8) /* [SAM9 only] */
#define AT91SAM9_PMC_MDIV_2 (1 << 8)
#define AT91SAM9_PMC_MDIV_4 (2 << 8)
#define AT91SAM9_PMC_MDIV_6 (3 << 8) /* [some SAM9 only] */
@@ -117,17 +115,15 @@
#define AT91_PMC_LOCKA (1 << 1) /* PLLA Lock */
#define AT91_PMC_LOCKB (1 << 2) /* PLLB Lock */
#define AT91_PMC_MCKRDY (1 << 3) /* Master Clock */
-#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9, AT91CAP9 only] */
-#define AT91_PMC_OSCSEL (1 << 7) /* Slow Clock Oscillator [AT91CAP9 revC only] */
+#define AT91_PMC_LOCKU (1 << 6) /* UPLL Lock [some SAM9] */
#define AT91_PMC_PCK0RDY (1 << 8) /* Programmable Clock 0 */
#define AT91_PMC_PCK1RDY (1 << 9) /* Programmable Clock 1 */
#define AT91_PMC_PCK2RDY (1 << 10) /* Programmable Clock 2 */
#define AT91_PMC_PCK3RDY (1 << 11) /* Programmable Clock 3 */
#define AT91_PMC_IMR (AT91_PMC + 0x6c) /* Interrupt Mask Register */
-#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Protect Register [AT91CAP9 revC only] */
+#define AT91_PMC_PROT (AT91_PMC + 0xe4) /* Write Protect Mode Register [some SAM9] */
#define AT91_PMC_PROTKEY 0x504d4301 /* Activation Code */
-#define AT91_PMC_VER (AT91_PMC + 0xfc) /* PMC Module Version [AT91CAP9 only] */
#endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9.h b/arch/arm/mach-at91/include/mach/at91cap9.h
deleted file mode 100644
index 61d952902f2..00000000000
--- a/arch/arm/mach-at91/include/mach/at91cap9.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91cap9.h
- *
- * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- * Copyright (C) 2007 Atmel Corporation.
- *
- * Common definitions.
- * Based on AT91CAP9 datasheet revision B (Preliminary).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91CAP9_H
-#define AT91CAP9_H
-
-/*
- * Peripheral identifiers/interrupts.
- */
-#define AT91CAP9_ID_PIOABCD 2 /* Parallel IO Controller A, B, C and D */
-#define AT91CAP9_ID_MPB0 3 /* MP Block Peripheral 0 */
-#define AT91CAP9_ID_MPB1 4 /* MP Block Peripheral 1 */
-#define AT91CAP9_ID_MPB2 5 /* MP Block Peripheral 2 */
-#define AT91CAP9_ID_MPB3 6 /* MP Block Peripheral 3 */
-#define AT91CAP9_ID_MPB4 7 /* MP Block Peripheral 4 */
-#define AT91CAP9_ID_US0 8 /* USART 0 */
-#define AT91CAP9_ID_US1 9 /* USART 1 */
-#define AT91CAP9_ID_US2 10 /* USART 2 */
-#define AT91CAP9_ID_MCI0 11 /* Multimedia Card Interface 0 */
-#define AT91CAP9_ID_MCI1 12 /* Multimedia Card Interface 1 */
-#define AT91CAP9_ID_CAN 13 /* CAN */
-#define AT91CAP9_ID_TWI 14 /* Two-Wire Interface */
-#define AT91CAP9_ID_SPI0 15 /* Serial Peripheral Interface 0 */
-#define AT91CAP9_ID_SPI1 16 /* Serial Peripheral Interface 0 */
-#define AT91CAP9_ID_SSC0 17 /* Serial Synchronous Controller 0 */
-#define AT91CAP9_ID_SSC1 18 /* Serial Synchronous Controller 1 */
-#define AT91CAP9_ID_AC97C 19 /* AC97 Controller */
-#define AT91CAP9_ID_TCB 20 /* Timer Counter 0, 1 and 2 */
-#define AT91CAP9_ID_PWMC 21 /* Pulse Width Modulation Controller */
-#define AT91CAP9_ID_EMAC 22 /* Ethernet */
-#define AT91CAP9_ID_AESTDES 23 /* Advanced Encryption Standard, Triple DES */
-#define AT91CAP9_ID_ADC 24 /* Analog-to-Digital Converter */
-#define AT91CAP9_ID_ISI 25 /* Image Sensor Interface */
-#define AT91CAP9_ID_LCDC 26 /* LCD Controller */
-#define AT91CAP9_ID_DMA 27 /* DMA Controller */
-#define AT91CAP9_ID_UDPHS 28 /* USB High Speed Device Port */
-#define AT91CAP9_ID_UHP 29 /* USB Host Port */
-#define AT91CAP9_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */
-#define AT91CAP9_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */
-
-/*
- * User Peripheral physical base addresses.
- */
-#define AT91CAP9_BASE_UDPHS 0xfff78000
-#define AT91CAP9_BASE_TCB0 0xfff7c000
-#define AT91CAP9_BASE_TC0 0xfff7c000
-#define AT91CAP9_BASE_TC1 0xfff7c040
-#define AT91CAP9_BASE_TC2 0xfff7c080
-#define AT91CAP9_BASE_MCI0 0xfff80000
-#define AT91CAP9_BASE_MCI1 0xfff84000
-#define AT91CAP9_BASE_TWI 0xfff88000
-#define AT91CAP9_BASE_US0 0xfff8c000
-#define AT91CAP9_BASE_US1 0xfff90000
-#define AT91CAP9_BASE_US2 0xfff94000
-#define AT91CAP9_BASE_SSC0 0xfff98000
-#define AT91CAP9_BASE_SSC1 0xfff9c000
-#define AT91CAP9_BASE_AC97C 0xfffa0000
-#define AT91CAP9_BASE_SPI0 0xfffa4000
-#define AT91CAP9_BASE_SPI1 0xfffa8000
-#define AT91CAP9_BASE_CAN 0xfffac000
-#define AT91CAP9_BASE_PWMC 0xfffb8000
-#define AT91CAP9_BASE_EMAC 0xfffbc000
-#define AT91CAP9_BASE_ADC 0xfffc0000
-#define AT91CAP9_BASE_ISI 0xfffc4000
-
-/*
- * System Peripherals (offset from AT91_BASE_SYS)
- */
-#define AT91_BCRAMC (0xffffe400 - AT91_BASE_SYS)
-#define AT91_DDRSDRC0 (0xffffe600 - AT91_BASE_SYS)
-#define AT91_MATRIX (0xffffea00 - AT91_BASE_SYS)
-#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
-#define AT91_GPBR (cpu_is_at91cap9_revB() ? \
- (0xfffffd50 - AT91_BASE_SYS) : \
- (0xfffffd60 - AT91_BASE_SYS))
-
-#define AT91CAP9_BASE_ECC 0xffffe200
-#define AT91CAP9_BASE_DMA 0xffffec00
-#define AT91CAP9_BASE_SMC 0xffffe800
-#define AT91CAP9_BASE_DBGU AT91_BASE_DBGU1
-#define AT91CAP9_BASE_PIOA 0xfffff200
-#define AT91CAP9_BASE_PIOB 0xfffff400
-#define AT91CAP9_BASE_PIOC 0xfffff600
-#define AT91CAP9_BASE_PIOD 0xfffff800
-#define AT91CAP9_BASE_RSTC 0xfffffd00
-#define AT91CAP9_BASE_SHDWC 0xfffffd10
-#define AT91CAP9_BASE_RTT 0xfffffd20
-#define AT91CAP9_BASE_PIT 0xfffffd30
-#define AT91CAP9_BASE_WDT 0xfffffd40
-
-#define AT91_USART0 AT91CAP9_BASE_US0
-#define AT91_USART1 AT91CAP9_BASE_US1
-#define AT91_USART2 AT91CAP9_BASE_US2
-
-
-/*
- * Internal Memory.
- */
-#define AT91CAP9_SRAM_BASE 0x00100000 /* Internal SRAM base address */
-#define AT91CAP9_SRAM_SIZE (32 * SZ_1K) /* Internal SRAM size (32Kb) */
-
-#define AT91CAP9_ROM_BASE 0x00400000 /* Internal ROM base address */
-#define AT91CAP9_ROM_SIZE (32 * SZ_1K) /* Internal ROM size (32Kb) */
-
-#define AT91CAP9_LCDC_BASE 0x00500000 /* LCD Controller */
-#define AT91CAP9_UDPHS_FIFO 0x00600000 /* USB High Speed Device Port */
-#define AT91CAP9_UHP_BASE 0x00700000 /* USB Host controller */
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h b/arch/arm/mach-at91/include/mach/at91cap9_matrix.h
deleted file mode 100644
index 4b9d4aff4b4..00000000000
--- a/arch/arm/mach-at91/include/mach/at91cap9_matrix.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91cap9_matrix.h
- *
- * Copyright (C) 2007 Stelian Pop <stelian.pop@leadtechdesign.com>
- * Copyright (C) 2007 Lead Tech Design <www.leadtechdesign.com>
- * Copyright (C) 2006 Atmel Corporation.
- *
- * Memory Controllers (MATRIX, EBI) - System peripherals registers.
- * Based on AT91CAP9 datasheet revision B (Preliminary).
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-
-#ifndef AT91CAP9_MATRIX_H
-#define AT91CAP9_MATRIX_H
-
-#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
-#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
-#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
-#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
-#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
-#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
-#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */
-#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */
-#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */
-#define AT91_MATRIX_MCFG9 (AT91_MATRIX + 0x24) /* Master Configuration Register 9 */
-#define AT91_MATRIX_MCFG10 (AT91_MATRIX + 0x28) /* Master Configuration Register 10 */
-#define AT91_MATRIX_MCFG11 (AT91_MATRIX + 0x2C) /* Master Configuration Register 11 */
-#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
-#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
-#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
-#define AT91_MATRIX_ULBT_FOUR (2 << 0)
-#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
-#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
-
-#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
-#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
-#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
-#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
-#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
-#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */
-#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */
-#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */
-#define AT91_MATRIX_SCFG8 (AT91_MATRIX + 0x60) /* Slave Configuration Register 8 */
-#define AT91_MATRIX_SCFG9 (AT91_MATRIX + 0x64) /* Slave Configuration Register 9 */
-#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
-#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
-#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
-#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
-#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
-#define AT91_MATRIX_FIXED_DEFMSTR (0xf << 18) /* Fixed Index of Default Master */
-#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
-#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
-#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
-
-#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
-#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */
-#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
-#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */
-#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
-#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */
-#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
-#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */
-#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
-#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */
-#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */
-#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */
-#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */
-#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */
-#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */
-#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */
-#define AT91_MATRIX_PRAS8 (AT91_MATRIX + 0xC0) /* Priority Register A for Slave 8 */
-#define AT91_MATRIX_PRBS8 (AT91_MATRIX + 0xC4) /* Priority Register B for Slave 8 */
-#define AT91_MATRIX_PRAS9 (AT91_MATRIX + 0xC8) /* Priority Register A for Slave 9 */
-#define AT91_MATRIX_PRBS9 (AT91_MATRIX + 0xCC) /* Priority Register B for Slave 9 */
-#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
-#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
-#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
-#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
-#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
-#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
-#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
-#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
-#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
-#define AT91_MATRIX_M9PR (3 << 4) /* Master 9 Priority (in Register B) */
-#define AT91_MATRIX_M10PR (3 << 8) /* Master 10 Priority (in Register B) */
-#define AT91_MATRIX_M11PR (3 << 12) /* Master 11 Priority (in Register B) */
-
-#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
-#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
-#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
-#define AT91_MATRIX_RCB2 (1 << 2)
-#define AT91_MATRIX_RCB3 (1 << 3)
-#define AT91_MATRIX_RCB4 (1 << 4)
-#define AT91_MATRIX_RCB5 (1 << 5)
-#define AT91_MATRIX_RCB6 (1 << 6)
-#define AT91_MATRIX_RCB7 (1 << 7)
-#define AT91_MATRIX_RCB8 (1 << 8)
-#define AT91_MATRIX_RCB9 (1 << 9)
-#define AT91_MATRIX_RCB10 (1 << 10)
-#define AT91_MATRIX_RCB11 (1 << 11)
-
-#define AT91_MPBS0_SFR (AT91_MATRIX + 0x114) /* MPBlock Slave 0 Special Function Register */
-#define AT91_MPBS1_SFR (AT91_MATRIX + 0x11C) /* MPBlock Slave 1 Special Function Register */
-
-#define AT91_MATRIX_UDPHS (AT91_MATRIX + 0x118) /* USBHS Special Function Register [AT91CAP9 only] */
-#define AT91_MATRIX_SELECT_UDPHS (0 << 31) /* select High Speed UDP */
-#define AT91_MATRIX_SELECT_UDP (1 << 31) /* select standard UDP */
-#define AT91_MATRIX_UDPHS_BYPASS_LOCK (1 << 30) /* bypass lock bit */
-
-#define AT91_MATRIX_EBICSA (AT91_MATRIX + 0x120) /* EBI Chip Select Assignment Register */
-#define AT91_MATRIX_EBI_CS1A (1 << 1) /* Chip Select 1 Assignment */
-#define AT91_MATRIX_EBI_CS1A_SMC (0 << 1)
-#define AT91_MATRIX_EBI_CS1A_BCRAMC (1 << 1)
-#define AT91_MATRIX_EBI_CS3A (1 << 3) /* Chip Select 3 Assignment */
-#define AT91_MATRIX_EBI_CS3A_SMC (0 << 3)
-#define AT91_MATRIX_EBI_CS3A_SMC_SMARTMEDIA (1 << 3)
-#define AT91_MATRIX_EBI_CS4A (1 << 4) /* Chip Select 4 Assignment */
-#define AT91_MATRIX_EBI_CS4A_SMC (0 << 4)
-#define AT91_MATRIX_EBI_CS4A_SMC_CF1 (1 << 4)
-#define AT91_MATRIX_EBI_CS5A (1 << 5) /* Chip Select 5 Assignment */
-#define AT91_MATRIX_EBI_CS5A_SMC (0 << 5)
-#define AT91_MATRIX_EBI_CS5A_SMC_CF2 (1 << 5)
-#define AT91_MATRIX_EBI_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
-#define AT91_MATRIX_EBI_DQSPDC (1 << 9) /* Data Qualifier Strobe Pull-Down Configuration */
-#define AT91_MATRIX_EBI_VDDIOMSEL (1 << 16) /* Memory voltage selection */
-#define AT91_MATRIX_EBI_VDDIOMSEL_1_8V (0 << 16)
-#define AT91_MATRIX_EBI_VDDIOMSEL_3_3V (1 << 16)
-
-#define AT91_MPBS2_SFR (AT91_MATRIX + 0x12C) /* MPBlock Slave 2 Special Function Register */
-#define AT91_MPBS3_SFR (AT91_MATRIX + 0x130) /* MPBlock Slave 3 Special Function Register */
-#define AT91_APB_SFR (AT91_MATRIX + 0x134) /* APB Bridge Special Function Register */
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
index e2f8da8ce5b..5d4a9f84658 100644
--- a/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
+++ b/arch/arm/mach-at91/include/mach/at91sam9_ddrsdr.h
@@ -59,7 +59,6 @@
#define AT91_DDRSDRC_TRP (0xf << 16) /* Row precharge delay */
#define AT91_DDRSDRC_TRRD (0xf << 20) /* Active BankA to BankB */
#define AT91_DDRSDRC_TWTR (0x7 << 24) /* Internal Write to Read delay */
-#define AT91CAP9_DDRSDRC_TWTR (1 << 24) /* Internal Write to Read delay */
#define AT91_DDRSDRC_RED_WRRD (0x1 << 27) /* Reduce Write to Read Delay [SAM9 Only] */
#define AT91_DDRSDRC_TMRD (0xf << 28) /* Load mode to active/refresh delay */
@@ -76,7 +75,6 @@
#define AT91_DDRSDRC_TRTP (0x7 << 12) /* Read to Precharge delay */
#define AT91_DDRSDRC_LPR 0x1C /* Low Power Register */
-#define AT91CAP9_DDRSDRC_LPR 0x18 /* Low Power Register */
#define AT91_DDRSDRC_LPCB (3 << 0) /* Low-power Configurations */
#define AT91_DDRSDRC_LPCB_DISABLE 0
#define AT91_DDRSDRC_LPCB_SELF_REFRESH 1
@@ -94,11 +92,9 @@
#define AT91_DDRSDRC_UPD_MR (3 << 20) /* Update load mode register and extended mode register */
#define AT91_DDRSDRC_MDR 0x20 /* Memory Device Register */
-#define AT91CAP9_DDRSDRC_MDR 0x1C /* Memory Device Register */
#define AT91_DDRSDRC_MD (3 << 0) /* Memory Device Type */
#define AT91_DDRSDRC_MD_SDR 0
#define AT91_DDRSDRC_MD_LOW_POWER_SDR 1
-#define AT91CAP9_DDRSDRC_MD_DDR 2
#define AT91_DDRSDRC_MD_LOW_POWER_DDR 3
#define AT91_DDRSDRC_MD_DDR2 6 /* [SAM9 Only] */
#define AT91_DDRSDRC_DBW (1 << 4) /* Data Bus Width */
@@ -106,16 +102,10 @@
#define AT91_DDRSDRC_DBW_16BITS (1 << 4)
#define AT91_DDRSDRC_DLL 0x24 /* DLL Information Register */
-#define AT91CAP9_DDRSDRC_DLL 0x20 /* DLL Information Register */
#define AT91_DDRSDRC_MDINC (1 << 0) /* Master Delay increment */
#define AT91_DDRSDRC_MDDEC (1 << 1) /* Master Delay decrement */
#define AT91_DDRSDRC_MDOVF (1 << 2) /* Master Delay Overflow */
-#define AT91CAP9_DDRSDRC_SDCOVF (1 << 3) /* Slave Delay Correction Overflow */
-#define AT91CAP9_DDRSDRC_SDCUDF (1 << 4) /* Slave Delay Correction Underflow */
-#define AT91CAP9_DDRSDRC_SDERF (1 << 5) /* Slave Delay Correction error */
#define AT91_DDRSDRC_MDVAL (0xff << 8) /* Master Delay value */
-#define AT91CAP9_DDRSDRC_SDVAL (0xff << 16) /* Slave Delay value */
-#define AT91CAP9_DDRSDRC_SDCVAL (0xff << 24) /* Slave Delay Correction value */
#define AT91_DDRSDRC_HS 0x2C /* High Speed Register [SAM9 Only] */
#define AT91_DDRSDRC_DIS_ATCP_RD (1 << 2) /* Anticip read access is disabled */
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h
index 3b33f07b1e1..dc8d6d4f17c 100644
--- a/arch/arm/mach-at91/include/mach/board.h
+++ b/arch/arm/mach-at91/include/mach/board.h
@@ -107,6 +107,8 @@ struct atmel_nand_data {
u8 ale; /* address line number connected to ALE */
u8 cle; /* address line number connected to CLE */
u8 bus_width_16; /* buswidth is 16 bit */
+ u8 correction_cap; /* PMECC correction capability */
+ u16 sector_size; /* Sector size for PMECC */
struct mtd_partition *parts;
unsigned int num_parts;
};
@@ -179,7 +181,9 @@ extern void __init at91_add_device_lcdc(struct atmel_lcdfb_info *data);
extern void __init at91_add_device_ac97(struct ac97c_platform_data *data);
/* ISI */
-extern void __init at91_add_device_isi(void);
+struct isi_platform_data;
+extern void __init at91_add_device_isi(struct isi_platform_data *data,
+ bool use_pck_as_mck);
/* Touchscreen Controller */
struct at91_tsadcc_data {
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index f6ce936dba2..0118c333855 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -25,7 +25,6 @@
#define ARCH_ID_AT91SAM9G45MRL 0x819b05a2 /* aka 9G45-ES2 & non ES lots */
#define ARCH_ID_AT91SAM9G45ES 0x819b05a1 /* 9G45-ES (Engineering Sample) */
#define ARCH_ID_AT91SAM9X5 0x819a05a0
-#define ARCH_ID_AT91CAP9 0x039A03A0
#define ARCH_ID_AT91SAM9XE128 0x329973a0
#define ARCH_ID_AT91SAM9XE256 0x329a93a0
@@ -51,10 +50,6 @@
#define ARCH_FAMILY_AT91SAM9 0x01900000
#define ARCH_FAMILY_AT91SAM9XE 0x02900000
-/* PMC revision */
-#define ARCH_REVISION_CAP9_B 0x399
-#define ARCH_REVISION_CAP9_C 0x601
-
/* RM9200 type */
#define ARCH_REVISON_9200_BGA (0 << 0)
#define ARCH_REVISON_9200_PQFP (1 << 0)
@@ -63,9 +58,6 @@ enum at91_soc_type {
/* 920T */
AT91_SOC_RM9200,
- /* CAP */
- AT91_SOC_CAP9,
-
/* SAM92xx */
AT91_SOC_SAM9260, AT91_SOC_SAM9261, AT91_SOC_SAM9263,
@@ -86,9 +78,6 @@ enum at91_soc_subtype {
/* RM9200 */
AT91_SOC_RM9200_BGA, AT91_SOC_RM9200_PQFP,
- /* CAP9 */
- AT91_SOC_CAP9_REV_B, AT91_SOC_CAP9_REV_C,
-
/* SAM9260 */
AT91_SOC_SAM9XE,
@@ -195,16 +184,6 @@ static inline int at91_soc_is_detected(void)
#define cpu_is_at91sam9x25() (0)
#endif
-#ifdef CONFIG_ARCH_AT91CAP9
-#define cpu_is_at91cap9() (at91_soc_initdata.type == AT91_SOC_CAP9)
-#define cpu_is_at91cap9_revB() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_B)
-#define cpu_is_at91cap9_revC() (at91_soc_initdata.subtype == AT91_SOC_CAP9_REV_C)
-#else
-#define cpu_is_at91cap9() (0)
-#define cpu_is_at91cap9_revB() (0)
-#define cpu_is_at91cap9_revC() (0)
-#endif
-
/*
* Since this is ARM, we will never run on any AVR32 CPU. But these
* definitions may reduce clutter in common drivers.
diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h
index 2d0e4e99856..c213f28628c 100644
--- a/arch/arm/mach-at91/include/mach/hardware.h
+++ b/arch/arm/mach-at91/include/mach/hardware.h
@@ -19,7 +19,7 @@
/* DBGU base */
/* rm9200, 9260/9g20, 9261/9g10, 9rl */
#define AT91_BASE_DBGU0 0xfffff200
-/* 9263, 9g45, cap9 */
+/* 9263, 9g45 */
#define AT91_BASE_DBGU1 0xffffee00
#if defined(CONFIG_ARCH_AT91RM9200)
@@ -34,8 +34,6 @@
#include <mach/at91sam9rl.h>
#elif defined(CONFIG_ARCH_AT91SAM9G45)
#include <mach/at91sam9g45.h>
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91cap9.h>
#elif defined(CONFIG_ARCH_AT91X40)
#include <mach/at91x40.h>
#else
diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h
deleted file mode 100644
index cbd64f3bcec..00000000000
--- a/arch/arm/mach-at91/include/mach/system.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/system.h
- *
- * Copyright (C) 2003 SAN People
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <mach/hardware.h>
-#include <mach/at91_st.h>
-#include <mach/at91_dbgu.h>
-#include <mach/at91_pmc.h>
-
-static inline void arch_idle(void)
-{
- /*
- * Disable the processor clock. The processor will be automatically
- * re-enabled by an interrupt or by a reset.
- */
-#ifdef AT91_PS
- at91_sys_write(AT91_PS_CR, AT91_PS_CR_CPU);
-#else
- at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-#endif
-#ifndef CONFIG_CPU_ARM920T
- /*
- * Set the processor (CP15) into 'Wait for Interrupt' mode.
- * Post-RM9200 processors need this in conjunction with the above
- * to save power when idle.
- */
- cpu_do_idle();
-#endif
-}
-
-#endif
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 1606379ac28..87be5aa1875 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -150,11 +150,6 @@ static int at91_pm_verify_clocks(void)
pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
return 0;
}
- } else if (cpu_is_at91cap9()) {
- if ((scsr & AT91CAP9_PMC_UHP) != 0) {
- pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
- return 0;
- }
}
#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h
index 7eb40d24242..218d816427c 100644
--- a/arch/arm/mach-at91/pm.h
+++ b/arch/arm/mach-at91/pm.h
@@ -24,24 +24,6 @@ static inline u32 sdram_selfrefresh_enable(void)
#define wait_for_interrupt_enable() asm volatile ("mcr p15, 0, %0, c7, c0, 4" \
: : "r" (0))
-#elif defined(CONFIG_ARCH_AT91CAP9)
-#include <mach/at91sam9_ddrsdr.h>
-
-
-static inline u32 sdram_selfrefresh_enable(void)
-{
- u32 saved_lpr, lpr;
-
- saved_lpr = at91_ramc_read(0, AT91CAP9_DDRSDRC_LPR);
-
- lpr = saved_lpr & ~AT91_DDRSDRC_LPCB;
- at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH);
- return saved_lpr;
-}
-
-#define sdram_selfrefresh_disable(saved_lpr) at91_ramc_write(0, AT91CAP9_DDRSDRC_LPR, saved_lpr)
-#define wait_for_interrupt_enable() cpu_do_idle()
-
#elif defined(CONFIG_ARCH_AT91SAM9G45)
#include <mach/at91sam9_ddrsdr.h>
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index 92dfb846139..f8539a8bcd6 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -18,8 +18,7 @@
#if defined(CONFIG_ARCH_AT91RM9200)
#include <mach/at91rm9200_mc.h>
-#elif defined(CONFIG_ARCH_AT91CAP9) \
- || defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
#include <mach/at91sam9_ddrsdr.h>
#else
#include <mach/at91sam9_sdramc.h>
@@ -130,8 +129,7 @@ ENTRY(at91_slow_clock)
/* Put SDRAM in self-refresh mode */
mov r3, #1
str r3, [r2, #AT91_SDRAMC_SRR]
-#elif defined(CONFIG_ARCH_AT91CAP9) \
- || defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
/* prepare for DDRAM self-refresh mode */
ldr r3, [r2, #AT91_DDRSDRC_LPR]
@@ -263,8 +261,7 @@ ENTRY(at91_slow_clock)
#ifdef CONFIG_ARCH_AT91RM9200
/* Do nothing - self-refresh is automatically disabled. */
-#elif defined(CONFIG_ARCH_AT91CAP9) \
- || defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
/* Restore LPR on AT91 with DDRAM */
ldr r3, .saved_sam9_lpr
str r3, [r2, #AT91_DDRSDRC_LPR]
@@ -305,8 +302,7 @@ ENTRY(at91_slow_clock)
#ifdef CONFIG_ARCH_AT91RM9200
.at91_va_base_sdramc:
.word AT91_VA_BASE_SYS
-#elif defined(CONFIG_ARCH_AT91CAP9) \
- || defined(CONFIG_ARCH_AT91SAM9G45)
+#elif defined(CONFIG_ARCH_AT91SAM9G45)
.at91_va_base_sdramc:
.word AT91_VA_BASE_SYS + AT91_DDRSDRC0
#else
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index 69d3fc4c46f..620c67e8f81 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -86,20 +86,6 @@ static void __init soc_detect(u32 dbgu_base)
socid = cidr & ~AT91_CIDR_VERSION;
switch (socid) {
- case ARCH_ID_AT91CAP9: {
-#ifdef CONFIG_AT91_PMC_UNIT
- u32 pmc_ver = at91_sys_read(AT91_PMC_VER);
-
- if (pmc_ver == ARCH_REVISION_CAP9_B)
- at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_B;
- else if (pmc_ver == ARCH_REVISION_CAP9_C)
- at91_soc_initdata.subtype = AT91_SOC_CAP9_REV_C;
-#endif
- at91_soc_initdata.type = AT91_SOC_CAP9;
- at91_boot_soc = at91cap9_soc;
- break;
- }
-
case ARCH_ID_AT91RM9200:
at91_soc_initdata.type = AT91_SOC_RM9200;
at91_boot_soc = at91rm9200_soc;
@@ -200,7 +186,6 @@ static void __init soc_detect(u32 dbgu_base)
static const char *soc_name[] = {
[AT91_SOC_RM9200] = "at91rm9200",
- [AT91_SOC_CAP9] = "at91cap9",
[AT91_SOC_SAM9260] = "at91sam9260",
[AT91_SOC_SAM9261] = "at91sam9261",
[AT91_SOC_SAM9263] = "at91sam9263",
@@ -221,8 +206,6 @@ EXPORT_SYMBOL(at91_get_soc_type);
static const char *soc_subtype_name[] = {
[AT91_SOC_RM9200_BGA] = "at91rm9200 BGA",
[AT91_SOC_RM9200_PQFP] = "at91rm9200 PQFP",
- [AT91_SOC_CAP9_REV_B] = "at91cap9 revB",
- [AT91_SOC_CAP9_REV_C] = "at91cap9 revC",
[AT91_SOC_SAM9XE] = "at91sam9xe",
[AT91_SOC_SAM9G45ES] = "at91sam9g45es",
[AT91_SOC_SAM9M10] = "at91sam9m10",
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
index 4588ae6f7ac..5db4aa45404 100644
--- a/arch/arm/mach-at91/soc.h
+++ b/arch/arm/mach-at91/soc.h
@@ -13,7 +13,6 @@ struct at91_init_soc {
};
extern struct at91_init_soc at91_boot_soc;
-extern struct at91_init_soc at91cap9_soc;
extern struct at91_init_soc at91rm9200_soc;
extern struct at91_init_soc at91sam9260_soc;
extern struct at91_init_soc at91sam9261_soc;
@@ -27,10 +26,6 @@ static inline int at91_soc_is_enabled(void)
return at91_boot_soc.init != NULL;
}
-#if !defined(CONFIG_ARCH_AT91CAP9)
-#define at91cap9_soc at91_boot_soc
-#endif
-
#if !defined(CONFIG_ARCH_AT91RM9200)
#define at91rm9200_soc at91_boot_soc
#endif
diff --git a/arch/arm/mach-bcmring/core.c b/arch/arm/mach-bcmring/core.c
index 6b67b7e8426..22e4e0a28ad 100644
--- a/arch/arm/mach-bcmring/core.c
+++ b/arch/arm/mach-bcmring/core.c
@@ -52,27 +52,8 @@
#include <mach/csp/chipcHw_inline.h>
#include <mach/csp/tmrHw_reg.h>
-#define AMBA_DEVICE(name, initname, base, plat, size) \
-static struct amba_device name##_device = { \
- .dev = { \
- .coherent_dma_mask = ~0, \
- .init_name = initname, \
- .platform_data = plat \
- }, \
- .res = { \
- .start = MM_ADDR_IO_##base, \
- .end = MM_ADDR_IO_##base + (size) - 1, \
- .flags = IORESOURCE_MEM \
- }, \
- .dma_mask = ~0, \
- .irq = { \
- IRQ_##base \
- } \
-}
-
-
-AMBA_DEVICE(uartA, "uarta", UARTA, NULL, SZ_4K);
-AMBA_DEVICE(uartB, "uartb", UARTB, NULL, SZ_4K);
+static AMBA_APB_DEVICE(uartA, "uarta", MM_ADDR_IO_UARTA, { IRQ_UARTA }, NULL);
+static AMBA_APB_DEVICE(uartB, "uartb", MM_ADDR_IO_UARTB, { IRQ_UARTB }, NULL);
static struct clk pll1_clk = {
.name = "PLL1",
diff --git a/arch/arm/mach-bcmring/include/mach/system.h b/arch/arm/mach-bcmring/include/mach/system.h
deleted file mode 100644
index cb78250db64..00000000000
--- a/arch/arm/mach-bcmring/include/mach/system.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- *
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-clps711x/common.c b/arch/arm/mach-clps711x/common.c
index ab1711b9b4d..8736c1acc16 100644
--- a/arch/arm/mach-clps711x/common.c
+++ b/arch/arm/mach-clps711x/common.c
@@ -225,3 +225,19 @@ void clps711x_restart(char mode, const char *cmd)
{
soft_restart(0);
}
+
+static void clps711x_idle(void)
+{
+ clps_writel(1, HALT);
+ __asm__ __volatile__(
+ "mov r0, r0\n\
+ mov r0, r0");
+}
+
+static int __init clps711x_idle_init(void)
+{
+ arm_pm_idle = clps711x_idle;
+ return 0;
+}
+
+arch_initcall(clps711x_idle_init);
diff --git a/arch/arm/mach-clps711x/include/mach/system.h b/arch/arm/mach-clps711x/include/mach/system.h
deleted file mode 100644
index 23d6ef8c84d..00000000000
--- a/arch/arm/mach-clps711x/include/mach/system.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-clps711x/include/mach/system.h
- *
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <linux/io.h>
-#include <mach/hardware.h>
-#include <asm/hardware/clps7111.h>
-
-static inline void arch_idle(void)
-{
- clps_writel(1, HALT);
- __asm__ __volatile__(
- "mov r0, r0\n\
- mov r0, r0");
-}
-
-#endif
diff --git a/arch/arm/mach-cns3xxx/include/mach/system.h b/arch/arm/mach-cns3xxx/include/mach/system.h
deleted file mode 100644
index 9e56b7dc133..00000000000
--- a/arch/arm/mach-cns3xxx/include/mach/system.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright 2000 Deep Blue Solutions Ltd
- * Copyright 2003 ARM Limited
- * Copyright 2008 Cavium Networks
- *
- * This file is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, Version 2, as
- * published by the Free Software Foundation.
- */
-
-#ifndef __MACH_SYSTEM_H
-#define __MACH_SYSTEM_H
-
-#include <asm/proc-fns.h>
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks
- */
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h
deleted file mode 100644
index fcb7a015aba..00000000000
--- a/arch/arm/mach-davinci/include/mach/system.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * DaVinci system defines
- *
- * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <mach/common.h>
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-dove/include/mach/system.h b/arch/arm/mach-dove/include/mach/system.h
deleted file mode 100644
index 3027954f616..00000000000
--- a/arch/arm/mach-dove/include/mach/system.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-dove/include/mach/system.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-ebsa110/core.c b/arch/arm/mach-ebsa110/core.c
index 294aad07f7a..804c9122b7b 100644
--- a/arch/arm/mach-ebsa110/core.c
+++ b/arch/arm/mach-ebsa110/core.c
@@ -271,8 +271,33 @@ static struct platform_device *ebsa110_devices[] = {
&am79c961_device,
};
+/*
+ * EBSA110 idling methodology:
+ *
+ * We can not execute the "wait for interrupt" instruction since that
+ * will stop our MCLK signal (which provides the clock for the glue
+ * logic, and therefore the timer interrupt).
+ *
+ * Instead, we spin, polling the IRQ_STAT register for the occurrence
+ * of any interrupt with core clock down to the memory clock.
+ */
+static void ebsa110_idle(void)
+{
+ const char *irq_stat = (char *)0xff000000;
+
+ /* disable clock switching */
+ asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
+
+ /* wait for an interrupt to occur */
+ while (!*irq_stat);
+
+ /* enable clock switching */
+ asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
+}
+
static int __init ebsa110_init(void)
{
+ arm_pm_idle = ebsa110_idle;
return platform_add_devices(ebsa110_devices, ARRAY_SIZE(ebsa110_devices));
}
diff --git a/arch/arm/mach-ebsa110/include/mach/system.h b/arch/arm/mach-ebsa110/include/mach/system.h
deleted file mode 100644
index 2e4af65edb6..00000000000
--- a/arch/arm/mach-ebsa110/include/mach/system.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * arch/arm/mach-ebsa110/include/mach/system.h
- *
- * Copyright (C) 1996-2000 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-/*
- * EBSA110 idling methodology:
- *
- * We can not execute the "wait for interrupt" instruction since that
- * will stop our MCLK signal (which provides the clock for the glue
- * logic, and therefore the timer interrupt).
- *
- * Instead, we spin, polling the IRQ_STAT register for the occurrence
- * of any interrupt with core clock down to the memory clock.
- */
-static inline void arch_idle(void)
-{
- const char *irq_stat = (char *)0xff000000;
-
- /* disable clock switching */
- asm volatile ("mcr p15, 0, ip, c15, c2, 2" : : : "cc");
-
- /* wait for an interrupt to occur */
- while (!*irq_stat);
-
- /* enable clock switching */
- asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc");
-}
-
-#endif
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 24203f9a679..903edb02fe4 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -279,48 +279,14 @@ static struct amba_pl010_data ep93xx_uart_data = {
.set_mctrl = ep93xx_uart_set_mctrl,
};
-static struct amba_device uart1_device = {
- .dev = {
- .init_name = "apb:uart1",
- .platform_data = &ep93xx_uart_data,
- },
- .res = {
- .start = EP93XX_UART1_PHYS_BASE,
- .end = EP93XX_UART1_PHYS_BASE + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_EP93XX_UART1, NO_IRQ },
- .periphid = 0x00041010,
-};
-
-static struct amba_device uart2_device = {
- .dev = {
- .init_name = "apb:uart2",
- .platform_data = &ep93xx_uart_data,
- },
- .res = {
- .start = EP93XX_UART2_PHYS_BASE,
- .end = EP93XX_UART2_PHYS_BASE + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_EP93XX_UART2, NO_IRQ },
- .periphid = 0x00041010,
-};
+static AMBA_APB_DEVICE(uart1, "apb:uart1", 0x00041010, EP93XX_UART1_PHYS_BASE,
+ { IRQ_EP93XX_UART1 }, &ep93xx_uart_data);
-static struct amba_device uart3_device = {
- .dev = {
- .init_name = "apb:uart3",
- .platform_data = &ep93xx_uart_data,
- },
- .res = {
- .start = EP93XX_UART3_PHYS_BASE,
- .end = EP93XX_UART3_PHYS_BASE + 0x0fff,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_EP93XX_UART3, NO_IRQ },
- .periphid = 0x00041010,
-};
+static AMBA_APB_DEVICE(uart2, "apb:uart2", 0x00041010, EP93XX_UART2_PHYS_BASE,
+ { IRQ_EP93XX_UART2 }, &ep93xx_uart_data);
+static AMBA_APB_DEVICE(uart3, "apb:uart3", 0x00041010, EP93XX_UART3_PHYS_BASE,
+ { IRQ_EP93XX_UART3 }, &ep93xx_uart_data);
static struct resource ep93xx_rtc_resource[] = {
{
diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h
deleted file mode 100644
index b5bec7cb9b5..00000000000
--- a/arch/arm/mach-ep93xx/include/mach/system.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * arch/arm/mach-ep93xx/include/mach/system.h
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c
index c59e1887100..93fa2d532e4 100644
--- a/arch/arm/mach-exynos/common.c
+++ b/arch/arm/mach-exynos/common.c
@@ -201,14 +201,6 @@ static struct map_desc exynos4_iodesc1[] __initdata = {
},
};
-static void exynos_idle(void)
-{
- if (!need_resched())
- cpu_do_idle();
-
- local_irq_enable();
-}
-
void exynos4_restart(char mode, const char *cmd)
{
__raw_writel(0x1, S5P_SWRESET);
@@ -402,7 +394,7 @@ void __init exynos4_init_irq(void)
gic_bank_offset = soc_is_exynos4412() ? 0x4000 : 0x8000;
if (!of_have_populated_dt())
- gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset);
+ gic_init_bases(0, IRQ_PPI(0), S5P_VA_GIC_DIST, S5P_VA_GIC_CPU, gic_bank_offset, NULL);
#ifdef CONFIG_OF
else
of_irq_init(exynos4_dt_irq_match);
@@ -467,10 +459,6 @@ early_initcall(exynos4_l2x0_cache_init);
int __init exynos_init(void)
{
printk(KERN_INFO "EXYNOS: Initializing architecture\n");
-
- /* set idle function */
- pm_idle = exynos_idle;
-
return device_register(&exynos4_dev);
}
diff --git a/arch/arm/mach-exynos/dma.c b/arch/arm/mach-exynos/dma.c
index b10fcd270f0..91370def4a7 100644
--- a/arch/arm/mach-exynos/dma.c
+++ b/arch/arm/mach-exynos/dma.c
@@ -74,21 +74,8 @@ struct dma_pl330_platdata exynos4_pdma0_pdata = {
.peri_id = pdma0_peri,
};
-struct amba_device exynos4_device_pdma0 = {
- .dev = {
- .init_name = "dma-pl330.0",
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &exynos4_pdma0_pdata,
- },
- .res = {
- .start = EXYNOS4_PA_PDMA0,
- .end = EXYNOS4_PA_PDMA0 + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_PDMA0, NO_IRQ},
- .periphid = 0x00041330,
-};
+AMBA_AHB_DEVICE(exynos4_pdma0, "dma-pl330.0", 0x00041330, EXYNOS4_PA_PDMA0,
+ {IRQ_PDMA0}, &exynos4_pdma0_pdata);
u8 pdma1_peri[] = {
DMACH_PCM0_RX,
@@ -123,21 +110,8 @@ struct dma_pl330_platdata exynos4_pdma1_pdata = {
.peri_id = pdma1_peri,
};
-struct amba_device exynos4_device_pdma1 = {
- .dev = {
- .init_name = "dma-pl330.1",
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &exynos4_pdma1_pdata,
- },
- .res = {
- .start = EXYNOS4_PA_PDMA1,
- .end = EXYNOS4_PA_PDMA1 + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_PDMA1, NO_IRQ},
- .periphid = 0x00041330,
-};
+AMBA_AHB_DEVICE(exynos4_pdma1, "dma-pl330.1", 0x00041330, EXYNOS4_PA_PDMA1,
+ {IRQ_PDMA1}, &exynos4_pdma1_pdata);
static int __init exynos4_dma_init(void)
{
@@ -146,11 +120,11 @@ static int __init exynos4_dma_init(void)
dma_cap_set(DMA_SLAVE, exynos4_pdma0_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, exynos4_pdma0_pdata.cap_mask);
- amba_device_register(&exynos4_device_pdma0, &iomem_resource);
+ amba_device_register(&exynos4_pdma0_device, &iomem_resource);
dma_cap_set(DMA_SLAVE, exynos4_pdma1_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, exynos4_pdma1_pdata.cap_mask);
- amba_device_register(&exynos4_device_pdma1, &iomem_resource);
+ amba_device_register(&exynos4_pdma1_device, &iomem_resource);
return 0;
}
diff --git a/arch/arm/mach-exynos/include/mach/system.h b/arch/arm/mach-exynos/include/mach/system.h
deleted file mode 100644
index 0063a6de3dc..00000000000
--- a/arch/arm/mach-exynos/include/mach/system.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* linux/arch/arm/mach-exynos4/include/mach/system.h
- *
- * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS4 - system support header
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
- /* nothing here yet */
-}
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-footbridge/include/mach/system.h b/arch/arm/mach-footbridge/include/mach/system.h
deleted file mode 100644
index a174a5841bc..00000000000
--- a/arch/arm/mach-footbridge/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-footbridge/include/mach/system.h
- *
- * Copyright (C) 1996-1999 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-gemini/Makefile b/arch/arm/mach-gemini/Makefile
index c5b24b95a76..7355c0bbcb5 100644
--- a/arch/arm/mach-gemini/Makefile
+++ b/arch/arm/mach-gemini/Makefile
@@ -4,7 +4,7 @@
# Object file lists.
-obj-y := irq.o mm.o time.o devices.o gpio.o
+obj-y := irq.o mm.o time.o devices.o gpio.o idle.o
# Board-specific support
obj-$(CONFIG_MACH_NAS4220B) += board-nas4220b.o
diff --git a/arch/arm/mach-gemini/idle.c b/arch/arm/mach-gemini/idle.c
new file mode 100644
index 00000000000..92bbd6bb600
--- /dev/null
+++ b/arch/arm/mach-gemini/idle.c
@@ -0,0 +1,29 @@
+/*
+ * arch/arm/mach-gemini/idle.c
+ */
+
+#include <linux/init.h>
+#include <asm/system.h>
+#include <asm/proc-fns.h>
+
+static void gemini_idle(void)
+{
+ /*
+ * Because of broken hardware we have to enable interrupts or the CPU
+ * will never wakeup... Acctualy it is not very good to enable
+ * interrupts first since scheduler can miss a tick, but there is
+ * no other way around this. Platforms that needs it for power saving
+ * should call enable_hlt() in init code, since by default it is
+ * disabled.
+ */
+ local_irq_enable();
+ cpu_do_idle();
+}
+
+static int __init gemini_idle_init(void)
+{
+ arm_pm_idle = gemini_idle;
+ return 0;
+}
+
+arch_initcall(gemini_idle_init);
diff --git a/arch/arm/mach-gemini/include/mach/system.h b/arch/arm/mach-gemini/include/mach/system.h
index 4d9c1f87247..a33b5a1f8ab 100644
--- a/arch/arm/mach-gemini/include/mach/system.h
+++ b/arch/arm/mach-gemini/include/mach/system.h
@@ -14,20 +14,6 @@
#include <mach/hardware.h>
#include <mach/global_reg.h>
-static inline void arch_idle(void)
-{
- /*
- * Because of broken hardware we have to enable interrupts or the CPU
- * will never wakeup... Acctualy it is not very good to enable
- * interrupts here since scheduler can miss a tick, but there is
- * no other way around this. Platforms that needs it for power saving
- * should call enable_hlt() in init code, since by default it is
- * disabled.
- */
- local_irq_enable();
- cpu_do_idle();
-}
-
static inline void arch_reset(char mode, const char *cmd)
{
__raw_writel(RESET_GLOBAL | RESET_CPU1,
diff --git a/arch/arm/mach-gemini/irq.c b/arch/arm/mach-gemini/irq.c
index 9485a8fdf85..ca70e5fcc7a 100644
--- a/arch/arm/mach-gemini/irq.c
+++ b/arch/arm/mach-gemini/irq.c
@@ -73,8 +73,8 @@ void __init gemini_init_irq(void)
unsigned int i, mode = 0, level = 0;
/*
- * Disable arch_idle() by default since it is buggy
- * For more info see arch/arm/mach-gemini/include/mach/system.h
+ * Disable the idle handler by default since it is buggy
+ * For more info see arch/arm/mach-gemini/idle.c
*/
disable_hlt();
diff --git a/arch/arm/mach-h720x/common.c b/arch/arm/mach-h720x/common.c
index f8a2f6bb548..e756d1ac00c 100644
--- a/arch/arm/mach-h720x/common.c
+++ b/arch/arm/mach-h720x/common.c
@@ -247,3 +247,21 @@ void h720x_restart(char mode, const char *cmd)
{
CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET;
}
+
+static void h720x__idle(void)
+{
+ CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE;
+ nop();
+ nop();
+ CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN;
+ nop();
+ nop();
+}
+
+static int __init h720x_idle_init(void)
+{
+ arm_pm_idle = h720x__idle;
+ return 0;
+}
+
+arch_initcall(h720x_idle_init);
diff --git a/arch/arm/mach-h720x/include/mach/system.h b/arch/arm/mach-h720x/include/mach/system.h
deleted file mode 100644
index 16ac46e239a..00000000000
--- a/arch/arm/mach-h720x/include/mach/system.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * arch/arm/mach-h720x/include/mach/system.h
- *
- * Copyright (C) 2001-2002 Jungjun Kim, Hynix Semiconductor 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.
- * arch/arm/mach-h720x/include/mach/system.h
- *
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-#include <mach/hardware.h>
-
-static void arch_idle(void)
-{
- CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_IDLE;
- nop();
- nop();
- CPU_REG (PMU_BASE, PMU_MODE) = PMU_MODE_RUN;
- nop();
- nop();
-}
-
-#endif
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 4defb97bbfc..f7da8724965 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -304,6 +304,7 @@ config MACH_MX27_3DS
select IMX_HAVE_PLATFORM_IMX_I2C
select IMX_HAVE_PLATFORM_IMX_KEYPAD
select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_MX2_CAMERA
select IMX_HAVE_PLATFORM_MXC_EHCI
select IMX_HAVE_PLATFORM_MXC_MMC
select IMX_HAVE_PLATFORM_SPI_IMX
diff --git a/arch/arm/mach-imx/clock-imx6q.c b/arch/arm/mach-imx/clock-imx6q.c
index 2d88f8b9a45..111c328f542 100644
--- a/arch/arm/mach-imx/clock-imx6q.c
+++ b/arch/arm/mach-imx/clock-imx6q.c
@@ -329,6 +329,12 @@
#define BM_CLPCR_MASK_SCU_IDLE (0x1 << 26)
#define BM_CLPCR_MASK_L2CC_IDLE (0x1 << 27)
+#define BP_CCOSR_CKO1_EN 7
+#define BP_CCOSR_CKO1_PODF 4
+#define BM_CCOSR_CKO1_PODF (0x7 << 4)
+#define BP_CCOSR_CKO1_SEL 0
+#define BM_CCOSR_CKO1_SEL (0xf << 0)
+
#define FREQ_480M 480000000
#define FREQ_528M 528000000
#define FREQ_594M 594000000
@@ -393,6 +399,7 @@ static struct clk ipu1_di1_clk;
static struct clk ipu2_di0_clk;
static struct clk ipu2_di1_clk;
static struct clk enfc_clk;
+static struct clk cko1_clk;
static struct clk dummy_clk = {};
static unsigned long external_high_reference;
@@ -938,6 +945,24 @@ static void _clk_disable(struct clk *clk)
writel_relaxed(reg, clk->enable_reg);
}
+static int _clk_enable_1b(struct clk *clk)
+{
+ u32 reg;
+ reg = readl_relaxed(clk->enable_reg);
+ reg |= 0x1 << clk->enable_shift;
+ writel_relaxed(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable_1b(struct clk *clk)
+{
+ u32 reg;
+ reg = readl_relaxed(clk->enable_reg);
+ reg &= ~(0x1 << clk->enable_shift);
+ writel_relaxed(reg, clk->enable_reg);
+}
+
struct divider {
struct clk *clk;
void __iomem *reg;
@@ -983,6 +1008,7 @@ DEF_CLK_DIV1(ipu2_di0_pre_div, &ipu2_di0_pre_clk, CSCDR2, IPU2_DI0_PRE);
DEF_CLK_DIV1(ipu2_di1_pre_div, &ipu2_di1_pre_clk, CSCDR2, IPU2_DI1_PRE);
DEF_CLK_DIV1(ipu1_div, &ipu1_clk, CSCDR3, IPU1_HSP);
DEF_CLK_DIV1(ipu2_div, &ipu2_clk, CSCDR3, IPU2_HSP);
+DEF_CLK_DIV1(cko1_div, &cko1_clk, CCOSR, CKO1);
#define DEF_CLK_DIV2(d, c, r, b) \
static struct divider d = { \
@@ -1038,6 +1064,7 @@ static struct divider *dividers[] = {
&enfc_div,
&spdif_div,
&asrc_serial_div,
+ &cko1_div,
};
static unsigned long ldb_di_clk_get_rate(struct clk *clk)
@@ -1625,6 +1652,32 @@ DEF_IPU_DI_MUX(CSCDR2, 2, 1);
DEF_IPU_MUX(1);
DEF_IPU_MUX(2);
+static struct multiplexer cko1_mux = {
+ .clk = &cko1_clk,
+ .reg = CCOSR,
+ .bp = BP_CCOSR_CKO1_SEL,
+ .bm = BM_CCOSR_CKO1_SEL,
+ .parents = {
+ &pll3_usb_otg,
+ &pll2_bus,
+ &pll1_sys,
+ &pll5_video,
+ &dummy_clk,
+ &axi_clk,
+ &enfc_clk,
+ &ipu1_di0_clk,
+ &ipu1_di1_clk,
+ &ipu2_di0_clk,
+ &ipu2_di1_clk,
+ &ahb_clk,
+ &ipg_clk,
+ &ipg_perclk,
+ &ckil_clk,
+ &pll4_audio,
+ NULL
+ },
+};
+
static struct multiplexer *multiplexers[] = {
&axi_mux,
&periph_mux,
@@ -1667,6 +1720,7 @@ static struct multiplexer *multiplexers[] = {
&ipu2_di1_mux,
&ipu1_mux,
&ipu2_mux,
+ &cko1_mux,
};
static int _clk_set_parent(struct clk *clk, struct clk *parent)
@@ -1690,7 +1744,7 @@ static int _clk_set_parent(struct clk *clk, struct clk *parent)
break;
i++;
}
- if (!m->parents[i])
+ if (!m->parents[i] || m->parents[i] == &dummy_clk)
return -EINVAL;
val = readl_relaxed(m->reg);
@@ -1745,6 +1799,20 @@ DEF_NG_CLK(asrc_serial_clk, &pll3_usb_otg);
.secondary = s, \
}
+#define DEF_CLK_1B(name, er, es, p, s) \
+ static struct clk name = { \
+ .enable_reg = er, \
+ .enable_shift = es, \
+ .enable = _clk_enable_1b, \
+ .disable = _clk_disable_1b, \
+ .get_rate = _clk_get_rate, \
+ .set_rate = _clk_set_rate, \
+ .round_rate = _clk_round_rate, \
+ .set_parent = _clk_set_parent, \
+ .parent = p, \
+ .secondary = s, \
+ }
+
DEF_CLK(aips_tz1_clk, CCGR0, CG0, &ahb_clk, NULL);
DEF_CLK(aips_tz2_clk, CCGR0, CG1, &ahb_clk, NULL);
DEF_CLK(apbh_dma_clk, CCGR0, CG2, &ahb_clk, NULL);
@@ -1811,6 +1879,7 @@ DEF_CLK(usdhc4_clk, CCGR6, CG4, &pll2_pfd_400m, NULL);
DEF_CLK(emi_slow_clk, CCGR6, CG5, &axi_clk, NULL);
DEF_CLK(vdo_axi_clk, CCGR6, CG6, &axi_clk, NULL);
DEF_CLK(vpu_clk, CCGR6, CG7, &axi_clk, NULL);
+DEF_CLK_1B(cko1_clk, CCOSR, BP_CCOSR_CKO1_EN, &pll2_bus, NULL);
static int pcie_clk_enable(struct clk *clk)
{
@@ -1922,6 +1991,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "gpmi_io_clk", gpmi_io_clk),
_REGISTER_CLOCK(NULL, "usboh3_clk", usboh3_clk),
_REGISTER_CLOCK(NULL, "sata_clk", sata_clk),
+ _REGISTER_CLOCK(NULL, "cko1_clk", cko1_clk),
};
int imx6q_set_lpm(enum mxc_cpu_pwr_mode mode)
@@ -2029,6 +2099,8 @@ int __init mx6q_clocks_init(void)
clk_set_rate(&usdhc3_clk, 49500000);
clk_set_rate(&usdhc4_clk, 49500000);
+ clk_set_parent(&cko1_clk, &ahb_clk);
+
np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-gpt");
base = of_iomap(np, 0);
WARN_ON(!base);
diff --git a/arch/arm/mach-imx/imx51-dt.c b/arch/arm/mach-imx/imx51-dt.c
index e6bad17b908..1e03ef42faa 100644
--- a/arch/arm/mach-imx/imx51-dt.c
+++ b/arch/arm/mach-imx/imx51-dt.c
@@ -47,7 +47,7 @@ static const struct of_dev_auxdata imx51_auxdata_lookup[] __initconst = {
static int __init imx51_tzic_add_irq_domain(struct device_node *np,
struct device_node *interrupt_parent)
{
- irq_domain_add_simple(np, 0);
+ irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
return 0;
}
@@ -57,7 +57,7 @@ static int __init imx51_gpio_add_irq_domain(struct device_node *np,
static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
gpio_irq_base -= 32;
- irq_domain_add_simple(np, gpio_irq_base);
+ irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/imx53-dt.c b/arch/arm/mach-imx/imx53-dt.c
index 05ebb3e6867..fd5be0f20fb 100644
--- a/arch/arm/mach-imx/imx53-dt.c
+++ b/arch/arm/mach-imx/imx53-dt.c
@@ -51,7 +51,7 @@ static const struct of_dev_auxdata imx53_auxdata_lookup[] __initconst = {
static int __init imx53_tzic_add_irq_domain(struct device_node *np,
struct device_node *interrupt_parent)
{
- irq_domain_add_simple(np, 0);
+ irq_domain_add_legacy(np, 128, 0, 0, &irq_domain_simple_ops, NULL);
return 0;
}
@@ -61,7 +61,7 @@ static int __init imx53_gpio_add_irq_domain(struct device_node *np,
static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
gpio_irq_base -= 32;
- irq_domain_add_simple(np, gpio_irq_base);
+ irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/lluart.c b/arch/arm/mach-imx/lluart.c
index d4ab6f29a76..0213f8dcee8 100644
--- a/arch/arm/mach-imx/lluart.c
+++ b/arch/arm/mach-imx/lluart.c
@@ -17,7 +17,7 @@
#include <mach/hardware.h>
static struct map_desc imx_lluart_desc = {
-#ifdef CONFIG_DEBUG_IMX6Q_UART
+#ifdef CONFIG_DEBUG_IMX6Q_UART4
.virtual = MX6Q_IO_P2V(MX6Q_UART4_BASE_ADDR),
.pfn = __phys_to_pfn(MX6Q_UART4_BASE_ADDR),
.length = MX6Q_UART4_SIZE,
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index c2572810691..6075d4d62dd 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -97,7 +97,8 @@ static int __init imx6q_gpio_add_irq_domain(struct device_node *np,
static int gpio_irq_base = MXC_GPIO_IRQ_START + ARCH_NR_GPIOS;
gpio_irq_base -= 32;
- irq_domain_add_simple(np, gpio_irq_base);
+ irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops,
+ NULL);
return 0;
}
diff --git a/arch/arm/mach-imx/mach-mx21ads.c b/arch/arm/mach-imx/mach-mx21ads.c
index 8d9f95514b1..e432d4acee1 100644
--- a/arch/arm/mach-imx/mach-mx21ads.c
+++ b/arch/arm/mach-imx/mach-mx21ads.c
@@ -37,8 +37,8 @@
#define MX21ADS_REG_ADDR(offset) (void __force __iomem *) \
(MX21ADS_MMIO_BASE_ADDR + (offset))
+#define MX21ADS_CS8900A_MMIO_SIZE 0x200000
#define MX21ADS_CS8900A_IRQ IRQ_GPIOE(11)
-#define MX21ADS_CS8900A_IOBASE_REG MX21ADS_REG_ADDR(0x000000)
#define MX21ADS_ST16C255_IOBASE_REG MX21ADS_REG_ADDR(0x200000)
#define MX21ADS_VERSION_REG MX21ADS_REG_ADDR(0x400000)
#define MX21ADS_IO_REG MX21ADS_REG_ADDR(0x800000)
@@ -159,6 +159,18 @@ static struct platform_device mx21ads_nor_mtd_device = {
.resource = &mx21ads_flash_resource,
};
+static const struct resource mx21ads_cs8900_resources[] __initconst = {
+ DEFINE_RES_MEM(MX21_CS1_BASE_ADDR, MX21ADS_CS8900A_MMIO_SIZE),
+ DEFINE_RES_IRQ(MX21ADS_CS8900A_IRQ),
+};
+
+static const struct platform_device_info mx21ads_cs8900_devinfo __initconst = {
+ .name = "cs89x0",
+ .id = 0,
+ .res = mx21ads_cs8900_resources,
+ .num_res = ARRAY_SIZE(mx21ads_cs8900_resources),
+};
+
static const struct imxuart_platform_data uart_pdata_rts __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -292,6 +304,8 @@ static void __init mx21ads_board_init(void)
imx21_add_mxc_nand(&mx21ads_nand_board_info);
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
+ platform_device_register_full(
+ (struct platform_device_info *)&mx21ads_cs8900_devinfo);
}
static void __init mx21ads_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index 18f35816706..c6d385c5225 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -31,6 +31,8 @@
#include <linux/regulator/machine.h>
#include <linux/spi/l4f00242t03.h>
+#include <media/soc_camera.h>
+
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/time.h>
@@ -52,6 +54,8 @@
#define SD1_CD IMX_GPIO_NR(2, 26)
#define LCD_RESET IMX_GPIO_NR(1, 3)
#define LCD_ENABLE IMX_GPIO_NR(1, 31)
+#define CSI_PWRDWN IMX_GPIO_NR(4, 19)
+#define CSI_RESET IMX_GPIO_NR(3, 6)
static const int mx27pdk_pins[] __initconst = {
/* UART1 */
@@ -141,6 +145,26 @@ static const int mx27pdk_pins[] __initconst = {
PA30_PF_CONTRAST,
LCD_ENABLE | GPIO_GPIO | GPIO_OUT,
LCD_RESET | GPIO_GPIO | GPIO_OUT,
+ /* CSI */
+ PB10_PF_CSI_D0,
+ PB11_PF_CSI_D1,
+ PB12_PF_CSI_D2,
+ PB13_PF_CSI_D3,
+ PB14_PF_CSI_D4,
+ PB15_PF_CSI_MCLK,
+ PB16_PF_CSI_PIXCLK,
+ PB17_PF_CSI_D5,
+ PB18_PF_CSI_D6,
+ PB19_PF_CSI_D7,
+ PB20_PF_CSI_VSYNC,
+ PB21_PF_CSI_HSYNC,
+ CSI_PWRDWN | GPIO_GPIO | GPIO_OUT,
+ CSI_RESET | GPIO_GPIO | GPIO_OUT,
+};
+
+static struct gpio mx27_3ds_camera_gpios[] = {
+ { CSI_PWRDWN, GPIOF_OUT_INIT_HIGH, "camera-power" },
+ { CSI_RESET, GPIOF_OUT_INIT_HIGH, "camera-reset" },
};
static const struct imxuart_platform_data uart_pdata __initconst = {
@@ -242,6 +266,7 @@ static struct regulator_init_data gpo_init = {
static struct regulator_consumer_supply vmmc1_consumers[] = {
REGULATOR_SUPPLY("vcore", "spi0.0"),
+ REGULATOR_SUPPLY("cmos_2v8", "soc-camera-pdrv.0"),
};
static struct regulator_init_data vmmc1_init = {
@@ -270,6 +295,22 @@ static struct regulator_init_data vgen_init = {
.consumer_supplies = vgen_consumers,
};
+static struct regulator_consumer_supply vvib_consumers[] = {
+ REGULATOR_SUPPLY("cmos_vcore", "soc-camera-pdrv.0"),
+};
+
+static struct regulator_init_data vvib_init = {
+ .constraints = {
+ .min_uV = 1300000,
+ .max_uV = 1300000,
+ .apply_uV = 1,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
+ REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(vvib_consumers),
+ .consumer_supplies = vvib_consumers,
+};
+
static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = {
{
.id = MC13783_REG_VMMC1,
@@ -283,6 +324,9 @@ static struct mc13xxx_regulator_init_data mx27_3ds_regulators[] = {
}, {
.id = MC13783_REG_GPO3, /* Turn on 3.3V */
.init_data = &gpo_init,
+ }, {
+ .id = MC13783_REG_VVIB, /* Power OV2640 */
+ .init_data = &vvib_init,
},
};
@@ -311,6 +355,51 @@ static const struct spi_imx_master spi2_pdata __initconst = {
.num_chipselect = ARRAY_SIZE(spi2_chipselect),
};
+static int mx27_3ds_camera_power(struct device *dev, int on)
+{
+ /* enable or disable the camera */
+ pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
+ gpio_set_value(CSI_PWRDWN, on ? 0 : 1);
+
+ if (!on)
+ goto out;
+
+ /* If enabled, give a reset impulse */
+ gpio_set_value(CSI_RESET, 0);
+ msleep(20);
+ gpio_set_value(CSI_RESET, 1);
+ msleep(100);
+
+out:
+ return 0;
+}
+
+static struct i2c_board_info mx27_3ds_i2c_camera = {
+ I2C_BOARD_INFO("ov2640", 0x30),
+};
+
+static struct regulator_bulk_data mx27_3ds_camera_regs[] = {
+ { .supply = "cmos_vcore" },
+ { .supply = "cmos_2v8" },
+};
+
+static struct soc_camera_link iclink_ov2640 = {
+ .bus_id = 0,
+ .board_info = &mx27_3ds_i2c_camera,
+ .i2c_adapter_id = 0,
+ .power = mx27_3ds_camera_power,
+ .regulators = mx27_3ds_camera_regs,
+ .num_regulators = ARRAY_SIZE(mx27_3ds_camera_regs),
+};
+
+static struct platform_device mx27_3ds_ov2640 = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &iclink_ov2640,
+ },
+};
+
static struct imx_fb_videomode mx27_3ds_modes[] = {
{ /* 480x640 @ 60 Hz */
.mode = {
@@ -367,12 +456,21 @@ static struct spi_board_info mx27_3ds_spi_devs[] __initdata = {
},
};
+static struct platform_device *devices[] __initdata = {
+ &mx27_3ds_ov2640,
+};
+
+static const struct mx2_camera_platform_data mx27_3ds_cam_pdata __initconst = {
+ .clk = 26000000,
+};
+
static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = {
.bitrate = 100000,
};
static void __init mx27pdk_init(void)
{
+ int ret;
imx27_soc_init();
mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins),
@@ -404,7 +502,17 @@ static void __init mx27pdk_init(void)
if (mxc_expio_init(MX27_CS5_BASE_ADDR, EXPIO_PARENT_INT))
pr_warn("Init of the debugboard failed, all devices on the debugboard are unusable.\n");
imx27_add_imx_i2c(0, &mx27_3ds_i2c0_data);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
imx27_add_imx_fb(&mx27_3ds_fb_data);
+
+ ret = gpio_request_array(mx27_3ds_camera_gpios,
+ ARRAY_SIZE(mx27_3ds_camera_gpios));
+ if (ret) {
+ pr_err("Failed to request camera gpios");
+ iclink_ov2640.power = NULL;
+ }
+
+ imx27_add_mx2_camera(&mx27_3ds_cam_pdata);
}
static void __init mx27pdk_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c
index 4917aab0e25..4518e544822 100644
--- a/arch/arm/mach-imx/mach-mx31ads.c
+++ b/arch/arm/mach-imx/mach-mx31ads.c
@@ -28,7 +28,6 @@
#include <asm/memory.h>
#include <asm/mach/map.h>
#include <mach/common.h>
-#include <mach/board-mx31ads.h>
#include <mach/iomux-mx3.h>
#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
@@ -39,6 +38,9 @@
#include "devices-imx31.h"
+/* Base address of PBC controller */
+#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
+
/* PBC Board interrupt status register */
#define PBC_INTSTATUS 0x000016
@@ -62,6 +64,7 @@
#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
+#define MXC_EXP_IO_BASE MXC_BOARD_IRQ_START
#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
@@ -69,6 +72,10 @@
#define MXC_MAX_EXP_IO_LINES 16
+/* CS8900 */
+#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
+#define CS4_CS8900_MMIO_START 0x20000
+
/*
* The serial port definition structure.
*/
@@ -101,11 +108,29 @@ static struct platform_device serial_device = {
},
};
+static const struct resource mx31ads_cs8900_resources[] __initconst = {
+ DEFINE_RES_MEM(MX31_CS4_BASE_ADDR + CS4_CS8900_MMIO_START, SZ_64K),
+ DEFINE_RES_IRQ(EXPIO_INT_ENET_INT),
+};
+
+static const struct platform_device_info mx31ads_cs8900_devinfo __initconst = {
+ .name = "cs89x0",
+ .id = 0,
+ .res = mx31ads_cs8900_resources,
+ .num_res = ARRAY_SIZE(mx31ads_cs8900_resources),
+};
+
static int __init mxc_init_extuart(void)
{
return platform_device_register(&serial_device);
}
+static void __init mxc_init_ext_ethernet(void)
+{
+ platform_device_register_full(
+ (struct platform_device_info *)&mx31ads_cs8900_devinfo);
+}
+
static const struct imxuart_platform_data uart_pdata __initconst = {
.flags = IMXUART_HAVE_RTSCTS,
};
@@ -492,12 +517,15 @@ static void __init mxc_init_audio(void)
mxc_iomux_setup_multiple_pins(ssi_pins, ARRAY_SIZE(ssi_pins), "ssi");
}
-/* static mappings */
+/*
+ * Static mappings, starting from the CS4 start address up to the start address
+ * of the CS8900.
+ */
static struct map_desc mx31ads_io_desc[] __initdata = {
{
.virtual = MX31_CS4_BASE_ADDR_VIRT,
.pfn = __phys_to_pfn(MX31_CS4_BASE_ADDR),
- .length = MX31_CS4_SIZE / 2,
+ .length = CS4_CS8900_MMIO_START,
.type = MT_DEVICE
},
};
@@ -522,6 +550,7 @@ static void __init mx31ads_init(void)
mxc_init_imx_uart();
mxc_init_i2c();
mxc_init_audio();
+ mxc_init_ext_ethernet();
}
static void __init mx31ads_timer_init(void)
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
index f225262b5c3..96e042d0c9a 100644
--- a/arch/arm/mach-imx/mach-mx31moboard.c
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -507,7 +507,7 @@ static void mx31moboard_poweroff(void)
struct clk *clk = clk_get_sys("imx2-wdt.0", NULL);
if (!IS_ERR(clk))
- clk_enable(clk);
+ clk_prepare_enable(clk);
mxc_iomux_mode(MX31_PIN_WATCHDOG_RST__WATCHDOG_RST);
diff --git a/arch/arm/mach-imx/mm-imx3.c b/arch/arm/mach-imx/mm-imx3.c
index 31807d2a8b7..8404ee72555 100644
--- a/arch/arm/mach-imx/mm-imx3.c
+++ b/arch/arm/mach-imx/mm-imx3.c
@@ -34,31 +34,29 @@ static void imx3_idle(void)
{
unsigned long reg = 0;
- if (!need_resched())
- __asm__ __volatile__(
- /* disable I and D cache */
- "mrc p15, 0, %0, c1, c0, 0\n"
- "bic %0, %0, #0x00001000\n"
- "bic %0, %0, #0x00000004\n"
- "mcr p15, 0, %0, c1, c0, 0\n"
- /* invalidate I cache */
- "mov %0, #0\n"
- "mcr p15, 0, %0, c7, c5, 0\n"
- /* clear and invalidate D cache */
- "mov %0, #0\n"
- "mcr p15, 0, %0, c7, c14, 0\n"
- /* WFI */
- "mov %0, #0\n"
- "mcr p15, 0, %0, c7, c0, 4\n"
- "nop\n" "nop\n" "nop\n" "nop\n"
- "nop\n" "nop\n" "nop\n"
- /* enable I and D cache */
- "mrc p15, 0, %0, c1, c0, 0\n"
- "orr %0, %0, #0x00001000\n"
- "orr %0, %0, #0x00000004\n"
- "mcr p15, 0, %0, c1, c0, 0\n"
- : "=r" (reg));
- local_irq_enable();
+ __asm__ __volatile__(
+ /* disable I and D cache */
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ "bic %0, %0, #0x00001000\n"
+ "bic %0, %0, #0x00000004\n"
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ /* invalidate I cache */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c5, 0\n"
+ /* clear and invalidate D cache */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c14, 0\n"
+ /* WFI */
+ "mov %0, #0\n"
+ "mcr p15, 0, %0, c7, c0, 4\n"
+ "nop\n" "nop\n" "nop\n" "nop\n"
+ "nop\n" "nop\n" "nop\n"
+ /* enable I and D cache */
+ "mrc p15, 0, %0, c1, c0, 0\n"
+ "orr %0, %0, #0x00001000\n"
+ "orr %0, %0, #0x00000004\n"
+ "mcr p15, 0, %0, c1, c0, 0\n"
+ : "=r" (reg));
}
static void __iomem *imx3_ioremap(unsigned long phys_addr, size_t size,
@@ -134,8 +132,8 @@ void __init imx31_init_early(void)
{
mxc_set_cpu_type(MXC_CPU_MX31);
mxc_arch_reset_init(MX31_IO_ADDRESS(MX31_WDOG_BASE_ADDR));
- pm_idle = imx3_idle;
imx_ioremap = imx3_ioremap;
+ arm_pm_idle = imx3_idle;
}
void __init mx31_init_irq(void)
@@ -197,7 +195,7 @@ void __init imx35_init_early(void)
mxc_set_cpu_type(MXC_CPU_MX35);
mxc_iomux_v3_init(MX35_IO_ADDRESS(MX35_IOMUXC_BASE_ADDR));
mxc_arch_reset_init(MX35_IO_ADDRESS(MX35_WDOG_BASE_ADDR));
- pm_idle = imx3_idle;
+ arm_pm_idle = imx3_idle;
imx_ioremap = imx3_ioremap;
}
diff --git a/arch/arm/mach-imx/mm-imx5.c b/arch/arm/mach-imx/mm-imx5.c
index bc17dfea381..49549a72dc7 100644
--- a/arch/arm/mach-imx/mm-imx5.c
+++ b/arch/arm/mach-imx/mm-imx5.c
@@ -26,23 +26,17 @@ static struct clk *gpc_dvfs_clk;
static void imx5_idle(void)
{
- if (!need_resched()) {
- /* gpc clock is needed for SRPG */
- if (gpc_dvfs_clk == NULL) {
- gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
- if (IS_ERR(gpc_dvfs_clk))
- goto err0;
- }
- clk_enable(gpc_dvfs_clk);
- mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
- if (tzic_enable_wake())
- goto err1;
- cpu_do_idle();
-err1:
- clk_disable(gpc_dvfs_clk);
+ /* gpc clock is needed for SRPG */
+ if (gpc_dvfs_clk == NULL) {
+ gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs");
+ if (IS_ERR(gpc_dvfs_clk))
+ return;
}
-err0:
- local_irq_enable();
+ clk_enable(gpc_dvfs_clk);
+ mx5_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+ if (tzic_enable_wake() != 0)
+ cpu_do_idle();
+ clk_disable(gpc_dvfs_clk);
}
/*
@@ -108,7 +102,7 @@ void __init imx51_init_early(void)
mxc_set_cpu_type(MXC_CPU_MX51);
mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG1_BASE_ADDR));
- pm_idle = imx5_idle;
+ arm_pm_idle = imx5_idle;
}
void __init imx53_init_early(void)
diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c
index e455d2f855b..6fcffa7db97 100644
--- a/arch/arm/mach-imx/pm-imx27.c
+++ b/arch/arm/mach-imx/pm-imx27.c
@@ -10,7 +10,6 @@
#include <linux/kernel.h>
#include <linux/suspend.h>
#include <linux/io.h>
-#include <mach/system.h>
#include <mach/hardware.h>
static int mx27_suspend_enter(suspend_state_t state)
@@ -23,7 +22,7 @@ static int mx27_suspend_enter(suspend_state_t state)
cscr &= 0xFFFFFFFC;
__raw_writel(cscr, MX27_IO_ADDRESS(MX27_CCM_BASE_ADDR));
/* Executes WFI */
- arch_idle();
+ cpu_do_idle();
break;
default:
diff --git a/arch/arm/mach-imx/pm-imx5.c b/arch/arm/mach-imx/pm-imx5.c
index 6dc09344805..e26a9cb05ed 100644
--- a/arch/arm/mach-imx/pm-imx5.c
+++ b/arch/arm/mach-imx/pm-imx5.c
@@ -89,7 +89,7 @@ void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
static int mx5_suspend_prepare(void)
{
- return clk_enable(gpc_dvfs_clk);
+ return clk_prepare_enable(gpc_dvfs_clk);
}
static int mx5_suspend_enter(suspend_state_t state)
@@ -119,7 +119,7 @@ static int mx5_suspend_enter(suspend_state_t state)
static void mx5_suspend_finish(void)
{
- clk_disable(gpc_dvfs_clk);
+ clk_disable_unprepare(gpc_dvfs_clk);
}
static int mx5_pm_valid(suspend_state_t state)
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
index 019f0ab08f6..15b87f26ac9 100644
--- a/arch/arm/mach-integrator/core.c
+++ b/arch/arm/mach-integrator/core.c
@@ -35,67 +35,23 @@
static struct amba_pl010_data integrator_uart_data;
-static struct amba_device rtc_device = {
- .dev = {
- .init_name = "mb:15",
- },
- .res = {
- .start = INTEGRATOR_RTC_BASE,
- .end = INTEGRATOR_RTC_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_RTCINT, NO_IRQ },
-};
+#define INTEGRATOR_RTC_IRQ { IRQ_RTCINT }
+#define INTEGRATOR_UART0_IRQ { IRQ_UARTINT0 }
+#define INTEGRATOR_UART1_IRQ { IRQ_UARTINT1 }
+#define KMI0_IRQ { IRQ_KMIINT0 }
+#define KMI1_IRQ { IRQ_KMIINT1 }
-static struct amba_device uart0_device = {
- .dev = {
- .init_name = "mb:16",
- .platform_data = &integrator_uart_data,
- },
- .res = {
- .start = INTEGRATOR_UART0_BASE,
- .end = INTEGRATOR_UART0_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_UARTINT0, NO_IRQ },
-};
+static AMBA_APB_DEVICE(rtc, "mb:15", 0,
+ INTEGRATOR_RTC_BASE, INTEGRATOR_RTC_IRQ, NULL);
-static struct amba_device uart1_device = {
- .dev = {
- .init_name = "mb:17",
- .platform_data = &integrator_uart_data,
- },
- .res = {
- .start = INTEGRATOR_UART1_BASE,
- .end = INTEGRATOR_UART1_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_UARTINT1, NO_IRQ },
-};
+static AMBA_APB_DEVICE(uart0, "mb:16", 0,
+ INTEGRATOR_UART0_BASE, INTEGRATOR_UART0_IRQ, &integrator_uart_data);
-static struct amba_device kmi0_device = {
- .dev = {
- .init_name = "mb:18",
- },
- .res = {
- .start = KMI0_BASE,
- .end = KMI0_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_KMIINT0, NO_IRQ },
-};
+static AMBA_APB_DEVICE(uart1, "mb:17", 0,
+ INTEGRATOR_UART1_BASE, INTEGRATOR_UART1_IRQ, &integrator_uart_data);
-static struct amba_device kmi1_device = {
- .dev = {
- .init_name = "mb:19",
- },
- .res = {
- .start = KMI1_BASE,
- .end = KMI1_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_KMIINT1, NO_IRQ },
-};
+static AMBA_APB_DEVICE(kmi0, "mb:18", 0, KMI0_BASE, KMI0_IRQ, NULL);
+static AMBA_APB_DEVICE(kmi1, "mb:19", 0, KMI1_BASE, KMI1_IRQ, NULL);
static struct amba_device *amba_devs[] __initdata = {
&rtc_device,
diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
index 8cbb75a96bd..3e538da6cb1 100644
--- a/arch/arm/mach-integrator/impd1.c
+++ b/arch/arm/mach-integrator/impd1.c
@@ -401,24 +401,21 @@ static int impd1_probe(struct lm_device *dev)
pc_base = dev->resource.start + idev->offset;
- d = kzalloc(sizeof(struct amba_device), GFP_KERNEL);
+ d = amba_device_alloc(NULL, pc_base, SZ_4K);
if (!d)
continue;
dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
d->dev.parent = &dev->dev;
- d->res.start = dev->resource.start + idev->offset;
- d->res.end = d->res.start + SZ_4K - 1;
- d->res.flags = IORESOURCE_MEM;
d->irq[0] = dev->irq;
d->irq[1] = dev->irq;
d->periphid = idev->id;
d->dev.platform_data = idev->platform_data;
- ret = amba_device_register(d, &dev->resource);
+ ret = amba_device_add(d, &dev->resource);
if (ret) {
dev_err(&d->dev, "unable to register device: %d\n", ret);
- kfree(d);
+ amba_device_put(d);
}
}
diff --git a/arch/arm/mach-integrator/include/mach/system.h b/arch/arm/mach-integrator/include/mach/system.h
deleted file mode 100644
index 901514eba4a..00000000000
--- a/arch/arm/mach-integrator/include/mach/system.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/mach-integrator/include/mach/system.h
- *
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks
- */
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c
index a8b6aa6003f..be9ead4a3bc 100644
--- a/arch/arm/mach-integrator/integrator_cp.c
+++ b/arch/arm/mach-integrator/integrator_cp.c
@@ -347,32 +347,14 @@ static struct mmci_platform_data mmc_data = {
.gpio_cd = -1,
};
-static struct amba_device mmc_device = {
- .dev = {
- .init_name = "mb:1c",
- .platform_data = &mmc_data,
- },
- .res = {
- .start = INTEGRATOR_CP_MMC_BASE,
- .end = INTEGRATOR_CP_MMC_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 },
- .periphid = 0,
-};
+#define INTEGRATOR_CP_MMC_IRQS { IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 }
+#define INTEGRATOR_CP_AACI_IRQS { IRQ_CP_AACIINT }
-static struct amba_device aaci_device = {
- .dev = {
- .init_name = "mb:1d",
- },
- .res = {
- .start = INTEGRATOR_CP_AACI_BASE,
- .end = INTEGRATOR_CP_AACI_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_CP_AACIINT, NO_IRQ },
- .periphid = 0,
-};
+static AMBA_APB_DEVICE(mmc, "mb:1c", 0, INTEGRATOR_CP_MMC_BASE,
+ INTEGRATOR_CP_MMC_IRQS, &mmc_data);
+
+static AMBA_APB_DEVICE(aaci, "mb:1d", 0, INTEGRATOR_CP_AACI_BASE,
+ INTEGRATOR_CP_AACI_IRQS, NULL);
/*
@@ -425,21 +407,8 @@ static struct clcd_board clcd_data = {
.remove = versatile_clcd_remove_dma,
};
-static struct amba_device clcd_device = {
- .dev = {
- .init_name = "mb:c0",
- .coherent_dma_mask = ~0,
- .platform_data = &clcd_data,
- },
- .res = {
- .start = INTCP_PA_CLCD_BASE,
- .end = INTCP_PA_CLCD_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .dma_mask = ~0,
- .irq = { IRQ_CP_CLCDCINT, NO_IRQ },
- .periphid = 0,
-};
+static AMBA_AHB_DEVICE(clcd, "mb:c0", 0, INTCP_PA_CLCD_BASE,
+ { IRQ_CP_CLCDCINT }, &clcd_data);
static struct amba_device *amba_devs[] __initdata = {
&mmc_device,
diff --git a/arch/arm/mach-iop13xx/include/mach/system.h b/arch/arm/mach-iop13xx/include/mach/system.h
deleted file mode 100644
index 1f31ed3f8ae..00000000000
--- a/arch/arm/mach-iop13xx/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-iop13xx/include/mach/system.h
- *
- * Copyright (C) 2004 Intel Corp.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-iop32x/include/mach/system.h b/arch/arm/mach-iop32x/include/mach/system.h
deleted file mode 100644
index 4a88727bca9..00000000000
--- a/arch/arm/mach-iop32x/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-iop32x/include/mach/system.h
- *
- * Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-iop33x/include/mach/system.h b/arch/arm/mach-iop33x/include/mach/system.h
deleted file mode 100644
index 4f98e765397..00000000000
--- a/arch/arm/mach-iop33x/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-iop33x/include/mach/system.h
- *
- * Copyright (C) 2001 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-ixp2000/include/mach/system.h b/arch/arm/mach-ixp2000/include/mach/system.h
deleted file mode 100644
index a7fb08b2b8e..00000000000
--- a/arch/arm/mach-ixp2000/include/mach/system.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * arch/arm/mach-ixp2000/include/mach/system.h
- *
- * Copyright (C) 2002 Intel Corp.
- * Copyricht (C) 2003-2005 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-ixp23xx/core.c b/arch/arm/mach-ixp23xx/core.c
index 0923bb905cc..7c1495e4fe7 100644
--- a/arch/arm/mach-ixp23xx/core.c
+++ b/arch/arm/mach-ixp23xx/core.c
@@ -441,6 +441,9 @@ static struct platform_device *ixp23xx_devices[] __initdata = {
void __init ixp23xx_sys_init(void)
{
+ /* by default, the idle code is disabled */
+ disable_hlt();
+
*IXP23XX_EXP_UNIT_FUSE |= 0xf;
platform_add_devices(ixp23xx_devices, ARRAY_SIZE(ixp23xx_devices));
}
diff --git a/arch/arm/mach-ixp23xx/include/mach/system.h b/arch/arm/mach-ixp23xx/include/mach/system.h
deleted file mode 100644
index 277dda7334b..00000000000
--- a/arch/arm/mach-ixp23xx/include/mach/system.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * arch/arm/mach-ixp23xx/include/mach/system.h
- *
- * Copyright (C) 2003 Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
-#if 0
- if (!hlt_counter)
- cpu_do_idle();
-#endif
-}
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c
index 3841ab4146b..a6329a0a8ec 100644
--- a/arch/arm/mach-ixp4xx/common.c
+++ b/arch/arm/mach-ixp4xx/common.c
@@ -236,6 +236,12 @@ void __init ixp4xx_init_irq(void)
{
int i = 0;
+ /*
+ * ixp4xx does not implement the XScale PWRMODE register
+ * so it must not call cpu_do_idle().
+ */
+ disable_hlt();
+
/* Route all sources to IRQ instead of FIQ */
*IXP4XX_ICLR = 0x0;
diff --git a/arch/arm/mach-ixp4xx/include/mach/system.h b/arch/arm/mach-ixp4xx/include/mach/system.h
deleted file mode 100644
index 140a9bef446..00000000000
--- a/arch/arm/mach-ixp4xx/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-ixp4xx/include/mach/system.h
- *
- * Copyright (C) 2002 Intel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-static inline void arch_idle(void)
-{
- /* ixp4xx does not implement the XScale PWRMODE register,
- * so it must not call cpu_do_idle() here.
- */
-#if 0
- cpu_do_idle();
-#endif
-}
diff --git a/arch/arm/mach-kirkwood/include/mach/system.h b/arch/arm/mach-kirkwood/include/mach/system.h
deleted file mode 100644
index 5fddde002b5..00000000000
--- a/arch/arm/mach-kirkwood/include/mach/system.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-kirkwood/include/mach/system.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-ks8695/include/mach/system.h b/arch/arm/mach-ks8695/include/mach/system.h
deleted file mode 100644
index 59fe992395b..00000000000
--- a/arch/arm/mach-ks8695/include/mach/system.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * arch/arm/mach-s3c2410/include/mach/system.h
- *
- * Copyright (C) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * KS8695 - System function defines and includes
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks,
- */
- cpu_do_idle();
-
-}
-
-#endif
diff --git a/arch/arm/mach-lpc32xx/clock.c b/arch/arm/mach-lpc32xx/clock.c
index 1e027514096..473015ac07b 100644
--- a/arch/arm/mach-lpc32xx/clock.c
+++ b/arch/arm/mach-lpc32xx/clock.c
@@ -719,6 +719,41 @@ static struct clk clk_tsc = {
.get_rate = local_return_parent_rate,
};
+static int adc_onoff_enable(struct clk *clk, int enable)
+{
+ u32 tmp;
+ u32 divider;
+
+ /* Use PERIPH_CLOCK */
+ tmp = __raw_readl(LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
+ tmp |= LPC32XX_CLKPWR_ADCCTRL1_PCLK_SEL;
+ /*
+ * Set clock divider so that we have equal to or less than
+ * 4.5MHz clock at ADC
+ */
+ divider = clk->get_rate(clk) / 4500000 + 1;
+ tmp |= divider;
+ __raw_writel(tmp, LPC32XX_CLKPWR_ADC_CLK_CTRL_1);
+
+ /* synchronize rate of this clock w/ actual HW setting */
+ clk->rate = clk->get_rate(clk->parent) / divider;
+
+ if (enable == 0)
+ __raw_writel(0, clk->enable_reg);
+ else
+ __raw_writel(clk->enable_mask, clk->enable_reg);
+
+ return 0;
+}
+
+static struct clk clk_adc = {
+ .parent = &clk_pclk,
+ .enable = adc_onoff_enable,
+ .enable_reg = LPC32XX_CLKPWR_ADC_CLK_CTRL,
+ .enable_mask = LPC32XX_CLKPWR_ADC32CLKCTRL_CLK_EN,
+ .get_rate = local_return_parent_rate,
+};
+
static int mmc_onoff_enable(struct clk *clk, int enable)
{
u32 tmp;
@@ -1075,6 +1110,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("dev:ssp1", NULL, clk_ssp1)
_REGISTER_CLOCK("lpc32xx_keys.0", NULL, clk_kscan)
_REGISTER_CLOCK("lpc32xx-nand.0", "nand_ck", clk_nand)
+ _REGISTER_CLOCK("lpc32xx-adc", NULL, clk_adc)
_REGISTER_CLOCK("tbd", "i2s0_ck", clk_i2s0)
_REGISTER_CLOCK("tbd", "i2s1_ck", clk_i2s1)
_REGISTER_CLOCK("ts-lpc32xx", NULL, clk_tsc)
diff --git a/arch/arm/mach-lpc32xx/common.c b/arch/arm/mach-lpc32xx/common.c
index 369b152896c..6c76bb36559 100644
--- a/arch/arm/mach-lpc32xx/common.c
+++ b/arch/arm/mach-lpc32xx/common.c
@@ -138,6 +138,28 @@ struct platform_device lpc32xx_rtc_device = {
};
/*
+ * ADC support
+ */
+static struct resource adc_resources[] = {
+ {
+ .start = LPC32XX_ADC_BASE,
+ .end = LPC32XX_ADC_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_LPC32XX_TS_IRQ,
+ .end = IRQ_LPC32XX_TS_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device lpc32xx_adc_device = {
+ .name = "lpc32xx-adc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(adc_resources),
+ .resource = adc_resources,
+};
+
+/*
* Returns the unique ID for the device
*/
void lpc32xx_get_uid(u32 devid[4])
diff --git a/arch/arm/mach-lpc32xx/common.h b/arch/arm/mach-lpc32xx/common.h
index 4b4e700343c..04b72739eb9 100644
--- a/arch/arm/mach-lpc32xx/common.h
+++ b/arch/arm/mach-lpc32xx/common.h
@@ -29,6 +29,7 @@ extern struct platform_device lpc32xx_i2c0_device;
extern struct platform_device lpc32xx_i2c1_device;
extern struct platform_device lpc32xx_i2c2_device;
extern struct platform_device lpc32xx_tsc_device;
+extern struct platform_device lpc32xx_adc_device;
extern struct platform_device lpc32xx_rtc_device;
/*
diff --git a/arch/arm/mach-lpc32xx/include/mach/irqs.h b/arch/arm/mach-lpc32xx/include/mach/irqs.h
index 2667f52e3b0..9e3b90df32e 100644
--- a/arch/arm/mach-lpc32xx/include/mach/irqs.h
+++ b/arch/arm/mach-lpc32xx/include/mach/irqs.h
@@ -61,7 +61,7 @@
*/
#define IRQ_LPC32XX_JTAG_COMM_TX LPC32XX_SIC1_IRQ(1)
#define IRQ_LPC32XX_JTAG_COMM_RX LPC32XX_SIC1_IRQ(2)
-#define IRQ_LPC32XX_GPI_11 LPC32XX_SIC1_IRQ(4)
+#define IRQ_LPC32XX_GPI_28 LPC32XX_SIC1_IRQ(4)
#define IRQ_LPC32XX_TS_P LPC32XX_SIC1_IRQ(6)
#define IRQ_LPC32XX_TS_IRQ LPC32XX_SIC1_IRQ(7)
#define IRQ_LPC32XX_TS_AUX LPC32XX_SIC1_IRQ(8)
diff --git a/arch/arm/mach-lpc32xx/include/mach/system.h b/arch/arm/mach-lpc32xx/include/mach/system.h
deleted file mode 100644
index bf176c99152..00000000000
--- a/arch/arm/mach-lpc32xx/include/mach/system.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * arch/arm/mach-lpc32xx/include/mach/system.h
- *
- * Author: Kevin Wells <kevin.wells@nxp.com>
- *
- * Copyright (C) 2010 NXP Semiconductors
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-lpc32xx/irq.c b/arch/arm/mach-lpc32xx/irq.c
index 4eae566dfdc..c74de01ab5b 100644
--- a/arch/arm/mach-lpc32xx/irq.c
+++ b/arch/arm/mach-lpc32xx/irq.c
@@ -118,6 +118,10 @@ static const struct lpc32xx_event_info lpc32xx_events[NR_IRQS] = {
.event_group = &lpc32xx_event_pin_regs,
.mask = LPC32XX_CLKPWR_EXTSRC_GPI_06_BIT,
},
+ [IRQ_LPC32XX_GPI_28] = {
+ .event_group = &lpc32xx_event_pin_regs,
+ .mask = LPC32XX_CLKPWR_EXTSRC_GPI_28_BIT,
+ },
[IRQ_LPC32XX_GPIO_00] = {
.event_group = &lpc32xx_event_int_regs,
.mask = LPC32XX_CLKPWR_INTSRC_GPIO_00_BIT,
@@ -305,9 +309,18 @@ static int lpc32xx_irq_wake(struct irq_data *d, unsigned int state)
if (state)
eventreg |= lpc32xx_events[d->irq].mask;
- else
+ else {
eventreg &= ~lpc32xx_events[d->irq].mask;
+ /*
+ * When disabling the wakeup, clear the latched
+ * event
+ */
+ __raw_writel(lpc32xx_events[d->irq].mask,
+ lpc32xx_events[d->irq].
+ event_group->rawstat_reg);
+ }
+
__raw_writel(eventreg,
lpc32xx_events[d->irq].event_group->enab_reg);
@@ -380,13 +393,15 @@ void __init lpc32xx_init_irq(void)
/* Setup SIC1 */
__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC1_BASE));
- __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE));
- __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE));
+ __raw_writel(SIC1_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC1_BASE));
+ __raw_writel(SIC1_ATR_DEFAULT,
+ LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC1_BASE));
/* Setup SIC2 */
__raw_writel(0, LPC32XX_INTC_MASK(LPC32XX_SIC2_BASE));
- __raw_writel(MIC_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE));
- __raw_writel(MIC_ATR_DEFAULT, LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE));
+ __raw_writel(SIC2_APR_DEFAULT, LPC32XX_INTC_POLAR(LPC32XX_SIC2_BASE));
+ __raw_writel(SIC2_ATR_DEFAULT,
+ LPC32XX_INTC_ACT_TYPE(LPC32XX_SIC2_BASE));
/* Configure supported IRQ's */
for (i = 0; i < NR_IRQS; i++) {
diff --git a/arch/arm/mach-lpc32xx/phy3250.c b/arch/arm/mach-lpc32xx/phy3250.c
index bfee5b45510..a539f4f72f2 100644
--- a/arch/arm/mach-lpc32xx/phy3250.c
+++ b/arch/arm/mach-lpc32xx/phy3250.c
@@ -149,20 +149,8 @@ static struct clcd_board lpc32xx_clcd_data = {
.remove = lpc32xx_clcd_remove,
};
-static struct amba_device lpc32xx_clcd_device = {
- .dev = {
- .coherent_dma_mask = ~0,
- .init_name = "dev:clcd",
- .platform_data = &lpc32xx_clcd_data,
- },
- .res = {
- .start = LPC32XX_LCD_BASE,
- .end = (LPC32XX_LCD_BASE + SZ_4K - 1),
- .flags = IORESOURCE_MEM,
- },
- .dma_mask = ~0,
- .irq = {IRQ_LPC32XX_LCD, NO_IRQ},
-};
+static AMBA_AHB_DEVICE(lpc32xx_clcd, "dev:clcd", 0,
+ LPC32XX_LCD_BASE, { IRQ_LPC32XX_LCD }, &lpc32xx_clcd_data);
/*
* AMBA SSP (SPI)
@@ -191,20 +179,8 @@ static struct pl022_ssp_controller lpc32xx_ssp0_data = {
.enable_dma = 0,
};
-static struct amba_device lpc32xx_ssp0_device = {
- .dev = {
- .coherent_dma_mask = ~0,
- .init_name = "dev:ssp0",
- .platform_data = &lpc32xx_ssp0_data,
- },
- .res = {
- .start = LPC32XX_SSP0_BASE,
- .end = (LPC32XX_SSP0_BASE + SZ_4K - 1),
- .flags = IORESOURCE_MEM,
- },
- .dma_mask = ~0,
- .irq = {IRQ_LPC32XX_SSP0, NO_IRQ},
-};
+static AMBA_APB_DEVICE(lpc32xx_ssp0, "dev:ssp0", 0,
+ LPC32XX_SSP0_BASE, { IRQ_LPC32XX_SSP0 }, &lpc32xx_ssp0_data);
/* AT25 driver registration */
static int __init phy3250_spi_board_register(void)
@@ -276,6 +252,7 @@ static struct platform_device *phy3250_devs[] __initdata = {
&lpc32xx_i2c2_device,
&lpc32xx_watchdog_device,
&lpc32xx_gpio_led_device,
+ &lpc32xx_adc_device,
};
static struct amba_device *amba_devs[] __initdata = {
diff --git a/arch/arm/mach-lpc32xx/serial.c b/arch/arm/mach-lpc32xx/serial.c
index 429cfdbb2b3..f2735281616 100644
--- a/arch/arm/mach-lpc32xx/serial.c
+++ b/arch/arm/mach-lpc32xx/serial.c
@@ -88,6 +88,7 @@ struct uartinit {
char *uart_ck_name;
u32 ck_mode_mask;
void __iomem *pdiv_clk_reg;
+ resource_size_t mapbase;
};
static struct uartinit uartinit_data[] __initdata = {
@@ -97,6 +98,7 @@ static struct uartinit uartinit_data[] __initdata = {
.ck_mode_mask =
LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 5),
.pdiv_clk_reg = LPC32XX_CLKPWR_UART5_CLK_CTRL,
+ .mapbase = LPC32XX_UART5_BASE,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART3_SELECT
@@ -105,6 +107,7 @@ static struct uartinit uartinit_data[] __initdata = {
.ck_mode_mask =
LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 3),
.pdiv_clk_reg = LPC32XX_CLKPWR_UART3_CLK_CTRL,
+ .mapbase = LPC32XX_UART3_BASE,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART4_SELECT
@@ -113,6 +116,7 @@ static struct uartinit uartinit_data[] __initdata = {
.ck_mode_mask =
LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 4),
.pdiv_clk_reg = LPC32XX_CLKPWR_UART4_CLK_CTRL,
+ .mapbase = LPC32XX_UART4_BASE,
},
#endif
#ifdef CONFIG_ARCH_LPC32XX_UART6_SELECT
@@ -121,6 +125,7 @@ static struct uartinit uartinit_data[] __initdata = {
.ck_mode_mask =
LPC32XX_UART_CLKMODE_LOAD(LPC32XX_UART_CLKMODE_ON, 6),
.pdiv_clk_reg = LPC32XX_CLKPWR_UART6_CLK_CTRL,
+ .mapbase = LPC32XX_UART6_BASE,
},
#endif
};
@@ -165,11 +170,24 @@ void __init lpc32xx_serial_init(void)
/* pre-UART clock divider set to 1 */
__raw_writel(0x0101, uartinit_data[i].pdiv_clk_reg);
+
+ /*
+ * Force a flush of the RX FIFOs to work around a
+ * HW bug
+ */
+ puart = uartinit_data[i].mapbase;
+ __raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
+ __raw_writel(0x00, LPC32XX_UART_DLL_FIFO(puart));
+ j = LPC32XX_SUART_FIFO_SIZE;
+ while (j--)
+ tmp = __raw_readl(
+ LPC32XX_UART_DLL_FIFO(puart));
+ __raw_writel(0, LPC32XX_UART_IIR_FCR(puart));
}
/* This needs to be done after all UART clocks are setup */
__raw_writel(clkmodes, LPC32XX_UARTCTL_CLKMODE);
- for (i = 0; i < ARRAY_SIZE(uartinit_data) - 1; i++) {
+ for (i = 0; i < ARRAY_SIZE(uartinit_data); i++) {
/* Force a flush of the RX FIFOs to work around a HW bug */
puart = serial_std_platform_data[i].mapbase;
__raw_writel(0xC1, LPC32XX_UART_IIR_FCR(puart));
diff --git a/arch/arm/mach-mmp/aspenite.c b/arch/arm/mach-mmp/aspenite.c
index 17cb7606012..3588a558415 100644
--- a/arch/arm/mach-mmp/aspenite.c
+++ b/arch/arm/mach-mmp/aspenite.c
@@ -17,7 +17,6 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/interrupt.h>
-#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-mmp/include/mach/pxa910.h b/arch/arm/mach-mmp/include/mach/pxa910.h
index 4de13abef7b..e2e1f1e5e12 100644
--- a/arch/arm/mach-mmp/include/mach/pxa910.h
+++ b/arch/arm/mach-mmp/include/mach/pxa910.h
@@ -22,6 +22,7 @@ extern struct pxa_device_desc pxa910_device_pwm4;
extern struct pxa_device_desc pxa910_device_nand;
extern struct platform_device pxa910_device_gpio;
+extern struct platform_device pxa910_device_rtc;
static inline int pxa910_add_uart(int id)
{
diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h
index 1a96585336b..8a37fb00365 100644
--- a/arch/arm/mach-mmp/include/mach/regs-apbc.h
+++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h
@@ -57,6 +57,7 @@
#define APBC_PXA910_SSP1 APBC_REG(0x01c)
#define APBC_PXA910_SSP2 APBC_REG(0x020)
#define APBC_PXA910_IPC APBC_REG(0x024)
+#define APBC_PXA910_RTC APBC_REG(0x028)
#define APBC_PXA910_TWSI0 APBC_REG(0x02c)
#define APBC_PXA910_KPC APBC_REG(0x030)
#define APBC_PXA910_TIMERS APBC_REG(0x034)
diff --git a/arch/arm/mach-mmp/include/mach/regs-rtc.h b/arch/arm/mach-mmp/include/mach/regs-rtc.h
new file mode 100644
index 00000000000..5bff886a394
--- /dev/null
+++ b/arch/arm/mach-mmp/include/mach/regs-rtc.h
@@ -0,0 +1,23 @@
+#ifndef __ASM_MACH_REGS_RTC_H
+#define __ASM_MACH_REGS_RTC_H
+
+#include <mach/addr-map.h>
+
+#define RTC_VIRT_BASE (APB_VIRT_BASE + 0x10000)
+#define RTC_REG(x) (*((volatile u32 __iomem *)(RTC_VIRT_BASE + (x))))
+
+/*
+ * Real Time Clock
+ */
+
+#define RCNR RTC_REG(0x00) /* RTC Count Register */
+#define RTAR RTC_REG(0x04) /* RTC Alarm Register */
+#define RTSR RTC_REG(0x08) /* RTC Status Register */
+#define RTTR RTC_REG(0x0C) /* RTC Timer Trim Register */
+
+#define RTSR_HZE (1 << 3) /* HZ interrupt enable */
+#define RTSR_ALE (1 << 2) /* RTC alarm interrupt enable */
+#define RTSR_HZ (1 << 1) /* HZ rising-edge detected */
+#define RTSR_AL (1 << 0) /* RTC alarm detected */
+
+#endif /* __ASM_MACH_REGS_RTC_H */
diff --git a/arch/arm/mach-mmp/include/mach/system.h b/arch/arm/mach-mmp/include/mach/system.h
deleted file mode 100644
index 1d001eab81e..00000000000
--- a/arch/arm/mach-mmp/include/mach/system.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * linux/arch/arm/mach-mmp/include/mach/system.h
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#ifndef __ASM_MACH_SYSTEM_H
-#define __ASM_MACH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-#endif /* __ASM_MACH_SYSTEM_H */
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c
index 7bc17eaa12e..ada1213982b 100644
--- a/arch/arm/mach-mmp/pxa168.c
+++ b/arch/arm/mach-mmp/pxa168.c
@@ -24,7 +24,6 @@
#include <mach/dma.h>
#include <mach/devices.h>
#include <mach/mfp.h>
-#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <mach/pxa168.h>
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c
index 3241a25784d..b6e15272397 100644
--- a/arch/arm/mach-mmp/pxa910.c
+++ b/arch/arm/mach-mmp/pxa910.c
@@ -92,6 +92,7 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000);
static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000);
static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000);
static APBC_CLK(gpio, PXA910_GPIO, 0, 13000000);
+static APBC_CLK(rtc, PXA910_RTC, 8, 32768);
static APMU_CLK(nand, NAND, 0x19b, 156000000);
static APMU_CLK(u2o, USB, 0x1b, 480000000);
@@ -109,6 +110,7 @@ static struct clk_lookup pxa910_clkregs[] = {
INIT_CLKREG(&clk_nand, "pxa3xx-nand", NULL),
INIT_CLKREG(&clk_gpio, "pxa-gpio", NULL),
INIT_CLKREG(&clk_u2o, "pxa-u2o", "U2OCLK"),
+ INIT_CLKREG(&clk_rtc, "sa1100-rtc", NULL),
};
static int __init pxa910_init(void)
@@ -183,3 +185,28 @@ struct platform_device pxa910_device_gpio = {
.num_resources = ARRAY_SIZE(pxa910_resource_gpio),
.resource = pxa910_resource_gpio,
};
+
+static struct resource pxa910_resource_rtc[] = {
+ {
+ .start = 0xd4010000,
+ .end = 0xd401003f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_PXA910_RTC_INT,
+ .end = IRQ_PXA910_RTC_INT,
+ .name = "rtc 1Hz",
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_PXA910_RTC_ALARM,
+ .end = IRQ_PXA910_RTC_ALARM,
+ .name = "rtc alarm",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device pxa910_device_rtc = {
+ .name = "sa1100-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pxa910_resource_rtc),
+ .resource = pxa910_resource_rtc,
+};
diff --git a/arch/arm/mach-mmp/tavorevb.c b/arch/arm/mach-mmp/tavorevb.c
index 8e3b5af04a5..bc97170125b 100644
--- a/arch/arm/mach-mmp/tavorevb.c
+++ b/arch/arm/mach-mmp/tavorevb.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/smc91x.h>
-#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c
index 5ac5d5832e4..e72c709da44 100644
--- a/arch/arm/mach-mmp/ttc_dkb.c
+++ b/arch/arm/mach-mmp/ttc_dkb.c
@@ -124,6 +124,7 @@ static struct platform_device ttc_dkb_device_onenand = {
static struct platform_device *ttc_dkb_devices[] = {
&pxa910_device_gpio,
+ &pxa910_device_rtc,
&ttc_dkb_device_onenand,
};
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 0a113424632..962e7116975 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -80,12 +80,8 @@ static struct of_device_id msm_dt_gic_match[] __initdata = {
static void __init msm8x60_dt_init(void)
{
- struct device_node *node;
-
- node = of_find_matching_node_by_address(NULL, msm_dt_gic_match,
- MSM8X60_QGIC_DIST_PHYS);
- if (node)
- irq_domain_add_simple(node, GIC_SPI_START);
+ irq_domain_generate_simple(msm_dt_gic_match, MSM8X60_QGIC_DIST_PHYS,
+ GIC_SPI_START);
if (of_machine_is_compatible("qcom,msm8660-surf")) {
printk(KERN_INFO "Init surf UART registers\n");
diff --git a/arch/arm/mach-msm/idle.S b/arch/arm/mach-msm/idle.S
deleted file mode 100644
index 6a94f052713..00000000000
--- a/arch/arm/mach-msm/idle.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/* arch/arm/mach-msm/include/mach/idle.S
- *
- * Idle processing for MSM7K - work around bugs with SWFI.
- *
- * Copyright (c) 2007 QUALCOMM Incorporated.
- * Copyright (C) 2007 Google, Inc.
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-
-ENTRY(arch_idle)
-#ifdef CONFIG_MSM7X00A_IDLE
- mrc p15, 0, r1, c1, c0, 0 /* read current CR */
- bic r0, r1, #(1 << 2) /* clear dcache bit */
- bic r0, r0, #(1 << 12) /* clear icache bit */
- mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */
-
- mov r0, #0 /* prepare wfi value */
- mcr p15, 0, r0, c7, c10, 0 /* flush the cache */
- mcr p15, 0, r0, c7, c10, 4 /* memory barrier */
- mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */
-
- mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */
-#endif
- mov pc, lr
diff --git a/arch/arm/mach-msm/idle.c b/arch/arm/mach-msm/idle.c
new file mode 100644
index 00000000000..0c9e13c6574
--- /dev/null
+++ b/arch/arm/mach-msm/idle.c
@@ -0,0 +1,49 @@
+/* arch/arm/mach-msm/idle.c
+ *
+ * Idle processing for MSM7K - work around bugs with SWFI.
+ *
+ * Copyright (c) 2007 QUALCOMM Incorporated.
+ * Copyright (C) 2007 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <asm/system.h>
+
+static void msm_idle(void)
+{
+#ifdef CONFIG_MSM7X00A_IDLE
+ asm volatile (
+
+ "mrc p15, 0, r1, c1, c0, 0 /* read current CR */ \n\t"
+ "bic r0, r1, #(1 << 2) /* clear dcache bit */ \n\t"
+ "bic r0, r0, #(1 << 12) /* clear icache bit */ \n\t"
+ "mcr p15, 0, r0, c1, c0, 0 /* disable d/i cache */ \n\t"
+
+ "mov r0, #0 /* prepare wfi value */ \n\t"
+ "mcr p15, 0, r0, c7, c10, 0 /* flush the cache */ \n\t"
+ "mcr p15, 0, r0, c7, c10, 4 /* memory barrier */ \n\t"
+ "mcr p15, 0, r0, c7, c0, 4 /* wait for interrupt */ \n\t"
+
+ "mcr p15, 0, r1, c1, c0, 0 /* restore d/i cache */ \n\t"
+
+ : : : "r0","r1" );
+#endif
+}
+
+static int __init msm_idle_init(void)
+{
+ arm_pm_idle = msm_idle;
+ return 0;
+}
+
+arch_initcall(msm_idle_init);
diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h
index 311db2b35da..f5fb2ec87ff 100644
--- a/arch/arm/mach-msm/include/mach/system.h
+++ b/arch/arm/mach-msm/include/mach/system.h
@@ -12,7 +12,6 @@
* GNU General Public License for more details.
*
*/
-void arch_idle(void);
/* low level hardware reset hook -- for example, hitting the
* PSHOLD line on the PMIC to hard reset the system
diff --git a/arch/arm/mach-mv78xx0/include/mach/system.h b/arch/arm/mach-mv78xx0/include/mach/system.h
deleted file mode 100644
index 8c3a5387cec..00000000000
--- a/arch/arm/mach-mv78xx0/include/mach/system.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-mv78xx0/include/mach/system.h
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
index e12e11231dc..aec34712c32 100644
--- a/arch/arm/mach-mxs/clock-mx23.c
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -456,6 +456,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("mxs-pwm.3", NULL, pwm_clk)
_REGISTER_CLOCK("mxs-pwm.4", NULL, pwm_clk)
_REGISTER_CLOCK("imx23-fb", NULL, lcdif_clk)
+ _REGISTER_CLOCK("imx23-gpmi-nand", NULL, gpmi_clk)
};
static int clk_misc_init(void)
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index 5d68e415222..8dd7b02a4b9 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -643,6 +643,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("duart", NULL, uart_clk)
_REGISTER_CLOCK("imx28-fec.0", NULL, fec_clk)
_REGISTER_CLOCK("imx28-fec.1", NULL, fec_clk)
+ _REGISTER_CLOCK("imx28-gpmi-nand", NULL, gpmi_clk)
_REGISTER_CLOCK("mxs-auart.0", NULL, uart_clk)
_REGISTER_CLOCK("mxs-auart.1", NULL, uart_clk)
_REGISTER_CLOCK("mxs-auart.2", NULL, uart_clk)
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
index 3fa651d2c99..4d1329d5928 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_gpmi_nand_data mx23_gpmi_nand_data __initconst;
+#define mx23_add_gpmi_nand(pdata) \
+ mxs_add_gpmi_nand(pdata, &mx23_gpmi_nand_data)
+
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)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 4f50094e293..9dbeae13084 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -34,6 +34,10 @@ extern const struct mxs_flexcan_data mx28_flexcan_data[] __initconst;
#define mx28_add_flexcan0(pdata) mx28_add_flexcan(0, pdata)
#define mx28_add_flexcan1(pdata) mx28_add_flexcan(1, pdata)
+extern const struct mxs_gpmi_nand_data mx28_gpmi_nand_data __initconst;
+#define mx28_add_gpmi_nand(pdata) \
+ mxs_add_gpmi_nand(pdata, &mx28_gpmi_nand_data)
+
extern const struct mxs_mxs_i2c_data mx28_mxs_i2c_data[] __initconst;
#define mx28_add_mxs_i2c(id) mxs_add_mxs_i2c(&mx28_mxs_i2c_data[id])
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
index fe3e847930c..01faffec306 100644
--- a/arch/arm/mach-mxs/devices.c
+++ b/arch/arm/mach-mxs/devices.c
@@ -77,16 +77,18 @@ err:
int __init mxs_add_amba_device(const struct amba_device *dev)
{
- struct amba_device *adev = kmalloc(sizeof(*adev), GFP_KERNEL);
+ struct amba_device *adev = amba_device_alloc(dev->dev.init_name,
+ dev->res.start, resource_size(&dev->res));
if (!adev) {
pr_err("%s: failed to allocate memory", __func__);
return -ENOMEM;
}
- *adev = *dev;
+ adev->irq[0] = dev->irq[0];
+ adev->irq[1] = dev->irq[1];
- return amba_device_register(adev, &iomem_resource);
+ return amba_device_add(adev, &iomem_resource);
}
struct device mxs_apbh_bus = {
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
index 18b6bf526a2..b8913df4cfa 100644
--- a/arch/arm/mach-mxs/devices/Kconfig
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -12,6 +12,9 @@ config MXS_HAVE_PLATFORM_FLEXCAN
select HAVE_CAN_FLEXCAN if CAN
bool
+config MXS_HAVE_PLATFORM_GPMI_NAND
+ bool
+
config MXS_HAVE_PLATFORM_MXS_I2C
bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
index f52e3e53bae..c8f5c9541a3 100644
--- a/arch/arm/mach-mxs/devices/Makefile
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_MXS_HAVE_PLATFORM_AUART) += platform-auart.o
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_GPMI_NAND) += platform-gpmi-nand.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
diff --git a/arch/arm/mach-mxs/devices/amba-duart.c b/arch/arm/mach-mxs/devices/amba-duart.c
index a559db09b49..a5479f76604 100644
--- a/arch/arm/mach-mxs/devices/amba-duart.c
+++ b/arch/arm/mach-mxs/devices/amba-duart.c
@@ -23,7 +23,7 @@ const struct amba_device name##_device __initconst = { \
.end = (soc ## _DUART_BASE_ADDR) + SZ_8K - 1, \
.flags = IORESOURCE_MEM, \
}, \
- .irq = {soc ## _INT_DUART, NO_IRQ}, \
+ .irq = {soc ## _INT_DUART}, \
}
#ifdef CONFIG_SOC_IMX23
diff --git a/arch/arm/mach-mxs/devices/platform-gpmi-nand.c b/arch/arm/mach-mxs/devices/platform-gpmi-nand.c
new file mode 100644
index 00000000000..3e22df5944a
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-gpmi-nand.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 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 as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <asm/sizes.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+#include <linux/dma-mapping.h>
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_gpmi_nand_data mx23_gpmi_nand_data __initconst = {
+ .devid = "imx23-gpmi-nand",
+ .res = {
+ /* GPMI */
+ DEFINE_RES_MEM_NAMED(MX23_GPMI_BASE_ADDR, SZ_8K,
+ GPMI_NAND_GPMI_REGS_ADDR_RES_NAME),
+ DEFINE_RES_IRQ_NAMED(MX23_INT_GPMI_ATTENTION,
+ GPMI_NAND_GPMI_INTERRUPT_RES_NAME),
+ /* BCH */
+ DEFINE_RES_MEM_NAMED(MX23_BCH_BASE_ADDR, SZ_8K,
+ GPMI_NAND_BCH_REGS_ADDR_RES_NAME),
+ DEFINE_RES_IRQ_NAMED(MX23_INT_BCH,
+ GPMI_NAND_BCH_INTERRUPT_RES_NAME),
+ /* DMA */
+ DEFINE_RES_NAMED(MX23_DMA_GPMI0,
+ MX23_DMA_GPMI3 - MX23_DMA_GPMI0 + 1,
+ GPMI_NAND_DMA_CHANNELS_RES_NAME,
+ IORESOURCE_DMA),
+ DEFINE_RES_IRQ_NAMED(MX23_INT_GPMI_DMA,
+ GPMI_NAND_DMA_INTERRUPT_RES_NAME),
+ },
+};
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_gpmi_nand_data mx28_gpmi_nand_data __initconst = {
+ .devid = "imx28-gpmi-nand",
+ .res = {
+ /* GPMI */
+ DEFINE_RES_MEM_NAMED(MX28_GPMI_BASE_ADDR, SZ_8K,
+ GPMI_NAND_GPMI_REGS_ADDR_RES_NAME),
+ DEFINE_RES_IRQ_NAMED(MX28_INT_GPMI,
+ GPMI_NAND_GPMI_INTERRUPT_RES_NAME),
+ /* BCH */
+ DEFINE_RES_MEM_NAMED(MX28_BCH_BASE_ADDR, SZ_8K,
+ GPMI_NAND_BCH_REGS_ADDR_RES_NAME),
+ DEFINE_RES_IRQ_NAMED(MX28_INT_BCH,
+ GPMI_NAND_BCH_INTERRUPT_RES_NAME),
+ /* DMA */
+ DEFINE_RES_NAMED(MX28_DMA_GPMI0,
+ MX28_DMA_GPMI7 - MX28_DMA_GPMI0 + 1,
+ GPMI_NAND_DMA_CHANNELS_RES_NAME,
+ IORESOURCE_DMA),
+ DEFINE_RES_IRQ_NAMED(MX28_INT_GPMI_DMA,
+ GPMI_NAND_DMA_INTERRUPT_RES_NAME),
+ },
+};
+#endif
+
+struct platform_device *__init
+mxs_add_gpmi_nand(const struct gpmi_nand_platform_data *pdata,
+ const struct mxs_gpmi_nand_data *data)
+{
+ return mxs_add_platform_device_dmamask(data->devid, -1,
+ data->res, GPMI_NAND_RES_SIZE,
+ pdata, sizeof(*pdata), DMA_BIT_MASK(32));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index dc369c1239f..f2e383955d8 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -66,6 +66,16 @@ struct platform_device *__init mxs_add_flexcan(
const struct mxs_flexcan_data *data,
const struct flexcan_platform_data *pdata);
+/* gpmi-nand */
+#include <linux/mtd/gpmi-nand.h>
+struct mxs_gpmi_nand_data {
+ const char *devid;
+ const struct resource res[GPMI_NAND_RES_SIZE];
+};
+struct platform_device *__init
+mxs_add_gpmi_nand(const struct gpmi_nand_platform_data *pdata,
+ const struct mxs_gpmi_nand_data *data);
+
/* i2c */
struct mxs_mxs_i2c_data {
int id;
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
deleted file mode 100644
index e7ad1bb2942..00000000000
--- a/arch/arm/mach-mxs/include/mach/system.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2004-2008 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __MACH_MXS_SYSTEM_H__
-#define __MACH_MXS_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
index fb042da29bd..a9b4bbcdafb 100644
--- a/arch/arm/mach-mxs/pm.c
+++ b/arch/arm/mach-mxs/pm.c
@@ -15,13 +15,12 @@
#include <linux/kernel.h>
#include <linux/suspend.h>
#include <linux/io.h>
-#include <mach/system.h>
static int mxs_suspend_enter(suspend_state_t state)
{
switch (state) {
case PM_SUSPEND_MEM:
- arch_idle();
+ cpu_do_idle();
break;
default:
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c
index b9913234bbf..2cdf6ef69be 100644
--- a/arch/arm/mach-netx/fb.c
+++ b/arch/arm/mach-netx/fb.c
@@ -92,18 +92,7 @@ void clk_put(struct clk *clk)
{
}
-static struct amba_device fb_device = {
- .dev = {
- .init_name = "fb",
- .coherent_dma_mask = ~0,
- },
- .res = {
- .start = 0x00104000,
- .end = 0x00104fff,
- .flags = IORESOURCE_MEM,
- },
- .irq = { NETX_IRQ_LCD, NO_IRQ },
-};
+static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL);
int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel)
{
diff --git a/arch/arm/mach-netx/include/mach/system.h b/arch/arm/mach-netx/include/mach/system.h
deleted file mode 100644
index b38fa36d58c..00000000000
--- a/arch/arm/mach-netx/include/mach/system.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * arch/arm/mach-netx/include/mach/system.h
- *
- * Copyright (C) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
-
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c
index 7c878bf0034..f6f74adbe8c 100644
--- a/arch/arm/mach-nomadik/board-nhk8815.c
+++ b/arch/arm/mach-nomadik/board-nhk8815.c
@@ -185,20 +185,11 @@ static void __init nhk8815_onenand_init(void)
#endif
}
-#define __MEM_4K_RESOURCE(x) \
- .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM}
+static AMBA_APB_DEVICE(uart0, "uart0", 0, NOMADIK_UART0_BASE,
+ { IRQ_UART0 }, NULL);
-static struct amba_device uart0_device = {
- .dev = { .init_name = "uart0" },
- __MEM_4K_RESOURCE(NOMADIK_UART0_BASE),
- .irq = {IRQ_UART0, NO_IRQ},
-};
-
-static struct amba_device uart1_device = {
- .dev = { .init_name = "uart1" },
- __MEM_4K_RESOURCE(NOMADIK_UART1_BASE),
- .irq = {IRQ_UART1, NO_IRQ},
-};
+static AMBA_APB_DEVICE(uart1, "uart1", 0, NOMADIK_UART1_BASE,
+ { IRQ_UART1 }, NULL);
static struct amba_device *amba_devs[] __initdata = {
&uart0_device,
diff --git a/arch/arm/mach-nomadik/cpu-8815.c b/arch/arm/mach-nomadik/cpu-8815.c
index 65df7b4fdd3..27f43a46985 100644
--- a/arch/arm/mach-nomadik/cpu-8815.c
+++ b/arch/arm/mach-nomadik/cpu-8815.c
@@ -97,12 +97,7 @@ static struct platform_device cpu8815_platform_gpio[] = {
GPIO_DEVICE(3),
};
-static struct amba_device cpu8815_amba_rng = {
- .dev = {
- .init_name = "rng",
- },
- __MEM_4K_RESOURCE(NOMADIK_RNG_BASE),
-};
+static AMBA_APB_DEVICE(cpu8815_amba_rng, "rng", 0, NOMADIK_RNG_BASE, { }, NULL);
static struct platform_device *platform_devs[] __initdata = {
cpu8815_platform_gpio + 0,
@@ -112,7 +107,7 @@ static struct platform_device *platform_devs[] __initdata = {
};
static struct amba_device *amba_devs[] __initdata = {
- &cpu8815_amba_rng
+ &cpu8815_amba_rng_device
};
static int __init cpu8815_init(void)
diff --git a/arch/arm/mach-nomadik/include/mach/system.h b/arch/arm/mach-nomadik/include/mach/system.h
deleted file mode 100644
index 25e198b8976..00000000000
--- a/arch/arm/mach-nomadik/include/mach/system.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * mach-nomadik/include/mach/system.h
- *
- * Copyright (C) 2008 STMicroelectronics
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks
- */
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-omap1/board-innovator.c b/arch/arm/mach-omap1/board-innovator.c
index 309369ea697..be2002f42de 100644
--- a/arch/arm/mach-omap1/board-innovator.c
+++ b/arch/arm/mach-omap1/board-innovator.c
@@ -416,13 +416,13 @@ static void __init innovator_init(void)
#ifdef CONFIG_ARCH_OMAP15XX
if (cpu_is_omap1510()) {
omap1_usb_init(&innovator1510_usb_config);
- innovator_config[1].data = &innovator1510_lcd_config;
+ innovator_config[0].data = &innovator1510_lcd_config;
}
#endif
#ifdef CONFIG_ARCH_OMAP16XX
if (cpu_is_omap1610()) {
omap1_usb_init(&h2_usb_config);
- innovator_config[1].data = &innovator1610_lcd_config;
+ innovator_config[0].data = &innovator1610_lcd_config;
}
#endif
omap_board_config = innovator_config;
diff --git a/arch/arm/mach-omap1/include/mach/system.h b/arch/arm/mach-omap1/include/mach/system.h
deleted file mode 100644
index a6c1b3a16df..00000000000
--- a/arch/arm/mach-omap1/include/mach/system.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * arch/arm/mach-omap1/include/mach/system.h
- */
-
-#include <plat/system.h>
diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c
index 89ea20ca0cc..0c2c3669d59 100644
--- a/arch/arm/mach-omap1/pm.c
+++ b/arch/arm/mach-omap1/pm.c
@@ -42,9 +42,9 @@
#include <linux/sysfs.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/atomic.h>
#include <asm/irq.h>
-#include <linux/atomic.h>
#include <asm/mach/time.h>
#include <asm/mach/irq.h>
@@ -108,13 +108,7 @@ void omap1_pm_idle(void)
__u32 use_idlect1 = arm_idlect1_mask;
int do_sleep = 0;
- local_irq_disable();
local_fiq_disable();
- if (need_resched()) {
- local_fiq_enable();
- local_irq_enable();
- return;
- }
#if defined(CONFIG_OMAP_MPU_TIMER) && !defined(CONFIG_OMAP_DM_TIMER)
#warning Enable 32kHz OS timer in order to allow sleep states in idle
@@ -157,14 +151,12 @@ void omap1_pm_idle(void)
omap_writel(saved_idlect1, ARM_IDLECT1);
local_fiq_enable();
- local_irq_enable();
return;
}
omap_sram_suspend(omap_readl(ARM_IDLECT1),
omap_readl(ARM_IDLECT2));
local_fiq_enable();
- local_irq_enable();
}
/*
@@ -583,8 +575,6 @@ static void omap_pm_init_proc(void)
#endif /* DEBUG && CONFIG_PROC_FS */
-static void (*saved_idle)(void) = NULL;
-
/*
* omap_pm_prepare - Do preliminary suspend work.
*
@@ -592,8 +582,7 @@ static void (*saved_idle)(void) = NULL;
static int omap_pm_prepare(void)
{
/* We cannot sleep in idle until we have resumed */
- saved_idle = pm_idle;
- pm_idle = NULL;
+ disable_hlt();
return 0;
}
@@ -630,7 +619,7 @@ static int omap_pm_enter(suspend_state_t state)
static void omap_pm_finish(void)
{
- pm_idle = saved_idle;
+ enable_hlt();
}
@@ -687,7 +676,7 @@ static int __init omap_pm_init(void)
return -ENODEV;
}
- pm_idle = omap1_pm_idle;
+ arm_pm_idle = omap1_pm_idle;
if (cpu_is_omap7xx())
setup_irq(INT_7XX_WAKE_UP_REQ, &omap_wakeup_irq);
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 337f98dd814..21a4095a100 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -364,8 +364,8 @@ config OMAP3_SDRC_AC_TIMING
going on could result in system crashes;
config OMAP4_ERRATA_I688
- bool "OMAP4 errata: Async Bridge Corruption (BROKEN)"
- depends on ARCH_OMAP4 && BROKEN
+ bool "OMAP4 errata: Async Bridge Corruption"
+ depends on ARCH_OMAP4
select ARCH_HAS_BARRIERS
help
If a data is stalled inside asynchronous bridge because of back
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index ad497620539..45fdfe2bd9d 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -68,7 +68,7 @@ static void __init omap_generic_init(void)
{
struct device_node *node = of_find_matching_node(NULL, intc_match);
if (node)
- irq_domain_add_simple(node, 0);
+ irq_domain_add_legacy(node, 32, 0, 0, &irq_domain_simple_ops, NULL);
omap_sdrc_init(NULL, NULL);
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 42a4d11fad2..67226271760 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -371,7 +371,11 @@ static void n8x0_mmc_callback(void *data, u8 card_mask)
else
*openp = 0;
+#ifdef CONFIG_MMC_OMAP
omap_mmc_notify_cover_event(mmc_device, index, *openp);
+#else
+ pr_warn("MMC: notify cover event not available\n");
+#endif
}
static int n8x0_mmc_late_init(struct device *dev)
diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
index c775bead149..c877236a844 100644
--- a/arch/arm/mach-omap2/board-omap3evm.c
+++ b/arch/arm/mach-omap2/board-omap3evm.c
@@ -381,7 +381,7 @@ static int omap3evm_twl_gpio_setup(struct device *dev,
gpio_request_one(gpio + 7, GPIOF_OUT_INIT_LOW, "EN_DVI");
/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
- gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
+ gpio_leds[0].gpio = gpio + TWL4030_GPIO_MAX + 1;
platform_device_register(&leds_gpio);
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index febffde2ff1..7e9338e8d68 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -132,6 +132,7 @@ void omap3_map_io(void);
void am33xx_map_io(void);
void omap4_map_io(void);
void ti81xx_map_io(void);
+void omap_barriers_init(void);
/**
* omap_test_timeout - busy-loop, testing a condition
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c
index cfdbb86bc84..72e018b9b26 100644
--- a/arch/arm/mach-omap2/cpuidle44xx.c
+++ b/arch/arm/mach-omap2/cpuidle44xx.c
@@ -65,7 +65,6 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
struct timespec ts_preidle, ts_postidle, ts_idle;
u32 cpu1_state;
int idle_time;
- int new_state_idx;
int cpu_id = smp_processor_id();
/* Used to keep track of the total time in idle */
@@ -84,8 +83,8 @@ static int omap4_enter_idle(struct cpuidle_device *dev,
*/
cpu1_state = pwrdm_read_pwrst(cpu1_pd);
if (cpu1_state != PWRDM_POWER_OFF) {
- new_state_idx = drv->safe_state_index;
- cx = cpuidle_get_statedata(&dev->states_usage[new_state_idx]);
+ index = drv->safe_state_index;
+ cx = cpuidle_get_statedata(&dev->states_usage[index]);
}
if (index > 0)
diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c
index 9c442e290cc..ce91aad4cda 100644
--- a/arch/arm/mach-omap2/emu.c
+++ b/arch/arm/mach-omap2/emu.c
@@ -30,29 +30,8 @@ MODULE_AUTHOR("Alexander Shishkin");
#define ETB_BASE (L4_EMU_34XX_PHYS + 0x1b000)
#define DAPCTL (L4_EMU_34XX_PHYS + 0x1d000)
-static struct amba_device omap3_etb_device = {
- .dev = {
- .init_name = "etb",
- },
- .res = {
- .start = ETB_BASE,
- .end = ETB_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .periphid = 0x000bb907,
-};
-
-static struct amba_device omap3_etm_device = {
- .dev = {
- .init_name = "etm",
- },
- .res = {
- .start = ETM_BASE,
- .end = ETM_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .periphid = 0x102bb921,
-};
+static AMBA_APB_DEVICE(omap3_etb, "etb", 0x000bb907, ETB_BASE, { }, NULL);
+static AMBA_APB_DEVICE(omap3_etm, "etm", 0x102bb921, ETM_BASE, { }, NULL);
static int __init emu_init(void)
{
@@ -66,4 +45,3 @@ static int __init emu_init(void)
}
subsys_initcall(emu_init);
-
diff --git a/arch/arm/mach-omap2/gpmc-smsc911x.c b/arch/arm/mach-omap2/gpmc-smsc911x.c
index 997033129d2..bbb870c04a5 100644
--- a/arch/arm/mach-omap2/gpmc-smsc911x.c
+++ b/arch/arm/mach-omap2/gpmc-smsc911x.c
@@ -19,6 +19,8 @@
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/smsc911x.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <plat/board.h>
#include <plat/gpmc.h>
@@ -42,6 +44,50 @@ static struct smsc911x_platform_config gpmc_smsc911x_config = {
.flags = SMSC911X_USE_16BIT,
};
+static struct regulator_consumer_supply gpmc_smsc911x_supply[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x.0"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x.0"),
+};
+
+/* Generic regulator definition to satisfy smsc911x */
+static struct regulator_init_data gpmc_smsc911x_reg_init_data = {
+ .constraints = {
+ .min_uV = 3300000,
+ .max_uV = 3300000,
+ .valid_modes_mask = REGULATOR_MODE_NORMAL
+ | REGULATOR_MODE_STANDBY,
+ .valid_ops_mask = REGULATOR_CHANGE_MODE
+ | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(gpmc_smsc911x_supply),
+ .consumer_supplies = gpmc_smsc911x_supply,
+};
+
+static struct fixed_voltage_config gpmc_smsc911x_fixed_reg_data = {
+ .supply_name = "gpmc_smsc911x",
+ .microvolts = 3300000,
+ .gpio = -EINVAL,
+ .startup_delay = 0,
+ .enable_high = 0,
+ .enabled_at_boot = 1,
+ .init_data = &gpmc_smsc911x_reg_init_data,
+};
+
+/*
+ * Platform device id of 42 is a temporary fix to avoid conflicts
+ * with other reg-fixed-voltage devices. The real fix should
+ * involve the driver core providing a way of dynamically
+ * assigning a unique id on registration for platform devices
+ * in the same name space.
+ */
+static struct platform_device gpmc_smsc911x_regulator = {
+ .name = "reg-fixed-voltage",
+ .id = 42,
+ .dev = {
+ .platform_data = &gpmc_smsc911x_fixed_reg_data,
+ },
+};
+
/*
* Initialize smsc911x device connected to the GPMC. Note that we
* assume that pin multiplexing is done in the board-*.c file,
@@ -55,6 +101,12 @@ void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data)
gpmc_cfg = board_data;
+ ret = platform_device_register(&gpmc_smsc911x_regulator);
+ if (ret < 0) {
+ pr_err("Unable to register smsc911x regulators: %d\n", ret);
+ return;
+ }
+
if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) {
pr_err("Failed to request GPMC mem region\n");
return;
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index b40c2889529..19dd1657245 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -428,6 +428,7 @@ static int omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
return 0;
}
+static int omap_hsmmc_done;
#define MAX_OMAP_MMC_HWMOD_NAME_LEN 16
void omap_init_hsmmc(struct omap2_hsmmc_info *hsmmcinfo, int ctrl_nr)
@@ -491,6 +492,11 @@ void omap2_hsmmc_init(struct omap2_hsmmc_info *controllers)
{
u32 reg;
+ if (omap_hsmmc_done)
+ return;
+
+ omap_hsmmc_done = 1;
+
if (!cpu_is_omap44xx()) {
if (cpu_is_omap2430()) {
control_pbias_offset = OMAP243X_CONTROL_PBIAS_LITE;
diff --git a/arch/arm/mach-omap2/include/mach/system.h b/arch/arm/mach-omap2/include/mach/system.h
deleted file mode 100644
index d488721ab90..00000000000
--- a/arch/arm/mach-omap2/include/mach/system.h
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * arch/arm/mach-omap2/include/mach/system.h
- */
-
-#include <plat/system.h>
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index eb50c29fb64..fb11b44fbde 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -307,6 +307,7 @@ void __init omapam33xx_map_common_io(void)
void __init omap44xx_map_common_io(void)
{
iotable_init(omap44xx_io_desc, ARRAY_SIZE(omap44xx_io_desc));
+ omap_barriers_init();
}
#endif
diff --git a/arch/arm/mach-omap2/mailbox.c b/arch/arm/mach-omap2/mailbox.c
index 609ea2ded7e..2cc1aa004b9 100644
--- a/arch/arm/mach-omap2/mailbox.c
+++ b/arch/arm/mach-omap2/mailbox.c
@@ -281,8 +281,16 @@ static struct omap_mbox mbox_iva_info = {
.ops = &omap2_mbox_ops,
.priv = &omap2_mbox_iva_priv,
};
+#endif
-struct omap_mbox *omap2_mboxes[] = { &mbox_dsp_info, &mbox_iva_info, NULL };
+#ifdef CONFIG_ARCH_OMAP2
+struct omap_mbox *omap2_mboxes[] = {
+ &mbox_dsp_info,
+#ifdef CONFIG_SOC_OMAP2420
+ &mbox_iva_info,
+#endif
+ NULL
+};
#endif
#if defined(CONFIG_ARCH_OMAP4)
@@ -412,7 +420,8 @@ static void __exit omap2_mbox_exit(void)
platform_driver_unregister(&omap2_mbox_driver);
}
-module_init(omap2_mbox_init);
+/* must be ready before omap3isp is probed */
+subsys_initcall(omap2_mbox_init);
module_exit(omap2_mbox_exit);
MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c
index fb8bc9fa43b..611a0e3d54c 100644
--- a/arch/arm/mach-omap2/mux.c
+++ b/arch/arm/mach-omap2/mux.c
@@ -218,7 +218,7 @@ static int _omap_mux_get_by_name(struct omap_mux_partition *partition,
return -ENODEV;
}
-static int __init
+static int
omap_mux_get_by_name(const char *muxname,
struct omap_mux_partition **found_partition,
struct omap_mux **found_mux)
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 40a8fbc07e4..ebc59509131 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -24,6 +24,7 @@
#include <plat/irqs.h>
#include <plat/sram.h>
+#include <plat/omap-secure.h>
#include <mach/hardware.h>
#include <mach/omap-wakeupgen.h>
@@ -43,6 +44,9 @@ static void __iomem *sar_ram_base;
void __iomem *dram_sync, *sram_sync;
+static phys_addr_t paddr;
+static u32 size;
+
void omap_bus_sync(void)
{
if (dram_sync && sram_sync) {
@@ -52,18 +56,20 @@ void omap_bus_sync(void)
}
}
-static int __init omap_barriers_init(void)
+/* Steal one page physical memory for barrier implementation */
+int __init omap_barrier_reserve_memblock(void)
{
- struct map_desc dram_io_desc[1];
- phys_addr_t paddr;
- u32 size;
-
- if (!cpu_is_omap44xx())
- return -ENODEV;
size = ALIGN(PAGE_SIZE, SZ_1M);
paddr = arm_memblock_steal(size, SZ_1M);
+ return 0;
+}
+
+void __init omap_barriers_init(void)
+{
+ struct map_desc dram_io_desc[1];
+
dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
dram_io_desc[0].pfn = __phys_to_pfn(paddr);
dram_io_desc[0].length = size;
@@ -75,9 +81,10 @@ static int __init omap_barriers_init(void)
pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
(long long) paddr, dram_io_desc[0].virtual);
- return 0;
}
-core_initcall(omap_barriers_init);
+#else
+void __init omap_barriers_init(void)
+{}
#endif
void __init gic_init_irq(void)
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 1881fe91514..5a65dd04aa3 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -174,14 +174,17 @@ static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
freq = clk->rate;
clk_put(clk);
+ rcu_read_lock();
opp = opp_find_freq_ceil(dev, &freq);
if (IS_ERR(opp)) {
+ rcu_read_unlock();
pr_err("%s: unable to find boot up OPP for vdd_%s\n",
__func__, vdd_name);
goto exit;
}
bootup_volt = opp_get_voltage(opp);
+ rcu_read_unlock();
if (!bootup_volt) {
pr_err("%s: unable to find voltage corresponding "
"to the bootup OPP for vdd_%s\n", __func__, vdd_name);
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c
index 23de98d0384..a4eb5c28043 100644
--- a/arch/arm/mach-omap2/pm24xx.c
+++ b/arch/arm/mach-omap2/pm24xx.c
@@ -226,7 +226,6 @@ static int omap2_can_sleep(void)
static void omap2_pm_idle(void)
{
- local_irq_disable();
local_fiq_disable();
if (!omap2_can_sleep()) {
@@ -243,7 +242,6 @@ static void omap2_pm_idle(void)
out:
local_fiq_enable();
- local_irq_enable();
}
#ifdef CONFIG_SUSPEND
@@ -462,7 +460,7 @@ static int __init omap2_pm_init(void)
}
suspend_set_ops(&omap_pm_ops);
- pm_idle = omap2_pm_idle;
+ arm_pm_idle = omap2_pm_idle;
return 0;
}
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c
index fc698757892..b77df735fa6 100644
--- a/arch/arm/mach-omap2/pm34xx.c
+++ b/arch/arm/mach-omap2/pm34xx.c
@@ -418,10 +418,9 @@ void omap_sram_idle(void)
static void omap3_pm_idle(void)
{
- local_irq_disable();
local_fiq_disable();
- if (omap_irq_pending() || need_resched())
+ if (omap_irq_pending())
goto out;
trace_power_start(POWER_CSTATE, 1, smp_processor_id());
@@ -434,7 +433,6 @@ static void omap3_pm_idle(void)
out:
local_fiq_enable();
- local_irq_enable();
}
#ifdef CONFIG_SUSPEND
@@ -848,7 +846,7 @@ static int __init omap3_pm_init(void)
suspend_set_ops(&omap_pm_ops);
#endif /* CONFIG_SUSPEND */
- pm_idle = omap3_pm_idle;
+ arm_pm_idle = omap3_pm_idle;
omap3_idle_init();
/*
diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c
index c264ef7219c..c840689df24 100644
--- a/arch/arm/mach-omap2/pm44xx.c
+++ b/arch/arm/mach-omap2/pm44xx.c
@@ -173,18 +173,16 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
* omap_default_idle - OMAP4 default ilde routine.'
*
* Implements OMAP4 memory, IO ordering requirements which can't be addressed
- * with default arch_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and
+ * with default cpu_do_idle() hook. Used by all CPUs with !CONFIG_CPUIDLE and
* by secondary CPU with CONFIG_CPUIDLE.
*/
static void omap_default_idle(void)
{
- local_irq_disable();
local_fiq_disable();
omap_do_wfi();
local_fiq_enable();
- local_irq_enable();
}
/**
@@ -255,8 +253,8 @@ static int __init omap4_pm_init(void)
suspend_set_ops(&omap_pm_ops);
#endif /* CONFIG_SUSPEND */
- /* Overwrite the default arch_idle() */
- pm_idle = omap_default_idle;
+ /* Overwrite the default cpu_do_idle() */
+ arm_pm_idle = omap_default_idle;
omap4_idle_init();
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 860118ab43e..873b51d494e 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -24,7 +24,6 @@
#include <linux/interrupt.h>
#include <linux/slab.h>
-#include <mach/system.h>
#include <plat/common.h>
#include <plat/prcm.h>
#include <plat/irqs.h>
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index 771dc781b74..f51348dafaf 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -486,7 +486,7 @@ static void setup_4430ohci_io_mux(const enum usbhs_omap_port_mode *port_mode)
void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
{
struct omap_hwmod *oh[2];
- struct omap_device *od;
+ struct platform_device *pdev;
int bus_id = -1;
int i;
@@ -522,11 +522,11 @@ void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
return;
}
- od = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
+ pdev = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
(void *)&usbhs_data, sizeof(usbhs_data),
omap_uhhtll_latency,
ARRAY_SIZE(omap_uhhtll_latency), false);
- if (IS_ERR(od)) {
+ if (IS_ERR(pdev)) {
pr_err("Could not build hwmod devices %s,%s\n",
USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
return;
diff --git a/arch/arm/mach-omap2/voltagedomains3xxx_data.c b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
index c005e2f5e38..57db2038b23 100644
--- a/arch/arm/mach-omap2/voltagedomains3xxx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains3xxx_data.c
@@ -108,6 +108,7 @@ void __init omap3xxx_voltagedomains_init(void)
* XXX Will depend on the process, validation, and binning
* for the currently-running IC
*/
+#ifdef CONFIG_PM_OPP
if (cpu_is_omap3630()) {
omap3_voltdm_mpu.volt_data = omap36xx_vddmpu_volt_data;
omap3_voltdm_core.volt_data = omap36xx_vddcore_volt_data;
@@ -115,6 +116,7 @@ void __init omap3xxx_voltagedomains_init(void)
omap3_voltdm_mpu.volt_data = omap34xx_vddmpu_volt_data;
omap3_voltdm_core.volt_data = omap34xx_vddcore_volt_data;
}
+#endif
if (cpu_is_omap3517() || cpu_is_omap3505())
voltdms = voltagedomains_am35xx;
diff --git a/arch/arm/mach-omap2/voltagedomains44xx_data.c b/arch/arm/mach-omap2/voltagedomains44xx_data.c
index 4e11d022595..c3115f6853d 100644
--- a/arch/arm/mach-omap2/voltagedomains44xx_data.c
+++ b/arch/arm/mach-omap2/voltagedomains44xx_data.c
@@ -100,9 +100,11 @@ void __init omap44xx_voltagedomains_init(void)
* XXX Will depend on the process, validation, and binning
* for the currently-running IC
*/
+#ifdef CONFIG_PM_OPP
omap4_voltdm_mpu.volt_data = omap44xx_vdd_mpu_volt_data;
omap4_voltdm_iva.volt_data = omap44xx_vdd_iva_volt_data;
omap4_voltdm_core.volt_data = omap44xx_vdd_core_volt_data;
+#endif
for (i = 0; voltdm = voltagedomains_omap4[i], voltdm; i++)
voltdm->sys_clk.name = sys_clk_name;
diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h
deleted file mode 100644
index 825a2650cef..00000000000
--- a/arch/arm/mach-orion5x/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-orion5x/include/mach/system.h
- *
- * Tzachi Perelstein <tzachi@marvell.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-picoxcell/include/mach/system.h b/arch/arm/mach-picoxcell/include/mach/system.h
deleted file mode 100644
index 1a5d8cb57df..00000000000
--- a/arch/arm/mach-picoxcell/include/mach/system.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (c) 2011 Picochip Ltd., Jamie Iles
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching and wait for interrupt
- * tricks.
- */
- cpu_do_idle();
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-pnx4008/include/mach/system.h b/arch/arm/mach-pnx4008/include/mach/system.h
deleted file mode 100644
index 60cfe718809..00000000000
--- a/arch/arm/mach-pnx4008/include/mach/system.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * arch/arm/mach-pnx4008/include/mach/system.h
- *
- * Copyright (C) 2003 Philips Semiconductors
- * Copyright (C) 2005 MontaVista Software, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-prima2/include/mach/system.h b/arch/arm/mach-prima2/include/mach/system.h
deleted file mode 100644
index 2c7d2a9d0c9..00000000000
--- a/arch/arm/mach-prima2/include/mach/system.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * arch/arm/mach-prima2/include/mach/system.h
- *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-#ifndef __MACH_SYSTEM_H__
-#define __MACH_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-prima2/irq.c b/arch/arm/mach-prima2/irq.c
index d93ceef4a50..37c2de9b6f2 100644
--- a/arch/arm/mach-prima2/irq.c
+++ b/arch/arm/mach-prima2/irq.c
@@ -68,7 +68,7 @@ void __init sirfsoc_of_irq_init(void)
if (!sirfsoc_intc_base)
panic("unable to map intc cpu registers\n");
- irq_domain_add_simple(np, 0);
+ irq_domain_add_legacy(np, 32, 0, 0, &irq_domain_simple_ops, NULL);
of_node_put(np);
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 5bc13121eac..84f2d7015cf 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -406,20 +406,17 @@ static struct resource pxa_rtc_resources[] = {
[1] = {
.start = IRQ_RTC1Hz,
.end = IRQ_RTC1Hz,
+ .name = "rtc 1Hz",
.flags = IORESOURCE_IRQ,
},
[2] = {
.start = IRQ_RTCAlrm,
.end = IRQ_RTCAlrm,
+ .name = "rtc alarm",
.flags = IORESOURCE_IRQ,
},
};
-struct platform_device sa1100_device_rtc = {
- .name = "sa1100-rtc",
- .id = -1,
-};
-
struct platform_device pxa_device_rtc = {
.name = "pxa-rtc",
.id = -1,
@@ -427,6 +424,27 @@ struct platform_device pxa_device_rtc = {
.resource = pxa_rtc_resources,
};
+static struct resource sa1100_rtc_resources[] = {
+ {
+ .start = IRQ_RTC1Hz,
+ .end = IRQ_RTC1Hz,
+ .name = "rtc 1Hz",
+ .flags = IORESOURCE_IRQ,
+ }, {
+ .start = IRQ_RTCAlrm,
+ .end = IRQ_RTCAlrm,
+ .name = "rtc alarm",
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device sa1100_device_rtc = {
+ .name = "sa1100-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sa1100_rtc_resources),
+ .resource = sa1100_rtc_resources,
+};
+
static struct resource pxa_ac97_resources[] = {
[0] = {
.start = 0x40500000,
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index fb9b62dcf4c..8a1ef2734d5 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -28,7 +28,8 @@
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
-#include <linux/regulator/bq24022.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/gpio-regulator.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/max1586.h>
#include <linux/spi/ads7846.h>
@@ -45,6 +46,7 @@
#include <mach/hx4700.h>
#include <mach/irda.h>
+#include <sound/ak4641.h>
#include <video/platform_lcd.h>
#include <video/w100fb.h>
@@ -681,14 +683,34 @@ static struct regulator_init_data bq24022_init_data = {
.consumer_supplies = bq24022_consumers,
};
-static struct bq24022_mach_info bq24022_info = {
- .gpio_nce = GPIO72_HX4700_BQ24022_nCHARGE_EN,
- .gpio_iset2 = GPIO96_HX4700_BQ24022_ISET2,
- .init_data = &bq24022_init_data,
+static struct gpio bq24022_gpios[] = {
+ { GPIO96_HX4700_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
+};
+
+static struct gpio_regulator_state bq24022_states[] = {
+ { .value = 100000, .gpios = (0 << 0) },
+ { .value = 500000, .gpios = (1 << 0) },
+};
+
+static struct gpio_regulator_config bq24022_info = {
+ .supply_name = "bq24022",
+
+ .enable_gpio = GPIO72_HX4700_BQ24022_nCHARGE_EN,
+ .enable_high = 0,
+ .enabled_at_boot = 0,
+
+ .gpios = bq24022_gpios,
+ .nr_gpios = ARRAY_SIZE(bq24022_gpios),
+
+ .states = bq24022_states,
+ .nr_states = ARRAY_SIZE(bq24022_states),
+
+ .type = REGULATOR_CURRENT,
+ .init_data = &bq24022_init_data,
};
static struct platform_device bq24022 = {
- .name = "bq24022",
+ .name = "gpio-regulator",
.id = -1,
.dev = {
.platform_data = &bq24022_info,
@@ -765,6 +787,28 @@ static struct i2c_board_info __initdata pi2c_board_info[] = {
};
/*
+ * Asahi Kasei AK4641 on I2C
+ */
+
+static struct ak4641_platform_data ak4641_info = {
+ .gpio_power = GPIO27_HX4700_CODEC_ON,
+ .gpio_npdn = GPIO109_HX4700_CODEC_nPDN,
+};
+
+static struct i2c_board_info i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ak4641", 0x12),
+ .platform_data = &ak4641_info,
+ },
+};
+
+static struct platform_device audio = {
+ .name = "hx4700-audio",
+ .id = -1,
+};
+
+
+/*
* PCMCIA
*/
@@ -790,6 +834,7 @@ static struct platform_device *devices[] __initdata = {
&gpio_vbus,
&power_supply,
&strataflash,
+ &audio,
&pcmcia,
};
@@ -827,6 +872,7 @@ static void __init hx4700_init(void)
pxa_set_ficp_info(&ficp_info);
pxa27x_set_i2c_power_info(NULL);
pxa_set_i2c_info(NULL);
+ i2c_register_board_info(0, ARRAY_AND_SIZE(i2c_board_info));
i2c_register_board_info(1, ARRAY_AND_SIZE(pi2c_board_info));
pxa2xx_set_spi_info(2, &pxa_ssp2_master_info);
spi_register_board_info(ARRAY_AND_SIZE(tsc2046_board_info));
diff --git a/arch/arm/mach-pxa/include/mach/system.h b/arch/arm/mach-pxa/include/mach/system.h
deleted file mode 100644
index c5afacd3cc0..00000000000
--- a/arch/arm/mach-pxa/include/mach/system.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * arch/arm/mach-pxa/include/mach/system.h
- *
- * Author: Nicolas Pitre
- * Created: Jun 15, 2001
- * Copyright: MontaVista Software Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 3d6baf91396..5e26f3e93fd 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -25,7 +25,8 @@
#include <linux/mtd/physmap.h>
#include <linux/pda_power.h>
#include <linux/pwm_backlight.h>
-#include <linux/regulator/bq24022.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/gpio-regulator.h>
#include <linux/regulator/machine.h>
#include <linux/usb/gpio_vbus.h>
#include <linux/i2c/pxa-i2c.h>
@@ -596,14 +597,34 @@ static struct regulator_init_data bq24022_init_data = {
.consumer_supplies = bq24022_consumers,
};
-static struct bq24022_mach_info bq24022_info = {
- .gpio_nce = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
- .gpio_iset2 = EGPIO_MAGICIAN_BQ24022_ISET2,
- .init_data = &bq24022_init_data,
+static struct gpio bq24022_gpios[] = {
+ { EGPIO_MAGICIAN_BQ24022_ISET2, GPIOF_OUT_INIT_LOW, "bq24022_iset2" },
+};
+
+static struct gpio_regulator_state bq24022_states[] = {
+ { .value = 100000, .gpios = (0 << 0) },
+ { .value = 500000, .gpios = (1 << 0) },
+};
+
+static struct gpio_regulator_config bq24022_info = {
+ .supply_name = "bq24022",
+
+ .enable_gpio = GPIO30_MAGICIAN_BQ24022_nCHARGE_EN,
+ .enable_high = 0,
+ .enabled_at_boot = 0,
+
+ .gpios = bq24022_gpios,
+ .nr_gpios = ARRAY_SIZE(bq24022_gpios),
+
+ .states = bq24022_states,
+ .nr_states = ARRAY_SIZE(bq24022_states),
+
+ .type = REGULATOR_CURRENT,
+ .init_data = &bq24022_init_data,
};
static struct platform_device bq24022 = {
- .name = "bq24022",
+ .name = "gpio-regulator",
.id = -1,
.dev = {
.platform_data = &bq24022_info,
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c
index 91e4f6c0376..e48033eb2be 100644
--- a/arch/arm/mach-pxa/pxa25x.c
+++ b/arch/arm/mach-pxa/pxa25x.c
@@ -25,7 +25,6 @@
#include <linux/suspend.h>
#include <linux/syscore_ops.h>
#include <linux/irq.h>
-#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <asm/suspend.h>
@@ -209,6 +208,7 @@ static struct clk_lookup pxa25x_clkregs[] = {
INIT_CLKREG(&clk_pxa25x_gpio11, NULL, "GPIO11_CLK"),
INIT_CLKREG(&clk_pxa25x_gpio12, NULL, "GPIO12_CLK"),
INIT_CLKREG(&clk_pxa25x_mem, "pxa2xx-pcmcia", NULL),
+ INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};
static struct clk_lookup pxa25x_hwuart_clkreg =
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c
index aed6cbcf386..a70b7e23fa4 100644
--- a/arch/arm/mach-pxa/pxa27x.c
+++ b/arch/arm/mach-pxa/pxa27x.c
@@ -22,7 +22,6 @@
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/i2c/pxa-i2c.h>
-#include <linux/gpio.h>
#include <asm/mach/map.h>
#include <mach/hardware.h>
@@ -230,6 +229,7 @@ static struct clk_lookup pxa27x_clkregs[] = {
INIT_CLKREG(&clk_pxa27x_im, NULL, "IMCLK"),
INIT_CLKREG(&clk_pxa27x_memc, NULL, "MEMCLK"),
INIT_CLKREG(&clk_pxa27x_mem, "pxa2xx-pcmcia", NULL),
+ INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};
#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index 4f402afa660..881934899bd 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -89,6 +89,7 @@ static struct clk_lookup pxa3xx_clkregs[] = {
INIT_CLKREG(&clk_pxa3xx_mmc2, "pxa2xx-mci.1", NULL),
INIT_CLKREG(&clk_pxa3xx_smemc, "pxa2xx-pcmcia", NULL),
INIT_CLKREG(&clk_pxa3xx_gpio, "pxa-gpio", NULL),
+ INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};
#ifdef CONFIG_PM
diff --git a/arch/arm/mach-pxa/pxa95x.c b/arch/arm/mach-pxa/pxa95x.c
index d082a583df7..35023d7d3cd 100644
--- a/arch/arm/mach-pxa/pxa95x.c
+++ b/arch/arm/mach-pxa/pxa95x.c
@@ -231,6 +231,7 @@ static struct clk_lookup pxa95x_clkregs[] = {
INIT_CLKREG(&clk_pxa95x_pwm0, "pxa27x-pwm.0", NULL),
INIT_CLKREG(&clk_pxa95x_pwm1, "pxa27x-pwm.1", NULL),
INIT_CLKREG(&clk_pxa95x_gpio, "pxa-gpio", NULL),
+ INIT_CLKREG(&clk_dummy, "sa1100-rtc", NULL),
};
void __init pxa95x_init_irq(void)
diff --git a/arch/arm/mach-pxa/saarb.c b/arch/arm/mach-pxa/saarb.c
index febc809ed5a..5aded5e6148 100644
--- a/arch/arm/mach-pxa/saarb.c
+++ b/arch/arm/mach-pxa/saarb.c
@@ -15,7 +15,6 @@
#include <linux/i2c.h>
#include <linux/i2c/pxa-i2c.h>
#include <linux/mfd/88pm860x.h>
-#include <linux/gpio.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
index 8d5168d253a..30989baf7f2 100644
--- a/arch/arm/mach-pxa/sharpsl_pm.c
+++ b/arch/arm/mach-pxa/sharpsl_pm.c
@@ -168,6 +168,7 @@ struct battery_thresh sharpsl_battery_levels_noac[] = {
#define MAXCTRL_SEL_SH 4
#define MAXCTRL_STR (1u << 7)
+extern int max1111_read_channel(int);
/*
* Read MAX1111 ADC
*/
@@ -177,8 +178,6 @@ int sharpsl_pm_pxa_read_max1111(int channel)
if (machine_is_tosa())
return 0;
- extern int max1111_read_channel(int);
-
/* max1111 accepts channels from 0-3, however,
* it is encoded from 0-7 here in the code.
*/
diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
index 34cbdac5152..438f02fe122 100644
--- a/arch/arm/mach-pxa/spitz_pm.c
+++ b/arch/arm/mach-pxa/spitz_pm.c
@@ -172,10 +172,9 @@ static int spitz_should_wakeup(unsigned int resume_on_alarm)
static unsigned long spitz_charger_wakeup(void)
{
unsigned long ret;
- ret = (!gpio_get_value(SPITZ_GPIO_KEY_INT)
+ ret = ((!gpio_get_value(SPITZ_GPIO_KEY_INT)
<< GPIO_bit(SPITZ_GPIO_KEY_INT))
- | (!gpio_get_value(SPITZ_GPIO_SYNC)
- << GPIO_bit(SPITZ_GPIO_SYNC));
+ | gpio_get_value(SPITZ_GPIO_SYNC));
return ret;
}
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h
index 735b57aaf2d..f8f2c0ac4c0 100644
--- a/arch/arm/mach-realview/core.h
+++ b/arch/arm/mach-realview/core.h
@@ -28,21 +28,11 @@
#include <asm/setup.h>
#include <asm/leds.h>
-#define AMBA_DEVICE(name,busid,base,plat) \
-static struct amba_device name##_device = { \
- .dev = { \
- .coherent_dma_mask = ~0, \
- .init_name = busid, \
- .platform_data = plat, \
- }, \
- .res = { \
- .start = REALVIEW_##base##_BASE, \
- .end = (REALVIEW_##base##_BASE) + SZ_4K - 1, \
- .flags = IORESOURCE_MEM, \
- }, \
- .dma_mask = ~0, \
- .irq = base##_IRQ, \
-}
+#define APB_DEVICE(name, busid, base, plat) \
+static AMBA_APB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat)
+
+#define AHB_DEVICE(name, busid, base, plat) \
+static AMBA_AHB_DEVICE(name, busid, 0, REALVIEW_##base##_BASE, base##_IRQ, plat)
struct machine_desc;
diff --git a/arch/arm/mach-realview/include/mach/irqs-pb1176.h b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
index 5c3c625e3e0..708f84156f2 100644
--- a/arch/arm/mach-realview/include/mach/irqs-pb1176.h
+++ b/arch/arm/mach-realview/include/mach/irqs-pb1176.h
@@ -40,6 +40,7 @@
#define IRQ_DC1176_L2CC (IRQ_DC1176_GIC_START + 13)
#define IRQ_DC1176_RTC (IRQ_DC1176_GIC_START + 14)
#define IRQ_DC1176_CLCD (IRQ_DC1176_GIC_START + 15) /* CLCD controller */
+#define IRQ_DC1176_GPIO0 (IRQ_DC1176_GIC_START + 16)
#define IRQ_DC1176_SSP (IRQ_DC1176_GIC_START + 17) /* SSP port */
#define IRQ_DC1176_UART0 (IRQ_DC1176_GIC_START + 18) /* UART 0 on development chip */
#define IRQ_DC1176_UART1 (IRQ_DC1176_GIC_START + 19) /* UART 1 on development chip */
@@ -73,7 +74,6 @@
#define IRQ_PB1176_DMAC (IRQ_PB1176_GIC_START + 24) /* DMA controller */
#define IRQ_PB1176_RTC (IRQ_PB1176_GIC_START + 25) /* Real Time Clock */
-#define IRQ_PB1176_GPIO0 -1
#define IRQ_PB1176_SCTL -1
#define NR_GIC_PB1176 2
diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h
deleted file mode 100644
index 471b671159c..00000000000
--- a/arch/arm/mach-realview/include/mach/system.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/mach-realview/include/mach/system.h
- *
- * Copyright (C) 2003 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks
- */
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 9578145f2df..157e1bc6e83 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -135,63 +135,63 @@ static struct pl022_ssp_controller ssp0_plat_data = {
/*
* These devices are connected via the core APB bridge
*/
-#define GPIO2_IRQ { IRQ_EB_GPIO2, NO_IRQ }
-#define GPIO3_IRQ { IRQ_EB_GPIO3, NO_IRQ }
+#define GPIO2_IRQ { IRQ_EB_GPIO2 }
+#define GPIO3_IRQ { IRQ_EB_GPIO3 }
-#define AACI_IRQ { IRQ_EB_AACI, NO_IRQ }
+#define AACI_IRQ { IRQ_EB_AACI }
#define MMCI0_IRQ { IRQ_EB_MMCI0A, IRQ_EB_MMCI0B }
-#define KMI0_IRQ { IRQ_EB_KMI0, NO_IRQ }
-#define KMI1_IRQ { IRQ_EB_KMI1, NO_IRQ }
+#define KMI0_IRQ { IRQ_EB_KMI0 }
+#define KMI1_IRQ { IRQ_EB_KMI1 }
/*
* These devices are connected directly to the multi-layer AHB switch
*/
-#define EB_SMC_IRQ { NO_IRQ, NO_IRQ }
-#define MPMC_IRQ { NO_IRQ, NO_IRQ }
-#define EB_CLCD_IRQ { IRQ_EB_CLCD, NO_IRQ }
-#define DMAC_IRQ { IRQ_EB_DMA, NO_IRQ }
+#define EB_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define EB_CLCD_IRQ { IRQ_EB_CLCD }
+#define DMAC_IRQ { IRQ_EB_DMA }
/*
* These devices are connected via the core APB bridge
*/
-#define SCTL_IRQ { NO_IRQ, NO_IRQ }
-#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG, NO_IRQ }
-#define EB_GPIO0_IRQ { IRQ_EB_GPIO0, NO_IRQ }
-#define GPIO1_IRQ { IRQ_EB_GPIO1, NO_IRQ }
-#define EB_RTC_IRQ { IRQ_EB_RTC, NO_IRQ }
+#define SCTL_IRQ { }
+#define EB_WATCHDOG_IRQ { IRQ_EB_WDOG }
+#define EB_GPIO0_IRQ { IRQ_EB_GPIO0 }
+#define GPIO1_IRQ { IRQ_EB_GPIO1 }
+#define EB_RTC_IRQ { IRQ_EB_RTC }
/*
* These devices are connected via the DMA APB bridge
*/
-#define SCI_IRQ { IRQ_EB_SCI, NO_IRQ }
-#define EB_UART0_IRQ { IRQ_EB_UART0, NO_IRQ }
-#define EB_UART1_IRQ { IRQ_EB_UART1, NO_IRQ }
-#define EB_UART2_IRQ { IRQ_EB_UART2, NO_IRQ }
-#define EB_UART3_IRQ { IRQ_EB_UART3, NO_IRQ }
-#define EB_SSP_IRQ { IRQ_EB_SSP, NO_IRQ }
+#define SCI_IRQ { IRQ_EB_SCI }
+#define EB_UART0_IRQ { IRQ_EB_UART0 }
+#define EB_UART1_IRQ { IRQ_EB_UART1 }
+#define EB_UART2_IRQ { IRQ_EB_UART2 }
+#define EB_UART3_IRQ { IRQ_EB_UART3 }
+#define EB_SSP_IRQ { IRQ_EB_SSP }
/* FPGA Primecells */
-AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
-AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
-AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
-AMBA_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart3, "fpga:uart3", EB_UART3, NULL);
/* DevChip Primecells */
-AMBA_DEVICE(smc, "dev:smc", EB_SMC, NULL);
-AMBA_DEVICE(clcd, "dev:clcd", EB_CLCD, &clcd_plat_data);
-AMBA_DEVICE(dmac, "dev:dmac", DMAC, NULL);
-AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
-AMBA_DEVICE(wdog, "dev:wdog", EB_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
-AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
-AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
-AMBA_DEVICE(rtc, "dev:rtc", EB_RTC, NULL);
-AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
-AMBA_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
-AMBA_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
-AMBA_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
-AMBA_DEVICE(ssp0, "dev:ssp0", EB_SSP, &ssp0_plat_data);
+AHB_DEVICE(smc, "dev:smc", EB_SMC, NULL);
+AHB_DEVICE(clcd, "dev:clcd", EB_CLCD, &clcd_plat_data);
+AHB_DEVICE(dmac, "dev:dmac", DMAC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", EB_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", EB_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", EB_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", EB_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", EB_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", EB_UART2, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", EB_SSP, &ssp0_plat_data);
static struct amba_device *amba_devs[] __initdata = {
&dmac_device,
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index e4abe94fb11..b1d7cafa1a6 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -132,50 +132,50 @@ static struct pl022_ssp_controller ssp0_plat_data = {
/*
* RealView PB1176 AMBA devices
*/
-#define GPIO2_IRQ { IRQ_PB1176_GPIO2, NO_IRQ }
-#define GPIO3_IRQ { IRQ_PB1176_GPIO3, NO_IRQ }
-#define AACI_IRQ { IRQ_PB1176_AACI, NO_IRQ }
+#define GPIO2_IRQ { IRQ_PB1176_GPIO2 }
+#define GPIO3_IRQ { IRQ_PB1176_GPIO3 }
+#define AACI_IRQ { IRQ_PB1176_AACI }
#define MMCI0_IRQ { IRQ_PB1176_MMCI0A, IRQ_PB1176_MMCI0B }
-#define KMI0_IRQ { IRQ_PB1176_KMI0, NO_IRQ }
-#define KMI1_IRQ { IRQ_PB1176_KMI1, NO_IRQ }
-#define PB1176_SMC_IRQ { NO_IRQ, NO_IRQ }
-#define MPMC_IRQ { NO_IRQ, NO_IRQ }
-#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD, NO_IRQ }
-#define SCTL_IRQ { NO_IRQ, NO_IRQ }
-#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG, NO_IRQ }
-#define PB1176_GPIO0_IRQ { IRQ_PB1176_GPIO0, NO_IRQ }
-#define GPIO1_IRQ { IRQ_PB1176_GPIO1, NO_IRQ }
-#define PB1176_RTC_IRQ { IRQ_DC1176_RTC, NO_IRQ }
-#define SCI_IRQ { IRQ_PB1176_SCI, NO_IRQ }
-#define PB1176_UART0_IRQ { IRQ_DC1176_UART0, NO_IRQ }
-#define PB1176_UART1_IRQ { IRQ_DC1176_UART1, NO_IRQ }
-#define PB1176_UART2_IRQ { IRQ_DC1176_UART2, NO_IRQ }
-#define PB1176_UART3_IRQ { IRQ_DC1176_UART3, NO_IRQ }
-#define PB1176_UART4_IRQ { IRQ_PB1176_UART4, NO_IRQ }
-#define PB1176_SSP_IRQ { IRQ_DC1176_SSP, NO_IRQ }
+#define KMI0_IRQ { IRQ_PB1176_KMI0 }
+#define KMI1_IRQ { IRQ_PB1176_KMI1 }
+#define PB1176_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define PB1176_CLCD_IRQ { IRQ_DC1176_CLCD }
+#define SCTL_IRQ { }
+#define PB1176_WATCHDOG_IRQ { IRQ_DC1176_WATCHDOG }
+#define PB1176_GPIO0_IRQ { IRQ_DC1176_GPIO0 }
+#define GPIO1_IRQ { IRQ_PB1176_GPIO1 }
+#define PB1176_RTC_IRQ { IRQ_DC1176_RTC }
+#define SCI_IRQ { IRQ_PB1176_SCI }
+#define PB1176_UART0_IRQ { IRQ_DC1176_UART0 }
+#define PB1176_UART1_IRQ { IRQ_DC1176_UART1 }
+#define PB1176_UART2_IRQ { IRQ_DC1176_UART2 }
+#define PB1176_UART3_IRQ { IRQ_DC1176_UART3 }
+#define PB1176_UART4_IRQ { IRQ_PB1176_UART4 }
+#define PB1176_SSP_IRQ { IRQ_DC1176_SSP }
/* FPGA Primecells */
-AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
-AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
-AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
-AMBA_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL);
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart4, "fpga:uart4", PB1176_UART4, NULL);
/* DevChip Primecells */
-AMBA_DEVICE(smc, "dev:smc", PB1176_SMC, NULL);
-AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
-AMBA_DEVICE(wdog, "dev:wdog", PB1176_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:gpio0", PB1176_GPIO0, &gpio0_plat_data);
-AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
-AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
-AMBA_DEVICE(rtc, "dev:rtc", PB1176_RTC, NULL);
-AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
-AMBA_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL);
-AMBA_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL);
-AMBA_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL);
-AMBA_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL);
-AMBA_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, &ssp0_plat_data);
-AMBA_DEVICE(clcd, "dev:clcd", PB1176_CLCD, &clcd_plat_data);
+AHB_DEVICE(smc, "dev:smc", PB1176_SMC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", PB1176_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", PB1176_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", PB1176_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", PB1176_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", PB1176_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", PB1176_UART2, NULL);
+APB_DEVICE(uart3, "dev:uart3", PB1176_UART3, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", PB1176_SSP, &ssp0_plat_data);
+AHB_DEVICE(clcd, "dev:clcd", PB1176_CLCD, &clcd_plat_data);
static struct amba_device *amba_devs[] __initdata = {
&uart0_device,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 2147335f66f..ae7fe54f6eb 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -127,52 +127,52 @@ static struct pl022_ssp_controller ssp0_plat_data = {
* RealView PB11MPCore AMBA devices
*/
-#define GPIO2_IRQ { IRQ_PB11MP_GPIO2, NO_IRQ }
-#define GPIO3_IRQ { IRQ_PB11MP_GPIO3, NO_IRQ }
-#define AACI_IRQ { IRQ_TC11MP_AACI, NO_IRQ }
+#define GPIO2_IRQ { IRQ_PB11MP_GPIO2 }
+#define GPIO3_IRQ { IRQ_PB11MP_GPIO3 }
+#define AACI_IRQ { IRQ_TC11MP_AACI }
#define MMCI0_IRQ { IRQ_TC11MP_MMCI0A, IRQ_TC11MP_MMCI0B }
-#define KMI0_IRQ { IRQ_TC11MP_KMI0, NO_IRQ }
-#define KMI1_IRQ { IRQ_TC11MP_KMI1, NO_IRQ }
-#define PB11MP_SMC_IRQ { NO_IRQ, NO_IRQ }
-#define MPMC_IRQ { NO_IRQ, NO_IRQ }
-#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD, NO_IRQ }
-#define DMAC_IRQ { IRQ_PB11MP_DMAC, NO_IRQ }
-#define SCTL_IRQ { NO_IRQ, NO_IRQ }
-#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG, NO_IRQ }
-#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0, NO_IRQ }
-#define GPIO1_IRQ { IRQ_PB11MP_GPIO1, NO_IRQ }
-#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC, NO_IRQ }
-#define SCI_IRQ { IRQ_PB11MP_SCI, NO_IRQ }
-#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0, NO_IRQ }
-#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1, NO_IRQ }
-#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2, NO_IRQ }
-#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3, NO_IRQ }
-#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP, NO_IRQ }
+#define KMI0_IRQ { IRQ_TC11MP_KMI0 }
+#define KMI1_IRQ { IRQ_TC11MP_KMI1 }
+#define PB11MP_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define PB11MP_CLCD_IRQ { IRQ_PB11MP_CLCD }
+#define DMAC_IRQ { IRQ_PB11MP_DMAC }
+#define SCTL_IRQ { }
+#define PB11MP_WATCHDOG_IRQ { IRQ_PB11MP_WATCHDOG }
+#define PB11MP_GPIO0_IRQ { IRQ_PB11MP_GPIO0 }
+#define GPIO1_IRQ { IRQ_PB11MP_GPIO1 }
+#define PB11MP_RTC_IRQ { IRQ_TC11MP_RTC }
+#define SCI_IRQ { IRQ_PB11MP_SCI }
+#define PB11MP_UART0_IRQ { IRQ_TC11MP_UART0 }
+#define PB11MP_UART1_IRQ { IRQ_TC11MP_UART1 }
+#define PB11MP_UART2_IRQ { IRQ_PB11MP_UART2 }
+#define PB11MP_UART3_IRQ { IRQ_PB11MP_UART3 }
+#define PB11MP_SSP_IRQ { IRQ_PB11MP_SSP }
/* FPGA Primecells */
-AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
-AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
-AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
-AMBA_DEVICE(uart3, "fpga:uart3", PB11MP_UART3, NULL);
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart3, "fpga:uart3", PB11MP_UART3, NULL);
/* DevChip Primecells */
-AMBA_DEVICE(smc, "dev:smc", PB11MP_SMC, NULL);
-AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
-AMBA_DEVICE(wdog, "dev:wdog", PB11MP_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:gpio0", PB11MP_GPIO0, &gpio0_plat_data);
-AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
-AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
-AMBA_DEVICE(rtc, "dev:rtc", PB11MP_RTC, NULL);
-AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
-AMBA_DEVICE(uart0, "dev:uart0", PB11MP_UART0, NULL);
-AMBA_DEVICE(uart1, "dev:uart1", PB11MP_UART1, NULL);
-AMBA_DEVICE(uart2, "dev:uart2", PB11MP_UART2, NULL);
-AMBA_DEVICE(ssp0, "dev:ssp0", PB11MP_SSP, &ssp0_plat_data);
+AHB_DEVICE(smc, "dev:smc", PB11MP_SMC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", PB11MP_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", PB11MP_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", PB11MP_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", PB11MP_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", PB11MP_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", PB11MP_UART2, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", PB11MP_SSP, &ssp0_plat_data);
/* Primecells on the NEC ISSP chip */
-AMBA_DEVICE(clcd, "issp:clcd", PB11MP_CLCD, &clcd_plat_data);
-AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL);
+AHB_DEVICE(clcd, "issp:clcd", PB11MP_CLCD, &clcd_plat_data);
+AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL);
static struct amba_device *amba_devs[] __initdata = {
&dmac_device,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 25b2e59296f..59650174e6e 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -122,52 +122,52 @@ static struct pl022_ssp_controller ssp0_plat_data = {
* RealView PBA8Core AMBA devices
*/
-#define GPIO2_IRQ { IRQ_PBA8_GPIO2, NO_IRQ }
-#define GPIO3_IRQ { IRQ_PBA8_GPIO3, NO_IRQ }
-#define AACI_IRQ { IRQ_PBA8_AACI, NO_IRQ }
+#define GPIO2_IRQ { IRQ_PBA8_GPIO2 }
+#define GPIO3_IRQ { IRQ_PBA8_GPIO3 }
+#define AACI_IRQ { IRQ_PBA8_AACI }
#define MMCI0_IRQ { IRQ_PBA8_MMCI0A, IRQ_PBA8_MMCI0B }
-#define KMI0_IRQ { IRQ_PBA8_KMI0, NO_IRQ }
-#define KMI1_IRQ { IRQ_PBA8_KMI1, NO_IRQ }
-#define PBA8_SMC_IRQ { NO_IRQ, NO_IRQ }
-#define MPMC_IRQ { NO_IRQ, NO_IRQ }
-#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD, NO_IRQ }
-#define DMAC_IRQ { IRQ_PBA8_DMAC, NO_IRQ }
-#define SCTL_IRQ { NO_IRQ, NO_IRQ }
-#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG, NO_IRQ }
-#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0, NO_IRQ }
-#define GPIO1_IRQ { IRQ_PBA8_GPIO1, NO_IRQ }
-#define PBA8_RTC_IRQ { IRQ_PBA8_RTC, NO_IRQ }
-#define SCI_IRQ { IRQ_PBA8_SCI, NO_IRQ }
-#define PBA8_UART0_IRQ { IRQ_PBA8_UART0, NO_IRQ }
-#define PBA8_UART1_IRQ { IRQ_PBA8_UART1, NO_IRQ }
-#define PBA8_UART2_IRQ { IRQ_PBA8_UART2, NO_IRQ }
-#define PBA8_UART3_IRQ { IRQ_PBA8_UART3, NO_IRQ }
-#define PBA8_SSP_IRQ { IRQ_PBA8_SSP, NO_IRQ }
+#define KMI0_IRQ { IRQ_PBA8_KMI0 }
+#define KMI1_IRQ { IRQ_PBA8_KMI1 }
+#define PBA8_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define PBA8_CLCD_IRQ { IRQ_PBA8_CLCD }
+#define DMAC_IRQ { IRQ_PBA8_DMAC }
+#define SCTL_IRQ { }
+#define PBA8_WATCHDOG_IRQ { IRQ_PBA8_WATCHDOG }
+#define PBA8_GPIO0_IRQ { IRQ_PBA8_GPIO0 }
+#define GPIO1_IRQ { IRQ_PBA8_GPIO1 }
+#define PBA8_RTC_IRQ { IRQ_PBA8_RTC }
+#define SCI_IRQ { IRQ_PBA8_SCI }
+#define PBA8_UART0_IRQ { IRQ_PBA8_UART0 }
+#define PBA8_UART1_IRQ { IRQ_PBA8_UART1 }
+#define PBA8_UART2_IRQ { IRQ_PBA8_UART2 }
+#define PBA8_UART3_IRQ { IRQ_PBA8_UART3 }
+#define PBA8_SSP_IRQ { IRQ_PBA8_SSP }
/* FPGA Primecells */
-AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
-AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
-AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
-AMBA_DEVICE(uart3, "fpga:uart3", PBA8_UART3, NULL);
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart3, "fpga:uart3", PBA8_UART3, NULL);
/* DevChip Primecells */
-AMBA_DEVICE(smc, "dev:smc", PBA8_SMC, NULL);
-AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
-AMBA_DEVICE(wdog, "dev:wdog", PBA8_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:gpio0", PBA8_GPIO0, &gpio0_plat_data);
-AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
-AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
-AMBA_DEVICE(rtc, "dev:rtc", PBA8_RTC, NULL);
-AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
-AMBA_DEVICE(uart0, "dev:uart0", PBA8_UART0, NULL);
-AMBA_DEVICE(uart1, "dev:uart1", PBA8_UART1, NULL);
-AMBA_DEVICE(uart2, "dev:uart2", PBA8_UART2, NULL);
-AMBA_DEVICE(ssp0, "dev:ssp0", PBA8_SSP, &ssp0_plat_data);
+AHB_DEVICE(smc, "dev:smc", PBA8_SMC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", PBA8_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", PBA8_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", PBA8_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", PBA8_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", PBA8_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", PBA8_UART2, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", PBA8_SSP, &ssp0_plat_data);
/* Primecells on the NEC ISSP chip */
-AMBA_DEVICE(clcd, "issp:clcd", PBA8_CLCD, &clcd_plat_data);
-AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL);
+AHB_DEVICE(clcd, "issp:clcd", PBA8_CLCD, &clcd_plat_data);
+AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL);
static struct amba_device *amba_devs[] __initdata = {
&dmac_device,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index ac715645b86..1cd9956f587 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -144,52 +144,52 @@ static struct pl022_ssp_controller ssp0_plat_data = {
* RealView PBXCore AMBA devices
*/
-#define GPIO2_IRQ { IRQ_PBX_GPIO2, NO_IRQ }
-#define GPIO3_IRQ { IRQ_PBX_GPIO3, NO_IRQ }
-#define AACI_IRQ { IRQ_PBX_AACI, NO_IRQ }
+#define GPIO2_IRQ { IRQ_PBX_GPIO2 }
+#define GPIO3_IRQ { IRQ_PBX_GPIO3 }
+#define AACI_IRQ { IRQ_PBX_AACI }
#define MMCI0_IRQ { IRQ_PBX_MMCI0A, IRQ_PBX_MMCI0B }
-#define KMI0_IRQ { IRQ_PBX_KMI0, NO_IRQ }
-#define KMI1_IRQ { IRQ_PBX_KMI1, NO_IRQ }
-#define PBX_SMC_IRQ { NO_IRQ, NO_IRQ }
-#define MPMC_IRQ { NO_IRQ, NO_IRQ }
-#define PBX_CLCD_IRQ { IRQ_PBX_CLCD, NO_IRQ }
-#define DMAC_IRQ { IRQ_PBX_DMAC, NO_IRQ }
-#define SCTL_IRQ { NO_IRQ, NO_IRQ }
-#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG, NO_IRQ }
-#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0, NO_IRQ }
-#define GPIO1_IRQ { IRQ_PBX_GPIO1, NO_IRQ }
-#define PBX_RTC_IRQ { IRQ_PBX_RTC, NO_IRQ }
-#define SCI_IRQ { IRQ_PBX_SCI, NO_IRQ }
-#define PBX_UART0_IRQ { IRQ_PBX_UART0, NO_IRQ }
-#define PBX_UART1_IRQ { IRQ_PBX_UART1, NO_IRQ }
-#define PBX_UART2_IRQ { IRQ_PBX_UART2, NO_IRQ }
-#define PBX_UART3_IRQ { IRQ_PBX_UART3, NO_IRQ }
-#define PBX_SSP_IRQ { IRQ_PBX_SSP, NO_IRQ }
+#define KMI0_IRQ { IRQ_PBX_KMI0 }
+#define KMI1_IRQ { IRQ_PBX_KMI1 }
+#define PBX_SMC_IRQ { }
+#define MPMC_IRQ { }
+#define PBX_CLCD_IRQ { IRQ_PBX_CLCD }
+#define DMAC_IRQ { IRQ_PBX_DMAC }
+#define SCTL_IRQ { }
+#define PBX_WATCHDOG_IRQ { IRQ_PBX_WATCHDOG }
+#define PBX_GPIO0_IRQ { IRQ_PBX_GPIO0 }
+#define GPIO1_IRQ { IRQ_PBX_GPIO1 }
+#define PBX_RTC_IRQ { IRQ_PBX_RTC }
+#define SCI_IRQ { IRQ_PBX_SCI }
+#define PBX_UART0_IRQ { IRQ_PBX_UART0 }
+#define PBX_UART1_IRQ { IRQ_PBX_UART1 }
+#define PBX_UART2_IRQ { IRQ_PBX_UART2 }
+#define PBX_UART3_IRQ { IRQ_PBX_UART3 }
+#define PBX_SSP_IRQ { IRQ_PBX_SSP }
/* FPGA Primecells */
-AMBA_DEVICE(aaci, "fpga:aaci", AACI, NULL);
-AMBA_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
-AMBA_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
-AMBA_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
-AMBA_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL);
+APB_DEVICE(aaci, "fpga:aaci", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:mmc0", MMCI0, &realview_mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:kmi0", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:kmi1", KMI1, NULL);
+APB_DEVICE(uart3, "fpga:uart3", PBX_UART3, NULL);
/* DevChip Primecells */
-AMBA_DEVICE(smc, "dev:smc", PBX_SMC, NULL);
-AMBA_DEVICE(sctl, "dev:sctl", SCTL, NULL);
-AMBA_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data);
-AMBA_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
-AMBA_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
-AMBA_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL);
-AMBA_DEVICE(sci0, "dev:sci0", SCI, NULL);
-AMBA_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL);
-AMBA_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL);
-AMBA_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL);
-AMBA_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data);
+AHB_DEVICE(smc, "dev:smc", PBX_SMC, NULL);
+AHB_DEVICE(sctl, "dev:sctl", SCTL, NULL);
+APB_DEVICE(wdog, "dev:wdog", PBX_WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:gpio0", PBX_GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:gpio1", GPIO1, &gpio1_plat_data);
+APB_DEVICE(gpio2, "dev:gpio2", GPIO2, &gpio2_plat_data);
+APB_DEVICE(rtc, "dev:rtc", PBX_RTC, NULL);
+APB_DEVICE(sci0, "dev:sci0", SCI, NULL);
+APB_DEVICE(uart0, "dev:uart0", PBX_UART0, NULL);
+APB_DEVICE(uart1, "dev:uart1", PBX_UART1, NULL);
+APB_DEVICE(uart2, "dev:uart2", PBX_UART2, NULL);
+APB_DEVICE(ssp0, "dev:ssp0", PBX_SSP, &ssp0_plat_data);
/* Primecells on the NEC ISSP chip */
-AMBA_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data);
-AMBA_DEVICE(dmac, "issp:dmac", DMAC, NULL);
+AHB_DEVICE(clcd, "issp:clcd", PBX_CLCD, &clcd_plat_data);
+AHB_DEVICE(dmac, "issp:dmac", DMAC, NULL);
static struct amba_device *amba_devs[] __initdata = {
&dmac_device,
diff --git a/arch/arm/mach-rpc/include/mach/system.h b/arch/arm/mach-rpc/include/mach/system.h
deleted file mode 100644
index 359bab94b6a..00000000000
--- a/arch/arm/mach-rpc/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-rpc/include/mach/system.h
- *
- * Copyright (C) 1996-1999 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-s3c2410/include/mach/system.h b/arch/arm/mach-s3c2410/include/mach/system.h
deleted file mode 100644
index 5e215c1a5c8..00000000000
--- a/arch/arm/mach-s3c2410/include/mach/system.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/* arch/arm/mach-s3c2410/include/mach/system.h
- *
- * Copyright (c) 2003 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 - System function defines and includes
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/io.h>
-#include <mach/hardware.h>
-
-#include <mach/map.h>
-#include <mach/idle.h>
-
-#include <mach/regs-clock.h>
-
-void (*s3c24xx_idle)(void);
-
-void s3c24xx_default_idle(void)
-{
- unsigned long tmp;
- int i;
-
- /* idle the system by using the idle mode which will wait for an
- * interrupt to happen before restarting the system.
- */
-
- /* Warning: going into idle state upsets jtag scanning */
-
- __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
- S3C2410_CLKCON);
-
- /* the samsung port seems to do a loop and then unset idle.. */
- for (i = 0; i < 50; i++) {
- tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
- }
-
- /* this bit is not cleared on re-start... */
-
- __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
- S3C2410_CLKCON);
-}
-
-static void arch_idle(void)
-{
- if (s3c24xx_idle != NULL)
- (s3c24xx_idle)();
- else
- s3c24xx_default_idle();
-}
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index aff6e85a97c..c6eac987109 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -32,8 +32,6 @@
#include <asm/proc-fns.h>
#include <asm/irq.h>
-#include <mach/idle.h>
-
#include <plat/cpu-freq.h>
#include <mach/regs-clock.h>
@@ -164,7 +162,7 @@ void __init s3c2412_map_io(void)
/* set our idle function */
- s3c24xx_idle = s3c2412_idle;
+ arm_pm_idle = s3c2412_idle;
/* register our io-tables */
diff --git a/arch/arm/mach-s3c2416/s3c2416.c b/arch/arm/mach-s3c2416/s3c2416.c
index 5287d2808d3..0e9a71c90ed 100644
--- a/arch/arm/mach-s3c2416/s3c2416.c
+++ b/arch/arm/mach-s3c2416/s3c2416.c
@@ -44,7 +44,6 @@
#include <asm/proc-fns.h>
#include <asm/irq.h>
-#include <mach/idle.h>
#include <mach/regs-s3c2443-clock.h>
#include <plat/gpio-core.h>
@@ -60,6 +59,7 @@
#include <plat/fb-core.h>
#include <plat/nand-core.h>
#include <plat/adc-core.h>
+#include <plat/rtc-core.h>
static struct map_desc s3c2416_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
@@ -88,8 +88,6 @@ int __init s3c2416_init(void)
{
printk(KERN_INFO "S3C2416: Initializing architecture\n");
- /* s3c24xx_idle = s3c2416_idle; */
-
/* change WDT IRQ number */
s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
s3c_device_wdt.resource[1].end = IRQ_S3C2443_WDT;
@@ -101,6 +99,7 @@ int __init s3c2416_init(void)
s3c_fb_setname("s3c2443-fb");
s3c_adc_setname("s3c2416-adc");
+ s3c_rtc_setname("s3c2416-rtc");
#ifdef CONFIG_PM
register_syscore_ops(&s3c2416_pm_syscore_ops);
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
index b9deaeb0dff..b7778a9dafa 100644
--- a/arch/arm/mach-s3c2443/s3c2443.c
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -41,6 +41,7 @@
#include <plat/fb-core.h>
#include <plat/nand-core.h>
#include <plat/adc-core.h>
+#include <plat/rtc-core.h>
static struct map_desc s3c2443_iodesc[] __initdata = {
IODESC_ENT(WATCHDOG),
@@ -73,6 +74,7 @@ int __init s3c2443_init(void)
s3c_fb_setname("s3c2443-fb");
s3c_adc_setname("s3c2443-adc");
+ s3c_rtc_setname("s3c2443-rtc");
/* change WDT IRQ number */
s3c_device_wdt.resource[1].start = IRQ_S3C2443_WDT;
diff --git a/arch/arm/mach-s3c64xx/include/mach/system.h b/arch/arm/mach-s3c64xx/include/mach/system.h
deleted file mode 100644
index 353ed4389ae..00000000000
--- a/arch/arm/mach-s3c64xx/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* linux/arch/arm/mach-s3c6400/include/mach/system.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C6400 - system implementation
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
- /* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5p64x0/common.c b/arch/arm/mach-s5p64x0/common.c
index 52b89a37644..9143f8b1996 100644
--- a/arch/arm/mach-s5p64x0/common.c
+++ b/arch/arm/mach-s5p64x0/common.c
@@ -146,15 +146,12 @@ static void s5p64x0_idle(void)
{
unsigned long val;
- if (!need_resched()) {
- val = __raw_readl(S5P64X0_PWR_CFG);
- val &= ~(0x3 << 5);
- val |= (0x1 << 5);
- __raw_writel(val, S5P64X0_PWR_CFG);
+ val = __raw_readl(S5P64X0_PWR_CFG);
+ val &= ~(0x3 << 5);
+ val |= (0x1 << 5);
+ __raw_writel(val, S5P64X0_PWR_CFG);
- cpu_do_idle();
- }
- local_irq_enable();
+ cpu_do_idle();
}
/*
@@ -286,7 +283,7 @@ int __init s5p64x0_init(void)
printk(KERN_INFO "S5P64X0(S5P6440/S5P6450): Initializing architecture\n");
/* set idle function */
- pm_idle = s5p64x0_idle;
+ arm_pm_idle = s5p64x0_idle;
return device_register(&s5p64x0_dev);
}
diff --git a/arch/arm/mach-s5p64x0/dma.c b/arch/arm/mach-s5p64x0/dma.c
index f820c074440..f7f68ad7791 100644
--- a/arch/arm/mach-s5p64x0/dma.c
+++ b/arch/arm/mach-s5p64x0/dma.c
@@ -108,34 +108,22 @@ struct dma_pl330_platdata s5p6450_pdma_pdata = {
.peri_id = s5p6450_pdma_peri,
};
-struct amba_device s5p64x0_device_pdma = {
- .dev = {
- .init_name = "dma-pl330",
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .res = {
- .start = S5P64X0_PA_PDMA,
- .end = S5P64X0_PA_PDMA + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_DMA0, NO_IRQ},
- .periphid = 0x00041330,
-};
+AMBA_AHB_DEVICE(s5p64x0_pdma, "dma-pl330", 0x00041330, S5P64X0_PA_PDMA,
+ {IRQ_DMA0}, NULL);
static int __init s5p64x0_dma_init(void)
{
if (soc_is_s5p6450()) {
dma_cap_set(DMA_SLAVE, s5p6450_pdma_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5p6450_pdma_pdata.cap_mask);
- s5p64x0_device_pdma.dev.platform_data = &s5p6450_pdma_pdata;
+ s5p64x0_pdma_device.dev.platform_data = &s5p6450_pdma_pdata;
} else {
dma_cap_set(DMA_SLAVE, s5p6440_pdma_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5p6440_pdma_pdata.cap_mask);
- s5p64x0_device_pdma.dev.platform_data = &s5p6440_pdma_pdata;
+ s5p64x0_pdma_device.dev.platform_data = &s5p6440_pdma_pdata;
}
- amba_device_register(&s5p64x0_device_pdma, &iomem_resource);
+ amba_device_register(&s5p64x0_pdma_device, &iomem_resource);
return 0;
}
diff --git a/arch/arm/mach-s5p64x0/include/mach/system.h b/arch/arm/mach-s5p64x0/include/mach/system.h
deleted file mode 100644
index cf26e0954a2..00000000000
--- a/arch/arm/mach-s5p64x0/include/mach/system.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* linux/arch/arm/mach-s5p64x0/include/mach/system.h
- *
- * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * S5P64X0 - system support header
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
- /* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-s5pc100/common.c b/arch/arm/mach-s5pc100/common.c
index c9095730a7f..ff71e2d467c 100644
--- a/arch/arm/mach-s5pc100/common.c
+++ b/arch/arm/mach-s5pc100/common.c
@@ -129,14 +129,6 @@ static struct map_desc s5pc100_iodesc[] __initdata = {
}
};
-static void s5pc100_idle(void)
-{
- if (!need_resched())
- cpu_do_idle();
-
- local_irq_enable();
-}
-
/*
* s5pc100_map_io
*
@@ -210,10 +202,6 @@ core_initcall(s5pc100_core_init);
int __init s5pc100_init(void)
{
printk(KERN_INFO "S5PC100: Initializing architecture\n");
-
- /* set idle function */
- pm_idle = s5pc100_idle;
-
return device_register(&s5pc100_dev);
}
diff --git a/arch/arm/mach-s5pc100/dma.c b/arch/arm/mach-s5pc100/dma.c
index c841f4d313f..96b1ab3dcd4 100644
--- a/arch/arm/mach-s5pc100/dma.c
+++ b/arch/arm/mach-s5pc100/dma.c
@@ -73,21 +73,8 @@ struct dma_pl330_platdata s5pc100_pdma0_pdata = {
.peri_id = pdma0_peri,
};
-struct amba_device s5pc100_device_pdma0 = {
- .dev = {
- .init_name = "dma-pl330.0",
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &s5pc100_pdma0_pdata,
- },
- .res = {
- .start = S5PC100_PA_PDMA0,
- .end = S5PC100_PA_PDMA0 + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_PDMA0, NO_IRQ},
- .periphid = 0x00041330,
-};
+AMBA_AHB_DEVICE(s5pc100_pdma0, "dma-pl330.0", 0x00041330, S5PC100_PA_PDMA0,
+ {IRQ_PDMA0}, &s5pc100_pdma0_pdata);
u8 pdma1_peri[] = {
DMACH_UART0_RX,
@@ -127,31 +114,18 @@ struct dma_pl330_platdata s5pc100_pdma1_pdata = {
.peri_id = pdma1_peri,
};
-struct amba_device s5pc100_device_pdma1 = {
- .dev = {
- .init_name = "dma-pl330.1",
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &s5pc100_pdma1_pdata,
- },
- .res = {
- .start = S5PC100_PA_PDMA1,
- .end = S5PC100_PA_PDMA1 + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_PDMA1, NO_IRQ},
- .periphid = 0x00041330,
-};
+AMBA_AHB_DEVICE(s5pc100_pdma1, "dma-pl330.1", 0x00041330, S5PC100_PA_PDMA1,
+ {IRQ_PDMA1}, &s5pc100_pdma1_pdata);
static int __init s5pc100_dma_init(void)
{
dma_cap_set(DMA_SLAVE, s5pc100_pdma0_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5pc100_pdma0_pdata.cap_mask);
- amba_device_register(&s5pc100_device_pdma0, &iomem_resource);
+ amba_device_register(&s5pc100_pdma0_device, &iomem_resource);
dma_cap_set(DMA_SLAVE, s5pc100_pdma1_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5pc100_pdma1_pdata.cap_mask);
- amba_device_register(&s5pc100_device_pdma1, &iomem_resource);
+ amba_device_register(&s5pc100_pdma1_device, &iomem_resource);
return 0;
}
diff --git a/arch/arm/mach-s5pc100/include/mach/system.h b/arch/arm/mach-s5pc100/include/mach/system.h
deleted file mode 100644
index afc96c29851..00000000000
--- a/arch/arm/mach-s5pc100/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/* linux/arch/arm/mach-s5pc100/include/mach/system.h
- *
- * Copyright 2009 Samsung Electronics Co.
- * Byungho Min <bhmin@samsung.com>
- *
- * S5PC100 - system implementation
- *
- * Based on mach-s3c6400/include/mach/system.h
- */
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
- /* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-s5pv210/common.c b/arch/arm/mach-s5pv210/common.c
index 9c1bcdcc12c..4c9e9027df9 100644
--- a/arch/arm/mach-s5pv210/common.c
+++ b/arch/arm/mach-s5pv210/common.c
@@ -142,14 +142,6 @@ static struct map_desc s5pv210_iodesc[] __initdata = {
}
};
-static void s5pv210_idle(void)
-{
- if (!need_resched())
- cpu_do_idle();
-
- local_irq_enable();
-}
-
void s5pv210_restart(char mode, const char *cmd)
{
__raw_writel(0x1, S5P_SWRESET);
@@ -247,10 +239,6 @@ core_initcall(s5pv210_core_init);
int __init s5pv210_init(void)
{
printk(KERN_INFO "S5PV210: Initializing architecture\n");
-
- /* set idle function */
- pm_idle = s5pv210_idle;
-
return device_register(&s5pv210_dev);
}
diff --git a/arch/arm/mach-s5pv210/dma.c b/arch/arm/mach-s5pv210/dma.c
index a6113e0267f..f6885d247d1 100644
--- a/arch/arm/mach-s5pv210/dma.c
+++ b/arch/arm/mach-s5pv210/dma.c
@@ -71,21 +71,8 @@ struct dma_pl330_platdata s5pv210_pdma0_pdata = {
.peri_id = pdma0_peri,
};
-struct amba_device s5pv210_device_pdma0 = {
- .dev = {
- .init_name = "dma-pl330.0",
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &s5pv210_pdma0_pdata,
- },
- .res = {
- .start = S5PV210_PA_PDMA0,
- .end = S5PV210_PA_PDMA0 + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_PDMA0, NO_IRQ},
- .periphid = 0x00041330,
-};
+AMBA_AHB_DEVICE(s5pv210_pdma0, "dma-pl330.0", 0x00041330, S5PV210_PA_PDMA0,
+ {IRQ_PDMA0}, &s5pv210_pdma0_pdata);
u8 pdma1_peri[] = {
DMACH_UART0_RX,
@@ -127,31 +114,18 @@ struct dma_pl330_platdata s5pv210_pdma1_pdata = {
.peri_id = pdma1_peri,
};
-struct amba_device s5pv210_device_pdma1 = {
- .dev = {
- .init_name = "dma-pl330.1",
- .dma_mask = &dma_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &s5pv210_pdma1_pdata,
- },
- .res = {
- .start = S5PV210_PA_PDMA1,
- .end = S5PV210_PA_PDMA1 + SZ_4K,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_PDMA1, NO_IRQ},
- .periphid = 0x00041330,
-};
+AMBA_AHB_DEVICE(s5pv210_pdma1, "dma-pl330.1", 0x00041330, S5PV210_PA_PDMA1,
+ {IRQ_PDMA1}, &s5pv210_pdma1_pdata);
static int __init s5pv210_dma_init(void)
{
dma_cap_set(DMA_SLAVE, s5pv210_pdma0_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5pv210_pdma0_pdata.cap_mask);
- amba_device_register(&s5pv210_device_pdma0, &iomem_resource);
+ amba_device_register(&s5pv210_pdma0_device, &iomem_resource);
dma_cap_set(DMA_SLAVE, s5pv210_pdma1_pdata.cap_mask);
dma_cap_set(DMA_CYCLIC, s5pv210_pdma1_pdata.cap_mask);
- amba_device_register(&s5pv210_device_pdma1, &iomem_resource);
+ amba_device_register(&s5pv210_pdma1_device, &iomem_resource);
return 0;
}
diff --git a/arch/arm/mach-s5pv210/include/mach/system.h b/arch/arm/mach-s5pv210/include/mach/system.h
deleted file mode 100644
index bf288ced860..00000000000
--- a/arch/arm/mach-s5pv210/include/mach/system.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* linux/arch/arm/mach-s5pv210/include/mach/system.h
- *
- * Copyright (c) 2010 Samsung Electronics Co., Ltd.
- * http://www.samsung.com/
- *
- * S5PV210 - system support header
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H __FILE__
-
-static void arch_idle(void)
-{
- /* nothing here yet */
-}
-
-#endif /* __ASM_ARCH_SYSTEM_H */
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index dab3c6347a8..172ebd0ee0a 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -11,17 +11,29 @@
#include <linux/clk.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/clkdev.h>
#include <mach/hardware.h>
-/*
- * Very simple clock implementation - we only have one clock to deal with.
- */
+struct clkops {
+ void (*enable)(struct clk *);
+ void (*disable)(struct clk *);
+};
+
struct clk {
+ const struct clkops *ops;
unsigned int enabled;
};
-static void clk_gpio27_enable(void)
+#define DEFINE_CLK(_name, _ops) \
+struct clk clk_##_name = { \
+ .ops = _ops, \
+ }
+
+static DEFINE_SPINLOCK(clocks_lock);
+
+static void clk_gpio27_enable(struct clk *clk)
{
/*
* First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
@@ -32,38 +44,24 @@ static void clk_gpio27_enable(void)
TUCR = TUCR_3_6864MHz;
}
-static void clk_gpio27_disable(void)
+static void clk_gpio27_disable(struct clk *clk)
{
TUCR = 0;
GPDR &= ~GPIO_32_768kHz;
GAFR &= ~GPIO_32_768kHz;
}
-static struct clk clk_gpio27;
-
-static DEFINE_SPINLOCK(clocks_lock);
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
- const char *devname = dev_name(dev);
-
- return strcmp(devname, "sa1111.0") ? ERR_PTR(-ENOENT) : &clk_gpio27;
-}
-EXPORT_SYMBOL(clk_get);
-
-void clk_put(struct clk *clk)
-{
-}
-EXPORT_SYMBOL(clk_put);
-
int clk_enable(struct clk *clk)
{
unsigned long flags;
- spin_lock_irqsave(&clocks_lock, flags);
- if (clk->enabled++ == 0)
- clk_gpio27_enable();
- spin_unlock_irqrestore(&clocks_lock, flags);
+ if (clk) {
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (clk->enabled++ == 0)
+ clk->ops->enable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ }
+
return 0;
}
EXPORT_SYMBOL(clk_enable);
@@ -72,17 +70,31 @@ void clk_disable(struct clk *clk)
{
unsigned long flags;
- WARN_ON(clk->enabled == 0);
-
- spin_lock_irqsave(&clocks_lock, flags);
- if (--clk->enabled == 0)
- clk_gpio27_disable();
- spin_unlock_irqrestore(&clocks_lock, flags);
+ if (clk) {
+ WARN_ON(clk->enabled == 0);
+ spin_lock_irqsave(&clocks_lock, flags);
+ if (--clk->enabled == 0)
+ clk->ops->disable(clk);
+ spin_unlock_irqrestore(&clocks_lock, flags);
+ }
}
EXPORT_SYMBOL(clk_disable);
-unsigned long clk_get_rate(struct clk *clk)
+const struct clkops clk_gpio27_ops = {
+ .enable = clk_gpio27_enable,
+ .disable = clk_gpio27_disable,
+};
+
+static DEFINE_CLK(gpio27, &clk_gpio27_ops);
+
+static struct clk_lookup sa11xx_clkregs[] = {
+ CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
+ CLKDEV_INIT("sa1100-rtc", NULL, NULL),
+};
+
+static int __init sa11xx_clk_init(void)
{
- return 3686400;
+ clkdev_add_table(sa11xx_clkregs, ARRAY_SIZE(sa11xx_clkregs));
+ return 0;
}
-EXPORT_SYMBOL(clk_get_rate);
+core_initcall(sa11xx_clk_init);
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index bb10ee2cb89..7c1ebf4a792 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -345,9 +345,17 @@ void sa11x0_register_irda(struct irda_platform_data *irda)
sa11x0_register_device(&sa11x0ir_device, irda);
}
+static struct resource sa1100_rtc_resources[] = {
+ DEFINE_RES_MEM(0x90010000, 0x9001003f),
+ DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
+ DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
+};
+
static struct platform_device sa11x0rtc_device = {
.name = "sa1100-rtc",
.id = -1,
+ .num_resources = ARRAY_SIZE(sa1100_rtc_resources),
+ .resource = sa1100_rtc_resources,
};
static struct platform_device *sa11x0_devices[] __initdata = {
diff --git a/arch/arm/mach-sa1100/include/mach/system.h b/arch/arm/mach-sa1100/include/mach/system.h
deleted file mode 100644
index e17b208f76d..00000000000
--- a/arch/arm/mach-sa1100/include/mach/system.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * arch/arm/mach-sa1100/include/mach/system.h
- *
- * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c
index a851c254ad6..6a2a7f2c255 100644
--- a/arch/arm/mach-shark/core.c
+++ b/arch/arm/mach-shark/core.c
@@ -149,10 +149,16 @@ static struct sys_timer shark_timer = {
.init = shark_timer_init,
};
+static void shark_init_early(void)
+{
+ disable_hlt();
+}
+
MACHINE_START(SHARK, "Shark")
/* Maintainer: Alexander Schulz */
.atag_offset = 0x3000,
.map_io = shark_map_io,
+ .init_early = shark_init_early,
.init_irq = shark_init_irq,
.timer = &shark_timer,
.dma_zone_size = SZ_4M,
diff --git a/arch/arm/mach-shark/include/mach/system.h b/arch/arm/mach-shark/include/mach/system.h
deleted file mode 100644
index 1b2f2c5050a..00000000000
--- a/arch/arm/mach-shark/include/mach/system.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * arch/arm/mach-shark/include/mach/system.h
- *
- * by Alexander Schulz
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
-}
-
-#endif
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index eff8a96c75e..068b754bc34 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -30,6 +30,7 @@
#include <linux/serial_sci.h>
#include <linux/smsc911x.h>
#include <linux/gpio.h>
+#include <linux/videodev2.h>
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
#include <linux/mmc/host.h>
@@ -37,7 +38,6 @@
#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/sh_clk.h>
-#include <linux/dma-mapping.h>
#include <video/sh_mobile_lcdc.h>
#include <video/sh_mipi_dsi.h>
#include <sound/sh_fsi.h>
@@ -159,19 +159,12 @@ static struct resource sh_mmcif_resources[] = {
},
};
-static struct sh_mmcif_dma sh_mmcif_dma = {
- .chan_priv_rx = {
- .slave_id = SHDMA_SLAVE_MMCIF_RX,
- },
- .chan_priv_tx = {
- .slave_id = SHDMA_SLAVE_MMCIF_TX,
- },
-};
static struct sh_mmcif_plat_data sh_mmcif_platdata = {
.sup_pclk = 0,
.ocr = MMC_VDD_165_195,
.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
- .dma = &sh_mmcif_dma,
+ .slave_id_tx = SHDMA_SLAVE_MMCIF_TX,
+ .slave_id_rx = SHDMA_SLAVE_MMCIF_RX,
};
static struct platform_device mmc_device = {
@@ -321,12 +314,11 @@ static struct resource mipidsi0_resources[] = {
},
};
-#define DSI0PHYCR 0xe615006c
static int sh_mipi_set_dot_clock(struct platform_device *pdev,
void __iomem *base,
int enable)
{
- struct clk *pck;
+ struct clk *pck, *phy;
int ret;
pck = clk_get(&pdev->dev, "dsip_clk");
@@ -335,18 +327,27 @@ static int sh_mipi_set_dot_clock(struct platform_device *pdev,
goto sh_mipi_set_dot_clock_pck_err;
}
+ phy = clk_get(&pdev->dev, "dsiphy_clk");
+ if (IS_ERR(phy)) {
+ ret = PTR_ERR(phy);
+ goto sh_mipi_set_dot_clock_phy_err;
+ }
+
if (enable) {
clk_set_rate(pck, clk_round_rate(pck, 24000000));
- __raw_writel(0x2a809010, DSI0PHYCR);
+ clk_set_rate(phy, clk_round_rate(pck, 510000000));
clk_enable(pck);
+ clk_enable(phy);
} else {
clk_disable(pck);
+ clk_disable(phy);
}
ret = 0;
+ clk_put(phy);
+sh_mipi_set_dot_clock_phy_err:
clk_put(pck);
-
sh_mipi_set_dot_clock_pck_err:
return ret;
}
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index aab0a349f75..eeb4d966458 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -295,15 +295,6 @@ static struct resource sh_mmcif_resources[] = {
},
};
-static struct sh_mmcif_dma sh_mmcif_dma = {
- .chan_priv_rx = {
- .slave_id = SHDMA_SLAVE_MMCIF_RX,
- },
- .chan_priv_tx = {
- .slave_id = SHDMA_SLAVE_MMCIF_TX,
- },
-};
-
static struct sh_mmcif_plat_data sh_mmcif_plat = {
.sup_pclk = 0,
.ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -311,7 +302,8 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
MMC_CAP_8_BIT_DATA |
MMC_CAP_NEEDS_POLL,
.get_cd = slot_cn7_get_cd,
- .dma = &sh_mmcif_dma,
+ .slave_id_tx = SHDMA_SLAVE_MMCIF_TX,
+ .slave_id_rx = SHDMA_SLAVE_MMCIF_RX,
};
static struct platform_device sh_mmcif_device = {
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index 857ceeec1bb..c8e7ca23fc0 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -143,11 +143,10 @@ static struct gpio_keys_button gpio_buttons[] = {
static struct gpio_keys_platform_data gpio_key_info = {
.buttons = gpio_buttons,
.nbuttons = ARRAY_SIZE(gpio_buttons),
- .poll_interval = 250, /* polled for now */
};
static struct platform_device gpio_keys_device = {
- .name = "gpio-keys-polled", /* polled for now */
+ .name = "gpio-keys",
.id = -1,
.dev = {
.platform_data = &gpio_key_info,
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 9b42fbd10f8..a2813247b45 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -43,7 +43,6 @@
#include <linux/smsc911x.h>
#include <linux/sh_intc.h>
#include <linux/tca6416_keypad.h>
-#include <linux/usb/r8a66597.h>
#include <linux/usb/renesas_usbhs.h>
#include <linux/dma-mapping.h>
@@ -145,11 +144,6 @@
* 1-2 short | VBUS 5V | Host
* open | external VBUS | Function
*
- * *1
- * CN31 is used as
- * CONFIG_USB_R8A66597_HCD Host
- * CONFIG_USB_RENESAS_USBHS Function
- *
* CAUTION
*
* renesas_usbhs driver can use external interrupt mode
@@ -161,15 +155,6 @@
* mackerel can not use external interrupt (IRQ7-PORT167) mode on "USB0",
* because Touchscreen is using IRQ7-PORT40.
* It is impossible to use IRQ7 demux on this board.
- *
- * We can use external interrupt mode USB-Function on "USB1".
- * USB1 can become Host by r8a66597, and become Function by renesas_usbhs.
- * But don't select both drivers in same time.
- * These uses same IRQ number for request_irq(), and aren't supporting
- * IRQF_SHARED / IORESOURCE_IRQ_SHAREABLE.
- *
- * Actually these are old/new version of USB driver.
- * This mean its register will be broken if it supports shared IRQ,
*/
/*
@@ -208,6 +193,16 @@
*/
/*
+ * FSI - AK4642
+ *
+ * it needs amixer settings for playing
+ *
+ * amixer set "Headphone" on
+ * amixer set "HPOUTL Mixer DACH" on
+ * amixer set "HPOUTR Mixer DACH" on
+ */
+
+/*
* FIXME !!
*
* gpio_no_direction
@@ -676,51 +671,16 @@ static struct platform_device usbhs0_device = {
* Use J30 to select between Host and Function. This setting
* can however not be detected by software. Hotplug of USBHS1
* is provided via IRQ8.
+ *
+ * Current USB1 works as "USB Host".
+ * - set J30 "short"
+ *
+ * If you want to use it as "USB gadget",
+ * - J30 "open"
+ * - modify usbhs1_get_id() USBHS_HOST -> USBHS_GADGET
+ * - add .get_vbus = usbhs_get_vbus in usbhs1_private
*/
#define IRQ8 evt2irq(0x0300)
-
-/* USBHS1 USB Host support via r8a66597_hcd */
-static void usb1_host_port_power(int port, int power)
-{
- if (!power) /* only power-on is supported for now */
- return;
-
- /* set VBOUT/PWEN and EXTLP1 in DVSTCTR */
- __raw_writew(__raw_readw(0xE68B0008) | 0x600, 0xE68B0008);
-}
-
-static struct r8a66597_platdata usb1_host_data = {
- .on_chip = 1,
- .port_power = usb1_host_port_power,
-};
-
-static struct resource usb1_host_resources[] = {
- [0] = {
- .name = "USBHS1",
- .start = 0xe68b0000,
- .end = 0xe68b00e6 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = evt2irq(0x1ce0) /* USB1_USB1I0 */,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device usb1_host_device = {
- .name = "r8a66597_hcd",
- .id = 1,
- .dev = {
- .dma_mask = NULL, /* not use dma */
- .coherent_dma_mask = 0xffffffff,
- .platform_data = &usb1_host_data,
- },
- .num_resources = ARRAY_SIZE(usb1_host_resources),
- .resource = usb1_host_resources,
-};
-
-/* USBHS1 USB Function support via renesas_usbhs */
-
#define USB_PHY_MODE (1 << 4)
#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
#define USB_PHY_ON (1 << 1)
@@ -776,7 +736,7 @@ static void usbhs1_hardware_exit(struct platform_device *pdev)
static int usbhs1_get_id(struct platform_device *pdev)
{
- return USBHS_GADGET;
+ return USBHS_HOST;
}
static u32 usbhs1_pipe_cfg[] = {
@@ -807,7 +767,6 @@ static struct usbhs_private usbhs1_private = {
.hardware_exit = usbhs1_hardware_exit,
.get_id = usbhs1_get_id,
.phy_reset = usbhs_phy_reset,
- .get_vbus = usbhs_get_vbus,
},
.driver_param = {
.buswait_bwait = 4,
@@ -1184,15 +1143,6 @@ static struct resource sh_mmcif_resources[] = {
},
};
-static struct sh_mmcif_dma sh_mmcif_dma = {
- .chan_priv_rx = {
- .slave_id = SHDMA_SLAVE_MMCIF_RX,
- },
- .chan_priv_tx = {
- .slave_id = SHDMA_SLAVE_MMCIF_TX,
- },
-};
-
static struct sh_mmcif_plat_data sh_mmcif_plat = {
.sup_pclk = 0,
.ocr = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -1200,7 +1150,8 @@ static struct sh_mmcif_plat_data sh_mmcif_plat = {
MMC_CAP_8_BIT_DATA |
MMC_CAP_NEEDS_POLL,
.get_cd = slot_cn7_get_cd,
- .dma = &sh_mmcif_dma,
+ .slave_id_tx = SHDMA_SLAVE_MMCIF_TX,
+ .slave_id_rx = SHDMA_SLAVE_MMCIF_RX,
};
static struct platform_device sh_mmcif_device = {
@@ -1311,7 +1262,6 @@ static struct platform_device *mackerel_devices[] __initdata = {
&nor_flash_device,
&smc911x_device,
&lcdc_device,
- &usb1_host_device,
&usbhs1_device,
&usbhs0_device,
&leds_device,
@@ -1473,9 +1423,6 @@ static void __init mackerel_init(void)
gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
gpio_request(GPIO_FN_IDIN_1_113, NULL);
- /* USB phy tweak to make the r8a66597_hcd host driver work */
- __raw_writew(0x8a0a, 0xe6058130); /* USBCR4 */
-
/* enable FSI2 port A (ak4643) */
gpio_request(GPIO_FN_FSIAIBT, NULL);
gpio_request(GPIO_FN_FSIAILR, NULL);
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index afbead6a6e1..7727cca6136 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -365,6 +365,114 @@ static struct clk div6_clks[DIV6_NR] = {
dsi_parent, ARRAY_SIZE(dsi_parent), 12, 3),
};
+/* DSI DIV */
+static unsigned long dsiphy_recalc(struct clk *clk)
+{
+ u32 value;
+
+ value = __raw_readl(clk->mapping->base);
+
+ /* FIXME */
+ if (!(value & 0x000B8000))
+ return clk->parent->rate;
+
+ value &= 0x3f;
+ value += 1;
+
+ if ((value < 12) ||
+ (value > 33)) {
+ pr_err("DSIPHY has wrong value (%d)", value);
+ return 0;
+ }
+
+ return clk->parent->rate / value;
+}
+
+static long dsiphy_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk_rate_mult_range_round(clk, 12, 33, rate);
+}
+
+static void dsiphy_disable(struct clk *clk)
+{
+ u32 value;
+
+ value = __raw_readl(clk->mapping->base);
+ value &= ~0x000B8000;
+
+ __raw_writel(value , clk->mapping->base);
+}
+
+static int dsiphy_enable(struct clk *clk)
+{
+ u32 value;
+ int multi;
+
+ value = __raw_readl(clk->mapping->base);
+ multi = (value & 0x3f) + 1;
+
+ if ((multi < 12) || (multi > 33))
+ return -EIO;
+
+ __raw_writel(value | 0x000B8000, clk->mapping->base);
+
+ return 0;
+}
+
+static int dsiphy_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 value;
+ int idx;
+
+ idx = rate / clk->parent->rate;
+ if ((idx < 12) || (idx > 33))
+ return -EINVAL;
+
+ idx += -1;
+
+ value = __raw_readl(clk->mapping->base);
+ value = (value & ~0x3f) + idx;
+
+ __raw_writel(value, clk->mapping->base);
+
+ return 0;
+}
+
+static struct clk_ops dsiphy_clk_ops = {
+ .recalc = dsiphy_recalc,
+ .round_rate = dsiphy_round_rate,
+ .set_rate = dsiphy_set_rate,
+ .enable = dsiphy_enable,
+ .disable = dsiphy_disable,
+};
+
+static struct clk_mapping dsi0phy_clk_mapping = {
+ .phys = DSI0PHYCR,
+ .len = 4,
+};
+
+static struct clk_mapping dsi1phy_clk_mapping = {
+ .phys = DSI1PHYCR,
+ .len = 4,
+};
+
+static struct clk dsi0phy_clk = {
+ .ops = &dsiphy_clk_ops,
+ .parent = &div6_clks[DIV6_DSI0P], /* late install */
+ .mapping = &dsi0phy_clk_mapping,
+};
+
+static struct clk dsi1phy_clk = {
+ .ops = &dsiphy_clk_ops,
+ .parent = &div6_clks[DIV6_DSI1P], /* late install */
+ .mapping = &dsi1phy_clk_mapping,
+};
+
+static struct clk *late_main_clks[] = {
+ &dsi0phy_clk,
+ &dsi1phy_clk,
+};
+
enum { MSTP001,
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
MSTP219,
@@ -429,6 +537,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
CLKDEV_ICK_ID("dsip_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.0", &dsi0phy_clk),
+ CLKDEV_ICK_ID("dsiphy_clk", "sh-mipi-dsi.1", &dsi1phy_clk),
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
@@ -504,6 +614,9 @@ void __init sh73a0_clock_init(void)
if (!ret)
ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
+
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
if (!ret)
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
index 881d515a968..cad57578cee 100644
--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -515,8 +515,8 @@ enum {
SHDMA_SLAVE_MMCIF_RX,
};
-/* PINT interrupts are located at Linux IRQ 768 and up */
-#define SH73A0_PINT0_IRQ(irq) ((irq) + 768)
-#define SH73A0_PINT1_IRQ(irq) ((irq) + 800)
+/* PINT interrupts are located at Linux IRQ 800 and up */
+#define SH73A0_PINT0_IRQ(irq) ((irq) + 800)
+#define SH73A0_PINT1_IRQ(irq) ((irq) + 832)
#endif /* __ASM_SH73A0_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/system.h b/arch/arm/mach-shmobile/include/mach/system.h
index 956ac18ddbf..3bbcb3fa077 100644
--- a/arch/arm/mach-shmobile/include/mach/system.h
+++ b/arch/arm/mach-shmobile/include/mach/system.h
@@ -1,11 +1,6 @@
#ifndef __ASM_ARCH_SYSTEM_H
#define __ASM_ARCH_SYSTEM_H
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
static inline void arch_reset(char mode, const char *cmd)
{
soft_restart(0);
diff --git a/arch/arm/mach-shmobile/intc-sh73a0.c b/arch/arm/mach-shmobile/intc-sh73a0.c
index 1eda6b0b69e..9857595eaa7 100644
--- a/arch/arm/mach-shmobile/intc-sh73a0.c
+++ b/arch/arm/mach-shmobile/intc-sh73a0.c
@@ -19,6 +19,7 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/module.h>
#include <linux/irq.h>
#include <linux/io.h>
#include <linux/sh_intc.h>
@@ -445,6 +446,7 @@ void __init sh73a0_init_irq(void)
setup_irq(gic_spi(1 + k), &sh73a0_irq_pin_cascade[k]);
n = intcs_evt2irq(to_intc_vect(gic_spi(1 + k)));
+ WARN_ON(irq_alloc_desc_at(n, numa_node_id()) != n);
irq_set_chip_and_handler_name(n, &intca_gic_irq_chip,
handle_level_irq, "level");
set_irq_flags(n, IRQF_VALID); /* yuck */
diff --git a/arch/arm/mach-shmobile/pfc-r8a7779.c b/arch/arm/mach-shmobile/pfc-r8a7779.c
index 963532f2b2c..d14c9b04807 100644
--- a/arch/arm/mach-shmobile/pfc-r8a7779.c
+++ b/arch/arm/mach-shmobile/pfc-r8a7779.c
@@ -2120,7 +2120,7 @@ static struct pinmux_cfg_reg pinmux_config_regs[] = {
FN_AUDATA3, 0, 0, 0 }
},
{ PINMUX_CFG_REG_VAR("IPSR4", 0xfffc0030, 32,
- 3, 1, 1, 1, 1, 1, 1, 3, 3, 1,
+ 3, 1, 1, 1, 1, 1, 1, 3, 3,
1, 1, 1, 1, 1, 1, 3, 3, 3, 2) {
/* IP4_31_29 [3] */
FN_DU1_DB0, FN_VI2_DATA4_VI2_B4, FN_SCL2_B, FN_SD3_DAT0,
diff --git a/arch/arm/mach-shmobile/pfc-sh7372.c b/arch/arm/mach-shmobile/pfc-sh7372.c
index 1bd6585a6ac..336093f9210 100644
--- a/arch/arm/mach-shmobile/pfc-sh7372.c
+++ b/arch/arm/mach-shmobile/pfc-sh7372.c
@@ -23,6 +23,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/gpio.h>
+#include <mach/irqs.h>
#include <mach/sh7372.h>
#define CPU_ALL_PORT(fn, pfx, sfx) \
@@ -1594,6 +1595,43 @@ static struct pinmux_data_reg pinmux_data_regs[] = {
{ },
};
+#define EXT_IRQ16L(n) evt2irq(0x200 + ((n) << 5))
+#define EXT_IRQ16H(n) evt2irq(0x3200 + (((n) - 16) << 5))
+static struct pinmux_irq pinmux_irqs[] = {
+ PINMUX_IRQ(EXT_IRQ16L(0), PORT6_FN0, PORT162_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(1), PORT12_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(2), PORT4_FN0, PORT5_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(3), PORT8_FN0, PORT16_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(4), PORT17_FN0, PORT163_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(5), PORT18_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(6), PORT39_FN0, PORT164_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(7), PORT40_FN0, PORT167_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(8), PORT41_FN0, PORT168_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(9), PORT42_FN0, PORT169_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(10), PORT65_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(11), PORT67_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(12), PORT80_FN0, PORT137_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(13), PORT81_FN0, PORT145_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(14), PORT82_FN0, PORT146_FN0),
+ PINMUX_IRQ(EXT_IRQ16L(15), PORT83_FN0, PORT147_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(16), PORT84_FN0, PORT170_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(17), PORT85_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(18), PORT86_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(19), PORT87_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(20), PORT92_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(21), PORT93_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(22), PORT94_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(23), PORT95_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(24), PORT112_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(25), PORT119_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(26), PORT121_FN0, PORT172_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(27), PORT122_FN0, PORT180_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(28), PORT123_FN0, PORT181_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(29), PORT129_FN0, PORT182_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(30), PORT130_FN0, PORT183_FN0),
+ PINMUX_IRQ(EXT_IRQ16H(31), PORT138_FN0, PORT184_FN0),
+};
+
static struct pinmux_info sh7372_pinmux_info = {
.name = "sh7372_pfc",
.reserved_id = PINMUX_RESERVED,
@@ -1614,6 +1652,9 @@ static struct pinmux_info sh7372_pinmux_info = {
.gpio_data = pinmux_data,
.gpio_data_size = ARRAY_SIZE(pinmux_data),
+
+ .gpio_irq = pinmux_irqs,
+ .gpio_irq_size = ARRAY_SIZE(pinmux_irqs),
};
void sh7372_pinmux_init(void)
diff --git a/arch/arm/mach-shmobile/smp-sh73a0.c b/arch/arm/mach-shmobile/smp-sh73a0.c
index 0d159d64a34..2d0d4212be4 100644
--- a/arch/arm/mach-shmobile/smp-sh73a0.c
+++ b/arch/arm/mach-shmobile/smp-sh73a0.c
@@ -80,7 +80,7 @@ int __cpuinit sh73a0_boot_secondary(unsigned int cpu)
/* enable cache coherency */
modify_scu_cpu_psr(0, 3 << (cpu * 8));
- if (((__raw_readw(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
+ if (((__raw_readl(__io(PSTR)) >> (4 * cpu)) & 3) == 3)
__raw_writel(1 << cpu, __io(WUPCR)); /* wake up */
else
__raw_writel(1 << cpu, __io(SRESCR)); /* reset */
diff --git a/arch/arm/mach-spear3xx/include/mach/system.h b/arch/arm/mach-spear3xx/include/mach/system.h
deleted file mode 100644
index 92cee6335c9..00000000000
--- a/arch/arm/mach-spear3xx/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-spear3xx/include/mach/system.h
- *
- * SPEAr3xx Machine family specific architecture functions
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MACH_SYSTEM_H
-#define __MACH_SYSTEM_H
-
-#include <plat/system.h>
-
-#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index a5e46b4ade2..9da50e281e9 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -430,18 +430,8 @@ static struct pl061_platform_data gpio1_plat_data = {
.irq_base = SPEAR300_GPIO1_INT_BASE,
};
-struct amba_device spear300_gpio1_device = {
- .dev = {
- .init_name = "gpio1",
- .platform_data = &gpio1_plat_data,
- },
- .res = {
- .start = SPEAR300_GPIO_BASE,
- .end = SPEAR300_GPIO_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {SPEAR300_VIRQ_GPIO1, NO_IRQ},
-};
+AMBA_APB_DEVICE(spear300_gpio1, "gpio1", 0, SPEAR300_GPIO_BASE,
+ {SPEAR300_VIRQ_GPIO1}, &gpio1_plat_data);
/* spear300 routines */
void __init spear300_init(struct pmx_mode *pmx_mode, struct pmx_dev **pmx_devs,
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 10af45da86a..b1733c37f20 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -28,31 +28,12 @@ static struct pl061_platform_data gpio_plat_data = {
.irq_base = SPEAR3XX_GPIO_INT_BASE,
};
-struct amba_device spear3xx_gpio_device = {
- .dev = {
- .init_name = "gpio",
- .platform_data = &gpio_plat_data,
- },
- .res = {
- .start = SPEAR3XX_ICM3_GPIO_BASE,
- .end = SPEAR3XX_ICM3_GPIO_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {SPEAR3XX_IRQ_BASIC_GPIO, NO_IRQ},
-};
+AMBA_APB_DEVICE(spear3xx_gpio, "gpio", 0, SPEAR3XX_ICM3_GPIO_BASE,
+ {SPEAR3XX_IRQ_BASIC_GPIO}, &gpio_plat_data);
/* uart device registration */
-struct amba_device spear3xx_uart_device = {
- .dev = {
- .init_name = "uart",
- },
- .res = {
- .start = SPEAR3XX_ICM1_UART_BASE,
- .end = SPEAR3XX_ICM1_UART_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {SPEAR3XX_IRQ_UART, NO_IRQ},
-};
+AMBA_APB_DEVICE(spear3xx_uart, "uart", 0, SPEAR3XX_ICM1_UART_BASE,
+ {SPEAR3XX_IRQ_UART}, NULL);
/* Do spear3xx familiy common initialization part here */
void __init spear3xx_init(void)
diff --git a/arch/arm/mach-spear6xx/include/mach/system.h b/arch/arm/mach-spear6xx/include/mach/system.h
deleted file mode 100644
index 0b1d2be81cf..00000000000
--- a/arch/arm/mach-spear6xx/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-spear6xx/include/mach/system.h
- *
- * SPEAr6xx Machine family specific architecture functions
- *
- * Copyright (C) 2009 ST Microelectronics
- * Rajeev Kumar<rajeev-dlh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __MACH_SYSTEM_H
-#define __MACH_SYSTEM_H
-
-#include <plat/system.h>
-
-#endif /* __MACH_SYSTEM_H */
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index e0f6628c8b2..b997b1b10ba 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -34,7 +34,7 @@ struct amba_device uart_device[] = {
.end = SPEAR6XX_ICM1_UART0_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
- .irq = {IRQ_UART_0, NO_IRQ},
+ .irq = {IRQ_UART_0},
}, {
.dev = {
.init_name = "uart1",
@@ -44,7 +44,7 @@ struct amba_device uart_device[] = {
.end = SPEAR6XX_ICM1_UART1_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
- .irq = {IRQ_UART_1, NO_IRQ},
+ .irq = {IRQ_UART_1},
}
};
@@ -73,7 +73,7 @@ struct amba_device gpio_device[] = {
.end = SPEAR6XX_CPU_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
- .irq = {IRQ_LOCAL_GPIO, NO_IRQ},
+ .irq = {IRQ_LOCAL_GPIO},
}, {
.dev = {
.init_name = "gpio1",
@@ -84,7 +84,7 @@ struct amba_device gpio_device[] = {
.end = SPEAR6XX_ICM3_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
- .irq = {IRQ_BASIC_GPIO, NO_IRQ},
+ .irq = {IRQ_BASIC_GPIO},
}, {
.dev = {
.init_name = "gpio2",
@@ -95,7 +95,7 @@ struct amba_device gpio_device[] = {
.end = SPEAR6XX_ICM2_GPIO_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
- .irq = {IRQ_APPL_GPIO, NO_IRQ},
+ .irq = {IRQ_APPL_GPIO},
}
};
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index e120ff54f66..e0b7a4d3259 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -7,6 +7,7 @@ obj-y += clock.o
obj-y += timer.o
obj-y += pinmux.o
obj-y += fuse.o
+obj-y += pmc.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += powergate.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_clocks.o
obj-$(CONFIG_ARCH_TEGRA_2x_SOC) += tegra2_emc.o
@@ -15,7 +16,7 @@ obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += pinmux-tegra30-tables.o
obj-$(CONFIG_ARCH_TEGRA_3x_SOC) += board-dt-tegra30.o
obj-$(CONFIG_SMP) += platsmp.o localtimer.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
-obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o
+obj-$(CONFIG_TEGRA_SYSTEM_DMA) += dma.o apbio.o
obj-$(CONFIG_CPU_FREQ) += cpu-tegra.o
obj-$(CONFIG_TEGRA_PCI) += pcie.o
obj-$(CONFIG_USB_SUPPORT) += usb_phy.o
diff --git a/arch/arm/mach-tegra/apbio.c b/arch/arm/mach-tegra/apbio.c
new file mode 100644
index 00000000000..e75451e517b
--- /dev/null
+++ b/arch/arm/mach-tegra/apbio.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/dma-mapping.h>
+#include <linux/spinlock.h>
+#include <linux/completion.h>
+#include <linux/sched.h>
+#include <linux/mutex.h>
+
+#include <mach/dma.h>
+#include <mach/iomap.h>
+
+#include "apbio.h"
+
+static DEFINE_MUTEX(tegra_apb_dma_lock);
+
+static struct tegra_dma_channel *tegra_apb_dma;
+static u32 *tegra_apb_bb;
+static dma_addr_t tegra_apb_bb_phys;
+static DECLARE_COMPLETION(tegra_apb_wait);
+
+bool tegra_apb_init(void)
+{
+ struct tegra_dma_channel *ch;
+
+ mutex_lock(&tegra_apb_dma_lock);
+
+ /* Check to see if we raced to setup */
+ if (tegra_apb_dma)
+ goto out;
+
+ ch = tegra_dma_allocate_channel(TEGRA_DMA_MODE_ONESHOT |
+ TEGRA_DMA_SHARED);
+
+ if (!ch)
+ goto out_fail;
+
+ tegra_apb_bb = dma_alloc_coherent(NULL, sizeof(u32),
+ &tegra_apb_bb_phys, GFP_KERNEL);
+ if (!tegra_apb_bb) {
+ pr_err("%s: can not allocate bounce buffer\n", __func__);
+ tegra_dma_free_channel(ch);
+ goto out_fail;
+ }
+
+ tegra_apb_dma = ch;
+out:
+ mutex_unlock(&tegra_apb_dma_lock);
+ return true;
+
+out_fail:
+ mutex_unlock(&tegra_apb_dma_lock);
+ return false;
+}
+
+static void apb_dma_complete(struct tegra_dma_req *req)
+{
+ complete(&tegra_apb_wait);
+}
+
+u32 tegra_apb_readl(unsigned long offset)
+{
+ struct tegra_dma_req req;
+ int ret;
+
+ if (!tegra_apb_dma && !tegra_apb_init())
+ return readl(IO_TO_VIRT(offset));
+
+ mutex_lock(&tegra_apb_dma_lock);
+ req.complete = apb_dma_complete;
+ req.to_memory = 1;
+ req.dest_addr = tegra_apb_bb_phys;
+ req.dest_bus_width = 32;
+ req.dest_wrap = 1;
+ req.source_addr = offset;
+ req.source_bus_width = 32;
+ req.source_wrap = 4;
+ req.req_sel = TEGRA_DMA_REQ_SEL_CNTR;
+ req.size = 4;
+
+ INIT_COMPLETION(tegra_apb_wait);
+
+ tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+ ret = wait_for_completion_timeout(&tegra_apb_wait,
+ msecs_to_jiffies(50));
+
+ if (WARN(ret == 0, "apb read dma timed out")) {
+ tegra_dma_dequeue_req(tegra_apb_dma, &req);
+ *(u32 *)tegra_apb_bb = 0;
+ }
+
+ mutex_unlock(&tegra_apb_dma_lock);
+ return *((u32 *)tegra_apb_bb);
+}
+
+void tegra_apb_writel(u32 value, unsigned long offset)
+{
+ struct tegra_dma_req req;
+ int ret;
+
+ if (!tegra_apb_dma && !tegra_apb_init()) {
+ writel(value, IO_TO_VIRT(offset));
+ return;
+ }
+
+ mutex_lock(&tegra_apb_dma_lock);
+ *((u32 *)tegra_apb_bb) = value;
+ req.complete = apb_dma_complete;
+ req.to_memory = 0;
+ req.dest_addr = offset;
+ req.dest_wrap = 4;
+ req.dest_bus_width = 32;
+ req.source_addr = tegra_apb_bb_phys;
+ req.source_bus_width = 32;
+ req.source_wrap = 1;
+ req.req_sel = TEGRA_DMA_REQ_SEL_CNTR;
+ req.size = 4;
+
+ INIT_COMPLETION(tegra_apb_wait);
+
+ tegra_dma_enqueue_req(tegra_apb_dma, &req);
+
+ ret = wait_for_completion_timeout(&tegra_apb_wait,
+ msecs_to_jiffies(50));
+
+ if (WARN(ret == 0, "apb write dma timed out"))
+ tegra_dma_dequeue_req(tegra_apb_dma, &req);
+
+ mutex_unlock(&tegra_apb_dma_lock);
+}
diff --git a/arch/arm/mach-tegra/apbio.h b/arch/arm/mach-tegra/apbio.h
new file mode 100644
index 00000000000..8b49e8c89a6
--- /dev/null
+++ b/arch/arm/mach-tegra/apbio.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 NVIDIA Corporation.
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_APBIO_H
+#define __MACH_TEGRA_APBIO_H
+
+#ifdef CONFIG_TEGRA_SYSTEM_DMA
+
+u32 tegra_apb_readl(unsigned long offset);
+void tegra_apb_writel(u32 value, unsigned long offset);
+
+#else
+#include <asm/io.h>
+#include <mach/io.h>
+
+static inline u32 tegra_apb_readl(unsigned long offset)
+{
+ return readl(IO_TO_VIRT(offset));
+}
+
+static inline void tegra_apb_writel(u32 value, unsigned long offset)
+{
+ writel(value, IO_TO_VIRT(offset));
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c
index 21d1285731b..976edfb0591 100644
--- a/arch/arm/mach-tegra/board-harmony-power.c
+++ b/arch/arm/mach-tegra/board-harmony-power.c
@@ -18,18 +18,13 @@
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
-#include <linux/io.h>
#include <linux/regulator/machine.h>
#include <linux/mfd/tps6586x.h>
-#include <mach/iomap.h>
#include <mach/irqs.h>
#include "board-harmony.h"
-#define PMC_CTRL 0x0
-#define PMC_CTRL_INTR_LOW (1 << 17)
-
static struct regulator_consumer_supply tps658621_ldo0_supply[] = {
REGULATOR_SUPPLY("pex_clk", NULL),
};
@@ -114,16 +109,6 @@ static struct i2c_board_info __initdata harmony_regulators[] = {
int __init harmony_regulator_init(void)
{
- void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
- u32 pmc_ctrl;
-
- /*
- * Configure the power management controller to trigger PMU
- * interrupts when low
- */
- pmc_ctrl = readl(pmc + PMC_CTRL);
- writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
-
i2c_register_board_info(3, harmony_regulators, 1);
return 0;
diff --git a/arch/arm/mach-tegra/board-harmony.c b/arch/arm/mach-tegra/board-harmony.c
index 789bdc9e8f9..c00aadb01e0 100644
--- a/arch/arm/mach-tegra/board-harmony.c
+++ b/arch/arm/mach-tegra/board-harmony.c
@@ -101,7 +101,6 @@ static struct wm8903_platform_data harmony_wm8903_pdata = {
static struct i2c_board_info __initdata wm8903_board_info = {
I2C_BOARD_INFO("wm8903", 0x1a),
.platform_data = &harmony_wm8903_pdata,
- .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
};
static void __init harmony_i2c_init(void)
@@ -111,6 +110,7 @@ static void __init harmony_i2c_init(void)
platform_device_register(&tegra_i2c_device3);
platform_device_register(&tegra_i2c_device4);
+ wm8903_board_info.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ);
i2c_register_board_info(0, &wm8903_board_info, 1);
}
diff --git a/arch/arm/mach-tegra/board-seaboard.c b/arch/arm/mach-tegra/board-seaboard.c
index ebac65f5251..d669847f048 100644
--- a/arch/arm/mach-tegra/board-seaboard.c
+++ b/arch/arm/mach-tegra/board-seaboard.c
@@ -159,7 +159,6 @@ static struct platform_device *seaboard_devices[] __initdata = {
static struct i2c_board_info __initdata isl29018_device = {
I2C_BOARD_INFO("isl29018", 0x44),
- .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_ISL29018_IRQ),
};
static struct i2c_board_info __initdata adt7461_device = {
@@ -183,7 +182,6 @@ static struct wm8903_platform_data wm8903_pdata = {
static struct i2c_board_info __initdata wm8903_device = {
I2C_BOARD_INFO("wm8903", 0x1a),
.platform_data = &wm8903_pdata,
- .irq = TEGRA_GPIO_TO_IRQ(TEGRA_GPIO_CDC_IRQ),
};
static int seaboard_ehci_init(void)
@@ -214,7 +212,10 @@ static void __init seaboard_i2c_init(void)
gpio_request(TEGRA_GPIO_ISL29018_IRQ, "isl29018");
gpio_direction_input(TEGRA_GPIO_ISL29018_IRQ);
+ isl29018_device.irq = gpio_to_irq(TEGRA_GPIO_ISL29018_IRQ);
i2c_register_board_info(0, &isl29018_device, 1);
+
+ wm8903_device.irq = gpio_to_irq(TEGRA_GPIO_CDC_IRQ);
i2c_register_board_info(0, &wm8903_device, 1);
i2c_register_board_info(3, &adt7461_device, 1);
diff --git a/arch/arm/mach-tegra/common.c b/arch/arm/mach-tegra/common.c
index a2eb90169ae..47ad750209a 100644
--- a/arch/arm/mach-tegra/common.c
+++ b/arch/arm/mach-tegra/common.c
@@ -27,11 +27,28 @@
#include <asm/hardware/gic.h>
#include <mach/iomap.h>
-#include <mach/system.h>
#include "board.h"
#include "clock.h"
#include "fuse.h"
+#include "pmc.h"
+
+/*
+ * Storage for debug-macro.S's state.
+ *
+ * This must be in .data not .bss so that it gets initialized each time the
+ * kernel is loaded. The data is declared here rather than debug-macro.S so
+ * that multiple inclusions of debug-macro.S point at the same data.
+ */
+#define TEGRA_DEBUG_UART_OFFSET (TEGRA_DEBUG_UART_BASE & 0xFFFF)
+u32 tegra_uart_config[3] = {
+ /* Debug UART initialization required */
+ 1,
+ /* Debug UART physical address */
+ (u32)(IO_APB_PHYS + TEGRA_DEBUG_UART_OFFSET),
+ /* Debug UART virtual address */
+ (u32)(IO_APB_VIRT + TEGRA_DEBUG_UART_OFFSET),
+};
#ifdef CONFIG_OF
static const struct of_device_id tegra_dt_irq_match[] __initconst = {
@@ -96,15 +113,19 @@ static void __init tegra_init_cache(u32 tag_latency, u32 data_latency)
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
void __init tegra20_init_early(void)
{
+ disable_hlt(); /* idle WFI usage needs to be confirmed */
+
tegra_init_fuse();
tegra2_init_clocks();
tegra_clk_init_from_table(tegra20_clk_init_table);
tegra_init_cache(0x331, 0x441);
+ tegra_pmc_init();
}
#endif
#ifdef CONFIG_ARCH_TEGRA_3x_SOC
void __init tegra30_init_early(void)
{
tegra_init_cache(0x441, 0x551);
+ tegra_pmc_init();
}
#endif
diff --git a/arch/arm/mach-tegra/dma.c b/arch/arm/mach-tegra/dma.c
index c0cf967e47d..abea4f6e2dd 100644
--- a/arch/arm/mach-tegra/dma.c
+++ b/arch/arm/mach-tegra/dma.c
@@ -33,6 +33,8 @@
#include <mach/iomap.h>
#include <mach/suspend.h>
+#include "apbio.h"
+
#define APB_DMA_GEN 0x000
#define GEN_ENABLE (1<<31)
@@ -50,8 +52,6 @@
#define CSR_ONCE (1<<27)
#define CSR_FLOW (1<<21)
#define CSR_REQ_SEL_SHIFT 16
-#define CSR_REQ_SEL_MASK (0x1F<<CSR_REQ_SEL_SHIFT)
-#define CSR_REQ_SEL_INVALID (31<<CSR_REQ_SEL_SHIFT)
#define CSR_WCOUNT_SHIFT 2
#define CSR_WCOUNT_MASK 0xFFFC
@@ -133,6 +133,7 @@ struct tegra_dma_channel {
static bool tegra_dma_initialized;
static DEFINE_MUTEX(tegra_dma_lock);
+static DEFINE_SPINLOCK(enable_lock);
static DECLARE_BITMAP(channel_usage, NV_DMA_MAX_CHANNELS);
static struct tegra_dma_channel dma_channels[NV_DMA_MAX_CHANNELS];
@@ -180,36 +181,94 @@ static void tegra_dma_stop(struct tegra_dma_channel *ch)
static int tegra_dma_cancel(struct tegra_dma_channel *ch)
{
- u32 csr;
unsigned long irq_flags;
spin_lock_irqsave(&ch->lock, irq_flags);
while (!list_empty(&ch->list))
list_del(ch->list.next);
- csr = readl(ch->addr + APB_DMA_CHAN_CSR);
- csr &= ~CSR_REQ_SEL_MASK;
- csr |= CSR_REQ_SEL_INVALID;
- writel(csr, ch->addr + APB_DMA_CHAN_CSR);
-
tegra_dma_stop(ch);
spin_unlock_irqrestore(&ch->lock, irq_flags);
return 0;
}
+static unsigned int get_channel_status(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req, bool is_stop_dma)
+{
+ void __iomem *addr = IO_ADDRESS(TEGRA_APB_DMA_BASE);
+ unsigned int status;
+
+ if (is_stop_dma) {
+ /*
+ * STOP the DMA and get the transfer count.
+ * Getting the transfer count is tricky.
+ * - Globally disable DMA on all channels
+ * - Read the channel's status register to know the number
+ * of pending bytes to be transfered.
+ * - Stop the dma channel
+ * - Globally re-enable DMA to resume other transfers
+ */
+ spin_lock(&enable_lock);
+ writel(0, addr + APB_DMA_GEN);
+ udelay(20);
+ status = readl(ch->addr + APB_DMA_CHAN_STA);
+ tegra_dma_stop(ch);
+ writel(GEN_ENABLE, addr + APB_DMA_GEN);
+ spin_unlock(&enable_lock);
+ if (status & STA_ISE_EOC) {
+ pr_err("Got Dma Int here clearing");
+ writel(status, ch->addr + APB_DMA_CHAN_STA);
+ }
+ req->status = TEGRA_DMA_REQ_ERROR_ABORTED;
+ } else {
+ status = readl(ch->addr + APB_DMA_CHAN_STA);
+ }
+ return status;
+}
+
+/* should be called with the channel lock held */
+static unsigned int dma_active_count(struct tegra_dma_channel *ch,
+ struct tegra_dma_req *req, unsigned int status)
+{
+ unsigned int to_transfer;
+ unsigned int req_transfer_count;
+ unsigned int bytes_transferred;
+
+ to_transfer = ((status & STA_COUNT_MASK) >> STA_COUNT_SHIFT) + 1;
+ req_transfer_count = ch->req_transfer_count + 1;
+ bytes_transferred = req_transfer_count;
+ if (status & STA_BUSY)
+ bytes_transferred -= to_transfer;
+ /*
+ * In continuous transfer mode, DMA only tracks the count of the
+ * half DMA buffer. So, if the DMA already finished half the DMA
+ * then add the half buffer to the completed count.
+ */
+ if (ch->mode & TEGRA_DMA_MODE_CONTINOUS) {
+ if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
+ bytes_transferred += req_transfer_count;
+ if (status & STA_ISE_EOC)
+ bytes_transferred += req_transfer_count;
+ }
+ bytes_transferred *= 4;
+ return bytes_transferred;
+}
+
int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
struct tegra_dma_req *_req)
{
- unsigned int csr;
unsigned int status;
struct tegra_dma_req *req = NULL;
int found = 0;
unsigned long irq_flags;
- int to_transfer;
- int req_transfer_count;
+ int stop = 0;
spin_lock_irqsave(&ch->lock, irq_flags);
+
+ if (list_entry(ch->list.next, struct tegra_dma_req, node) == _req)
+ stop = 1;
+
list_for_each_entry(req, &ch->list, node) {
if (req == _req) {
list_del(&req->node);
@@ -222,47 +281,12 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
return 0;
}
- /* STOP the DMA and get the transfer count.
- * Getting the transfer count is tricky.
- * - Change the source selector to invalid to stop the DMA from
- * FIFO to memory.
- * - Read the status register to know the number of pending
- * bytes to be transferred.
- * - Finally stop or program the DMA to the next buffer in the
- * list.
- */
- csr = readl(ch->addr + APB_DMA_CHAN_CSR);
- csr &= ~CSR_REQ_SEL_MASK;
- csr |= CSR_REQ_SEL_INVALID;
- writel(csr, ch->addr + APB_DMA_CHAN_CSR);
-
- /* Get the transfer count */
- status = readl(ch->addr + APB_DMA_CHAN_STA);
- to_transfer = (status & STA_COUNT_MASK) >> STA_COUNT_SHIFT;
- req_transfer_count = ch->req_transfer_count;
- req_transfer_count += 1;
- to_transfer += 1;
-
- req->bytes_transferred = req_transfer_count;
-
- if (status & STA_BUSY)
- req->bytes_transferred -= to_transfer;
-
- /* In continuous transfer mode, DMA only tracks the count of the
- * half DMA buffer. So, if the DMA already finished half the DMA
- * then add the half buffer to the completed count.
- *
- * FIXME: There can be a race here. What if the req to
- * dequue happens at the same time as the DMA just moved to
- * the new buffer and SW didn't yet received the interrupt?
- */
- if (ch->mode & TEGRA_DMA_MODE_CONTINOUS)
- if (req->buffer_status == TEGRA_DMA_REQ_BUF_STATUS_HALF_FULL)
- req->bytes_transferred += req_transfer_count;
+ if (!stop)
+ goto skip_stop_dma;
- req->bytes_transferred *= 4;
+ status = get_channel_status(ch, req, true);
+ req->bytes_transferred = dma_active_count(ch, req, status);
- tegra_dma_stop(ch);
if (!list_empty(&ch->list)) {
/* if the list is not empty, queue the next request */
struct tegra_dma_req *next_req;
@@ -270,6 +294,8 @@ int tegra_dma_dequeue_req(struct tegra_dma_channel *ch,
typeof(*next_req), node);
tegra_dma_update_hw(ch, next_req);
}
+
+skip_stop_dma:
req->status = -TEGRA_DMA_REQ_ERROR_ABORTED;
spin_unlock_irqrestore(&ch->lock, irq_flags);
@@ -357,7 +383,7 @@ struct tegra_dma_channel *tegra_dma_allocate_channel(int mode)
int channel;
struct tegra_dma_channel *ch = NULL;
- if (WARN_ON(!tegra_dma_initialized))
+ if (!tegra_dma_initialized)
return NULL;
mutex_lock(&tegra_dma_lock);
diff --git a/arch/arm/mach-tegra/fuse.c b/arch/arm/mach-tegra/fuse.c
index 1fa26d9a1a6..17fdd4086e6 100644
--- a/arch/arm/mach-tegra/fuse.c
+++ b/arch/arm/mach-tegra/fuse.c
@@ -23,20 +23,70 @@
#include <mach/iomap.h>
#include "fuse.h"
+#include "apbio.h"
#define FUSE_UID_LOW 0x108
#define FUSE_UID_HIGH 0x10c
#define FUSE_SKU_INFO 0x110
#define FUSE_SPARE_BIT 0x200
-static inline u32 fuse_readl(unsigned long offset)
+int tegra_sku_id;
+int tegra_cpu_process_id;
+int tegra_core_process_id;
+enum tegra_revision tegra_revision;
+
+/* The BCT to use at boot is specified by board straps that can be read
+ * through a APB misc register and decoded. 2 bits, i.e. 4 possible BCTs.
+ */
+int tegra_bct_strapping;
+
+#define STRAP_OPT 0x008
+#define GMI_AD0 (1 << 4)
+#define GMI_AD1 (1 << 5)
+#define RAM_ID_MASK (GMI_AD0 | GMI_AD1)
+#define RAM_CODE_SHIFT 4
+
+static const char *tegra_revision_name[TEGRA_REVISION_MAX] = {
+ [TEGRA_REVISION_UNKNOWN] = "unknown",
+ [TEGRA_REVISION_A01] = "A01",
+ [TEGRA_REVISION_A02] = "A02",
+ [TEGRA_REVISION_A03] = "A03",
+ [TEGRA_REVISION_A03p] = "A03 prime",
+ [TEGRA_REVISION_A04] = "A04",
+};
+
+static inline u32 tegra_fuse_readl(unsigned long offset)
+{
+ return tegra_apb_readl(TEGRA_FUSE_BASE + offset);
+}
+
+static inline bool get_spare_fuse(int bit)
{
- return readl(IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+ return tegra_fuse_readl(FUSE_SPARE_BIT + bit * 4);
}
-static inline void fuse_writel(u32 value, unsigned long offset)
+static enum tegra_revision tegra_get_revision(void)
{
- writel(value, IO_TO_VIRT(TEGRA_FUSE_BASE + offset));
+ void __iomem *chip_id = IO_ADDRESS(TEGRA_APB_MISC_BASE) + 0x804;
+ u32 id = readl(chip_id);
+ u32 minor_rev = (id >> 16) & 0xf;
+ u32 chipid = (id >> 8) & 0xff;
+
+ switch (minor_rev) {
+ case 1:
+ return TEGRA_REVISION_A01;
+ case 2:
+ return TEGRA_REVISION_A02;
+ case 3:
+ if (chipid == 0x20 && (get_spare_fuse(18) || get_spare_fuse(19)))
+ return TEGRA_REVISION_A03p;
+ else
+ return TEGRA_REVISION_A03;
+ case 4:
+ return TEGRA_REVISION_A04;
+ default:
+ return TEGRA_REVISION_UNKNOWN;
+ }
}
void tegra_init_fuse(void)
@@ -45,40 +95,31 @@ void tegra_init_fuse(void)
reg |= 1 << 28;
writel(reg, IO_TO_VIRT(TEGRA_CLK_RESET_BASE + 0x48));
- pr_info("Tegra SKU: %d CPU Process: %d Core Process: %d\n",
- tegra_sku_id(), tegra_cpu_process_id(),
- tegra_core_process_id());
-}
+ reg = tegra_fuse_readl(FUSE_SKU_INFO);
+ tegra_sku_id = reg & 0xFF;
-unsigned long long tegra_chip_uid(void)
-{
- unsigned long long lo, hi;
+ reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+ tegra_cpu_process_id = (reg >> 6) & 3;
- lo = fuse_readl(FUSE_UID_LOW);
- hi = fuse_readl(FUSE_UID_HIGH);
- return (hi << 32ull) | lo;
-}
+ reg = tegra_fuse_readl(FUSE_SPARE_BIT);
+ tegra_core_process_id = (reg >> 12) & 3;
-int tegra_sku_id(void)
-{
- int sku_id;
- u32 reg = fuse_readl(FUSE_SKU_INFO);
- sku_id = reg & 0xFF;
- return sku_id;
-}
+ reg = tegra_apb_readl(TEGRA_APB_MISC_BASE + STRAP_OPT);
+ tegra_bct_strapping = (reg & RAM_ID_MASK) >> RAM_CODE_SHIFT;
-int tegra_cpu_process_id(void)
-{
- int cpu_process_id;
- u32 reg = fuse_readl(FUSE_SPARE_BIT);
- cpu_process_id = (reg >> 6) & 3;
- return cpu_process_id;
+ tegra_revision = tegra_get_revision();
+
+ pr_info("Tegra Revision: %s SKU: %d CPU Process: %d Core Process: %d\n",
+ tegra_revision_name[tegra_get_revision()],
+ tegra_sku_id, tegra_cpu_process_id,
+ tegra_core_process_id);
}
-int tegra_core_process_id(void)
+unsigned long long tegra_chip_uid(void)
{
- int core_process_id;
- u32 reg = fuse_readl(FUSE_SPARE_BIT);
- core_process_id = (reg >> 12) & 3;
- return core_process_id;
+ unsigned long long lo, hi;
+
+ lo = tegra_fuse_readl(FUSE_UID_LOW);
+ hi = tegra_fuse_readl(FUSE_UID_HIGH);
+ return (hi << 32ull) | lo;
}
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index 584b2e27dbd..d65d2abf803 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -1,6 +1,4 @@
/*
- * arch/arm/mach-tegra/fuse.c
- *
* Copyright (C) 2010 Google, Inc.
*
* Author:
@@ -17,8 +15,34 @@
*
*/
+#ifndef __MACH_TEGRA_FUSE_H
+#define __MACH_TEGRA_FUSE_H
+
+enum tegra_revision {
+ TEGRA_REVISION_UNKNOWN = 0,
+ TEGRA_REVISION_A01,
+ TEGRA_REVISION_A02,
+ TEGRA_REVISION_A03,
+ TEGRA_REVISION_A03p,
+ TEGRA_REVISION_A04,
+ TEGRA_REVISION_MAX,
+};
+
+#define SKU_ID_T20 8
+#define SKU_ID_T25SE 20
+#define SKU_ID_AP25 23
+#define SKU_ID_T25 24
+#define SKU_ID_AP25E 27
+#define SKU_ID_T25E 28
+
+extern int tegra_sku_id;
+extern int tegra_cpu_process_id;
+extern int tegra_core_process_id;
+extern enum tegra_revision tegra_revision;
+
+extern int tegra_bct_strapping;
+
unsigned long long tegra_chip_uid(void);
-int tegra_sku_id(void);
-int tegra_cpu_process_id(void);
-int tegra_core_process_id(void);
void tegra_init_fuse(void);
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/debug-macro.S b/arch/arm/mach-tegra/include/mach/debug-macro.S
index 619abc63aee..90069abd37b 100644
--- a/arch/arm/mach-tegra/include/mach/debug-macro.S
+++ b/arch/arm/mach-tegra/include/mach/debug-macro.S
@@ -1,11 +1,17 @@
/*
* arch/arm/mach-tegra/include/mach/debug-macro.S
*
- * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010,2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
*
* Author:
* Colin Cross <ccross@google.com>
* Erik Gilling <konkers@google.com>
+ * Doug Anderson <dianders@chromium.org>
+ * Stephen Warren <swarren@nvidia.com>
+ *
+ * Portions based on mach-omap2's debug-macro.S
+ * Copyright (C) 1994-1999 Russell King
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -18,18 +24,78 @@
*
*/
+#include <linux/serial_reg.h>
+
#include <mach/io.h>
#include <mach/iomap.h>
+#include <mach/irammap.h>
+
+ .macro addruart, rp, rv, tmp
+ adr \rp, 99f @ actual addr of 99f
+ ldr \rv, [\rp] @ linked addr is stored there
+ sub \rv, \rv, \rp @ offset between the two
+ ldr \rp, [\rp, #4] @ linked tegra_uart_config
+ sub \tmp, \rp, \rv @ actual tegra_uart_config
+ ldr \rp, [\tmp] @ Load tegra_uart_config
+ cmp \rp, #1 @ needs intitialization?
+ bne 100f @ no; go load the addresses
+ mov \rv, #0 @ yes; record init is done
+ str \rv, [\tmp]
+ mov \rp, #TEGRA_IRAM_BASE @ See if cookie is in IRAM
+ ldr \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET]
+ movw \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE & 0xffff
+ movt \rp, #TEGRA_IRAM_DEBUG_UART_COOKIE >> 16
+ cmp \rv, \rp @ Cookie present?
+ bne 100f @ No, use default UART
+ mov \rp, #TEGRA_IRAM_BASE @ Load UART address from IRAM
+ ldr \rv, [\rp, #TEGRA_IRAM_DEBUG_UART_OFFSET + 4]
+ str \rv, [\tmp, #4] @ Store in tegra_uart_phys
+ sub \rv, \rv, #IO_APB_PHYS @ Calculate virt address
+ add \rv, \rv, #IO_APB_VIRT
+ str \rv, [\tmp, #8] @ Store in tegra_uart_virt
+ b 100f
+
+ .align
+99: .word .
+ .word tegra_uart_config
+ .ltorg
+
+100: ldr \rp, [\tmp, #4] @ Load tegra_uart_phys
+ ldr \rv, [\tmp, #8] @ Load tegra_uart_virt
+ .endm
+
+#define UART_SHIFT 2
+
+/*
+ * Code below is swiped from <asm/hardware/debug-8250.S>, but add an extra
+ * check to make sure that we aren't in the CONFIG_TEGRA_DEBUG_UART_NONE case.
+ * We use the fact that all 5 valid UART addresses all have something in the
+ * 2nd-to-lowest byte.
+ */
- .macro addruart, rp, rv, tmp
- ldr \rp, =IO_APB_PHYS @ physical
- ldr \rv, =IO_APB_VIRT @ virtual
- orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF)
- orr \rp, \rp, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
- orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF)
- orr \rv, \rv, #(TEGRA_DEBUG_UART_BASE & 0xFF00)
- .endm
+ .macro senduart, rd, rx
+ tst \rx, #0x0000ff00
+ strneb \rd, [\rx, #UART_TX << UART_SHIFT]
+1001:
+ .endm
-#define UART_SHIFT 2
-#include <asm/hardware/debug-8250.S>
+ .macro busyuart, rd, rx
+ tst \rx, #0x0000ff00
+ beq 1002f
+1001: ldrb \rd, [\rx, #UART_LSR << UART_SHIFT]
+ and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
+ bne 1001b
+1002:
+ .endm
+ .macro waituart, rd, rx
+#ifdef FLOW_CONTROL
+ tst \rx, #0x0000ff00
+ beq 1002f
+1001: ldrb \rd, [\rx, #UART_MSR << UART_SHIFT]
+ tst \rd, #UART_MSR_CTS
+ beq 1001b
+1002:
+#endif
+ .endm
diff --git a/arch/arm/mach-tegra/include/mach/gpio-tegra.h b/arch/arm/mach-tegra/include/mach/gpio-tegra.h
index 87d37fdf508..6140820555e 100644
--- a/arch/arm/mach-tegra/include/mach/gpio-tegra.h
+++ b/arch/arm/mach-tegra/include/mach/gpio-tegra.h
@@ -25,8 +25,6 @@
#define TEGRA_NR_GPIOS INT_GPIO_NR
-#define TEGRA_GPIO_TO_IRQ(gpio) (INT_GPIO_BASE + (gpio))
-
struct tegra_gpio_table {
int gpio; /* GPIO number */
bool enable; /* Enable for GPIO at init? */
diff --git a/arch/arm/mach-tegra/include/mach/irammap.h b/arch/arm/mach-tegra/include/mach/irammap.h
new file mode 100644
index 00000000000..0cbe6326185
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/irammap.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_TEGRA_IRAMMAP_H
+#define __MACH_TEGRA_IRAMMAP_H
+
+#include <asm/sizes.h>
+
+/* The first 1K of IRAM is permanently reserved for the CPU reset handler */
+#define TEGRA_IRAM_RESET_HANDLER_OFFSET 0
+#define TEGRA_IRAM_RESET_HANDLER_SIZE SZ_1K
+
+/*
+ * These locations are written to by uncompress.h, and read by debug-macro.S.
+ * The first word holds the cookie value if the data is valid. The second
+ * word holds the UART physical address.
+ */
+#define TEGRA_IRAM_DEBUG_UART_OFFSET SZ_1K
+#define TEGRA_IRAM_DEBUG_UART_SIZE 8
+#define TEGRA_IRAM_DEBUG_UART_COOKIE 0x55415254
+
+#endif
diff --git a/arch/arm/mach-tegra/include/mach/uncompress.h b/arch/arm/mach-tegra/include/mach/uncompress.h
index 4e8323770c7..5a440f315e5 100644
--- a/arch/arm/mach-tegra/include/mach/uncompress.h
+++ b/arch/arm/mach-tegra/include/mach/uncompress.h
@@ -2,10 +2,14 @@
* arch/arm/mach-tegra/include/mach/uncompress.h
*
* Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2011 Google, Inc.
+ * Copyright (C) 2011-2012 NVIDIA CORPORATION. All Rights Reserved.
*
* Author:
* Colin Cross <ccross@google.com>
* Erik Gilling <konkers@google.com>
+ * Doug Anderson <dianders@chromium.org>
+ * Stephen Warren <swarren@nvidia.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -25,36 +29,130 @@
#include <linux/serial_reg.h>
#include <mach/iomap.h>
+#include <mach/irammap.h>
+
+#define BIT(x) (1 << (x))
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+#define DEBUG_UART_SHIFT 2
+
+volatile u8 *uart;
static void putc(int c)
{
- volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
- int shift = 2;
-
if (uart == NULL)
return;
- while (!(uart[UART_LSR << shift] & UART_LSR_THRE))
+ while (!(uart[UART_LSR << DEBUG_UART_SHIFT] & UART_LSR_THRE))
barrier();
- uart[UART_TX << shift] = c;
+ uart[UART_TX << DEBUG_UART_SHIFT] = c;
}
static inline void flush(void)
{
}
+static inline void save_uart_address(void)
+{
+ u32 *buf = (u32 *)(TEGRA_IRAM_BASE + TEGRA_IRAM_DEBUG_UART_OFFSET);
+
+ if (uart) {
+ buf[0] = TEGRA_IRAM_DEBUG_UART_COOKIE;
+ buf[1] = (u32)uart;
+ } else
+ buf[0] = 0;
+}
+
+/*
+ * Setup before decompression. This is where we do UART selection for
+ * earlyprintk and init the uart_base register.
+ */
static inline void arch_decomp_setup(void)
{
- volatile u8 *uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
- int shift = 2;
+ static const struct {
+ u32 base;
+ u32 reset_reg;
+ u32 clock_reg;
+ u32 bit;
+ } uarts[] = {
+ {
+ TEGRA_UARTA_BASE,
+ TEGRA_CLK_RESET_BASE + 0x04,
+ TEGRA_CLK_RESET_BASE + 0x10,
+ 6,
+ },
+ {
+ TEGRA_UARTB_BASE,
+ TEGRA_CLK_RESET_BASE + 0x04,
+ TEGRA_CLK_RESET_BASE + 0x10,
+ 7,
+ },
+ {
+ TEGRA_UARTC_BASE,
+ TEGRA_CLK_RESET_BASE + 0x08,
+ TEGRA_CLK_RESET_BASE + 0x14,
+ 23,
+ },
+ {
+ TEGRA_UARTD_BASE,
+ TEGRA_CLK_RESET_BASE + 0x0c,
+ TEGRA_CLK_RESET_BASE + 0x18,
+ 1,
+ },
+ {
+ TEGRA_UARTE_BASE,
+ TEGRA_CLK_RESET_BASE + 0x0c,
+ TEGRA_CLK_RESET_BASE + 0x18,
+ 2,
+ },
+ };
+ int i;
+ volatile u32 *apb_misc = (volatile u32 *)TEGRA_APB_MISC_BASE;
+ u32 chip, div;
+
+ /*
+ * Look for the first UART that:
+ * a) Is not in reset.
+ * b) Is clocked.
+ * c) Has a 'D' in the scratchpad register.
+ *
+ * Note that on Tegra30, the first two conditions are required, since
+ * if not true, accesses to the UART scratch register will hang.
+ * Tegra20 doesn't have this issue.
+ *
+ * The intent is that the bootloader will tell the kernel which UART
+ * to use by setting up those conditions. If nothing found, we'll fall
+ * back to what's specified in TEGRA_DEBUG_UART_BASE.
+ */
+ for (i = 0; i < ARRAY_SIZE(uarts); i++) {
+ if (*(u8 *)uarts[i].reset_reg & BIT(uarts[i].bit))
+ continue;
+ if (!(*(u8 *)uarts[i].clock_reg & BIT(uarts[i].bit)))
+ continue;
+
+ uart = (volatile u8 *)uarts[i].base;
+ if (uart[UART_SCR << DEBUG_UART_SHIFT] != 'D')
+ continue;
+
+ break;
+ }
+ if (i == ARRAY_SIZE(uarts))
+ uart = (volatile u8 *)TEGRA_DEBUG_UART_BASE;
+ save_uart_address();
if (uart == NULL)
return;
- uart[UART_LCR << shift] |= UART_LCR_DLAB;
- uart[UART_DLL << shift] = 0x75;
- uart[UART_DLM << shift] = 0x0;
- uart[UART_LCR << shift] = 3;
+ chip = (apb_misc[0x804 / 4] >> 8) & 0xff;
+ if (chip == 0x20)
+ div = 0x0075;
+ else
+ div = 0x00dd;
+
+ uart[UART_LCR << DEBUG_UART_SHIFT] |= UART_LCR_DLAB;
+ uart[UART_DLL << DEBUG_UART_SHIFT] = div & 0xff;
+ uart[UART_DLM << DEBUG_UART_SHIFT] = div >> 8;
+ uart[UART_LCR << DEBUG_UART_SHIFT] = 3;
}
static inline void arch_decomp_wdog(void)
diff --git a/arch/arm/mach-tegra/pmc.c b/arch/arm/mach-tegra/pmc.c
new file mode 100644
index 00000000000..7af6a54404b
--- /dev/null
+++ b/arch/arm/mach-tegra/pmc.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+#include <linux/of.h>
+
+#include <mach/iomap.h>
+
+#define PMC_CTRL 0x0
+#define PMC_CTRL_INTR_LOW (1 << 17)
+
+static inline u32 tegra_pmc_readl(u32 reg)
+{
+ return readl(IO_ADDRESS(TEGRA_PMC_BASE + reg));
+}
+
+static inline void tegra_pmc_writel(u32 val, u32 reg)
+{
+ writel(val, IO_ADDRESS(TEGRA_PMC_BASE + reg));
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id matches[] __initconst = {
+ { .compatible = "nvidia,tegra20-pmc" },
+ { }
+};
+#endif
+
+void __init tegra_pmc_init(void)
+{
+ /*
+ * For now, Harmony is the only board that uses the PMC, and it wants
+ * the signal inverted. Seaboard would too if it used the PMC.
+ * Hopefully by the time other boards want to use the PMC, everything
+ * will be device-tree, or they also want it inverted.
+ */
+ bool invert_interrupt = true;
+ u32 val;
+
+#ifdef CONFIG_OF
+ if (of_have_populated_dt()) {
+ struct device_node *np;
+
+ invert_interrupt = false;
+
+ np = of_find_matching_node(NULL, matches);
+ if (np) {
+ if (of_find_property(np, "nvidia,invert-interrupt",
+ NULL))
+ invert_interrupt = true;
+ }
+ }
+#endif
+
+ val = tegra_pmc_readl(PMC_CTRL);
+ if (invert_interrupt)
+ val |= PMC_CTRL_INTR_LOW;
+ else
+ val &= ~PMC_CTRL_INTR_LOW;
+ tegra_pmc_writel(val, PMC_CTRL);
+}
diff --git a/arch/arm/mach-highbank/include/mach/system.h b/arch/arm/mach-tegra/pmc.h
index b1d8b5fbe37..8995ee4a876 100644
--- a/arch/arm/mach-highbank/include/mach/system.h
+++ b/arch/arm/mach-tegra/pmc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2010-2011 Calxeda, Inc.
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -10,15 +10,14 @@
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
- * You should have received a copy of the GNU General Public License along with
- * this program. If not, see <http://www.gnu.org/licenses/>.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
*/
-#ifndef __MACH_SYSTEM_H
-#define __MACH_SYSTEM_H
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
+#ifndef __MACH_TEGRA_PMC_H
+#define __MACH_TEGRA_PMC_H
+
+void tegra_pmc_init(void);
#endif
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index ff9e6b6c046..74d314fdf2f 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -720,7 +720,7 @@ static void tegra2_pllx_clk_init(struct clk *c)
{
tegra2_pll_clk_init(c);
- if (tegra_sku_id() == 7)
+ if (tegra_sku_id == 7)
c->max_rate = 750000000;
}
diff --git a/arch/arm/mach-tegra/tegra2_emc.c b/arch/arm/mach-tegra/tegra2_emc.c
index 0f7ae6e90b5..5070d833bdd 100644
--- a/arch/arm/mach-tegra/tegra2_emc.c
+++ b/arch/arm/mach-tegra/tegra2_emc.c
@@ -16,14 +16,19 @@
*/
#include <linux/kernel.h>
+#include <linux/device.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/tegra_emc.h>
#include <mach/iomap.h>
#include "tegra2_emc.h"
+#include "fuse.h"
#ifdef CONFIG_TEGRA_EMC_SCALING_ENABLE
static bool emc_enable = true;
@@ -32,18 +37,17 @@ static bool emc_enable;
#endif
module_param(emc_enable, bool, 0644);
-static void __iomem *emc = IO_ADDRESS(TEGRA_EMC_BASE);
-static const struct tegra_emc_table *tegra_emc_table;
-static int tegra_emc_table_size;
+static struct platform_device *emc_pdev;
+static void __iomem *emc_regbase;
static inline void emc_writel(u32 val, unsigned long addr)
{
- writel(val, emc + addr);
+ writel(val, emc_regbase + addr);
}
static inline u32 emc_readl(unsigned long addr)
{
- return readl(emc + addr);
+ return readl(emc_regbase + addr);
}
static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
@@ -98,15 +102,15 @@ static const unsigned long emc_reg_addr[TEGRA_EMC_NUM_REGS] = {
/* Select the closest EMC rate that is higher than the requested rate */
long tegra_emc_round_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int best = -1;
unsigned long distance = ULONG_MAX;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
- if (!emc_enable)
- return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
pr_debug("%s: %lu\n", __func__, rate);
@@ -116,10 +120,10 @@ long tegra_emc_round_rate(unsigned long rate)
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++) {
- if (tegra_emc_table[i].rate >= rate &&
- (tegra_emc_table[i].rate - rate) < distance) {
- distance = tegra_emc_table[i].rate - rate;
+ for (i = 0; i < pdata->num_tables; i++) {
+ if (pdata->tables[i].rate >= rate &&
+ (pdata->tables[i].rate - rate) < distance) {
+ distance = pdata->tables[i].rate - rate;
best = i;
}
}
@@ -127,9 +131,9 @@ long tegra_emc_round_rate(unsigned long rate)
if (best < 0)
return -EINVAL;
- pr_debug("%s: using %lu\n", __func__, tegra_emc_table[best].rate);
+ pr_debug("%s: using %lu\n", __func__, pdata->tables[best].rate);
- return tegra_emc_table[best].rate * 2 * 1000;
+ return pdata->tables[best].rate * 2 * 1000;
}
/*
@@ -142,37 +146,211 @@ long tegra_emc_round_rate(unsigned long rate)
*/
int tegra_emc_set_rate(unsigned long rate)
{
+ struct tegra_emc_pdata *pdata;
int i;
int j;
- if (!tegra_emc_table)
+ if (!emc_pdev)
return -EINVAL;
+ pdata = emc_pdev->dev.platform_data;
+
/*
* The EMC clock rate is twice the bus rate, and the bus rate is
* measured in kHz
*/
rate = rate / 2 / 1000;
- for (i = 0; i < tegra_emc_table_size; i++)
- if (tegra_emc_table[i].rate == rate)
+ for (i = 0; i < pdata->num_tables; i++)
+ if (pdata->tables[i].rate == rate)
break;
- if (i >= tegra_emc_table_size)
+ if (i >= pdata->num_tables)
return -EINVAL;
pr_debug("%s: setting to %lu\n", __func__, rate);
for (j = 0; j < TEGRA_EMC_NUM_REGS; j++)
- emc_writel(tegra_emc_table[i].regs[j], emc_reg_addr[j]);
+ emc_writel(pdata->tables[i].regs[j], emc_reg_addr[j]);
- emc_readl(tegra_emc_table[i].regs[TEGRA_EMC_NUM_REGS - 1]);
+ emc_readl(pdata->tables[i].regs[TEGRA_EMC_NUM_REGS - 1]);
return 0;
}
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size)
+#ifdef CONFIG_OF
+static struct device_node *tegra_emc_ramcode_devnode(struct device_node *np)
+{
+ struct device_node *iter;
+ u32 reg;
+
+ for_each_child_of_node(np, iter) {
+ if (of_property_read_u32(np, "nvidia,ram-code", &reg))
+ continue;
+ if (reg == tegra_bct_strapping)
+ return of_node_get(iter);
+ }
+
+ return NULL;
+}
+
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+ struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct device_node *tnp, *iter;
+ struct tegra_emc_pdata *pdata;
+ int ret, i, num_tables;
+
+ if (!np)
+ return NULL;
+
+ if (of_find_property(np, "nvidia,use-ram-code", NULL)) {
+ tnp = tegra_emc_ramcode_devnode(np);
+ if (!tnp)
+ dev_warn(&pdev->dev,
+ "can't find emc table for ram-code 0x%02x\n",
+ tegra_bct_strapping);
+ } else
+ tnp = of_node_get(np);
+
+ if (!tnp)
+ return NULL;
+
+ num_tables = 0;
+ for_each_child_of_node(tnp, iter)
+ if (of_device_is_compatible(iter, "nvidia,tegra20-emc-table"))
+ num_tables++;
+
+ if (!num_tables) {
+ pdata = NULL;
+ goto out;
+ }
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ pdata->tables = devm_kzalloc(&pdev->dev,
+ sizeof(*pdata->tables) * num_tables,
+ GFP_KERNEL);
+
+ i = 0;
+ for_each_child_of_node(tnp, iter) {
+ u32 prop;
+
+ ret = of_property_read_u32(iter, "clock-frequency", &prop);
+ if (ret) {
+ dev_err(&pdev->dev, "no clock-frequency in %s\n",
+ iter->full_name);
+ continue;
+ }
+ pdata->tables[i].rate = prop;
+
+ ret = of_property_read_u32_array(iter, "nvidia,emc-registers",
+ pdata->tables[i].regs,
+ TEGRA_EMC_NUM_REGS);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "malformed emc-registers property in %s\n",
+ iter->full_name);
+ continue;
+ }
+
+ i++;
+ }
+ pdata->num_tables = i;
+
+out:
+ of_node_put(tnp);
+ return pdata;
+}
+#else
+static struct tegra_emc_pdata *tegra_emc_dt_parse_pdata(
+ struct platform_device *pdev)
+{
+ return NULL;
+}
+#endif
+
+static struct tegra_emc_pdata __devinit *tegra_emc_fill_pdata(struct platform_device *pdev)
+{
+ struct clk *c = clk_get_sys(NULL, "emc");
+ struct tegra_emc_pdata *pdata;
+ unsigned long khz;
+ int i;
+
+ WARN_ON(pdev->dev.platform_data);
+ BUG_ON(IS_ERR_OR_NULL(c));
+
+ pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+ pdata->tables = devm_kzalloc(&pdev->dev, sizeof(*pdata->tables),
+ GFP_KERNEL);
+
+ pdata->tables[0].rate = clk_get_rate(c) / 2 / 1000;
+
+ for (i = 0; i < TEGRA_EMC_NUM_REGS; i++)
+ pdata->tables[0].regs[i] = emc_readl(emc_reg_addr[i]);
+
+ pdata->num_tables = 1;
+
+ khz = pdata->tables[0].rate;
+ dev_info(&pdev->dev, "no tables provided, using %ld kHz emc, "
+ "%ld kHz mem\n", khz * 2, khz);
+
+ return pdata;
+}
+
+static int __devinit tegra_emc_probe(struct platform_device *pdev)
+{
+ struct tegra_emc_pdata *pdata;
+ struct resource *res;
+
+ if (!emc_enable) {
+ dev_err(&pdev->dev, "disabled per module parameter\n");
+ return -ENODEV;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "missing register base\n");
+ return -ENOMEM;
+ }
+
+ emc_regbase = devm_request_and_ioremap(&pdev->dev, res);
+ if (!emc_regbase) {
+ dev_err(&pdev->dev, "failed to remap registers\n");
+ return -ENOMEM;
+ }
+
+ pdata = pdev->dev.platform_data;
+
+ if (!pdata)
+ pdata = tegra_emc_dt_parse_pdata(pdev);
+
+ if (!pdata)
+ pdata = tegra_emc_fill_pdata(pdev);
+
+ pdev->dev.platform_data = pdata;
+
+ emc_pdev = pdev;
+
+ return 0;
+}
+
+static struct of_device_id tegra_emc_of_match[] __devinitdata = {
+ { .compatible = "nvidia,tegra20-emc", },
+ { },
+};
+
+static struct platform_driver tegra_emc_driver = {
+ .driver = {
+ .name = "tegra-emc",
+ .owner = THIS_MODULE,
+ .of_match_table = tegra_emc_of_match,
+ },
+ .probe = tegra_emc_probe,
+};
+
+static int __init tegra_emc_init(void)
{
- tegra_emc_table = table;
- tegra_emc_table_size = table_size;
+ return platform_driver_register(&tegra_emc_driver);
}
+device_initcall(tegra_emc_init);
diff --git a/arch/arm/mach-tegra/tegra2_emc.h b/arch/arm/mach-tegra/tegra2_emc.h
index 19f08cb3160..f61409b54cb 100644
--- a/arch/arm/mach-tegra/tegra2_emc.h
+++ b/arch/arm/mach-tegra/tegra2_emc.h
@@ -15,13 +15,10 @@
*
*/
-#define TEGRA_EMC_NUM_REGS 46
-
-struct tegra_emc_table {
- unsigned long rate;
- u32 regs[TEGRA_EMC_NUM_REGS];
-};
+#ifndef __MACH_TEGRA_TEGRA2_EMC_H_
+#define __MACH_TEGRA_TEGRA2_EMC_H
int tegra_emc_set_rate(unsigned long rate);
long tegra_emc_round_rate(unsigned long rate);
-void tegra_init_emc(const struct tegra_emc_table *table, int table_size);
+
+#endif
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index b4c6926a700..b9865605da0 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -94,19 +94,9 @@ static struct amba_pl011_data uart0_plat_data = {
#endif
};
-static struct amba_device uart0_device = {
- .dev = {
- .coherent_dma_mask = ~0,
- .init_name = "uart0", /* Slow device at 0x3000 offset */
- .platform_data = &uart0_plat_data,
- },
- .res = {
- .start = U300_UART0_BASE,
- .end = U300_UART0_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_U300_UART0, NO_IRQ },
-};
+/* Slow device at 0x3000 offset */
+static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE,
+ { IRQ_U300_UART0 }, &uart0_plat_data);
/* The U335 have an additional UART1 on the APP CPU */
#ifdef CONFIG_MACH_U300_BS335
@@ -118,71 +108,28 @@ static struct amba_pl011_data uart1_plat_data = {
#endif
};
-static struct amba_device uart1_device = {
- .dev = {
- .coherent_dma_mask = ~0,
- .init_name = "uart1", /* Fast device at 0x7000 offset */
- .platform_data = &uart1_plat_data,
- },
- .res = {
- .start = U300_UART1_BASE,
- .end = U300_UART1_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = { IRQ_U300_UART1, NO_IRQ },
-};
+/* Fast device at 0x7000 offset */
+static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE,
+ { IRQ_U300_UART1 }, &uart1_plat_data);
#endif
-static struct amba_device pl172_device = {
- .dev = {
- .init_name = "pl172", /* AHB device at 0x4000 offset */
- .platform_data = NULL,
- },
- .res = {
- .start = U300_EMIF_CFG_BASE,
- .end = U300_EMIF_CFG_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
-};
+/* AHB device at 0x4000 offset */
+static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL);
/*
* Everything within this next ifdef deals with external devices connected to
* the APP SPI bus.
*/
-static struct amba_device pl022_device = {
- .dev = {
- .coherent_dma_mask = ~0,
- .init_name = "pl022", /* Fast device at 0x6000 offset */
- },
- .res = {
- .start = U300_SPI_BASE,
- .end = U300_SPI_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_U300_SPI, NO_IRQ },
- /*
- * This device has a DMA channel but the Linux driver does not use
- * it currently.
- */
-};
+/* Fast device at 0x6000 offset */
+static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE,
+ { IRQ_U300_SPI }, NULL);
-static struct amba_device mmcsd_device = {
- .dev = {
- .init_name = "mmci", /* Fast device at 0x1000 offset */
- .platform_data = NULL, /* Added later */
- },
- .res = {
- .start = U300_MMCSD_BASE,
- .end = U300_MMCSD_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 },
- /*
- * This device has a DMA channel but the Linux driver does not use
- * it currently.
- */
-};
+/* Fast device at 0x1000 offset */
+#define U300_MMCSD_IRQS { IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }
+
+static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE,
+ U300_MMCSD_IRQS, NULL);
/*
* The order of device declaration may be important, since some devices
diff --git a/arch/arm/mach-u300/include/mach/system.h b/arch/arm/mach-u300/include/mach/system.h
deleted file mode 100644
index 574d46e3829..00000000000
--- a/arch/arm/mach-u300/include/mach/system.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- *
- * arch/arm/mach-u300/include/mach/system.h
- *
- *
- * Copyright (C) 2007-2009 ST-Ericsson AB
- * License terms: GNU General Public License (GPL) version 2
- * System shutdown and reset functions.
- * Author: Linus Walleij <linus.walleij@stericsson.com>
- */
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
diff --git a/arch/arm/mach-ux500/devices-common.c b/arch/arm/mach-ux500/devices-common.c
index c563e5418d8..898a64517b0 100644
--- a/arch/arm/mach-ux500/devices-common.c
+++ b/arch/arm/mach-ux500/devices-common.c
@@ -26,29 +26,22 @@ dbx500_add_amba_device(const char *name, resource_size_t base,
struct amba_device *dev;
int ret;
- dev = kzalloc(sizeof *dev, GFP_KERNEL);
+ dev = amba_device_alloc(name, base, SZ_4K);
if (!dev)
return ERR_PTR(-ENOMEM);
- dev->dev.init_name = name;
-
- dev->res.start = base;
- dev->res.end = base + SZ_4K - 1;
- dev->res.flags = IORESOURCE_MEM;
-
dev->dma_mask = DMA_BIT_MASK(32);
dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
dev->irq[0] = irq;
- dev->irq[1] = NO_IRQ;
dev->periphid = periphid;
dev->dev.platform_data = pdata;
- ret = amba_device_register(dev, &iomem_resource);
+ ret = amba_device_add(dev, &iomem_resource);
if (ret) {
- kfree(dev);
+ amba_device_put(dev);
return ERR_PTR(ret);
}
diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h
deleted file mode 100644
index 258e5c919c2..00000000000
--- a/arch/arm/mach-ux500/include/mach/system.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright (C) 2009 ST-Ericsson.
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks
- */
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 02b7b9303f3..0968772aedb 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -98,8 +98,11 @@ static const struct of_device_id sic_of_match[] __initconst = {
void __init versatile_init_irq(void)
{
- vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0);
- irq_domain_generate_simple(vic_of_match, VERSATILE_VIC_BASE, IRQ_VIC_START);
+ struct device_node *np;
+
+ np = of_find_matching_node_by_address(NULL, vic_of_match,
+ VERSATILE_VIC_BASE);
+ __vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0, 0, np);
writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);
@@ -582,58 +585,58 @@ static struct pl022_ssp_controller ssp0_plat_data = {
.num_chipselect = 1,
};
-#define AACI_IRQ { IRQ_AACI, NO_IRQ }
+#define AACI_IRQ { IRQ_AACI }
#define MMCI0_IRQ { IRQ_MMCI0A,IRQ_SIC_MMCI0B }
-#define KMI0_IRQ { IRQ_SIC_KMI0, NO_IRQ }
-#define KMI1_IRQ { IRQ_SIC_KMI1, NO_IRQ }
+#define KMI0_IRQ { IRQ_SIC_KMI0 }
+#define KMI1_IRQ { IRQ_SIC_KMI1 }
/*
* These devices are connected directly to the multi-layer AHB switch
*/
-#define SMC_IRQ { NO_IRQ, NO_IRQ }
-#define MPMC_IRQ { NO_IRQ, NO_IRQ }
-#define CLCD_IRQ { IRQ_CLCDINT, NO_IRQ }
-#define DMAC_IRQ { IRQ_DMAINT, NO_IRQ }
+#define SMC_IRQ { }
+#define MPMC_IRQ { }
+#define CLCD_IRQ { IRQ_CLCDINT }
+#define DMAC_IRQ { IRQ_DMAINT }
/*
* These devices are connected via the core APB bridge
*/
-#define SCTL_IRQ { NO_IRQ, NO_IRQ }
-#define WATCHDOG_IRQ { IRQ_WDOGINT, NO_IRQ }
-#define GPIO0_IRQ { IRQ_GPIOINT0, NO_IRQ }
-#define GPIO1_IRQ { IRQ_GPIOINT1, NO_IRQ }
-#define RTC_IRQ { IRQ_RTCINT, NO_IRQ }
+#define SCTL_IRQ { }
+#define WATCHDOG_IRQ { IRQ_WDOGINT }
+#define GPIO0_IRQ { IRQ_GPIOINT0 }
+#define GPIO1_IRQ { IRQ_GPIOINT1 }
+#define RTC_IRQ { IRQ_RTCINT }
/*
* These devices are connected via the DMA APB bridge
*/
-#define SCI_IRQ { IRQ_SCIINT, NO_IRQ }
-#define UART0_IRQ { IRQ_UARTINT0, NO_IRQ }
-#define UART1_IRQ { IRQ_UARTINT1, NO_IRQ }
-#define UART2_IRQ { IRQ_UARTINT2, NO_IRQ }
-#define SSP_IRQ { IRQ_SSPINT, NO_IRQ }
+#define SCI_IRQ { IRQ_SCIINT }
+#define UART0_IRQ { IRQ_UARTINT0 }
+#define UART1_IRQ { IRQ_UARTINT1 }
+#define UART2_IRQ { IRQ_UARTINT2 }
+#define SSP_IRQ { IRQ_SSPINT }
/* FPGA Primecells */
-AMBA_DEVICE(aaci, "fpga:04", AACI, NULL);
-AMBA_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data);
-AMBA_DEVICE(kmi0, "fpga:06", KMI0, NULL);
-AMBA_DEVICE(kmi1, "fpga:07", KMI1, NULL);
+APB_DEVICE(aaci, "fpga:04", AACI, NULL);
+APB_DEVICE(mmc0, "fpga:05", MMCI0, &mmc0_plat_data);
+APB_DEVICE(kmi0, "fpga:06", KMI0, NULL);
+APB_DEVICE(kmi1, "fpga:07", KMI1, NULL);
/* DevChip Primecells */
-AMBA_DEVICE(smc, "dev:00", SMC, NULL);
-AMBA_DEVICE(mpmc, "dev:10", MPMC, NULL);
-AMBA_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data);
-AMBA_DEVICE(dmac, "dev:30", DMAC, NULL);
-AMBA_DEVICE(sctl, "dev:e0", SCTL, NULL);
-AMBA_DEVICE(wdog, "dev:e1", WATCHDOG, NULL);
-AMBA_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data);
-AMBA_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
-AMBA_DEVICE(rtc, "dev:e8", RTC, NULL);
-AMBA_DEVICE(sci0, "dev:f0", SCI, NULL);
-AMBA_DEVICE(uart0, "dev:f1", UART0, NULL);
-AMBA_DEVICE(uart1, "dev:f2", UART1, NULL);
-AMBA_DEVICE(uart2, "dev:f3", UART2, NULL);
-AMBA_DEVICE(ssp0, "dev:f4", SSP, &ssp0_plat_data);
+AHB_DEVICE(smc, "dev:00", SMC, NULL);
+AHB_DEVICE(mpmc, "dev:10", MPMC, NULL);
+AHB_DEVICE(clcd, "dev:20", CLCD, &clcd_plat_data);
+AHB_DEVICE(dmac, "dev:30", DMAC, NULL);
+APB_DEVICE(sctl, "dev:e0", SCTL, NULL);
+APB_DEVICE(wdog, "dev:e1", WATCHDOG, NULL);
+APB_DEVICE(gpio0, "dev:e4", GPIO0, &gpio0_plat_data);
+APB_DEVICE(gpio1, "dev:e5", GPIO1, &gpio1_plat_data);
+APB_DEVICE(rtc, "dev:e8", RTC, NULL);
+APB_DEVICE(sci0, "dev:f0", SCI, NULL);
+APB_DEVICE(uart0, "dev:f1", UART0, NULL);
+APB_DEVICE(uart1, "dev:f2", UART1, NULL);
+APB_DEVICE(uart2, "dev:f3", UART2, NULL);
+APB_DEVICE(ssp0, "dev:f4", SSP, &ssp0_plat_data);
static struct amba_device *amba_devs[] __initdata = {
&dmac_device,
diff --git a/arch/arm/mach-versatile/core.h b/arch/arm/mach-versatile/core.h
index 2ef2f555f31..683e60776a8 100644
--- a/arch/arm/mach-versatile/core.h
+++ b/arch/arm/mach-versatile/core.h
@@ -36,20 +36,10 @@ extern unsigned int mmc_status(struct device *dev);
extern struct of_dev_auxdata versatile_auxdata_lookup[];
#endif
-#define AMBA_DEVICE(name,busid,base,plat) \
-static struct amba_device name##_device = { \
- .dev = { \
- .coherent_dma_mask = ~0, \
- .init_name = busid, \
- .platform_data = plat, \
- }, \
- .res = { \
- .start = VERSATILE_##base##_BASE, \
- .end = (VERSATILE_##base##_BASE) + SZ_4K - 1,\
- .flags = IORESOURCE_MEM, \
- }, \
- .dma_mask = ~0, \
- .irq = base##_IRQ, \
-}
+#define APB_DEVICE(name, busid, base, plat) \
+static AMBA_APB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)
+
+#define AHB_DEVICE(name, busid, base, plat) \
+static AMBA_AHB_DEVICE(name, busid, 0, VERSATILE_##base##_BASE, base##_IRQ, plat)
#endif
diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h
deleted file mode 100644
index f3fa347895f..00000000000
--- a/arch/arm/mach-versatile/include/mach/system.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/mach-versatile/include/mach/system.h
- *
- * Copyright (C) 2003 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks
- */
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-versatile/versatile_pb.c b/arch/arm/mach-versatile/versatile_pb.c
index 9581c197500..19738331bd3 100644
--- a/arch/arm/mach-versatile/versatile_pb.c
+++ b/arch/arm/mach-versatile/versatile_pb.c
@@ -58,28 +58,28 @@ static struct pl061_platform_data gpio3_plat_data = {
.irq_base = IRQ_GPIO3_START,
};
-#define UART3_IRQ { IRQ_SIC_UART3, NO_IRQ }
-#define SCI1_IRQ { IRQ_SIC_SCI3, NO_IRQ }
+#define UART3_IRQ { IRQ_SIC_UART3 }
+#define SCI1_IRQ { IRQ_SIC_SCI3 }
#define MMCI1_IRQ { IRQ_MMCI1A, IRQ_SIC_MMCI1B }
/*
* These devices are connected via the core APB bridge
*/
-#define GPIO2_IRQ { IRQ_GPIOINT2, NO_IRQ }
-#define GPIO3_IRQ { IRQ_GPIOINT3, NO_IRQ }
+#define GPIO2_IRQ { IRQ_GPIOINT2 }
+#define GPIO3_IRQ { IRQ_GPIOINT3 }
/*
* These devices are connected via the DMA APB bridge
*/
/* FPGA Primecells */
-AMBA_DEVICE(uart3, "fpga:09", UART3, NULL);
-AMBA_DEVICE(sci1, "fpga:0a", SCI1, NULL);
-AMBA_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data);
+APB_DEVICE(uart3, "fpga:09", UART3, NULL);
+APB_DEVICE(sci1, "fpga:0a", SCI1, NULL);
+APB_DEVICE(mmc1, "fpga:0b", MMCI1, &mmc1_plat_data);
/* DevChip Primecells */
-AMBA_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
-AMBA_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data);
+APB_DEVICE(gpio2, "dev:e6", GPIO2, &gpio2_plat_data);
+APB_DEVICE(gpio3, "dev:e7", GPIO3, &gpio3_plat_data);
static struct amba_device *amba_devs[] __initdata = {
&uart3_device,
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h
index f4397159c17..9f0f2827c71 100644
--- a/arch/arm/mach-vexpress/core.h
+++ b/arch/arm/mach-vexpress/core.h
@@ -1,19 +1,2 @@
#define __MMIO_P2V(x) (((x) & 0xfffff) | (((x) & 0x0f000000) >> 4) | 0xf8000000)
#define MMIO_P2V(x) ((void __iomem *)__MMIO_P2V(x))
-
-#define AMBA_DEVICE(name,busid,base,plat) \
-struct amba_device name##_device = { \
- .dev = { \
- .coherent_dma_mask = ~0UL, \
- .init_name = busid, \
- .platform_data = plat, \
- }, \
- .res = { \
- .start = base, \
- .end = base + SZ_4K - 1, \
- .flags = IORESOURCE_MEM, \
- }, \
- .dma_mask = ~0UL, \
- .irq = IRQ_##base, \
- /* .dma = DMA_##base,*/ \
-}
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c
index b1e87c184e5..1b1d2e4892b 100644
--- a/arch/arm/mach-vexpress/ct-ca9x4.c
+++ b/arch/arm/mach-vexpress/ct-ca9x4.c
@@ -109,10 +109,10 @@ static struct clcd_board ct_ca9x4_clcd_data = {
.remove = versatile_clcd_remove_dma,
};
-static AMBA_DEVICE(clcd, "ct:clcd", CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
-static AMBA_DEVICE(dmc, "ct:dmc", CT_CA9X4_DMC, NULL);
-static AMBA_DEVICE(smc, "ct:smc", CT_CA9X4_SMC, NULL);
-static AMBA_DEVICE(gpio, "ct:gpio", CT_CA9X4_GPIO, NULL);
+static AMBA_AHB_DEVICE(clcd, "ct:clcd", 0, CT_CA9X4_CLCDC, IRQ_CT_CA9X4_CLCDC, &ct_ca9x4_clcd_data);
+static AMBA_APB_DEVICE(dmc, "ct:dmc", 0, CT_CA9X4_DMC, IRQ_CT_CA9X4_DMC, NULL);
+static AMBA_APB_DEVICE(smc, "ct:smc", 0, CT_CA9X4_SMC, IRQ_CT_CA9X4_SMC, NULL);
+static AMBA_APB_DEVICE(gpio, "ct:gpio", 0, CT_CA9X4_GPIO, IRQ_CT_CA9X4_GPIO, NULL);
static struct amba_device *ct_ca9x4_amba_devs[] __initdata = {
&clcd_device,
diff --git a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
index a34d3d4faae..a40468f3b93 100644
--- a/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
+++ b/arch/arm/mach-vexpress/include/mach/ct-ca9x4.h
@@ -35,7 +35,7 @@
* Interrupts. Those in {} are for AMBA devices
*/
#define IRQ_CT_CA9X4_CLCDC { 76 }
-#define IRQ_CT_CA9X4_DMC { -1 }
+#define IRQ_CT_CA9X4_DMC { 0 }
#define IRQ_CT_CA9X4_SMC { 77, 78 }
#define IRQ_CT_CA9X4_TIMER0 80
#define IRQ_CT_CA9X4_TIMER1 81
diff --git a/arch/arm/mach-vexpress/include/mach/system.h b/arch/arm/mach-vexpress/include/mach/system.h
deleted file mode 100644
index f653a8e265b..00000000000
--- a/arch/arm/mach-vexpress/include/mach/system.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * arch/arm/mach-vexpress/include/mach/system.h
- *
- * Copyright (C) 2003 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks
- */
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c
index b4a28ca0e50..ad64f97a200 100644
--- a/arch/arm/mach-vexpress/v2m.c
+++ b/arch/arm/mach-vexpress/v2m.c
@@ -266,16 +266,16 @@ static struct mmci_platform_data v2m_mmci_data = {
.status = v2m_mmci_status,
};
-static AMBA_DEVICE(aaci, "mb:aaci", V2M_AACI, NULL);
-static AMBA_DEVICE(mmci, "mb:mmci", V2M_MMCI, &v2m_mmci_data);
-static AMBA_DEVICE(kmi0, "mb:kmi0", V2M_KMI0, NULL);
-static AMBA_DEVICE(kmi1, "mb:kmi1", V2M_KMI1, NULL);
-static AMBA_DEVICE(uart0, "mb:uart0", V2M_UART0, NULL);
-static AMBA_DEVICE(uart1, "mb:uart1", V2M_UART1, NULL);
-static AMBA_DEVICE(uart2, "mb:uart2", V2M_UART2, NULL);
-static AMBA_DEVICE(uart3, "mb:uart3", V2M_UART3, NULL);
-static AMBA_DEVICE(wdt, "mb:wdt", V2M_WDT, NULL);
-static AMBA_DEVICE(rtc, "mb:rtc", V2M_RTC, NULL);
+static AMBA_APB_DEVICE(aaci, "mb:aaci", 0, V2M_AACI, IRQ_V2M_AACI, NULL);
+static AMBA_APB_DEVICE(mmci, "mb:mmci", 0, V2M_MMCI, IRQ_V2M_MMCI, &v2m_mmci_data);
+static AMBA_APB_DEVICE(kmi0, "mb:kmi0", 0, V2M_KMI0, IRQ_V2M_KMI0, NULL);
+static AMBA_APB_DEVICE(kmi1, "mb:kmi1", 0, V2M_KMI1, IRQ_V2M_KMI1, NULL);
+static AMBA_APB_DEVICE(uart0, "mb:uart0", 0, V2M_UART0, IRQ_V2M_UART0, NULL);
+static AMBA_APB_DEVICE(uart1, "mb:uart1", 0, V2M_UART1, IRQ_V2M_UART1, NULL);
+static AMBA_APB_DEVICE(uart2, "mb:uart2", 0, V2M_UART2, IRQ_V2M_UART2, NULL);
+static AMBA_APB_DEVICE(uart3, "mb:uart3", 0, V2M_UART3, IRQ_V2M_UART3, NULL);
+static AMBA_APB_DEVICE(wdt, "mb:wdt", 0, V2M_WDT, IRQ_V2M_WDT, NULL);
+static AMBA_APB_DEVICE(rtc, "mb:rtc", 0, V2M_RTC, IRQ_V2M_RTC, NULL);
static struct amba_device *v2m_amba_devs[] __initdata = {
&aaci_device,
diff --git a/arch/arm/mach-vt8500/include/mach/system.h b/arch/arm/mach-vt8500/include/mach/system.h
index d6c757eaf26..58fa8010ee6 100644
--- a/arch/arm/mach-vt8500/include/mach/system.h
+++ b/arch/arm/mach-vt8500/include/mach/system.h
@@ -7,11 +7,6 @@
/* PM Software Reset request register */
#define VT8500_PMSR_VIRT 0xf8130060
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
static inline void arch_reset(char mode, const char *cmd)
{
writel(1, VT8500_PMSR_VIRT);
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c
index 78110befb7a..db82568a998 100644
--- a/arch/arm/mach-w90x900/dev.c
+++ b/arch/arm/mach-w90x900/dev.c
@@ -530,6 +530,7 @@ static struct platform_device *nuc900_public_dev[] __initdata = {
void __init nuc900_board_init(struct platform_device **device, int size)
{
+ disable_hlt();
platform_add_devices(device, size);
platform_add_devices(nuc900_public_dev, ARRAY_SIZE(nuc900_public_dev));
spi_register_board_info(nuc900_spi_board_info,
diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h
deleted file mode 100644
index 2aaeb931161..00000000000
--- a/arch/arm/mach-w90x900/include/mach/system.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * arch/arm/mach-w90x900/include/mach/system.h
- *
- * Copyright (c) 2008 Nuvoton technology corporation
- * All rights reserved.
- *
- * Wan ZongShun <mcuos.com@gmail.com>
- *
- * Based on arch/arm/mach-s3c2410/include/mach/system.h
- *
- * 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.
- *
- */
-static void arch_idle(void)
-{
-}
diff --git a/arch/arm/mach-zynq/include/mach/system.h b/arch/arm/mach-zynq/include/mach/system.h
deleted file mode 100644
index 8e88e0b8d2b..00000000000
--- a/arch/arm/mach-zynq/include/mach/system.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* arch/arm/mach-zynq/include/mach/system.h
- *
- * Copyright (C) 2011 Xilinx
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __MACH_SYSTEM_H__
-#define __MACH_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 1a3ca248816..7edef912163 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -631,7 +631,8 @@ comment "Processor Features"
config ARM_LPAE
bool "Support for the Large Physical Address Extension"
- depends on MMU && CPU_V7
+ depends on MMU && CPU_32v7 && !CPU_32v6 && !CPU_32v5 && \
+ !CPU_32v4 && !CPU_32v3
help
Say Y if you have an ARMv7 processor supporting the LPAE page
table format and you would like to access memory beyond the
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S
index 7a24d39661f..a655d3da386 100644
--- a/arch/arm/mm/cache-v7.S
+++ b/arch/arm/mm/cache-v7.S
@@ -55,7 +55,7 @@ loop1:
cmp r1, #2 @ see what cache we have at this level
blt skip @ skip if no cache, or just i-cache
#ifdef CONFIG_PREEMPT
- save_and_disable_irqs r9 @ make cssr&csidr read atomic
+ save_and_disable_irqs_notrace r9 @ make cssr&csidr read atomic
#endif
mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
isb @ isb to sych the new cssr&csidr
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index 8cced35009b..0e51fc36b5b 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -73,13 +73,13 @@ static ssize_t audmux_read_file(struct file *file, char __user *user_buf,
return -ENOMEM;
if (audmux_clk)
- clk_enable(audmux_clk);
+ clk_prepare_enable(audmux_clk);
ptcr = readl(audmux_base + MXC_AUDMUX_V2_PTCR(port));
pdcr = readl(audmux_base + MXC_AUDMUX_V2_PDCR(port));
if (audmux_clk)
- clk_disable(audmux_clk);
+ clk_disable_unprepare(audmux_clk);
ret = snprintf(buf, PAGE_SIZE, "PDCR: %08x\nPTCR: %08x\n",
pdcr, ptcr);
@@ -172,13 +172,13 @@ int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
return -ENOSYS;
if (audmux_clk)
- clk_enable(audmux_clk);
+ clk_prepare_enable(audmux_clk);
writel(ptcr, audmux_base + MXC_AUDMUX_V2_PTCR(port));
writel(pdcr, audmux_base + MXC_AUDMUX_V2_PDCR(port));
if (audmux_clk)
- clk_disable(audmux_clk);
+ clk_disable_unprepare(audmux_clk);
return 0;
}
diff --git a/arch/arm/plat-mxc/devices/platform-ahci-imx.c b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
index d8a56aee521..ade4a1c4e2a 100644
--- a/arch/arm/plat-mxc/devices/platform-ahci-imx.c
+++ b/arch/arm/plat-mxc/devices/platform-ahci-imx.c
@@ -60,9 +60,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
dev_err(dev, "no sata clock.\n");
return PTR_ERR(sata_clk);
}
- ret = clk_enable(sata_clk);
+ ret = clk_prepare_enable(sata_clk);
if (ret) {
- dev_err(dev, "can't enable sata clock.\n");
+ dev_err(dev, "can't prepare/enable sata clock.\n");
goto put_sata_clk;
}
@@ -73,9 +73,9 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
ret = PTR_ERR(sata_ref_clk);
goto release_sata_clk;
}
- ret = clk_enable(sata_ref_clk);
+ ret = clk_prepare_enable(sata_ref_clk);
if (ret) {
- dev_err(dev, "can't enable sata ref clock.\n");
+ dev_err(dev, "can't prepare/enable sata ref clock.\n");
goto put_sata_ref_clk;
}
@@ -104,11 +104,11 @@ static int imx_sata_init(struct device *dev, void __iomem *addr)
return 0;
release_sata_ref_clk:
- clk_disable(sata_ref_clk);
+ clk_disable_unprepare(sata_ref_clk);
put_sata_ref_clk:
clk_put(sata_ref_clk);
release_sata_clk:
- clk_disable(sata_clk);
+ clk_disable_unprepare(sata_clk);
put_sata_clk:
clk_put(sata_clk);
@@ -117,10 +117,10 @@ put_sata_clk:
static void imx_sata_exit(struct device *dev)
{
- clk_disable(sata_ref_clk);
+ clk_disable_unprepare(sata_ref_clk);
clk_put(sata_ref_clk);
- clk_disable(sata_clk);
+ clk_disable_unprepare(sata_clk);
clk_put(sata_clk);
}
diff --git a/arch/arm/plat-mxc/epit.c b/arch/arm/plat-mxc/epit.c
index d3467f818c3..9129c9e7d53 100644
--- a/arch/arm/plat-mxc/epit.c
+++ b/arch/arm/plat-mxc/epit.c
@@ -203,7 +203,7 @@ static int __init epit_clockevent_init(struct clk *timer_clk)
void __init epit_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
{
- clk_enable(timer_clk);
+ clk_prepare_enable(timer_clk);
timer_base = base;
diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h
deleted file mode 100644
index 94b60dd4713..00000000000
--- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2005-2007 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.
- */
-
-#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
-#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
-
-#include <mach/hardware.h>
-
-/*
- * These symbols are used by drivers/net/cs89x0.c.
- * This is ugly as hell, but we have to provide them until
- * someone fixed the driver.
- */
-
-/* Base address of PBC controller */
-#define PBC_BASE_ADDRESS MX31_CS4_BASE_ADDR_VIRT
-/* Offsets for the PBC Controller register */
-
-/* Ethernet Controller IO base address */
-#define PBC_CS8900A_IOBASE 0x020000
-
-#define MXC_EXP_IO_BASE (MXC_BOARD_IRQ_START)
-
-#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
-
-#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 6e192c4a391..8ddda365f1a 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -24,7 +24,7 @@
#define UART_PADDR MX51_UART1_BASE_ADDR
#elif defined (CONFIG_DEBUG_IMX50_IMX53_UART)
#define UART_PADDR MX53_UART1_BASE_ADDR
-#elif defined (CONFIG_DEBUG_IMX6Q_UART)
+#elif defined (CONFIG_DEBUG_IMX6Q_UART4)
#define UART_PADDR MX6Q_UART4_BASE_ADDR
#endif
diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h
index 233d0a5e2d6..1b9080385b4 100644
--- a/arch/arm/plat-mxc/include/mach/dma.h
+++ b/arch/arm/plat-mxc/include/mach/dma.h
@@ -60,8 +60,7 @@ static inline int imx_dma_is_ipu(struct dma_chan *chan)
static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
{
- return !strcmp(dev_name(chan->device->dev), "imx31-sdma") ||
- !strcmp(dev_name(chan->device->dev), "imx35-sdma") ||
+ return strstr(dev_name(chan->device->dev), "sdma") ||
!strcmp(dev_name(chan->device->dev), "imx-dma");
}
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
deleted file mode 100644
index 13ad0df2e86..00000000000
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 1999 ARM Limited
- * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2004-2008 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#ifndef __ASM_ARCH_MXC_SYSTEM_H__
-#define __ASM_ARCH_MXC_SYSTEM_H__
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
index e032717f7d0..c0cab2270dd 100644
--- a/arch/arm/plat-mxc/pwm.c
+++ b/arch/arm/plat-mxc/pwm.c
@@ -132,7 +132,7 @@ int pwm_enable(struct pwm_device *pwm)
int rc = 0;
if (!pwm->clk_enabled) {
- rc = clk_enable(pwm->clk);
+ rc = clk_prepare_enable(pwm->clk);
if (!rc)
pwm->clk_enabled = 1;
}
@@ -145,7 +145,7 @@ void pwm_disable(struct pwm_device *pwm)
writel(0, pwm->mmio_base + MX3_PWMCR);
if (pwm->clk_enabled) {
- clk_disable(pwm->clk);
+ clk_disable_unprepare(pwm->clk);
pwm->clk_enabled = 0;
}
}
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index 3599bf2cfd4..f30dcacbbd0 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -48,7 +48,7 @@ void mxc_restart(char mode, const char *cmd)
clk = clk_get_sys("imx2-wdt.0", NULL);
if (!IS_ERR(clk))
- clk_enable(clk);
+ clk_prepare_enable(clk);
wcr_enable = (1 << 2);
}
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 1c96cdb4c35..7daf7c9a413 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -283,7 +283,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
{
uint32_t tctl_val;
- clk_enable(timer_clk);
+ clk_prepare_enable(timer_clk);
timer_base = base;
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 06383b51e65..4de7d1e79e7 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -69,6 +69,7 @@ void __init omap_reserve(void)
omap_vram_reserve_sdram_memblock();
omap_dsp_reserve_sdram_memblock();
omap_secure_ram_reserve_memblock();
+ omap_barrier_reserve_memblock();
}
void __init omap_init_consistent_dma_size(void)
diff --git a/arch/arm/plat-omap/include/plat/omap-secure.h b/arch/arm/plat-omap/include/plat/omap-secure.h
index 3047ff923a6..8c7994ce986 100644
--- a/arch/arm/plat-omap/include/plat/omap-secure.h
+++ b/arch/arm/plat-omap/include/plat/omap-secure.h
@@ -10,4 +10,10 @@ static inline void omap_secure_ram_reserve_memblock(void)
{ }
#endif
+#ifdef CONFIG_OMAP4_ERRATA_I688
+extern int omap_barrier_reserve_memblock(void);
+#else
+static inline void omap_barrier_reserve_memblock(void)
+{ }
+#endif
#endif /* __OMAP_SECURE_H__ */
diff --git a/arch/arm/plat-omap/include/plat/system.h b/arch/arm/plat-omap/include/plat/system.h
deleted file mode 100644
index 8e5ebd74b12..00000000000
--- a/arch/arm/plat-omap/include/plat/system.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copied from arch/arm/mach-sa1100/include/mach/system.h
- * Copyright (c) 1999 Nicolas Pitre <nico@fluxnic.net>
- */
-#ifndef __ASM_ARCH_SYSTEM_H
-#define __ASM_ARCH_SYSTEM_H
-
-#include <asm/proc-fns.h>
-
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
-
-#endif
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index 21f1fda8b66..32a09931350 100644
--- a/arch/arm/plat-s3c24xx/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -32,6 +32,7 @@
#include <linux/io.h>
#include <mach/hardware.h>
+#include <mach/regs-clock.h>
#include <asm/irq.h>
#include <asm/cacheflush.h>
@@ -190,8 +191,34 @@ static unsigned long s3c24xx_read_idcode_v4(void)
return __raw_readl(S3C2410_GSTATUS1);
}
+static void s3c24xx_default_idle(void)
+{
+ unsigned long tmp;
+ int i;
+
+ /* idle the system by using the idle mode which will wait for an
+ * interrupt to happen before restarting the system.
+ */
+
+ /* Warning: going into idle state upsets jtag scanning */
+
+ __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
+ S3C2410_CLKCON);
+
+ /* the samsung port seems to do a loop and then unset idle.. */
+ for (i = 0; i < 50; i++)
+ tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
+
+ /* this bit is not cleared on re-start... */
+
+ __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
+ S3C2410_CLKCON);
+}
+
void __init s3c24xx_init_io(struct map_desc *mach_desc, int size)
{
+ arm_pm_idle = s3c24xx_default_idle;
+
/* initialise the io descriptors we need for initialisation */
iotable_init(mach_desc, size);
iotable_init(s3c_iodesc, ARRAY_SIZE(s3c_iodesc));
diff --git a/arch/arm/plat-samsung/include/plat/regs-rtc.h b/arch/arm/plat-samsung/include/plat/regs-rtc.h
index 30b7cc14cef..0f8263e93ee 100644
--- a/arch/arm/plat-samsung/include/plat/regs-rtc.h
+++ b/arch/arm/plat-samsung/include/plat/regs-rtc.h
@@ -18,51 +18,54 @@
#define S3C2410_INTP_ALM (1 << 1)
#define S3C2410_INTP_TIC (1 << 0)
-#define S3C2410_RTCCON S3C2410_RTCREG(0x40)
-#define S3C2410_RTCCON_RTCEN (1<<0)
-#define S3C2410_RTCCON_CLKSEL (1<<1)
-#define S3C2410_RTCCON_CNTSEL (1<<2)
-#define S3C2410_RTCCON_CLKRST (1<<3)
-#define S3C64XX_RTCCON_TICEN (1<<8)
+#define S3C2410_RTCCON S3C2410_RTCREG(0x40)
+#define S3C2410_RTCCON_RTCEN (1 << 0)
+#define S3C2410_RTCCON_CNTSEL (1 << 2)
+#define S3C2410_RTCCON_CLKRST (1 << 3)
+#define S3C2443_RTCCON_TICSEL (1 << 4)
+#define S3C64XX_RTCCON_TICEN (1 << 8)
-#define S3C64XX_RTCCON_TICMSK (0xF<<7)
-#define S3C64XX_RTCCON_TICSHT (7)
+#define S3C2410_TICNT S3C2410_RTCREG(0x44)
+#define S3C2410_TICNT_ENABLE (1 << 7)
-#define S3C2410_TICNT S3C2410_RTCREG(0x44)
-#define S3C2410_TICNT_ENABLE (1<<7)
+/* S3C2443: tick count is 15 bit wide
+ * TICNT[6:0] contains upper 7 bits
+ * TICNT1[7:0] contains lower 8 bits
+ */
+#define S3C2443_TICNT_PART(x) ((x & 0x7f00) >> 8)
+#define S3C2443_TICNT1 S3C2410_RTCREG(0x4C)
+#define S3C2443_TICNT1_PART(x) (x & 0xff)
-#define S3C2410_RTCALM S3C2410_RTCREG(0x50)
-#define S3C2410_RTCALM_ALMEN (1<<6)
-#define S3C2410_RTCALM_YEAREN (1<<5)
-#define S3C2410_RTCALM_MONEN (1<<4)
-#define S3C2410_RTCALM_DAYEN (1<<3)
-#define S3C2410_RTCALM_HOUREN (1<<2)
-#define S3C2410_RTCALM_MINEN (1<<1)
-#define S3C2410_RTCALM_SECEN (1<<0)
+/* S3C2416: tick count is 32 bit wide
+ * TICNT[6:0] contains bits [14:8]
+ * TICNT1[7:0] contains lower 8 bits
+ * TICNT2[16:0] contains upper 17 bits
+ */
+#define S3C2416_TICNT2 S3C2410_RTCREG(0x48)
+#define S3C2416_TICNT2_PART(x) ((x & 0xffff8000) >> 15)
-#define S3C2410_RTCALM_ALL \
- S3C2410_RTCALM_ALMEN | S3C2410_RTCALM_YEAREN | S3C2410_RTCALM_MONEN |\
- S3C2410_RTCALM_DAYEN | S3C2410_RTCALM_HOUREN | S3C2410_RTCALM_MINEN |\
- S3C2410_RTCALM_SECEN
+#define S3C2410_RTCALM S3C2410_RTCREG(0x50)
+#define S3C2410_RTCALM_ALMEN (1 << 6)
+#define S3C2410_RTCALM_YEAREN (1 << 5)
+#define S3C2410_RTCALM_MONEN (1 << 4)
+#define S3C2410_RTCALM_DAYEN (1 << 3)
+#define S3C2410_RTCALM_HOUREN (1 << 2)
+#define S3C2410_RTCALM_MINEN (1 << 1)
+#define S3C2410_RTCALM_SECEN (1 << 0)
+#define S3C2410_ALMSEC S3C2410_RTCREG(0x54)
+#define S3C2410_ALMMIN S3C2410_RTCREG(0x58)
+#define S3C2410_ALMHOUR S3C2410_RTCREG(0x5c)
-#define S3C2410_ALMSEC S3C2410_RTCREG(0x54)
-#define S3C2410_ALMMIN S3C2410_RTCREG(0x58)
-#define S3C2410_ALMHOUR S3C2410_RTCREG(0x5c)
-
-#define S3C2410_ALMDATE S3C2410_RTCREG(0x60)
-#define S3C2410_ALMMON S3C2410_RTCREG(0x64)
-#define S3C2410_ALMYEAR S3C2410_RTCREG(0x68)
-
-#define S3C2410_RTCRST S3C2410_RTCREG(0x6c)
-
-#define S3C2410_RTCSEC S3C2410_RTCREG(0x70)
-#define S3C2410_RTCMIN S3C2410_RTCREG(0x74)
-#define S3C2410_RTCHOUR S3C2410_RTCREG(0x78)
-#define S3C2410_RTCDATE S3C2410_RTCREG(0x7c)
-#define S3C2410_RTCDAY S3C2410_RTCREG(0x80)
-#define S3C2410_RTCMON S3C2410_RTCREG(0x84)
-#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88)
+#define S3C2410_ALMDATE S3C2410_RTCREG(0x60)
+#define S3C2410_ALMMON S3C2410_RTCREG(0x64)
+#define S3C2410_ALMYEAR S3C2410_RTCREG(0x68)
+#define S3C2410_RTCSEC S3C2410_RTCREG(0x70)
+#define S3C2410_RTCMIN S3C2410_RTCREG(0x74)
+#define S3C2410_RTCHOUR S3C2410_RTCREG(0x78)
+#define S3C2410_RTCDATE S3C2410_RTCREG(0x7c)
+#define S3C2410_RTCMON S3C2410_RTCREG(0x84)
+#define S3C2410_RTCYEAR S3C2410_RTCREG(0x88)
#endif /* __ASM_ARCH_REGS_RTC_H */
diff --git a/arch/arm/plat-samsung/include/plat/rtc-core.h b/arch/arm/plat-samsung/include/plat/rtc-core.h
new file mode 100644
index 00000000000..21d8594d37c
--- /dev/null
+++ b/arch/arm/plat-samsung/include/plat/rtc-core.h
@@ -0,0 +1,27 @@
+/* linux/arch/arm/plat-samsung/include/plat/rtc-core.h
+ *
+ * Copyright (c) 2011 Heiko Stuebner <heiko@sntech.de>
+ *
+ * Samsung RTC Controller core functions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __ASM_PLAT_RTC_CORE_H
+#define __ASM_PLAT_RTC_CORE_H __FILE__
+
+/* These functions are only for use with the core support code, such as
+ * the cpu specific initialisation code
+ */
+
+/* re-define device name depending on support. */
+static inline void s3c_rtc_setname(char *name)
+{
+#if defined(CONFIG_SAMSUNG_DEV_RTC) || defined(CONFIG_PLAT_S3C24XX)
+ s3c_device_rtc.name = name;
+#endif
+}
+
+#endif /* __ASM_PLAT_RTC_CORE_H */
diff --git a/arch/arm/plat-spear/include/plat/system.h b/arch/arm/plat-spear/include/plat/system.h
deleted file mode 100644
index 86c6f83b44c..00000000000
--- a/arch/arm/plat-spear/include/plat/system.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/plat-spear/include/plat/system.h
- *
- * SPEAr platform specific architecture functions
- *
- * Copyright (C) 2009 ST Microelectronics
- * Viresh Kumar<viresh.kumar@st.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2. This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
- */
-
-#ifndef __PLAT_SYSTEM_H
-#define __PLAT_SYSTEM_H
-
-static inline void arch_idle(void)
-{
- /*
- * This should do all the clock switching
- * and wait for interrupt tricks
- */
- cpu_do_idle();
-}
-
-#endif /* __PLAT_SYSTEM_H */
diff --git a/arch/avr32/mach-at32ap/include/mach/cpu.h b/arch/avr32/mach-at32ap/include/mach/cpu.h
index 8181293115e..16a24b14146 100644
--- a/arch/avr32/mach-at32ap/include/mach/cpu.h
+++ b/arch/avr32/mach-at32ap/include/mach/cpu.h
@@ -30,9 +30,6 @@
#define cpu_is_at91sam9261() (0)
#define cpu_is_at91sam9263() (0)
#define cpu_is_at91sam9rl() (0)
-#define cpu_is_at91cap9() (0)
-#define cpu_is_at91cap9_revB() (0)
-#define cpu_is_at91cap9_revC() (0)
#define cpu_is_at91sam9g10() (0)
#define cpu_is_at91sam9g20() (0)
#define cpu_is_at91sam9g45() (0)
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
index 26e67f0f005..3c64b2894c1 100644
--- a/arch/c6x/Kconfig
+++ b/arch/c6x/Kconfig
@@ -12,6 +12,7 @@ config TMS320C6X
select HAVE_GENERIC_HARDIRQS
select HAVE_MEMBLOCK
select HAVE_SPARSE_IRQ
+ select IRQ_DOMAIN
select OF
select OF_EARLY_FLATTREE
diff --git a/arch/c6x/boot/Makefile b/arch/c6x/boot/Makefile
index ecca820e604..6891257d514 100644
--- a/arch/c6x/boot/Makefile
+++ b/arch/c6x/boot/Makefile
@@ -13,7 +13,7 @@ obj-y += linked_dtb.o
endif
$(obj)/%.dtb: $(src)/dts/%.dts FORCE
- $(call cmd,dtc)
+ $(call if_changed_dep,dtc)
quiet_cmd_cp = CP $< $@$2
cmd_cp = cat $< >$@$2 || (rm -f $@ && echo false)
diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h
index a6ae3c9d9c4..f13b78d5e1c 100644
--- a/arch/c6x/include/asm/irq.h
+++ b/arch/c6x/include/asm/irq.h
@@ -13,6 +13,7 @@
#ifndef _ASM_C6X_IRQ_H
#define _ASM_C6X_IRQ_H
+#include <linux/irqdomain.h>
#include <linux/threads.h>
#include <linux/list.h>
#include <linux/radix-tree.h>
@@ -41,253 +42,9 @@
/* This number is used when no interrupt has been assigned */
#define NO_IRQ 0
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-/* Interrupt controller "host" data structure. This could be defined as a
- * irq domain controller. That is, it handles the mapping between hardware
- * and virtual interrupt numbers for a given interrupt domain. The host
- * structure is generally created by the PIC code for a given PIC instance
- * (though a host can cover more than one PIC if they have a flat number
- * model). It's the host callbacks that are responsible for setting the
- * irq_chip on a given irq_desc after it's been mapped.
- *
- * The host code and data structures are fairly agnostic to the fact that
- * we use an open firmware device-tree. We do have references to struct
- * device_node in two places: in irq_find_host() to find the host matching
- * a given interrupt controller node, and of course as an argument to its
- * counterpart host->ops->match() callback. However, those are treated as
- * generic pointers by the core and the fact that it's actually a device-node
- * pointer is purely a convention between callers and implementation. This
- * code could thus be used on other architectures by replacing those two
- * by some sort of arch-specific void * "token" used to identify interrupt
- * controllers.
- */
-struct irq_host;
-struct radix_tree_root;
-struct device_node;
-
-/* Functions below are provided by the host and called whenever a new mapping
- * is created or an old mapping is disposed. The host can then proceed to
- * whatever internal data structures management is required. It also needs
- * to setup the irq_desc when returning from map().
- */
-struct irq_host_ops {
- /* Match an interrupt controller device node to a host, returns
- * 1 on a match
- */
- int (*match)(struct irq_host *h, struct device_node *node);
-
- /* Create or update a mapping between a virtual irq number and a hw
- * irq number. This is called only once for a given mapping.
- */
- int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
- /* Dispose of such a mapping */
- void (*unmap)(struct irq_host *h, unsigned int virq);
-
- /* Translate device-tree interrupt specifier from raw format coming
- * from the firmware to a irq_hw_number_t (interrupt line number) and
- * type (sense) that can be passed to set_irq_type(). In the absence
- * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
- * will return the hw number in the first cell and IRQ_TYPE_NONE for
- * the type (which amount to keeping whatever default value the
- * interrupt controller has for that line)
- */
- int (*xlate)(struct irq_host *h, struct device_node *ctrler,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type);
-};
-
-struct irq_host {
- struct list_head link;
-
- /* type of reverse mapping technique */
- unsigned int revmap_type;
-#define IRQ_HOST_MAP_PRIORITY 0 /* core priority irqs, get irqs 1..15 */
-#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */
-#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */
-#define IRQ_HOST_MAP_TREE 3 /* radix tree */
- union {
- struct {
- unsigned int size;
- unsigned int *revmap;
- } linear;
- struct radix_tree_root tree;
- } revmap_data;
- struct irq_host_ops *ops;
- void *host_data;
- irq_hw_number_t inval_irq;
-
- /* Optional device node pointer */
- struct device_node *of_node;
-};
-
struct irq_data;
extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
extern irq_hw_number_t virq_to_hw(unsigned int virq);
-extern bool virq_is_host(unsigned int virq, struct irq_host *host);
-
-/**
- * irq_alloc_host - Allocate a new irq_host data structure
- * @of_node: optional device-tree node of the interrupt controller
- * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
- * @ops: map/unmap host callbacks
- * @inval_irq: provide a hw number in that host space that is always invalid
- *
- * Allocates and initialize and irq_host structure. Note that in the case of
- * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
- * later during boot automatically (the reverse mapping will use the slow path
- * until that happens).
- */
-extern struct irq_host *irq_alloc_host(struct device_node *of_node,
- unsigned int revmap_type,
- unsigned int revmap_arg,
- struct irq_host_ops *ops,
- irq_hw_number_t inval_irq);
-
-
-/**
- * irq_find_host - Locates a host for a given device node
- * @node: device-tree node of the interrupt controller
- */
-extern struct irq_host *irq_find_host(struct device_node *node);
-
-
-/**
- * irq_set_default_host - Set a "default" host
- * @host: default host pointer
- *
- * For convenience, it's possible to set a "default" host that will be used
- * whenever NULL is passed to irq_create_mapping(). It makes life easier for
- * platforms that want to manipulate a few hard coded interrupt numbers that
- * aren't properly represented in the device-tree.
- */
-extern void irq_set_default_host(struct irq_host *host);
-
-
-/**
- * irq_set_virq_count - Set the maximum number of virt irqs
- * @count: number of linux virtual irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-extern void irq_set_virq_count(unsigned int count);
-
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-extern void irq_dispose_mapping(unsigned int virq);
-
-/**
- * irq_find_mapping - Find a linux virq from an hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
- */
-extern unsigned int irq_find_mapping(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-/**
- * irq_create_direct_mapping - Allocate a virq for direct mapping
- * @host: host to allocate the virq for or NULL for default host
- *
- * This routine is used for irq controllers which can choose the hardware
- * interrupt numbers they generate. In such a case it's simplest to use
- * the linux virq as the hardware interrupt number.
- */
-extern unsigned int irq_create_direct_mapping(struct irq_host *host);
-
-/**
- * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
- * @host: host owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that host space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq);
-
-/**
- * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses radix tree
- * revmaps
- */
-extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-/**
- * irq_linear_revmap - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses linear
- * revmaps. It does fallback to the slow path if the revmap doesn't exist
- * yet and will create the revmap entry with appropriate locking
- */
-
-extern unsigned int irq_linear_revmap(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-
-
-/**
- * irq_alloc_virt - Allocate virtual irq numbers
- * @host: host owning these new virtual irqs
- * @count: number of consecutive numbers to allocate
- * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
- *
- * This is a low level function that is used internally by irq_create_mapping()
- * and that can be used by some irq controllers implementations for things
- * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
- */
-extern unsigned int irq_alloc_virt(struct irq_host *host,
- unsigned int count,
- unsigned int hint);
-
-/**
- * irq_free_virt - Free virtual irq numbers
- * @virq: virtual irq number of the first interrupt to free
- * @count: number of interrupts to free
- *
- * This function is the opposite of irq_alloc_virt. It will not clear reverse
- * maps, this should be done previously by unmap'ing the interrupt. In fact,
- * all interrupts covered by the range being freed should have been unmapped
- * prior to calling this.
- */
-extern void irq_free_virt(unsigned int virq, unsigned int count);
extern void __init init_pic_c64xplus(void);
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
index 0929e4b2b24..d77bcfdf0d8 100644
--- a/arch/c6x/kernel/irq.c
+++ b/arch/c6x/kernel/irq.c
@@ -73,10 +73,10 @@ asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)
set_irq_regs(old_regs);
}
-static struct irq_host *core_host;
+static struct irq_domain *core_domain;
-static int core_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw)
+static int core_domain_map(struct irq_domain *h, unsigned int virq,
+ irq_hw_number_t hw)
{
if (hw < 4 || hw >= NR_PRIORITY_IRQS)
return -EINVAL;
@@ -86,8 +86,9 @@ static int core_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops core_host_ops = {
- .map = core_host_map,
+static const struct irq_domain_ops core_domain_ops = {
+ .map = core_domain_map,
+ .xlate = irq_domain_xlate_onecell,
};
void __init init_IRQ(void)
@@ -100,10 +101,11 @@ void __init init_IRQ(void)
np = of_find_compatible_node(NULL, NULL, "ti,c64x+core-pic");
if (np != NULL) {
/* create the core host */
- core_host = irq_alloc_host(np, IRQ_HOST_MAP_PRIORITY, 0,
- &core_host_ops, 0);
- if (core_host)
- irq_set_default_host(core_host);
+ core_domain = irq_domain_add_legacy(np, NR_PRIORITY_IRQS,
+ 0, 0, &core_domain_ops,
+ NULL);
+ if (core_domain)
+ irq_set_default_host(core_domain);
of_node_put(np);
}
@@ -128,601 +130,15 @@ int arch_show_interrupts(struct seq_file *p, int prec)
return 0;
}
-/*
- * IRQ controller and virtual interrupts
- */
-
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
- irq_hw_number_t hwirq;
- struct irq_host *host;
-};
-
-static LIST_HEAD(irq_hosts);
-static DEFINE_RAW_SPINLOCK(irq_big_lock);
-static DEFINE_MUTEX(revmap_trees_mutex);
-static struct irq_map_entry irq_map[NR_IRQS];
-static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_host *irq_default_host;
-
irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
{
- return irq_map[d->irq].hwirq;
+ return d->hwirq;
}
EXPORT_SYMBOL_GPL(irqd_to_hwirq);
irq_hw_number_t virq_to_hw(unsigned int virq)
{
- return irq_map[virq].hwirq;
+ struct irq_data *irq_data = irq_get_irq_data(virq);
+ return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
}
EXPORT_SYMBOL_GPL(virq_to_hw);
-
-bool virq_is_host(unsigned int virq, struct irq_host *host)
-{
- return irq_map[virq].host == host;
-}
-EXPORT_SYMBOL_GPL(virq_is_host);
-
-static int default_irq_host_match(struct irq_host *h, struct device_node *np)
-{
- return h->of_node != NULL && h->of_node == np;
-}
-
-struct irq_host *irq_alloc_host(struct device_node *of_node,
- unsigned int revmap_type,
- unsigned int revmap_arg,
- struct irq_host_ops *ops,
- irq_hw_number_t inval_irq)
-{
- struct irq_host *host;
- unsigned int size = sizeof(struct irq_host);
- unsigned int i;
- unsigned int *rmap;
- unsigned long flags;
-
- /* Allocate structure and revmap table if using linear mapping */
- if (revmap_type == IRQ_HOST_MAP_LINEAR)
- size += revmap_arg * sizeof(unsigned int);
- host = kzalloc(size, GFP_KERNEL);
- if (host == NULL)
- return NULL;
-
- /* Fill structure */
- host->revmap_type = revmap_type;
- host->inval_irq = inval_irq;
- host->ops = ops;
- host->of_node = of_node_get(of_node);
-
- if (host->ops->match == NULL)
- host->ops->match = default_irq_host_match;
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
-
- /* Check for the priority controller. */
- if (revmap_type == IRQ_HOST_MAP_PRIORITY) {
- if (irq_map[0].host != NULL) {
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- of_node_put(host->of_node);
- kfree(host);
- return NULL;
- }
- irq_map[0].host = host;
- }
-
- list_add(&host->link, &irq_hosts);
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-
- /* Additional setups per revmap type */
- switch (revmap_type) {
- case IRQ_HOST_MAP_PRIORITY:
- /* 0 is always the invalid number for priority */
- host->inval_irq = 0;
- /* setup us as the host for all priority interrupts */
- for (i = 1; i < NR_PRIORITY_IRQS; i++) {
- irq_map[i].hwirq = i;
- smp_wmb();
- irq_map[i].host = host;
- smp_wmb();
-
- ops->map(host, i, i);
- }
- break;
- case IRQ_HOST_MAP_LINEAR:
- rmap = (unsigned int *)(host + 1);
- for (i = 0; i < revmap_arg; i++)
- rmap[i] = NO_IRQ;
- host->revmap_data.linear.size = revmap_arg;
- smp_wmb();
- host->revmap_data.linear.revmap = rmap;
- break;
- case IRQ_HOST_MAP_TREE:
- INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
- break;
- default:
- break;
- }
-
- pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
-
- return host;
-}
-
-struct irq_host *irq_find_host(struct device_node *node)
-{
- struct irq_host *h, *found = NULL;
- unsigned long flags;
-
- /* We might want to match the legacy controller last since
- * it might potentially be set to match all interrupts in
- * the absence of a device node. This isn't a problem so far
- * yet though...
- */
- raw_spin_lock_irqsave(&irq_big_lock, flags);
- list_for_each_entry(h, &irq_hosts, link)
- if (h->ops->match(h, node)) {
- found = h;
- break;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return found;
-}
-EXPORT_SYMBOL_GPL(irq_find_host);
-
-void irq_set_default_host(struct irq_host *host)
-{
- pr_debug("irq: Default host set to @0x%p\n", host);
-
- irq_default_host = host;
-}
-
-void irq_set_virq_count(unsigned int count)
-{
- pr_debug("irq: Trying to set virq count to %d\n", count);
-
- BUG_ON(count < NR_PRIORITY_IRQS);
- if (count < NR_IRQS)
- irq_virq_count = count;
-}
-
-static int irq_setup_virq(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq)
-{
- int res;
-
- res = irq_alloc_desc_at(virq, 0);
- if (res != virq) {
- pr_debug("irq: -> allocating desc failed\n");
- goto error;
- }
-
- /* map it */
- smp_wmb();
- irq_map[virq].hwirq = hwirq;
- smp_mb();
-
- if (host->ops->map(host, virq, hwirq)) {
- pr_debug("irq: -> mapping failed, freeing\n");
- goto errdesc;
- }
-
- irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
- return 0;
-
-errdesc:
- irq_free_descs(virq, 1);
-error:
- irq_free_virt(virq, 1);
- return -1;
-}
-
-unsigned int irq_create_direct_mapping(struct irq_host *host)
-{
- unsigned int virq;
-
- if (host == NULL)
- host = irq_default_host;
-
- BUG_ON(host == NULL);
- WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
-
- virq = irq_alloc_virt(host, 1, 0);
- if (virq == NO_IRQ) {
- pr_debug("irq: create_direct virq allocation failed\n");
- return NO_IRQ;
- }
-
- pr_debug("irq: create_direct obtained virq %d\n", virq);
-
- if (irq_setup_virq(host, virq, virq))
- return NO_IRQ;
-
- return virq;
-}
-
-unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int virq, hint;
-
- pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
-
- /* Look for default host if nececssary */
- if (host == NULL)
- host = irq_default_host;
- if (host == NULL) {
- printk(KERN_WARNING "irq_create_mapping called for"
- " NULL host, hwirq=%lx\n", hwirq);
- WARN_ON(1);
- return NO_IRQ;
- }
- pr_debug("irq: -> using host @%p\n", host);
-
- /* Check if mapping already exists */
- virq = irq_find_mapping(host, hwirq);
- if (virq != NO_IRQ) {
- pr_debug("irq: -> existing mapping on virq %d\n", virq);
- return virq;
- }
-
- /* Allocate a virtual interrupt number */
- hint = hwirq % irq_virq_count;
- virq = irq_alloc_virt(host, 1, hint);
- if (virq == NO_IRQ) {
- pr_debug("irq: -> virq allocation failed\n");
- return NO_IRQ;
- }
-
- if (irq_setup_virq(host, virq, hwirq))
- return NO_IRQ;
-
- pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
- hwirq, host->of_node ? host->of_node->full_name : "null", virq);
-
- return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- struct irq_host *host;
- irq_hw_number_t hwirq;
- unsigned int type = IRQ_TYPE_NONE;
- unsigned int virq;
-
- if (controller == NULL)
- host = irq_default_host;
- else
- host = irq_find_host(controller);
- if (host == NULL) {
- printk(KERN_WARNING "irq: no irq host found for %s !\n",
- controller->full_name);
- return NO_IRQ;
- }
-
- /* If host has no translation, then we assume interrupt line */
- if (host->ops->xlate == NULL)
- hwirq = intspec[0];
- else {
- if (host->ops->xlate(host, controller, intspec, intsize,
- &hwirq, &type))
- return NO_IRQ;
- }
-
- /* Create mapping */
- virq = irq_create_mapping(host, hwirq);
- if (virq == NO_IRQ)
- return virq;
-
- /* Set type if specified and different than the current one */
- if (type != IRQ_TYPE_NONE &&
- 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);
-
-void irq_dispose_mapping(unsigned int virq)
-{
- struct irq_host *host;
- irq_hw_number_t hwirq;
-
- if (virq == NO_IRQ)
- return;
-
- /* Never unmap priority interrupts */
- if (virq < NR_PRIORITY_IRQS)
- return;
-
- host = irq_map[virq].host;
- if (WARN_ON(host == NULL))
- return;
-
- irq_set_status_flags(virq, IRQ_NOREQUEST);
-
- /* remove chip and handler */
- irq_set_chip_and_handler(virq, NULL, NULL);
-
- /* Make sure it's completed */
- synchronize_irq(virq);
-
- /* Tell the PIC about it */
- if (host->ops->unmap)
- host->ops->unmap(host, virq);
- smp_mb();
-
- /* Clear reverse map */
- hwirq = irq_map[virq].hwirq;
- switch (host->revmap_type) {
- case IRQ_HOST_MAP_LINEAR:
- if (hwirq < host->revmap_data.linear.size)
- host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
- break;
- case IRQ_HOST_MAP_TREE:
- mutex_lock(&revmap_trees_mutex);
- radix_tree_delete(&host->revmap_data.tree, hwirq);
- mutex_unlock(&revmap_trees_mutex);
- break;
- }
-
- /* Destroy map */
- smp_mb();
- irq_map[virq].hwirq = host->inval_irq;
-
- irq_free_descs(virq, 1);
- /* Free it */
- irq_free_virt(virq, 1);
-}
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-
-unsigned int irq_find_mapping(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int i;
- unsigned int hint = hwirq % irq_virq_count;
-
- /* Look for default host if nececssary */
- if (host == NULL)
- host = irq_default_host;
- if (host == NULL)
- return NO_IRQ;
-
- /* Slow path does a linear search of the map */
- i = hint;
- do {
- if (irq_map[i].host == host &&
- irq_map[i].hwirq == hwirq)
- return i;
- i++;
- if (i >= irq_virq_count)
- i = 4;
- } while (i != hint);
- return NO_IRQ;
-}
-EXPORT_SYMBOL_GPL(irq_find_mapping);
-
-unsigned int irq_radix_revmap_lookup(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- struct irq_map_entry *ptr;
- unsigned int virq;
-
- if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
- return irq_find_mapping(host, hwirq);
-
- /*
- * The ptr returned references the static global irq_map.
- * but freeing an irq can delete nodes along the path to
- * do the lookup via call_rcu.
- */
- rcu_read_lock();
- ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
- rcu_read_unlock();
-
- /*
- * If found in radix tree, then fine.
- * Else fallback to linear lookup - this should not happen in practice
- * as it means that we failed to insert the node in the radix tree.
- */
- if (ptr)
- virq = ptr - irq_map;
- else
- virq = irq_find_mapping(host, hwirq);
-
- return virq;
-}
-
-void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq)
-{
- if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
- return;
-
- if (virq != NO_IRQ) {
- mutex_lock(&revmap_trees_mutex);
- radix_tree_insert(&host->revmap_data.tree, hwirq,
- &irq_map[virq]);
- mutex_unlock(&revmap_trees_mutex);
- }
-}
-
-unsigned int irq_linear_revmap(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int *revmap;
-
- if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
- return irq_find_mapping(host, hwirq);
-
- /* Check revmap bounds */
- if (unlikely(hwirq >= host->revmap_data.linear.size))
- return irq_find_mapping(host, hwirq);
-
- /* Check if revmap was allocated */
- revmap = host->revmap_data.linear.revmap;
- if (unlikely(revmap == NULL))
- return irq_find_mapping(host, hwirq);
-
- /* Fill up revmap with slow path if no mapping found */
- if (unlikely(revmap[hwirq] == NO_IRQ))
- revmap[hwirq] = irq_find_mapping(host, hwirq);
-
- return revmap[hwirq];
-}
-
-unsigned int irq_alloc_virt(struct irq_host *host,
- unsigned int count,
- unsigned int hint)
-{
- unsigned long flags;
- unsigned int i, j, found = NO_IRQ;
-
- if (count == 0 || count > (irq_virq_count - NR_PRIORITY_IRQS))
- return NO_IRQ;
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
-
- /* Use hint for 1 interrupt if any */
- if (count == 1 && hint >= NR_PRIORITY_IRQS &&
- hint < irq_virq_count && irq_map[hint].host == NULL) {
- found = hint;
- goto hint_found;
- }
-
- /* Look for count consecutive numbers in the allocatable
- * (non-legacy) space
- */
- for (i = NR_PRIORITY_IRQS, j = 0; i < irq_virq_count; i++) {
- if (irq_map[i].host != NULL)
- j = 0;
- else
- j++;
-
- if (j == count) {
- found = i - count + 1;
- break;
- }
- }
- if (found == NO_IRQ) {
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return NO_IRQ;
- }
- hint_found:
- for (i = found; i < (found + count); i++) {
- irq_map[i].hwirq = host->inval_irq;
- smp_wmb();
- irq_map[i].host = host;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return found;
-}
-
-void irq_free_virt(unsigned int virq, unsigned int count)
-{
- unsigned long flags;
- unsigned int i;
-
- WARN_ON(virq < NR_PRIORITY_IRQS);
- WARN_ON(count == 0 || (virq + count) > irq_virq_count);
-
- if (virq < NR_PRIORITY_IRQS) {
- if (virq + count < NR_PRIORITY_IRQS)
- return;
- count -= NR_PRIORITY_IRQS - virq;
- virq = NR_PRIORITY_IRQS;
- }
-
- if (count > irq_virq_count || virq > irq_virq_count - count) {
- if (virq > irq_virq_count)
- return;
- count = irq_virq_count - virq;
- }
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
- for (i = virq; i < (virq + count); i++) {
- struct irq_host *host;
-
- host = irq_map[i].host;
- irq_map[i].hwirq = host->inval_irq;
- smp_wmb();
- irq_map[i].host = NULL;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-}
-
-#ifdef CONFIG_VIRQ_DEBUG
-static int virq_debug_show(struct seq_file *m, void *private)
-{
- unsigned long flags;
- struct irq_desc *desc;
- const char *p;
- static const char none[] = "none";
- void *data;
- int i;
-
- seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq",
- "chip name", "chip data", "host name");
-
- for (i = 1; i < nr_irqs; i++) {
- desc = irq_to_desc(i);
- if (!desc)
- continue;
-
- raw_spin_lock_irqsave(&desc->lock, flags);
-
- if (desc->action && desc->action->handler) {
- struct irq_chip *chip;
-
- seq_printf(m, "%5d ", i);
- seq_printf(m, "0x%05lx ", irq_map[i].hwirq);
-
- chip = irq_desc_get_chip(desc);
- if (chip && chip->name)
- p = chip->name;
- else
- p = none;
- seq_printf(m, "%-15s ", p);
-
- data = irq_desc_get_chip_data(desc);
- seq_printf(m, "0x%16p ", data);
-
- if (irq_map[i].host && irq_map[i].host->of_node)
- p = irq_map[i].host->of_node->full_name;
- else
- p = none;
- seq_printf(m, "%s\n", p);
- }
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- }
-
- return 0;
-}
-
-static int virq_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, virq_debug_show, inode->i_private);
-}
-
-static const struct file_operations virq_debug_fops = {
- .open = virq_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init irq_debugfs_init(void)
-{
- if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
- NULL, &virq_debug_fops) == NULL)
- return -ENOMEM;
-
- return 0;
-}
-device_initcall(irq_debugfs_init);
-#endif /* CONFIG_VIRQ_DEBUG */
diff --git a/arch/c6x/platforms/megamod-pic.c b/arch/c6x/platforms/megamod-pic.c
index 7c37a947fb1..c1c4e2ae3f8 100644
--- a/arch/c6x/platforms/megamod-pic.c
+++ b/arch/c6x/platforms/megamod-pic.c
@@ -48,7 +48,7 @@ struct megamod_regs {
};
struct megamod_pic {
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
struct megamod_regs __iomem *regs;
raw_spinlock_t lock;
@@ -116,7 +116,7 @@ static void megamod_irq_cascade(unsigned int irq, struct irq_desc *desc)
}
}
-static int megamod_map(struct irq_host *h, unsigned int virq,
+static int megamod_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct megamod_pic *pic = h->host_data;
@@ -136,21 +136,9 @@ static int megamod_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int megamod_xlate(struct irq_host *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type)
-
-{
- /* megamod intspecs must have 1 cell */
- BUG_ON(intsize != 1);
- *out_hwirq = intspec[0];
- *out_type = IRQ_TYPE_NONE;
- return 0;
-}
-
-static struct irq_host_ops megamod_host_ops = {
+static const struct irq_domain_ops megamod_domain_ops = {
.map = megamod_map,
- .xlate = megamod_xlate,
+ .xlate = irq_domain_xlate_onecell,
};
static void __init set_megamod_mux(struct megamod_pic *pic, int src, int output)
@@ -223,9 +211,8 @@ static struct megamod_pic * __init init_megamod_pic(struct device_node *np)
return NULL;
}
- pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
- NR_COMBINERS * 32, &megamod_host_ops,
- IRQ_UNMAPPED);
+ pic->irqhost = irq_domain_add_linear(np, NR_COMBINERS * 32,
+ &megamod_domain_ops, pic);
if (!pic->irqhost) {
pr_err("%s: Could not alloc host.\n", np->full_name);
goto error_free;
diff --git a/arch/m68k/include/asm/mcf_pgtable.h b/arch/m68k/include/asm/mcf_pgtable.h
index 756bde4fb4f..3c793682e5d 100644
--- a/arch/m68k/include/asm/mcf_pgtable.h
+++ b/arch/m68k/include/asm/mcf_pgtable.h
@@ -78,7 +78,8 @@
| CF_PAGE_READABLE \
| CF_PAGE_WRITABLE \
| CF_PAGE_EXEC \
- | CF_PAGE_SYSTEM)
+ | CF_PAGE_SYSTEM \
+ | CF_PAGE_SHARED)
#define PAGE_COPY __pgprot(CF_PAGE_VALID \
| CF_PAGE_ACCESSED \
diff --git a/arch/m68k/mm/mcfmmu.c b/arch/m68k/mm/mcfmmu.c
index babd5a97cdc..875b800ef0d 100644
--- a/arch/m68k/mm/mcfmmu.c
+++ b/arch/m68k/mm/mcfmmu.c
@@ -87,7 +87,7 @@ void __init paging_init(void)
int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
{
- unsigned long flags, mmuar;
+ unsigned long flags, mmuar, mmutr;
struct mm_struct *mm;
pgd_t *pgd;
pmd_t *pmd;
@@ -137,9 +137,10 @@ int cf_tlb_miss(struct pt_regs *regs, int write, int dtlb, int extension_word)
if (!pte_dirty(*pte) && !KMAPAREA(mmuar))
set_pte(pte, pte_wrprotect(*pte));
- mmu_write(MMUTR, (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) |
- (((int)(pte->pte) & (int)CF_PAGE_MMUTR_MASK)
- >> CF_PAGE_MMUTR_SHIFT) | MMUTR_V);
+ mmutr = (mmuar & PAGE_MASK) | (asid << MMUTR_IDN) | MMUTR_V;
+ if ((mmuar < TASK_UNMAPPED_BASE) || (mmuar >= TASK_SIZE))
+ mmutr |= (pte->pte & CF_PAGE_MMUTR_MASK) >> CF_PAGE_MMUTR_SHIFT;
+ mmu_write(MMUTR, mmutr);
mmu_write(MMUDR, (pte_val(*pte) & PAGE_MASK) |
((pte->pte) & CF_PAGE_MMUDR_MASK) | MMUDR_SZ_8KB | MMUDR_X);
diff --git a/arch/m68k/platform/coldfire/entry.S b/arch/m68k/platform/coldfire/entry.S
index 863889fc31c..281e38c2b6c 100644
--- a/arch/m68k/platform/coldfire/entry.S
+++ b/arch/m68k/platform/coldfire/entry.S
@@ -136,7 +136,7 @@ Luser_return:
movel %sp,%d1 /* get thread_info pointer */
andl #-THREAD_SIZE,%d1 /* at base of kernel stack */
movel %d1,%a0
- movel %a0@(TINFO_FLAGS),%d1 /* get thread_info->flags */
+ moveb %a0@(TINFO_FLAGS+3),%d1 /* thread_info->flags (low 8 bits) */
jne Lwork_to_do /* still work to do */
Lreturn:
@@ -148,8 +148,6 @@ Lwork_to_do:
btst #TIF_NEED_RESCHED,%d1
jne reschedule
- /* GERG: do we need something here for TRACEing?? */
-
Lsignal_return:
subql #4,%sp /* dummy return address */
SAVE_SWITCH_STACK
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index c8d6efb99db..11060fa87da 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -14,6 +14,7 @@ config MICROBLAZE
select TRACING_SUPPORT
select OF
select OF_EARLY_FLATTREE
+ select IRQ_DOMAIN
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
diff --git a/arch/microblaze/include/asm/hardirq.h b/arch/microblaze/include/asm/hardirq.h
index cd1ac9aad56..fb3c05a0cbb 100644
--- a/arch/microblaze/include/asm/hardirq.h
+++ b/arch/microblaze/include/asm/hardirq.h
@@ -1,17 +1 @@
-/*
- * Copyright (C) 2006 Atmark Techno, Inc.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- */
-
-#ifndef _ASM_MICROBLAZE_HARDIRQ_H
-#define _ASM_MICROBLAZE_HARDIRQ_H
-
-/* should be defined in each interrupt controller driver */
-extern unsigned int get_irq(struct pt_regs *regs);
-
#include <asm-generic/hardirq.h>
-
-#endif /* _ASM_MICROBLAZE_HARDIRQ_H */
diff --git a/arch/microblaze/include/asm/irq.h b/arch/microblaze/include/asm/irq.h
index a175132e449..bab3b1393ad 100644
--- a/arch/microblaze/include/asm/irq.h
+++ b/arch/microblaze/include/asm/irq.h
@@ -9,49 +9,13 @@
#ifndef _ASM_MICROBLAZE_IRQ_H
#define _ASM_MICROBLAZE_IRQ_H
-
-/*
- * Linux IRQ# is currently offset by one to map to the hardware
- * irq number. So hardware IRQ0 maps to Linux irq 1.
- */
-#define NO_IRQ_OFFSET 1
-#define IRQ_OFFSET NO_IRQ_OFFSET
-#define NR_IRQS (32 + IRQ_OFFSET)
+#define NR_IRQS (32 + 1)
#include <asm-generic/irq.h>
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-extern unsigned int nr_irq;
-
struct pt_regs;
extern void do_IRQ(struct pt_regs *regs);
-/** FIXME - not implement
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-static inline void irq_dispose_mapping(unsigned int virq)
-{
- return;
-}
-
-struct irq_host;
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq);
+/* should be defined in each interrupt controller driver */
+extern unsigned int get_irq(void);
#endif /* _ASM_MICROBLAZE_IRQ_H */
diff --git a/arch/microblaze/kernel/intc.c b/arch/microblaze/kernel/intc.c
index 44b177e2ab1..ad120672cee 100644
--- a/arch/microblaze/kernel/intc.c
+++ b/arch/microblaze/kernel/intc.c
@@ -9,6 +9,7 @@
*/
#include <linux/init.h>
+#include <linux/irqdomain.h>
#include <linux/irq.h>
#include <asm/page.h>
#include <linux/io.h>
@@ -25,8 +26,6 @@ static unsigned int intc_baseaddr;
#define INTC_BASE intc_baseaddr
#endif
-unsigned int nr_irq;
-
/* No one else should require these constants, so define them locally here. */
#define ISR 0x00 /* Interrupt Status Register */
#define IPR 0x04 /* Interrupt Pending Register */
@@ -84,24 +83,45 @@ static struct irq_chip intc_dev = {
.irq_mask_ack = intc_mask_ack,
};
-unsigned int get_irq(struct pt_regs *regs)
+static struct irq_domain *root_domain;
+
+unsigned int get_irq(void)
{
- int irq;
+ unsigned int hwirq, irq = -1;
- /*
- * NOTE: This function is the one that needs to be improved in
- * order to handle multiple interrupt controllers. It currently
- * is hardcoded to check for interrupts only on the first INTC.
- */
- irq = in_be32(INTC_BASE + IVR) + NO_IRQ_OFFSET;
- pr_debug("get_irq: %d\n", irq);
+ hwirq = in_be32(INTC_BASE + IVR);
+ if (hwirq != -1U)
+ irq = irq_find_mapping(root_domain, hwirq);
+
+ pr_debug("get_irq: hwirq=%d, irq=%d\n", hwirq, irq);
return irq;
}
+int xintc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
+{
+ u32 intr_mask = (u32)d->host_data;
+
+ if (intr_mask & (1 << hw)) {
+ irq_set_chip_and_handler_name(irq, &intc_dev,
+ handle_edge_irq, "edge");
+ irq_clear_status_flags(irq, IRQ_LEVEL);
+ } else {
+ irq_set_chip_and_handler_name(irq, &intc_dev,
+ handle_level_irq, "level");
+ irq_set_status_flags(irq, IRQ_LEVEL);
+ }
+ return 0;
+}
+
+static const struct irq_domain_ops xintc_irq_domain_ops = {
+ .xlate = irq_domain_xlate_onetwocell,
+ .map = xintc_map,
+};
+
void __init init_IRQ(void)
{
- u32 i, intr_mask;
+ u32 nr_irq, intr_mask;
struct device_node *intc = NULL;
#ifdef CONFIG_SELFMOD_INTC
unsigned int intc_baseaddr = 0;
@@ -146,16 +166,9 @@ void __init init_IRQ(void)
/* Turn on the Master Enable. */
out_be32(intc_baseaddr + MER, MER_HIE | MER_ME);
- for (i = IRQ_OFFSET; i < (nr_irq + IRQ_OFFSET); ++i) {
- if (intr_mask & (0x00000001 << (i - IRQ_OFFSET))) {
- irq_set_chip_and_handler_name(i, &intc_dev,
- handle_edge_irq, "edge");
- irq_clear_status_flags(i, IRQ_LEVEL);
- } else {
- irq_set_chip_and_handler_name(i, &intc_dev,
- handle_level_irq, "level");
- irq_set_status_flags(i, IRQ_LEVEL);
- }
- irq_get_irq_data(i)->hwirq = i - IRQ_OFFSET;
- }
+ /* Yeah, okay, casting the intr_mask to a void* is butt-ugly, but I'm
+ * lazy and Michal can clean it up to something nicer when he tests
+ * and commits this patch. ~~gcl */
+ root_domain = irq_domain_add_linear(intc, nr_irq, &xintc_irq_domain_ops,
+ (void *)intr_mask);
}
diff --git a/arch/microblaze/kernel/irq.c b/arch/microblaze/kernel/irq.c
index bbebcae72c0..ace700afbfd 100644
--- a/arch/microblaze/kernel/irq.c
+++ b/arch/microblaze/kernel/irq.c
@@ -31,14 +31,13 @@ void __irq_entry do_IRQ(struct pt_regs *regs)
trace_hardirqs_off();
irq_enter();
- irq = get_irq(regs);
+ irq = get_irq();
next_irq:
BUG_ON(!irq);
- /* Substract 1 because of get_irq */
- generic_handle_irq(irq + IRQ_OFFSET - NO_IRQ_OFFSET);
+ generic_handle_irq(irq);
- irq = get_irq(regs);
- if (irq) {
+ irq = get_irq();
+ if (irq != -1U) {
pr_debug("next irq: %d\n", irq);
++concurrent_irq;
goto next_irq;
@@ -48,18 +47,3 @@ next_irq:
set_irq_regs(old_regs);
trace_hardirqs_on();
}
-
-/* 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)
-{
- return hwirq + IRQ_OFFSET;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- return intspec[0] + IRQ_OFFSET;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c
index 604cd9dd133..70e6d0b41ab 100644
--- a/arch/microblaze/kernel/setup.c
+++ b/arch/microblaze/kernel/setup.c
@@ -51,8 +51,6 @@ void __init setup_arch(char **cmdline_p)
unflatten_device_tree();
- /* NOTE I think that this function is not necessary to call */
- /* irq_early_init(); */
setup_cpuinfo();
microblaze_cache_init();
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 5ab6e89603c..edbbae17e82 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2327,6 +2327,7 @@ config USE_OF
bool "Flattened Device Tree support"
select OF
select OF_EARLY_FLATTREE
+ select IRQ_DOMAIN
help
Include support for flattened device tree machine descriptions.
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index 2354c870a63..fb698dc09bc 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -11,15 +11,12 @@
#include <linux/linkage.h>
#include <linux/smp.h>
+#include <linux/irqdomain.h>
#include <asm/mipsmtregs.h>
#include <irq.h>
-static inline void irq_dispose_mapping(unsigned int virq)
-{
-}
-
#ifdef CONFIG_I8259
static inline int irq_canonicalize(int irq)
{
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index 6b8b4208481..558b5395795 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -60,20 +60,6 @@ void __init early_init_dt_setup_initrd_arch(unsigned long start,
}
#endif
-/*
- * irq_create_of_mapping - Hook to resolve OF irq specifier into a Linux irq#
- *
- * Currently the mapping mechanism is trivial; simple flat hwirq numbers are
- * mapped 1:1 onto Linux irq numbers. Cascaded irq controllers are not
- * supported.
- */
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- return intspec[0];
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
void __init early_init_devtree(void *params)
{
/* Setup flat device-tree pointer */
diff --git a/arch/openrisc/include/asm/prom.h b/arch/openrisc/include/asm/prom.h
index e1f3fe26606..bbb34e5343a 100644
--- a/arch/openrisc/include/asm/prom.h
+++ b/arch/openrisc/include/asm/prom.h
@@ -24,6 +24,7 @@
#include <linux/types.h>
#include <asm/irq.h>
+#include <linux/irqdomain.h>
#include <linux/atomic.h>
#include <linux/of_irq.h>
#include <linux/of_fdt.h>
@@ -63,15 +64,6 @@ extern const void *of_get_mac_address(struct device_node *np);
struct pci_dev;
extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
-/* This routine is here to provide compatibility with how powerpc
- * handles IRQ mapping for OF device nodes. We precompute and permanently
- * register them in the platform_device objects, whereas powerpc computes them
- * on request.
- */
-static inline void irq_dispose_mapping(unsigned int virq)
-{
-}
-
#endif /* __ASSEMBLY__ */
#endif /* __KERNEL__ */
#endif /* _ASM_OPENRISC_PROM_H */
diff --git a/arch/openrisc/include/asm/ptrace.h b/arch/openrisc/include/asm/ptrace.h
index 054537c5f9c..e612ce4512c 100644
--- a/arch/openrisc/include/asm/ptrace.h
+++ b/arch/openrisc/include/asm/ptrace.h
@@ -77,7 +77,6 @@ struct pt_regs {
long syscallno; /* Syscall number (used by strace) */
long dummy; /* Cheap alignment fix */
};
-#endif /* __ASSEMBLY__ */
/* TODO: Rename this to REDZONE because that's what it is */
#define STACK_FRAME_OVERHEAD 128 /* size of minimum stack frame */
@@ -87,6 +86,13 @@ struct pt_regs {
#define user_stack_pointer(regs) ((unsigned long)(regs)->sp)
#define profile_pc(regs) instruction_pointer(regs)
+static inline long regs_return_value(struct pt_regs *regs)
+{
+ return regs->gpr[11];
+}
+
+#endif /* __ASSEMBLY__ */
+
/*
* Offsets used by 'ptrace' system call interface.
*/
diff --git a/arch/openrisc/kernel/init_task.c b/arch/openrisc/kernel/init_task.c
index 45744a38492..ca534082d5f 100644
--- a/arch/openrisc/kernel/init_task.c
+++ b/arch/openrisc/kernel/init_task.c
@@ -17,6 +17,7 @@
#include <linux/init_task.h>
#include <linux/mqueue.h>
+#include <linux/export.h>
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
diff --git a/arch/openrisc/kernel/irq.c b/arch/openrisc/kernel/irq.c
index 59b30233833..4bfead22095 100644
--- a/arch/openrisc/kernel/irq.c
+++ b/arch/openrisc/kernel/irq.c
@@ -23,6 +23,7 @@
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/kernel_stat.h>
+#include <linux/export.h>
#include <linux/irqflags.h>
diff --git a/arch/openrisc/kernel/ptrace.c b/arch/openrisc/kernel/ptrace.c
index 656b94beab8..7259047d5f9 100644
--- a/arch/openrisc/kernel/ptrace.c
+++ b/arch/openrisc/kernel/ptrace.c
@@ -188,11 +188,9 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
*/
ret = -1L;
- /* Are these regs right??? */
- if (unlikely(current->audit_context))
- audit_syscall_entry(audit_arch(), regs->syscallno,
- regs->gpr[3], regs->gpr[4],
- regs->gpr[5], regs->gpr[6]);
+ audit_syscall_entry(audit_arch(), regs->syscallno,
+ regs->gpr[3], regs->gpr[4],
+ regs->gpr[5], regs->gpr[6]);
return ret ? : regs->syscallno;
}
@@ -201,9 +199,7 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
{
int step;
- if (unlikely(current->audit_context))
- audit_syscall_exit(AUDITSC_RESULT(regs->gpr[11]),
- regs->gpr[11]);
+ audit_syscall_exit(regs);
step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile
index 55cca1dac43..19ab7b2ea1c 100644
--- a/arch/parisc/Makefile
+++ b/arch/parisc/Makefile
@@ -31,7 +31,11 @@ ifdef CONFIG_64BIT
UTS_MACHINE := parisc64
CHECKFLAGS += -D__LP64__=1 -m64
WIDTH := 64
+
+# FIXME: if no default set, should really try to locate dynamically
+ifeq ($(CROSS_COMPILE),)
CROSS_COMPILE := hppa64-linux-gnu-
+endif
else # 32-bit
WIDTH :=
endif
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1919634a9b3..303703d716f 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -135,6 +135,7 @@ config PPC
select HAVE_GENERIC_HARDIRQS
select HAVE_SPARSE_IRQ
select IRQ_PER_CPU
+ select IRQ_DOMAIN
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_SHOW_LEVEL
select IRQ_FORCED_THREADING
diff --git a/arch/powerpc/include/asm/ehv_pic.h b/arch/powerpc/include/asm/ehv_pic.h
index a9e1f4f796f..dc7d48e3ea9 100644
--- a/arch/powerpc/include/asm/ehv_pic.h
+++ b/arch/powerpc/include/asm/ehv_pic.h
@@ -25,7 +25,7 @@
struct ehv_pic {
/* The remapper for this EHV_PIC */
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
/* The "linux" controller struct */
struct irq_chip hc_irq;
diff --git a/arch/powerpc/include/asm/i8259.h b/arch/powerpc/include/asm/i8259.h
index 105ade297aa..c3fdfbd5a67 100644
--- a/arch/powerpc/include/asm/i8259.h
+++ b/arch/powerpc/include/asm/i8259.h
@@ -6,7 +6,7 @@
extern void i8259_init(struct device_node *node, unsigned long intack_addr);
extern unsigned int i8259_irq(void);
-extern struct irq_host *i8259_get_host(void);
+extern struct irq_domain *i8259_get_host(void);
#endif /* __KERNEL__ */
#endif /* _ASM_POWERPC_I8259_H */
diff --git a/arch/powerpc/include/asm/irq.h b/arch/powerpc/include/asm/irq.h
index c0e1bc319e3..fe0b09dceb7 100644
--- a/arch/powerpc/include/asm/irq.h
+++ b/arch/powerpc/include/asm/irq.h
@@ -9,6 +9,7 @@
* 2 of the License, or (at your option) any later version.
*/
+#include <linux/irqdomain.h>
#include <linux/threads.h>
#include <linux/list.h>
#include <linux/radix-tree.h>
@@ -35,258 +36,12 @@ extern atomic_t ppc_n_lost_interrupts;
/* Total number of virq in the platform */
#define NR_IRQS CONFIG_NR_IRQS
-/* Number of irqs reserved for the legacy controller */
-#define NUM_ISA_INTERRUPTS 16
-
/* Same thing, used by the generic IRQ code */
#define NR_IRQS_LEGACY NUM_ISA_INTERRUPTS
-/* This type is the placeholder for a hardware interrupt number. It has to
- * be big enough to enclose whatever representation is used by a given
- * platform.
- */
-typedef unsigned long irq_hw_number_t;
-
-/* Interrupt controller "host" data structure. This could be defined as a
- * irq domain controller. That is, it handles the mapping between hardware
- * and virtual interrupt numbers for a given interrupt domain. The host
- * structure is generally created by the PIC code for a given PIC instance
- * (though a host can cover more than one PIC if they have a flat number
- * model). It's the host callbacks that are responsible for setting the
- * irq_chip on a given irq_desc after it's been mapped.
- *
- * The host code and data structures are fairly agnostic to the fact that
- * we use an open firmware device-tree. We do have references to struct
- * device_node in two places: in irq_find_host() to find the host matching
- * a given interrupt controller node, and of course as an argument to its
- * counterpart host->ops->match() callback. However, those are treated as
- * generic pointers by the core and the fact that it's actually a device-node
- * pointer is purely a convention between callers and implementation. This
- * code could thus be used on other architectures by replacing those two
- * by some sort of arch-specific void * "token" used to identify interrupt
- * controllers.
- */
-struct irq_host;
-struct radix_tree_root;
-
-/* Functions below are provided by the host and called whenever a new mapping
- * is created or an old mapping is disposed. The host can then proceed to
- * whatever internal data structures management is required. It also needs
- * to setup the irq_desc when returning from map().
- */
-struct irq_host_ops {
- /* Match an interrupt controller device node to a host, returns
- * 1 on a match
- */
- int (*match)(struct irq_host *h, struct device_node *node);
-
- /* Create or update a mapping between a virtual irq number and a hw
- * irq number. This is called only once for a given mapping.
- */
- int (*map)(struct irq_host *h, unsigned int virq, irq_hw_number_t hw);
-
- /* Dispose of such a mapping */
- void (*unmap)(struct irq_host *h, unsigned int virq);
-
- /* Translate device-tree interrupt specifier from raw format coming
- * from the firmware to a irq_hw_number_t (interrupt line number) and
- * type (sense) that can be passed to set_irq_type(). In the absence
- * of this callback, irq_create_of_mapping() and irq_of_parse_and_map()
- * will return the hw number in the first cell and IRQ_TYPE_NONE for
- * the type (which amount to keeping whatever default value the
- * interrupt controller has for that line)
- */
- int (*xlate)(struct irq_host *h, struct device_node *ctrler,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type);
-};
-
-struct irq_host {
- struct list_head link;
-
- /* type of reverse mapping technique */
- unsigned int revmap_type;
-#define IRQ_HOST_MAP_LEGACY 0 /* legacy 8259, gets irqs 1..15 */
-#define IRQ_HOST_MAP_NOMAP 1 /* no fast reverse mapping */
-#define IRQ_HOST_MAP_LINEAR 2 /* linear map of interrupts */
-#define IRQ_HOST_MAP_TREE 3 /* radix tree */
- union {
- struct {
- unsigned int size;
- unsigned int *revmap;
- } linear;
- struct radix_tree_root tree;
- } revmap_data;
- struct irq_host_ops *ops;
- void *host_data;
- irq_hw_number_t inval_irq;
-
- /* Optional device node pointer */
- struct device_node *of_node;
-};
-
struct irq_data;
extern irq_hw_number_t irqd_to_hwirq(struct irq_data *d);
extern irq_hw_number_t virq_to_hw(unsigned int virq);
-extern bool virq_is_host(unsigned int virq, struct irq_host *host);
-
-/**
- * irq_alloc_host - Allocate a new irq_host data structure
- * @of_node: optional device-tree node of the interrupt controller
- * @revmap_type: type of reverse mapping to use
- * @revmap_arg: for IRQ_HOST_MAP_LINEAR linear only: size of the map
- * @ops: map/unmap host callbacks
- * @inval_irq: provide a hw number in that host space that is always invalid
- *
- * Allocates and initialize and irq_host structure. Note that in the case of
- * IRQ_HOST_MAP_LEGACY, the map() callback will be called before this returns
- * for all legacy interrupts except 0 (which is always the invalid irq for
- * a legacy controller). For a IRQ_HOST_MAP_LINEAR, the map is allocated by
- * this call as well. For a IRQ_HOST_MAP_TREE, the radix tree will be allocated
- * later during boot automatically (the reverse mapping will use the slow path
- * until that happens).
- */
-extern struct irq_host *irq_alloc_host(struct device_node *of_node,
- unsigned int revmap_type,
- unsigned int revmap_arg,
- struct irq_host_ops *ops,
- irq_hw_number_t inval_irq);
-
-
-/**
- * irq_find_host - Locates a host for a given device node
- * @node: device-tree node of the interrupt controller
- */
-extern struct irq_host *irq_find_host(struct device_node *node);
-
-
-/**
- * irq_set_default_host - Set a "default" host
- * @host: default host pointer
- *
- * For convenience, it's possible to set a "default" host that will be used
- * whenever NULL is passed to irq_create_mapping(). It makes life easier for
- * platforms that want to manipulate a few hard coded interrupt numbers that
- * aren't properly represented in the device-tree.
- */
-extern void irq_set_default_host(struct irq_host *host);
-
-
-/**
- * irq_set_virq_count - Set the maximum number of virt irqs
- * @count: number of linux virtual irqs, capped with NR_IRQS
- *
- * This is mainly for use by platforms like iSeries who want to program
- * the virtual irq number in the controller to avoid the reverse mapping
- */
-extern void irq_set_virq_count(unsigned int count);
-
-
-/**
- * irq_create_mapping - Map a hardware interrupt into linux virq space
- * @host: host owning this hardware interrupt or NULL for default host
- * @hwirq: hardware irq number in that host space
- *
- * Only one mapping per hardware interrupt is permitted. Returns a linux
- * virq number.
- * If the sense/trigger is to be specified, set_irq_type() should be called
- * on the number returned from that call.
- */
-extern unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- */
-extern void irq_dispose_mapping(unsigned int virq);
-
-/**
- * irq_find_mapping - Find a linux virq from an hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a slow path, for use by generic code. It's expected that an
- * irq controller implementation directly calls the appropriate low level
- * mapping function.
- */
-extern unsigned int irq_find_mapping(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-/**
- * irq_create_direct_mapping - Allocate a virq for direct mapping
- * @host: host to allocate the virq for or NULL for default host
- *
- * This routine is used for irq controllers which can choose the hardware
- * interrupt numbers they generate. In such a case it's simplest to use
- * the linux virq as the hardware interrupt number.
- */
-extern unsigned int irq_create_direct_mapping(struct irq_host *host);
-
-/**
- * irq_radix_revmap_insert - Insert a hw irq to linux virq number mapping.
- * @host: host owning this hardware interrupt
- * @virq: linux irq number
- * @hwirq: hardware irq number in that host space
- *
- * This is for use by irq controllers that use a radix tree reverse
- * mapping for fast lookup.
- */
-extern void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq);
-
-/**
- * irq_radix_revmap_lookup - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses radix tree
- * revmaps
- */
-extern unsigned int irq_radix_revmap_lookup(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-/**
- * irq_linear_revmap - Find a linux virq from a hw irq number.
- * @host: host owning this hardware interrupt
- * @hwirq: hardware irq number in that host space
- *
- * This is a fast path, for use by irq controller code that uses linear
- * revmaps. It does fallback to the slow path if the revmap doesn't exist
- * yet and will create the revmap entry with appropriate locking
- */
-
-extern unsigned int irq_linear_revmap(struct irq_host *host,
- irq_hw_number_t hwirq);
-
-
-
-/**
- * irq_alloc_virt - Allocate virtual irq numbers
- * @host: host owning these new virtual irqs
- * @count: number of consecutive numbers to allocate
- * @hint: pass a hint number, the allocator will try to use a 1:1 mapping
- *
- * This is a low level function that is used internally by irq_create_mapping()
- * and that can be used by some irq controllers implementations for things
- * like allocating ranges of numbers for MSIs. The revmaps are left untouched.
- */
-extern unsigned int irq_alloc_virt(struct irq_host *host,
- unsigned int count,
- unsigned int hint);
-
-/**
- * irq_free_virt - Free virtual irq numbers
- * @virq: virtual irq number of the first interrupt to free
- * @count: number of interrupts to free
- *
- * This function is the opposite of irq_alloc_virt. It will not clear reverse
- * maps, this should be done previously by unmap'ing the interrupt. In fact,
- * all interrupts covered by the range being freed should have been unmapped
- * prior to calling this.
- */
-extern void irq_free_virt(unsigned int virq, unsigned int count);
/**
* irq_early_init - Init irq remapping subsystem
diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
index 67b4d983723..a5b7c56237f 100644
--- a/arch/powerpc/include/asm/mpic.h
+++ b/arch/powerpc/include/asm/mpic.h
@@ -255,7 +255,7 @@ struct mpic
struct device_node *node;
/* The remapper for this MPIC */
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
/* The "linux" controller struct */
struct irq_chip hc_irq;
diff --git a/arch/powerpc/include/asm/xics.h b/arch/powerpc/include/asm/xics.h
index c48de98ba94..4ae9a09c3b8 100644
--- a/arch/powerpc/include/asm/xics.h
+++ b/arch/powerpc/include/asm/xics.h
@@ -86,7 +86,7 @@ struct ics {
extern unsigned int xics_default_server;
extern unsigned int xics_default_distrib_server;
extern unsigned int xics_interrupt_server_size;
-extern struct irq_host *xics_host;
+extern struct irq_domain *xics_host;
struct xics_cppr {
unsigned char stack[MAX_NUM_PRIORITIES];
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 4f80cf1ce77..3e57a00b8cb 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -1213,7 +1213,7 @@ do_user_signal: /* r10 contains MSR_KERNEL here */
stw r3,_TRAP(r1)
2: addi r3,r1,STACK_FRAME_OVERHEAD
mr r4,r9
- bl do_signal
+ bl do_notify_resume
REST_NVGPRS(r1)
b recheck
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index d834425186a..866462cbe2d 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -751,12 +751,16 @@ user_work:
andi. r0,r4,_TIF_NEED_RESCHED
beq 1f
+ li r5,1
+ TRACE_AND_RESTORE_IRQ(r5);
bl .schedule
b .ret_from_except_lite
1: bl .save_nvgprs
+ li r5,1
+ TRACE_AND_RESTORE_IRQ(r5);
addi r3,r1,STACK_FRAME_OVERHEAD
- bl .do_signal
+ bl .do_notify_resume
b .ret_from_except
unrecov_restore:
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 3844ca7c509..15c5a4f6de0 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -774,8 +774,8 @@ alignment_common:
program_check_common:
EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
bl .save_nvgprs
- addi r3,r1,STACK_FRAME_OVERHEAD
DISABLE_INTS
+ addi r3,r1,STACK_FRAME_OVERHEAD
bl .program_check_exception
b .ret_from_except
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 01e2877e8e0..bdfb3eee3e6 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -490,409 +490,19 @@ void do_softirq(void)
local_irq_restore(flags);
}
-
-/*
- * IRQ controller and virtual interrupts
- */
-
-/* The main irq map itself is an array of NR_IRQ entries containing the
- * associate host and irq number. An entry with a host of NULL is free.
- * An entry can be allocated if it's free, the allocator always then sets
- * hwirq first to the host's invalid irq number and then fills ops.
- */
-struct irq_map_entry {
- irq_hw_number_t hwirq;
- struct irq_host *host;
-};
-
-static LIST_HEAD(irq_hosts);
-static DEFINE_RAW_SPINLOCK(irq_big_lock);
-static DEFINE_MUTEX(revmap_trees_mutex);
-static struct irq_map_entry irq_map[NR_IRQS];
-static unsigned int irq_virq_count = NR_IRQS;
-static struct irq_host *irq_default_host;
-
irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
{
- return irq_map[d->irq].hwirq;
+ return d->hwirq;
}
EXPORT_SYMBOL_GPL(irqd_to_hwirq);
irq_hw_number_t virq_to_hw(unsigned int virq)
{
- return irq_map[virq].hwirq;
+ struct irq_data *irq_data = irq_get_irq_data(virq);
+ return WARN_ON(!irq_data) ? 0 : irq_data->hwirq;
}
EXPORT_SYMBOL_GPL(virq_to_hw);
-bool virq_is_host(unsigned int virq, struct irq_host *host)
-{
- return irq_map[virq].host == host;
-}
-EXPORT_SYMBOL_GPL(virq_is_host);
-
-static int default_irq_host_match(struct irq_host *h, struct device_node *np)
-{
- return h->of_node != NULL && h->of_node == np;
-}
-
-struct irq_host *irq_alloc_host(struct device_node *of_node,
- unsigned int revmap_type,
- unsigned int revmap_arg,
- struct irq_host_ops *ops,
- irq_hw_number_t inval_irq)
-{
- struct irq_host *host;
- unsigned int size = sizeof(struct irq_host);
- unsigned int i;
- unsigned int *rmap;
- unsigned long flags;
-
- /* Allocate structure and revmap table if using linear mapping */
- if (revmap_type == IRQ_HOST_MAP_LINEAR)
- size += revmap_arg * sizeof(unsigned int);
- host = kzalloc(size, GFP_KERNEL);
- if (host == NULL)
- return NULL;
-
- /* Fill structure */
- host->revmap_type = revmap_type;
- host->inval_irq = inval_irq;
- host->ops = ops;
- host->of_node = of_node_get(of_node);
-
- if (host->ops->match == NULL)
- host->ops->match = default_irq_host_match;
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
-
- /* If it's a legacy controller, check for duplicates and
- * mark it as allocated (we use irq 0 host pointer for that
- */
- if (revmap_type == IRQ_HOST_MAP_LEGACY) {
- if (irq_map[0].host != NULL) {
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- of_node_put(host->of_node);
- kfree(host);
- return NULL;
- }
- irq_map[0].host = host;
- }
-
- list_add(&host->link, &irq_hosts);
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-
- /* Additional setups per revmap type */
- switch(revmap_type) {
- case IRQ_HOST_MAP_LEGACY:
- /* 0 is always the invalid number for legacy */
- host->inval_irq = 0;
- /* setup us as the host for all legacy interrupts */
- for (i = 1; i < NUM_ISA_INTERRUPTS; i++) {
- irq_map[i].hwirq = i;
- smp_wmb();
- irq_map[i].host = host;
- smp_wmb();
-
- /* Legacy flags are left to default at this point,
- * one can then use irq_create_mapping() to
- * explicitly change them
- */
- ops->map(host, i, i);
-
- /* Clear norequest flags */
- irq_clear_status_flags(i, IRQ_NOREQUEST);
- }
- break;
- case IRQ_HOST_MAP_LINEAR:
- rmap = (unsigned int *)(host + 1);
- for (i = 0; i < revmap_arg; i++)
- rmap[i] = NO_IRQ;
- host->revmap_data.linear.size = revmap_arg;
- smp_wmb();
- host->revmap_data.linear.revmap = rmap;
- break;
- case IRQ_HOST_MAP_TREE:
- INIT_RADIX_TREE(&host->revmap_data.tree, GFP_KERNEL);
- break;
- default:
- break;
- }
-
- pr_debug("irq: Allocated host of type %d @0x%p\n", revmap_type, host);
-
- return host;
-}
-
-struct irq_host *irq_find_host(struct device_node *node)
-{
- struct irq_host *h, *found = NULL;
- unsigned long flags;
-
- /* We might want to match the legacy controller last since
- * it might potentially be set to match all interrupts in
- * the absence of a device node. This isn't a problem so far
- * yet though...
- */
- raw_spin_lock_irqsave(&irq_big_lock, flags);
- list_for_each_entry(h, &irq_hosts, link)
- if (h->ops->match(h, node)) {
- found = h;
- break;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return found;
-}
-EXPORT_SYMBOL_GPL(irq_find_host);
-
-void irq_set_default_host(struct irq_host *host)
-{
- pr_debug("irq: Default host set to @0x%p\n", host);
-
- irq_default_host = host;
-}
-
-void irq_set_virq_count(unsigned int count)
-{
- pr_debug("irq: Trying to set virq count to %d\n", count);
-
- BUG_ON(count < NUM_ISA_INTERRUPTS);
- if (count < NR_IRQS)
- irq_virq_count = count;
-}
-
-static int irq_setup_virq(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq)
-{
- int res;
-
- res = irq_alloc_desc_at(virq, 0);
- if (res != virq) {
- pr_debug("irq: -> allocating desc failed\n");
- goto error;
- }
-
- /* map it */
- smp_wmb();
- irq_map[virq].hwirq = hwirq;
- smp_mb();
-
- if (host->ops->map(host, virq, hwirq)) {
- pr_debug("irq: -> mapping failed, freeing\n");
- goto errdesc;
- }
-
- irq_clear_status_flags(virq, IRQ_NOREQUEST);
-
- return 0;
-
-errdesc:
- irq_free_descs(virq, 1);
-error:
- irq_free_virt(virq, 1);
- return -1;
-}
-
-unsigned int irq_create_direct_mapping(struct irq_host *host)
-{
- unsigned int virq;
-
- if (host == NULL)
- host = irq_default_host;
-
- BUG_ON(host == NULL);
- WARN_ON(host->revmap_type != IRQ_HOST_MAP_NOMAP);
-
- virq = irq_alloc_virt(host, 1, 0);
- if (virq == NO_IRQ) {
- pr_debug("irq: create_direct virq allocation failed\n");
- return NO_IRQ;
- }
-
- pr_debug("irq: create_direct obtained virq %d\n", virq);
-
- if (irq_setup_virq(host, virq, virq))
- return NO_IRQ;
-
- return virq;
-}
-
-unsigned int irq_create_mapping(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int virq, hint;
-
- pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", host, hwirq);
-
- /* Look for default host if nececssary */
- if (host == NULL)
- host = irq_default_host;
- if (host == NULL) {
- printk(KERN_WARNING "irq_create_mapping called for"
- " NULL host, hwirq=%lx\n", hwirq);
- WARN_ON(1);
- return NO_IRQ;
- }
- pr_debug("irq: -> using host @%p\n", host);
-
- /* Check if mapping already exists */
- virq = irq_find_mapping(host, hwirq);
- if (virq != NO_IRQ) {
- pr_debug("irq: -> existing mapping on virq %d\n", virq);
- return virq;
- }
-
- /* Get a virtual interrupt number */
- if (host->revmap_type == IRQ_HOST_MAP_LEGACY) {
- /* Handle legacy */
- virq = (unsigned int)hwirq;
- if (virq == 0 || virq >= NUM_ISA_INTERRUPTS)
- return NO_IRQ;
- return virq;
- } else {
- /* Allocate a virtual interrupt number */
- hint = hwirq % irq_virq_count;
- virq = irq_alloc_virt(host, 1, hint);
- if (virq == NO_IRQ) {
- pr_debug("irq: -> virq allocation failed\n");
- return NO_IRQ;
- }
- }
-
- if (irq_setup_virq(host, virq, hwirq))
- return NO_IRQ;
-
- pr_debug("irq: irq %lu on host %s mapped to virtual irq %u\n",
- hwirq, host->of_node ? host->of_node->full_name : "null", virq);
-
- return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_mapping);
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- struct irq_host *host;
- irq_hw_number_t hwirq;
- unsigned int type = IRQ_TYPE_NONE;
- unsigned int virq;
-
- if (controller == NULL)
- host = irq_default_host;
- else
- host = irq_find_host(controller);
- if (host == NULL) {
- printk(KERN_WARNING "irq: no irq host found for %s !\n",
- controller->full_name);
- return NO_IRQ;
- }
-
- /* If host has no translation, then we assume interrupt line */
- if (host->ops->xlate == NULL)
- hwirq = intspec[0];
- else {
- if (host->ops->xlate(host, controller, intspec, intsize,
- &hwirq, &type))
- return NO_IRQ;
- }
-
- /* Create mapping */
- virq = irq_create_mapping(host, hwirq);
- if (virq == NO_IRQ)
- return virq;
-
- /* Set type if specified and different than the current one */
- if (type != IRQ_TYPE_NONE &&
- 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);
-
-void irq_dispose_mapping(unsigned int virq)
-{
- struct irq_host *host;
- irq_hw_number_t hwirq;
-
- if (virq == NO_IRQ)
- return;
-
- host = irq_map[virq].host;
- if (WARN_ON(host == NULL))
- return;
-
- /* Never unmap legacy interrupts */
- if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
- return;
-
- irq_set_status_flags(virq, IRQ_NOREQUEST);
-
- /* remove chip and handler */
- irq_set_chip_and_handler(virq, NULL, NULL);
-
- /* Make sure it's completed */
- synchronize_irq(virq);
-
- /* Tell the PIC about it */
- if (host->ops->unmap)
- host->ops->unmap(host, virq);
- smp_mb();
-
- /* Clear reverse map */
- hwirq = irq_map[virq].hwirq;
- switch(host->revmap_type) {
- case IRQ_HOST_MAP_LINEAR:
- if (hwirq < host->revmap_data.linear.size)
- host->revmap_data.linear.revmap[hwirq] = NO_IRQ;
- break;
- case IRQ_HOST_MAP_TREE:
- mutex_lock(&revmap_trees_mutex);
- radix_tree_delete(&host->revmap_data.tree, hwirq);
- mutex_unlock(&revmap_trees_mutex);
- break;
- }
-
- /* Destroy map */
- smp_mb();
- irq_map[virq].hwirq = host->inval_irq;
-
- irq_free_descs(virq, 1);
- /* Free it */
- irq_free_virt(virq, 1);
-}
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-
-unsigned int irq_find_mapping(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int i;
- unsigned int hint = hwirq % irq_virq_count;
-
- /* Look for default host if nececssary */
- if (host == NULL)
- host = irq_default_host;
- if (host == NULL)
- return NO_IRQ;
-
- /* legacy -> bail early */
- if (host->revmap_type == IRQ_HOST_MAP_LEGACY)
- return hwirq;
-
- /* Slow path does a linear search of the map */
- if (hint < NUM_ISA_INTERRUPTS)
- hint = NUM_ISA_INTERRUPTS;
- i = hint;
- do {
- if (irq_map[i].host == host &&
- irq_map[i].hwirq == hwirq)
- return i;
- i++;
- if (i >= irq_virq_count)
- i = NUM_ISA_INTERRUPTS;
- } while(i != hint);
- return NO_IRQ;
-}
-EXPORT_SYMBOL_GPL(irq_find_mapping);
-
#ifdef CONFIG_SMP
int irq_choose_cpu(const struct cpumask *mask)
{
@@ -929,232 +539,11 @@ int irq_choose_cpu(const struct cpumask *mask)
}
#endif
-unsigned int irq_radix_revmap_lookup(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- struct irq_map_entry *ptr;
- unsigned int virq;
-
- if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_TREE))
- return irq_find_mapping(host, hwirq);
-
- /*
- * The ptr returned references the static global irq_map.
- * but freeing an irq can delete nodes along the path to
- * do the lookup via call_rcu.
- */
- rcu_read_lock();
- ptr = radix_tree_lookup(&host->revmap_data.tree, hwirq);
- rcu_read_unlock();
-
- /*
- * If found in radix tree, then fine.
- * Else fallback to linear lookup - this should not happen in practice
- * as it means that we failed to insert the node in the radix tree.
- */
- if (ptr)
- virq = ptr - irq_map;
- else
- virq = irq_find_mapping(host, hwirq);
-
- return virq;
-}
-
-void irq_radix_revmap_insert(struct irq_host *host, unsigned int virq,
- irq_hw_number_t hwirq)
-{
- if (WARN_ON(host->revmap_type != IRQ_HOST_MAP_TREE))
- return;
-
- if (virq != NO_IRQ) {
- mutex_lock(&revmap_trees_mutex);
- radix_tree_insert(&host->revmap_data.tree, hwirq,
- &irq_map[virq]);
- mutex_unlock(&revmap_trees_mutex);
- }
-}
-
-unsigned int irq_linear_revmap(struct irq_host *host,
- irq_hw_number_t hwirq)
-{
- unsigned int *revmap;
-
- if (WARN_ON_ONCE(host->revmap_type != IRQ_HOST_MAP_LINEAR))
- return irq_find_mapping(host, hwirq);
-
- /* Check revmap bounds */
- if (unlikely(hwirq >= host->revmap_data.linear.size))
- return irq_find_mapping(host, hwirq);
-
- /* Check if revmap was allocated */
- revmap = host->revmap_data.linear.revmap;
- if (unlikely(revmap == NULL))
- return irq_find_mapping(host, hwirq);
-
- /* Fill up revmap with slow path if no mapping found */
- if (unlikely(revmap[hwirq] == NO_IRQ))
- revmap[hwirq] = irq_find_mapping(host, hwirq);
-
- return revmap[hwirq];
-}
-
-unsigned int irq_alloc_virt(struct irq_host *host,
- unsigned int count,
- unsigned int hint)
-{
- unsigned long flags;
- unsigned int i, j, found = NO_IRQ;
-
- if (count == 0 || count > (irq_virq_count - NUM_ISA_INTERRUPTS))
- return NO_IRQ;
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
-
- /* Use hint for 1 interrupt if any */
- if (count == 1 && hint >= NUM_ISA_INTERRUPTS &&
- hint < irq_virq_count && irq_map[hint].host == NULL) {
- found = hint;
- goto hint_found;
- }
-
- /* Look for count consecutive numbers in the allocatable
- * (non-legacy) space
- */
- for (i = NUM_ISA_INTERRUPTS, j = 0; i < irq_virq_count; i++) {
- if (irq_map[i].host != NULL)
- j = 0;
- else
- j++;
-
- if (j == count) {
- found = i - count + 1;
- break;
- }
- }
- if (found == NO_IRQ) {
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return NO_IRQ;
- }
- hint_found:
- for (i = found; i < (found + count); i++) {
- irq_map[i].hwirq = host->inval_irq;
- smp_wmb();
- irq_map[i].host = host;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
- return found;
-}
-
-void irq_free_virt(unsigned int virq, unsigned int count)
-{
- unsigned long flags;
- unsigned int i;
-
- WARN_ON (virq < NUM_ISA_INTERRUPTS);
- WARN_ON (count == 0 || (virq + count) > irq_virq_count);
-
- if (virq < NUM_ISA_INTERRUPTS) {
- if (virq + count < NUM_ISA_INTERRUPTS)
- return;
- count =- NUM_ISA_INTERRUPTS - virq;
- virq = NUM_ISA_INTERRUPTS;
- }
-
- if (count > irq_virq_count || virq > irq_virq_count - count) {
- if (virq > irq_virq_count)
- return;
- count = irq_virq_count - virq;
- }
-
- raw_spin_lock_irqsave(&irq_big_lock, flags);
- for (i = virq; i < (virq + count); i++) {
- struct irq_host *host;
-
- host = irq_map[i].host;
- irq_map[i].hwirq = host->inval_irq;
- smp_wmb();
- irq_map[i].host = NULL;
- }
- raw_spin_unlock_irqrestore(&irq_big_lock, flags);
-}
-
int arch_early_irq_init(void)
{
return 0;
}
-#ifdef CONFIG_VIRQ_DEBUG
-static int virq_debug_show(struct seq_file *m, void *private)
-{
- unsigned long flags;
- struct irq_desc *desc;
- const char *p;
- static const char none[] = "none";
- void *data;
- int i;
-
- seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq",
- "chip name", "chip data", "host name");
-
- for (i = 1; i < nr_irqs; i++) {
- desc = irq_to_desc(i);
- if (!desc)
- continue;
-
- raw_spin_lock_irqsave(&desc->lock, flags);
-
- if (desc->action && desc->action->handler) {
- struct irq_chip *chip;
-
- seq_printf(m, "%5d ", i);
- seq_printf(m, "0x%05lx ", irq_map[i].hwirq);
-
- chip = irq_desc_get_chip(desc);
- if (chip && chip->name)
- p = chip->name;
- else
- p = none;
- seq_printf(m, "%-15s ", p);
-
- data = irq_desc_get_chip_data(desc);
- seq_printf(m, "0x%16p ", data);
-
- if (irq_map[i].host && irq_map[i].host->of_node)
- p = irq_map[i].host->of_node->full_name;
- else
- p = none;
- seq_printf(m, "%s\n", p);
- }
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- }
-
- return 0;
-}
-
-static int virq_debug_open(struct inode *inode, struct file *file)
-{
- return single_open(file, virq_debug_show, inode->i_private);
-}
-
-static const struct file_operations virq_debug_fops = {
- .open = virq_debug_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static int __init irq_debugfs_init(void)
-{
- if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
- NULL, &virq_debug_fops) == NULL)
- return -ENOMEM;
-
- return 0;
-}
-__initcall(irq_debugfs_init);
-#endif /* CONFIG_VIRQ_DEBUG */
-
#ifdef CONFIG_PPC64
static int __init setup_noirqdistrib(char *str)
{
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 2300426e531..ac6e437b102 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
#include <linux/tracehook.h>
#include <linux/signal.h>
+#include <linux/key.h>
#include <asm/hw_breakpoint.h>
#include <asm/uaccess.h>
#include <asm/unistd.h>
@@ -113,8 +114,9 @@ static void check_syscall_restart(struct pt_regs *regs, struct k_sigaction *ka,
}
}
-static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
+static int do_signal(struct pt_regs *regs)
{
+ sigset_t *oldset;
siginfo_t info;
int signr;
struct k_sigaction ka;
@@ -123,7 +125,7 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
if (current_thread_info()->local_flags & _TLF_RESTORE_SIGMASK)
oldset = &current->saved_sigmask;
- else if (!oldset)
+ else
oldset = &current->blocked;
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
@@ -191,14 +193,16 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
return ret;
}
-void do_signal(struct pt_regs *regs, unsigned long thread_info_flags)
+void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
{
if (thread_info_flags & _TIF_SIGPENDING)
- do_signal_pending(NULL, regs);
+ do_signal(regs);
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
clear_thread_flag(TIF_NOTIFY_RESUME);
tracehook_notify_resume(regs);
+ if (current->replacement_session_keyring)
+ key_replace_session_keyring();
}
}
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 6c0ddfc0603..8dde973aaaf 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -12,7 +12,7 @@
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
-extern void do_signal(struct pt_regs *regs, unsigned long thread_info_flags);
+extern void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags);
extern void __user * get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
size_t frame_size, int is_32);
diff --git a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
index 9f09319352c..ca3a062ed1b 100644
--- a/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
+++ b/arch/powerpc/platforms/512x/mpc5121_ads_cpld.c
@@ -21,7 +21,7 @@
#include <asm/prom.h>
static struct device_node *cpld_pic_node;
-static struct irq_host *cpld_pic_host;
+static struct irq_domain *cpld_pic_host;
/*
* Bits to ignore in the misc_status register
@@ -123,13 +123,13 @@ cpld_pic_cascade(unsigned int irq, struct irq_desc *desc)
}
static int
-cpld_pic_host_match(struct irq_host *h, struct device_node *node)
+cpld_pic_host_match(struct irq_domain *h, struct device_node *node)
{
return cpld_pic_node == node;
}
static int
-cpld_pic_host_map(struct irq_host *h, unsigned int virq,
+cpld_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_status_flags(virq, IRQ_LEVEL);
@@ -137,8 +137,7 @@ cpld_pic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct
-irq_host_ops cpld_pic_host_ops = {
+static const struct irq_domain_ops cpld_pic_host_ops = {
.match = cpld_pic_host_match,
.map = cpld_pic_host_map,
};
@@ -191,8 +190,7 @@ mpc5121_ads_cpld_pic_init(void)
cpld_pic_node = of_node_get(np);
- cpld_pic_host =
- irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, 16, &cpld_pic_host_ops, 16);
+ cpld_pic_host = irq_domain_add_linear(np, 16, &cpld_pic_host_ops, NULL);
if (!cpld_pic_host) {
printk(KERN_ERR "CPLD PIC: failed to allocate irq host!\n");
goto end;
diff --git a/arch/powerpc/platforms/52xx/media5200.c b/arch/powerpc/platforms/52xx/media5200.c
index 96f85e5e0cd..17d91b7da31 100644
--- a/arch/powerpc/platforms/52xx/media5200.c
+++ b/arch/powerpc/platforms/52xx/media5200.c
@@ -45,7 +45,7 @@ static struct of_device_id mpc5200_gpio_ids[] __initdata = {
struct media5200_irq {
void __iomem *regs;
spinlock_t lock;
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
};
struct media5200_irq media5200_irq;
@@ -112,7 +112,7 @@ void media5200_irq_cascade(unsigned int virq, struct irq_desc *desc)
raw_spin_unlock(&desc->lock);
}
-static int media5200_irq_map(struct irq_host *h, unsigned int virq,
+static int media5200_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
pr_debug("%s: h=%p, virq=%i, hwirq=%i\n", __func__, h, virq, (int)hw);
@@ -122,7 +122,7 @@ static int media5200_irq_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
+static int media5200_irq_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq,
unsigned int *out_flags)
@@ -136,7 +136,7 @@ static int media5200_irq_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops media5200_irq_ops = {
+static const struct irq_domain_ops media5200_irq_ops = {
.map = media5200_irq_map,
.xlate = media5200_irq_xlate,
};
@@ -173,15 +173,12 @@ static void __init media5200_init_irq(void)
spin_lock_init(&media5200_irq.lock);
- media5200_irq.irqhost = irq_alloc_host(fpga_np, IRQ_HOST_MAP_LINEAR,
- MEDIA5200_NUM_IRQS,
- &media5200_irq_ops, -1);
+ media5200_irq.irqhost = irq_domain_add_linear(fpga_np,
+ MEDIA5200_NUM_IRQS, &media5200_irq_ops, &media5200_irq);
if (!media5200_irq.irqhost)
goto out;
pr_debug("%s: allocated irqhost\n", __func__);
- media5200_irq.irqhost->host_data = &media5200_irq;
-
irq_set_handler_data(cascade_virq, &media5200_irq);
irq_set_chained_handler(cascade_virq, media5200_irq_cascade);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
index f94f06e5276..028470b9588 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c
@@ -81,7 +81,7 @@ MODULE_LICENSE("GPL");
* @regs: virtual address of GPT registers
* @lock: spinlock to coordinate between different functions.
* @gc: gpio_chip instance structure; used when GPIO is enabled
- * @irqhost: Pointer to irq_host instance; used when IRQ mode is supported
+ * @irqhost: Pointer to irq_domain instance; used when IRQ mode is supported
* @wdt_mode: only relevant for gpt0: bit 0 (MPC52xx_GPT_CAN_WDT) indicates
* if the gpt may be used as wdt, bit 1 (MPC52xx_GPT_IS_WDT) indicates
* if the timer is actively used as wdt which blocks gpt functions
@@ -91,7 +91,7 @@ struct mpc52xx_gpt_priv {
struct device *dev;
struct mpc52xx_gpt __iomem *regs;
spinlock_t lock;
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
u32 ipb_freq;
u8 wdt_mode;
@@ -204,7 +204,7 @@ void mpc52xx_gpt_irq_cascade(unsigned int virq, struct irq_desc *desc)
}
}
-static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
+static int mpc52xx_gpt_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct mpc52xx_gpt_priv *gpt = h->host_data;
@@ -216,7 +216,7 @@ static int mpc52xx_gpt_irq_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc52xx_gpt_irq_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq,
unsigned int *out_flags)
@@ -236,7 +236,7 @@ static int mpc52xx_gpt_irq_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops mpc52xx_gpt_irq_ops = {
+static const struct irq_domain_ops mpc52xx_gpt_irq_ops = {
.map = mpc52xx_gpt_irq_map,
.xlate = mpc52xx_gpt_irq_xlate,
};
@@ -252,14 +252,12 @@ mpc52xx_gpt_irq_setup(struct mpc52xx_gpt_priv *gpt, struct device_node *node)
if (!cascade_virq)
return;
- gpt->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR, 1,
- &mpc52xx_gpt_irq_ops, -1);
+ gpt->irqhost = irq_domain_add_linear(node, 1, &mpc52xx_gpt_irq_ops, gpt);
if (!gpt->irqhost) {
- dev_err(gpt->dev, "irq_alloc_host() failed\n");
+ dev_err(gpt->dev, "irq_domain_add_linear() failed\n");
return;
}
- gpt->irqhost->host_data = gpt;
irq_set_handler_data(cascade_virq, gpt);
irq_set_chained_handler(cascade_virq, mpc52xx_gpt_irq_cascade);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
index 1a9a4957057..8520b58a5e9 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_pic.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -132,7 +132,7 @@ static struct of_device_id mpc52xx_sdma_ids[] __initdata = {
static struct mpc52xx_intr __iomem *intr;
static struct mpc52xx_sdma __iomem *sdma;
-static struct irq_host *mpc52xx_irqhost = NULL;
+static struct irq_domain *mpc52xx_irqhost = NULL;
static unsigned char mpc52xx_map_senses[4] = {
IRQ_TYPE_LEVEL_HIGH,
@@ -301,7 +301,7 @@ static int mpc52xx_is_extirq(int l1, int l2)
/**
* mpc52xx_irqhost_xlate - translate virq# from device tree interrupts property
*/
-static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc52xx_irqhost_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq,
unsigned int *out_flags)
@@ -335,7 +335,7 @@ static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
/**
* mpc52xx_irqhost_map - Hook to map from virq to an irq_chip structure
*/
-static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
+static int mpc52xx_irqhost_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t irq)
{
int l1irq;
@@ -384,7 +384,7 @@ static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops mpc52xx_irqhost_ops = {
+static const struct irq_domain_ops mpc52xx_irqhost_ops = {
.xlate = mpc52xx_irqhost_xlate,
.map = mpc52xx_irqhost_map,
};
@@ -444,9 +444,9 @@ void __init mpc52xx_init_irq(void)
* As last step, add an irq host to translate the real
* hw irq information provided by the ofw to linux virq
*/
- mpc52xx_irqhost = irq_alloc_host(picnode, IRQ_HOST_MAP_LINEAR,
+ mpc52xx_irqhost = irq_domain_add_linear(picnode,
MPC52xx_IRQ_HIGHTESTHWIRQ,
- &mpc52xx_irqhost_ops, -1);
+ &mpc52xx_irqhost_ops, NULL);
if (!mpc52xx_irqhost)
panic(__FILE__ ": Cannot allocate the IRQ host\n");
diff --git a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
index 8ccf9ed62fe..328d221fd1c 100644
--- a/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
+++ b/arch/powerpc/platforms/82xx/pq2ads-pci-pic.c
@@ -29,7 +29,7 @@ static DEFINE_RAW_SPINLOCK(pci_pic_lock);
struct pq2ads_pci_pic {
struct device_node *node;
- struct irq_host *host;
+ struct irq_domain *host;
struct {
u32 stat;
@@ -103,7 +103,7 @@ 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,
+static int pci_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_status_flags(virq, IRQ_LEVEL);
@@ -112,14 +112,14 @@ static int pci_pic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops pci_pic_host_ops = {
+static const struct irq_domain_ops pci_pic_host_ops = {
.map = pci_pic_host_map,
};
int __init pq2ads_pci_init_irq(void)
{
struct pq2ads_pci_pic *priv;
- struct irq_host *host;
+ struct irq_domain *host;
struct device_node *np;
int ret = -ENODEV;
int irq;
@@ -156,17 +156,13 @@ int __init pq2ads_pci_init_irq(void)
out_be32(&priv->regs->mask, ~0);
mb();
- host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, NUM_IRQS,
- &pci_pic_host_ops, NUM_IRQS);
+ host = irq_domain_add_linear(np, NUM_IRQS, &pci_pic_host_ops, priv);
if (!host) {
ret = -ENOMEM;
goto out_unmap_regs;
}
- host->host_data = priv;
-
priv->host = host;
- host->host_data = priv;
irq_set_handler_data(irq, priv);
irq_set_chained_handler(irq, pq2ads_pci_irq_demux);
diff --git a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
index 12cb9bb2cc6..3bbbf748948 100644
--- a/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
+++ b/arch/powerpc/platforms/85xx/socrates_fpga_pic.c
@@ -51,7 +51,7 @@ static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
static void __iomem *socrates_fpga_pic_iobase;
-static struct irq_host *socrates_fpga_pic_irq_host;
+static struct irq_domain *socrates_fpga_pic_irq_host;
static unsigned int socrates_fpga_irqs[3];
static inline uint32_t socrates_fpga_pic_read(int reg)
@@ -227,7 +227,7 @@ static struct irq_chip socrates_fpga_pic_chip = {
.irq_set_type = socrates_fpga_pic_set_type,
};
-static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
+static int socrates_fpga_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hwirq)
{
/* All interrupts are LEVEL sensitive */
@@ -238,7 +238,7 @@ static int socrates_fpga_pic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int socrates_fpga_pic_host_xlate(struct irq_host *h,
+static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
struct device_node *ct, const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
{
@@ -269,7 +269,7 @@ static int socrates_fpga_pic_host_xlate(struct irq_host *h,
return 0;
}
-static struct irq_host_ops socrates_fpga_pic_host_ops = {
+static const struct irq_domain_ops socrates_fpga_pic_host_ops = {
.map = socrates_fpga_pic_host_map,
.xlate = socrates_fpga_pic_host_xlate,
};
@@ -279,10 +279,9 @@ void socrates_fpga_pic_init(struct device_node *pic)
unsigned long flags;
int i;
- /* Setup an irq_host structure */
- socrates_fpga_pic_irq_host = irq_alloc_host(pic, IRQ_HOST_MAP_LINEAR,
- SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops,
- SOCRATES_FPGA_NUM_IRQS);
+ /* Setup an irq_domain structure */
+ socrates_fpga_pic_irq_host = irq_domain_add_linear(pic,
+ SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL);
if (socrates_fpga_pic_irq_host == NULL) {
pr_err("FPGA PIC: Unable to allocate host\n");
return;
diff --git a/arch/powerpc/platforms/86xx/gef_pic.c b/arch/powerpc/platforms/86xx/gef_pic.c
index 94594e58594..af3fd697de8 100644
--- a/arch/powerpc/platforms/86xx/gef_pic.c
+++ b/arch/powerpc/platforms/86xx/gef_pic.c
@@ -50,7 +50,7 @@
static DEFINE_RAW_SPINLOCK(gef_pic_lock);
static void __iomem *gef_pic_irq_reg_base;
-static struct irq_host *gef_pic_irq_host;
+static struct irq_domain *gef_pic_irq_host;
static int gef_pic_cascade_irq;
/*
@@ -153,7 +153,7 @@ static struct irq_chip gef_pic_chip = {
/* When an interrupt is being configured, this call allows some flexibilty
* in deciding which irq_chip structure is used
*/
-static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
+static int gef_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hwirq)
{
/* All interrupts are LEVEL sensitive */
@@ -163,7 +163,7 @@ static int gef_pic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int gef_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
{
@@ -177,7 +177,7 @@ static int gef_pic_host_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops gef_pic_host_ops = {
+static const struct irq_domain_ops gef_pic_host_ops = {
.map = gef_pic_host_map,
.xlate = gef_pic_host_xlate,
};
@@ -211,10 +211,9 @@ void __init gef_pic_init(struct device_node *np)
return;
}
- /* Setup an irq_host structure */
- gef_pic_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
- GEF_PIC_NUM_IRQS,
- &gef_pic_host_ops, NO_IRQ);
+ /* Setup an irq_domain structure */
+ gef_pic_irq_host = irq_domain_add_linear(np, GEF_PIC_NUM_IRQS,
+ &gef_pic_host_ops, NULL);
if (gef_pic_irq_host == NULL)
return;
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 40a6e34793b..db360fc4cf0 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -67,7 +67,7 @@
struct axon_msic {
- struct irq_host *irq_host;
+ struct irq_domain *irq_domain;
__le32 *fifo_virt;
dma_addr_t fifo_phys;
dcr_host_t dcr_host;
@@ -152,7 +152,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
static struct axon_msic *find_msi_translator(struct pci_dev *dev)
{
- struct irq_host *irq_host;
+ struct irq_domain *irq_domain;
struct device_node *dn, *tmp;
const phandle *ph;
struct axon_msic *msic = NULL;
@@ -184,14 +184,14 @@ static struct axon_msic *find_msi_translator(struct pci_dev *dev)
goto out_error;
}
- irq_host = irq_find_host(dn);
- if (!irq_host) {
- dev_dbg(&dev->dev, "axon_msi: no irq_host found for node %s\n",
+ irq_domain = irq_find_host(dn);
+ if (!irq_domain) {
+ dev_dbg(&dev->dev, "axon_msi: no irq_domain found for node %s\n",
dn->full_name);
goto out_error;
}
- msic = irq_host->host_data;
+ msic = irq_domain->host_data;
out_error:
of_node_put(dn);
@@ -280,7 +280,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
BUILD_BUG_ON(NR_IRQS > 65536);
list_for_each_entry(entry, &dev->msi_list, list) {
- virq = irq_create_direct_mapping(msic->irq_host);
+ virq = irq_create_direct_mapping(msic->irq_domain);
if (virq == NO_IRQ) {
dev_warn(&dev->dev,
"axon_msi: virq allocation failed!\n");
@@ -318,7 +318,7 @@ static struct irq_chip msic_irq_chip = {
.name = "AXON-MSI",
};
-static int msic_host_map(struct irq_host *h, unsigned int virq,
+static int msic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_chip_data(virq, h->host_data);
@@ -327,7 +327,7 @@ static int msic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops msic_host_ops = {
+static const struct irq_domain_ops msic_host_ops = {
.map = msic_host_map,
};
@@ -337,7 +337,7 @@ static void axon_msi_shutdown(struct platform_device *device)
u32 tmp;
pr_devel("axon_msi: disabling %s\n",
- msic->irq_host->of_node->full_name);
+ msic->irq_domain->of_node->full_name);
tmp = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
@@ -392,16 +392,13 @@ static int axon_msi_probe(struct platform_device *device)
}
memset(msic->fifo_virt, 0xff, MSIC_FIFO_SIZE_BYTES);
- msic->irq_host = irq_alloc_host(dn, IRQ_HOST_MAP_NOMAP,
- NR_IRQS, &msic_host_ops, 0);
- if (!msic->irq_host) {
- printk(KERN_ERR "axon_msi: couldn't allocate irq_host for %s\n",
+ msic->irq_domain = irq_domain_add_nomap(dn, &msic_host_ops, msic);
+ if (!msic->irq_domain) {
+ printk(KERN_ERR "axon_msi: couldn't allocate irq_domain for %s\n",
dn->full_name);
goto out_free_fifo;
}
- msic->irq_host->host_data = msic;
-
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);
diff --git a/arch/powerpc/platforms/cell/beat_interrupt.c b/arch/powerpc/platforms/cell/beat_interrupt.c
index 55015e1f693..e5c3a2c6090 100644
--- a/arch/powerpc/platforms/cell/beat_interrupt.c
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c
@@ -34,7 +34,7 @@ static DEFINE_RAW_SPINLOCK(beatic_irq_mask_lock);
static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64];
static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64];
-static struct irq_host *beatic_host;
+static struct irq_domain *beatic_host;
/*
* In this implementation, "virq" == "IRQ plug number",
@@ -122,7 +122,7 @@ static struct irq_chip beatic_pic = {
*
* Note that the number (virq) is already assigned at upper layer.
*/
-static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
+static void beatic_pic_host_unmap(struct irq_domain *h, unsigned int virq)
{
beat_destruct_irq_plug(virq);
}
@@ -133,7 +133,7 @@ static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
*
* Note that the number (virq) is already assigned at upper layer.
*/
-static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
+static int beatic_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
int64_t err;
@@ -154,7 +154,7 @@ static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
* Called from irq_create_of_mapping() only.
* Note: We have only 1 entry to translate.
*/
-static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int beatic_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq,
unsigned int *out_flags)
@@ -166,13 +166,13 @@ static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static int beatic_pic_host_match(struct irq_host *h, struct device_node *np)
+static int beatic_pic_host_match(struct irq_domain *h, struct device_node *np)
{
/* Match all */
return 1;
}
-static struct irq_host_ops beatic_pic_host_ops = {
+static const struct irq_domain_ops beatic_pic_host_ops = {
.map = beatic_pic_host_map,
.unmap = beatic_pic_host_unmap,
.xlate = beatic_pic_host_xlate,
@@ -239,9 +239,7 @@ void __init beatic_init_IRQ(void)
ppc_md.get_irq = beatic_get_irq;
/* Allocate an irq host */
- beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
- &beatic_pic_host_ops,
- 0);
+ beatic_host = irq_domain_add_nomap(NULL, &beatic_pic_host_ops, NULL);
BUG_ON(beatic_host == NULL);
irq_set_default_host(beatic_host);
}
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index 96a433dd2d6..2d42f3bb66d 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -56,7 +56,7 @@ struct iic {
static DEFINE_PER_CPU(struct iic, cpu_iic);
#define IIC_NODE_COUNT 2
-static struct irq_host *iic_host;
+static struct irq_domain *iic_host;
/* Convert between "pending" bits and hw irq number */
static irq_hw_number_t iic_pending_to_hwnum(struct cbe_iic_pending_bits bits)
@@ -186,7 +186,7 @@ void iic_message_pass(int cpu, int msg)
out_be64(&per_cpu(cpu_iic, cpu).regs->generate, (0xf - msg) << 4);
}
-struct irq_host *iic_get_irq_host(int node)
+struct irq_domain *iic_get_irq_host(int node)
{
return iic_host;
}
@@ -222,13 +222,13 @@ void iic_request_IPIs(void)
#endif /* CONFIG_SMP */
-static int iic_host_match(struct irq_host *h, struct device_node *node)
+static int iic_host_match(struct irq_domain *h, struct device_node *node)
{
return of_device_is_compatible(node,
"IBM,CBEA-Internal-Interrupt-Controller");
}
-static int iic_host_map(struct irq_host *h, unsigned int virq,
+static int iic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
switch (hw & IIC_IRQ_TYPE_MASK) {
@@ -245,7 +245,7 @@ static int iic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int iic_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
@@ -285,7 +285,7 @@ static int iic_host_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops iic_host_ops = {
+static const struct irq_domain_ops iic_host_ops = {
.match = iic_host_match,
.map = iic_host_map,
.xlate = iic_host_xlate,
@@ -378,8 +378,8 @@ static int __init setup_iic(void)
void __init iic_init_IRQ(void)
{
/* Setup an irq host data structure */
- iic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_LINEAR, IIC_SOURCE_COUNT,
- &iic_host_ops, IIC_IRQ_INVALID);
+ iic_host = irq_domain_add_linear(NULL, IIC_SOURCE_COUNT, &iic_host_ops,
+ NULL);
BUG_ON(iic_host == NULL);
irq_set_default_host(iic_host);
diff --git a/arch/powerpc/platforms/cell/spider-pic.c b/arch/powerpc/platforms/cell/spider-pic.c
index 442c28c00f8..d8b7cc8a66c 100644
--- a/arch/powerpc/platforms/cell/spider-pic.c
+++ b/arch/powerpc/platforms/cell/spider-pic.c
@@ -62,7 +62,7 @@ enum {
#define SPIDER_IRQ_INVALID 63
struct spider_pic {
- struct irq_host *host;
+ struct irq_domain *host;
void __iomem *regs;
unsigned int node_id;
};
@@ -168,7 +168,7 @@ static struct irq_chip spider_pic = {
.irq_set_type = spider_set_irq_type,
};
-static int spider_host_map(struct irq_host *h, unsigned int virq,
+static int spider_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_chip_data(virq, h->host_data);
@@ -180,7 +180,7 @@ static int spider_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
+static int spider_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
@@ -194,7 +194,7 @@ static int spider_host_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops spider_host_ops = {
+static const struct irq_domain_ops spider_host_ops = {
.map = spider_host_map,
.xlate = spider_host_xlate,
};
@@ -299,12 +299,10 @@ static void __init spider_init_one(struct device_node *of_node, int chip,
panic("spider_pic: can't map registers !");
/* Allocate a host */
- pic->host = irq_alloc_host(of_node, IRQ_HOST_MAP_LINEAR,
- SPIDER_SRC_COUNT, &spider_host_ops,
- SPIDER_IRQ_INVALID);
+ pic->host = irq_domain_add_linear(of_node, SPIDER_SRC_COUNT,
+ &spider_host_ops, pic);
if (pic->host == NULL)
panic("spider_pic: can't allocate irq host !");
- pic->host->host_data = pic;
/* Go through all sources and disable them */
for (i = 0; i < SPIDER_SRC_COUNT; i++) {
diff --git a/arch/powerpc/platforms/embedded6xx/flipper-pic.c b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
index f61a2dd96b9..53d6eee0196 100644
--- a/arch/powerpc/platforms/embedded6xx/flipper-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/flipper-pic.c
@@ -96,9 +96,9 @@ static struct irq_chip flipper_pic = {
*
*/
-static struct irq_host *flipper_irq_host;
+static struct irq_domain *flipper_irq_host;
-static int flipper_pic_map(struct irq_host *h, unsigned int virq,
+static int flipper_pic_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hwirq)
{
irq_set_chip_data(virq, h->host_data);
@@ -107,13 +107,13 @@ static int flipper_pic_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int flipper_pic_match(struct irq_host *h, struct device_node *np)
+static int flipper_pic_match(struct irq_domain *h, struct device_node *np)
{
return 1;
}
-static struct irq_host_ops flipper_irq_host_ops = {
+static const struct irq_domain_ops flipper_irq_domain_ops = {
.map = flipper_pic_map,
.match = flipper_pic_match,
};
@@ -130,10 +130,10 @@ static void __flipper_quiesce(void __iomem *io_base)
out_be32(io_base + FLIPPER_ICR, 0xffffffff);
}
-struct irq_host * __init flipper_pic_init(struct device_node *np)
+struct irq_domain * __init flipper_pic_init(struct device_node *np)
{
struct device_node *pi;
- struct irq_host *irq_host = NULL;
+ struct irq_domain *irq_domain = NULL;
struct resource res;
void __iomem *io_base;
int retval;
@@ -159,17 +159,15 @@ struct irq_host * __init flipper_pic_init(struct device_node *np)
__flipper_quiesce(io_base);
- irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, FLIPPER_NR_IRQS,
- &flipper_irq_host_ops, -1);
- if (!irq_host) {
- pr_err("failed to allocate irq_host\n");
+ irq_domain = irq_domain_add_linear(np, FLIPPER_NR_IRQS,
+ &flipper_irq_domain_ops, io_base);
+ if (!irq_domain) {
+ pr_err("failed to allocate irq_domain\n");
return NULL;
}
- irq_host->host_data = io_base;
-
out:
- return irq_host;
+ return irq_domain;
}
unsigned int flipper_pic_get_irq(void)
diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
index e4919170c6b..3006b5117ec 100644
--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
+++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c
@@ -89,9 +89,9 @@ static struct irq_chip hlwd_pic = {
*
*/
-static struct irq_host *hlwd_irq_host;
+static struct irq_domain *hlwd_irq_host;
-static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
+static int hlwd_pic_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hwirq)
{
irq_set_chip_data(virq, h->host_data);
@@ -100,11 +100,11 @@ static int hlwd_pic_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops hlwd_irq_host_ops = {
+static const struct irq_domain_ops hlwd_irq_domain_ops = {
.map = hlwd_pic_map,
};
-static unsigned int __hlwd_pic_get_irq(struct irq_host *h)
+static unsigned int __hlwd_pic_get_irq(struct irq_domain *h)
{
void __iomem *io_base = h->host_data;
int irq;
@@ -123,14 +123,14 @@ static void hlwd_pic_irq_cascade(unsigned int cascade_virq,
struct irq_desc *desc)
{
struct irq_chip *chip = irq_desc_get_chip(desc);
- struct irq_host *irq_host = irq_get_handler_data(cascade_virq);
+ struct irq_domain *irq_domain = irq_get_handler_data(cascade_virq);
unsigned int virq;
raw_spin_lock(&desc->lock);
chip->irq_mask(&desc->irq_data); /* IRQ_LEVEL */
raw_spin_unlock(&desc->lock);
- virq = __hlwd_pic_get_irq(irq_host);
+ virq = __hlwd_pic_get_irq(irq_domain);
if (virq != NO_IRQ)
generic_handle_irq(virq);
else
@@ -155,9 +155,9 @@ static void __hlwd_quiesce(void __iomem *io_base)
out_be32(io_base + HW_BROADWAY_ICR, 0xffffffff);
}
-struct irq_host *hlwd_pic_init(struct device_node *np)
+struct irq_domain *hlwd_pic_init(struct device_node *np)
{
- struct irq_host *irq_host;
+ struct irq_domain *irq_domain;
struct resource res;
void __iomem *io_base;
int retval;
@@ -177,15 +177,14 @@ struct irq_host *hlwd_pic_init(struct device_node *np)
__hlwd_quiesce(io_base);
- irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, HLWD_NR_IRQS,
- &hlwd_irq_host_ops, -1);
- if (!irq_host) {
- pr_err("failed to allocate irq_host\n");
+ irq_domain = irq_domain_add_linear(np, HLWD_NR_IRQS,
+ &hlwd_irq_domain_ops, io_base);
+ if (!irq_domain) {
+ pr_err("failed to allocate irq_domain\n");
return NULL;
}
- irq_host->host_data = io_base;
- return irq_host;
+ return irq_domain;
}
unsigned int hlwd_pic_get_irq(void)
@@ -200,7 +199,7 @@ unsigned int hlwd_pic_get_irq(void)
void hlwd_pic_probe(void)
{
- struct irq_host *host;
+ struct irq_domain *host;
struct device_node *np;
const u32 *interrupts;
int cascade_virq;
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index b2103453eb0..05ce5164caf 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -342,7 +342,7 @@ unsigned int iSeries_get_irq(void)
#ifdef CONFIG_PCI
-static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
+static int iseries_irq_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_chip_and_handler(virq, &iseries_pic, handle_fasteoi_irq);
@@ -350,13 +350,13 @@ static int iseries_irq_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int iseries_irq_host_match(struct irq_host *h, struct device_node *np)
+static int iseries_irq_host_match(struct irq_domain *h, struct device_node *np)
{
/* Match all */
return 1;
}
-static struct irq_host_ops iseries_irq_host_ops = {
+static const struct irq_domain_ops iseries_irq_domain_ops = {
.map = iseries_irq_host_map,
.match = iseries_irq_host_match,
};
@@ -368,7 +368,7 @@ static struct irq_host_ops iseries_irq_host_ops = {
void __init iSeries_init_IRQ(void)
{
/* Register PCI event handler and open an event path */
- struct irq_host *host;
+ struct irq_domain *host;
int ret;
/*
@@ -380,8 +380,7 @@ void __init iSeries_init_IRQ(void)
/* Create irq host. No need for a revmap since HV will give us
* back our virtual irq number
*/
- host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
- &iseries_irq_host_ops, 0);
+ host = irq_domain_add_nomap(NULL, &iseries_irq_domain_ops, NULL);
BUG_ON(host == NULL);
irq_set_default_host(host);
diff --git a/arch/powerpc/platforms/powermac/pic.c b/arch/powerpc/platforms/powermac/pic.c
index 7761aabfc29..92afc382a49 100644
--- a/arch/powerpc/platforms/powermac/pic.c
+++ b/arch/powerpc/platforms/powermac/pic.c
@@ -61,7 +61,7 @@ static DEFINE_RAW_SPINLOCK(pmac_pic_lock);
static unsigned long ppc_lost_interrupts[NR_MASK_WORDS];
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
static int pmac_irq_cascade = -1;
-static struct irq_host *pmac_pic_host;
+static struct irq_domain *pmac_pic_host;
static void __pmac_retrigger(unsigned int irq_nr)
{
@@ -268,13 +268,13 @@ static struct irqaction gatwick_cascade_action = {
.name = "cascade",
};
-static int pmac_pic_host_match(struct irq_host *h, struct device_node *node)
+static int pmac_pic_host_match(struct irq_domain *h, struct device_node *node)
{
/* We match all, we don't always have a node anyway */
return 1;
}
-static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
+static int pmac_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
if (hw >= max_irqs)
@@ -288,21 +288,10 @@ static int pmac_pic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int pmac_pic_host_xlate(struct irq_host *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_flags)
-
-{
- *out_flags = IRQ_TYPE_NONE;
- *out_hwirq = *intspec;
- return 0;
-}
-
-static struct irq_host_ops pmac_pic_host_ops = {
+static const struct irq_domain_ops pmac_pic_host_ops = {
.match = pmac_pic_host_match,
.map = pmac_pic_host_map,
- .xlate = pmac_pic_host_xlate,
+ .xlate = irq_domain_xlate_onecell,
};
static void __init pmac_pic_probe_oldstyle(void)
@@ -352,9 +341,8 @@ static void __init pmac_pic_probe_oldstyle(void)
/*
* Allocate an irq host
*/
- pmac_pic_host = irq_alloc_host(master, IRQ_HOST_MAP_LINEAR, max_irqs,
- &pmac_pic_host_ops,
- max_irqs);
+ pmac_pic_host = irq_domain_add_linear(master, max_irqs,
+ &pmac_pic_host_ops, NULL);
BUG_ON(pmac_pic_host == NULL);
irq_set_default_host(pmac_pic_host);
diff --git a/arch/powerpc/platforms/powermac/smp.c b/arch/powerpc/platforms/powermac/smp.c
index 44d769258eb..a81e5a88fbd 100644
--- a/arch/powerpc/platforms/powermac/smp.c
+++ b/arch/powerpc/platforms/powermac/smp.c
@@ -125,7 +125,7 @@ static volatile u32 __iomem *psurge_start;
static int psurge_type = PSURGE_NONE;
/* irq for secondary cpus to report */
-static struct irq_host *psurge_host;
+static struct irq_domain *psurge_host;
int psurge_secondary_virq;
/*
@@ -176,7 +176,7 @@ static void smp_psurge_cause_ipi(int cpu, unsigned long data)
psurge_set_ipi(cpu);
}
-static int psurge_host_map(struct irq_host *h, unsigned int virq,
+static int psurge_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_percpu_irq);
@@ -184,7 +184,7 @@ static int psurge_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-struct irq_host_ops psurge_host_ops = {
+static const struct irq_domain_ops psurge_host_ops = {
.map = psurge_host_map,
};
@@ -192,8 +192,7 @@ static int psurge_secondary_ipi_init(void)
{
int rc = -ENOMEM;
- psurge_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
- &psurge_host_ops, 0);
+ psurge_host = irq_domain_add_nomap(NULL, &psurge_host_ops, NULL);
if (psurge_host)
psurge_secondary_virq = irq_create_direct_mapping(psurge_host);
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
index 617efa12a3a..2a4ff86cc21 100644
--- a/arch/powerpc/platforms/ps3/interrupt.c
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -667,7 +667,7 @@ static void __maybe_unused _dump_mask(struct ps3_private *pd,
static void dump_bmp(struct ps3_private* pd) {};
#endif /* defined(DEBUG) */
-static int ps3_host_map(struct irq_host *h, unsigned int virq,
+static int ps3_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hwirq)
{
DBG("%s:%d: hwirq %lu, virq %u\n", __func__, __LINE__, hwirq,
@@ -678,13 +678,13 @@ static int ps3_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int ps3_host_match(struct irq_host *h, struct device_node *np)
+static int ps3_host_match(struct irq_domain *h, struct device_node *np)
{
/* Match all */
return 1;
}
-static struct irq_host_ops ps3_host_ops = {
+static const struct irq_domain_ops ps3_host_ops = {
.map = ps3_host_map,
.match = ps3_host_match,
};
@@ -751,10 +751,9 @@ void __init ps3_init_IRQ(void)
{
int result;
unsigned cpu;
- struct irq_host *host;
+ struct irq_domain *host;
- host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0, &ps3_host_ops,
- PS3_INVALID_OUTLET);
+ host = irq_domain_add_nomap(NULL, &ps3_host_ops, NULL);
irq_set_default_host(host);
irq_set_virq_count(PS3_PLUG_MAX + 1);
diff --git a/arch/powerpc/platforms/wsp/opb_pic.c b/arch/powerpc/platforms/wsp/opb_pic.c
index 19f353dfcd0..cb565bf9365 100644
--- a/arch/powerpc/platforms/wsp/opb_pic.c
+++ b/arch/powerpc/platforms/wsp/opb_pic.c
@@ -30,7 +30,7 @@
static int opb_index = 0;
struct opb_pic {
- struct irq_host *host;
+ struct irq_domain *host;
void *regs;
int index;
spinlock_t lock;
@@ -179,7 +179,7 @@ static struct irq_chip opb_irq_chip = {
.irq_set_type = opb_set_irq_type
};
-static int opb_host_map(struct irq_host *host, unsigned int virq,
+static int opb_host_map(struct irq_domain *host, unsigned int virq,
irq_hw_number_t hwirq)
{
struct opb_pic *opb;
@@ -196,20 +196,9 @@ static int opb_host_map(struct irq_host *host, unsigned int virq,
return 0;
}
-static int opb_host_xlate(struct irq_host *host, struct device_node *dn,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type)
-{
- /* Interrupt size must == 2 */
- BUG_ON(intsize != 2);
- *out_hwirq = intspec[0];
- *out_type = intspec[1];
- return 0;
-}
-
-static struct irq_host_ops opb_host_ops = {
+static const struct irq_domain_ops opb_host_ops = {
.map = opb_host_map,
- .xlate = opb_host_xlate,
+ .xlate = irq_domain_xlate_twocell,
};
irqreturn_t opb_irq_handler(int irq, void *private)
@@ -263,13 +252,11 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
goto free_opb;
}
- /* Allocate an irq host so that Linux knows that despite only
+ /* Allocate an irq domain so that Linux knows that despite only
* having one interrupt to issue, we're the controller for multiple
* hardware IRQs, so later we can lookup their virtual IRQs. */
- opb->host = irq_alloc_host(dn, IRQ_HOST_MAP_LINEAR,
- OPB_NR_IRQS, &opb_host_ops, -1);
-
+ opb->host = irq_domain_add_linear(dn, OPB_NR_IRQS, &opb_host_ops, opb);
if (!opb->host) {
printk(KERN_ERR "opb: Failed to allocate IRQ host!\n");
goto free_regs;
@@ -277,7 +264,6 @@ struct opb_pic *opb_pic_init_one(struct device_node *dn)
opb->index = opb_index++;
spin_lock_init(&opb->lock);
- opb->host->host_data = opb;
/* Disable all interrupts by default */
opb_out(opb, OPB_MLSASIER, 0);
diff --git a/arch/powerpc/platforms/wsp/smp.c b/arch/powerpc/platforms/wsp/smp.c
index 71bd105f386..0ba103ae83a 100644
--- a/arch/powerpc/platforms/wsp/smp.c
+++ b/arch/powerpc/platforms/wsp/smp.c
@@ -71,7 +71,7 @@ int __devinit smp_a2_kick_cpu(int nr)
static int __init smp_a2_probe(void)
{
- return cpus_weight(cpu_possible_map);
+ return num_possible_cpus();
}
static struct smp_ops_t a2_smp_ops = {
diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
index 5d7d59a43c4..d4fa03f2b6a 100644
--- a/arch/powerpc/sysdev/cpm1.c
+++ b/arch/powerpc/sysdev/cpm1.c
@@ -54,7 +54,7 @@ cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */
immap_t __iomem *mpc8xx_immr;
static cpic8xx_t __iomem *cpic_reg;
-static struct irq_host *cpm_pic_host;
+static struct irq_domain *cpm_pic_host;
static void cpm_mask_irq(struct irq_data *d)
{
@@ -98,7 +98,7 @@ int cpm_get_irq(void)
return irq_linear_revmap(cpm_pic_host, cpm_vec);
}
-static int cpm_pic_host_map(struct irq_host *h, unsigned int virq,
+static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -123,7 +123,7 @@ static struct irqaction cpm_error_irqaction = {
.name = "error",
};
-static struct irq_host_ops cpm_pic_host_ops = {
+static const struct irq_domain_ops cpm_pic_host_ops = {
.map = cpm_pic_host_map,
};
@@ -164,8 +164,7 @@ unsigned int cpm_pic_init(void)
out_be32(&cpic_reg->cpic_cimr, 0);
- cpm_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
- 64, &cpm_pic_host_ops, 64);
+ cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL);
if (cpm_pic_host == NULL) {
printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
sirq = NO_IRQ;
diff --git a/arch/powerpc/sysdev/cpm2_pic.c b/arch/powerpc/sysdev/cpm2_pic.c
index bcab50e2a9e..d3be961e2ae 100644
--- a/arch/powerpc/sysdev/cpm2_pic.c
+++ b/arch/powerpc/sysdev/cpm2_pic.c
@@ -50,7 +50,7 @@
static intctl_cpm2_t __iomem *cpm2_intctl;
-static struct irq_host *cpm2_pic_host;
+static struct irq_domain *cpm2_pic_host;
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
@@ -214,7 +214,7 @@ unsigned int cpm2_get_irq(void)
return irq_linear_revmap(cpm2_pic_host, irq);
}
-static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
+static int cpm2_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
pr_debug("cpm2_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -224,21 +224,9 @@ static int cpm2_pic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int cpm2_pic_host_xlate(struct irq_host *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-{
- *out_hwirq = intspec[0];
- if (intsize > 1)
- *out_flags = intspec[1];
- else
- *out_flags = IRQ_TYPE_NONE;
- return 0;
-}
-
-static struct irq_host_ops cpm2_pic_host_ops = {
+static const struct irq_domain_ops cpm2_pic_host_ops = {
.map = cpm2_pic_host_map,
- .xlate = cpm2_pic_host_xlate,
+ .xlate = irq_domain_xlate_onetwocell,
};
void cpm2_pic_init(struct device_node *node)
@@ -275,8 +263,7 @@ void cpm2_pic_init(struct device_node *node)
out_be32(&cpm2_intctl->ic_scprrl, 0x05309770);
/* create a legacy host */
- cpm2_pic_host = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
- 64, &cpm2_pic_host_ops, 64);
+ cpm2_pic_host = irq_domain_add_linear(node, 64, &cpm2_pic_host_ops, NULL);
if (cpm2_pic_host == NULL) {
printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n");
return;
diff --git a/arch/powerpc/sysdev/ehv_pic.c b/arch/powerpc/sysdev/ehv_pic.c
index b6731e4a664..6e0e1005227 100644
--- a/arch/powerpc/sysdev/ehv_pic.c
+++ b/arch/powerpc/sysdev/ehv_pic.c
@@ -182,13 +182,13 @@ unsigned int ehv_pic_get_irq(void)
return irq_linear_revmap(global_ehv_pic->irqhost, irq);
}
-static int ehv_pic_host_match(struct irq_host *h, struct device_node *node)
+static int ehv_pic_host_match(struct irq_domain *h, struct device_node *node)
{
/* Exact match, unless ehv_pic node is NULL */
return h->of_node == NULL || h->of_node == node;
}
-static int ehv_pic_host_map(struct irq_host *h, unsigned int virq,
+static int ehv_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct ehv_pic *ehv_pic = h->host_data;
@@ -217,7 +217,7 @@ static int ehv_pic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int ehv_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
@@ -248,7 +248,7 @@ static int ehv_pic_host_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops ehv_pic_host_ops = {
+static const struct irq_domain_ops ehv_pic_host_ops = {
.match = ehv_pic_host_match,
.map = ehv_pic_host_map,
.xlate = ehv_pic_host_xlate,
@@ -275,9 +275,8 @@ void __init ehv_pic_init(void)
return;
}
- ehv_pic->irqhost = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
- NR_EHV_PIC_INTS, &ehv_pic_host_ops, 0);
-
+ ehv_pic->irqhost = irq_domain_add_linear(np, NR_EHV_PIC_INTS,
+ &ehv_pic_host_ops, ehv_pic);
if (!ehv_pic->irqhost) {
of_node_put(np);
kfree(ehv_pic);
@@ -293,7 +292,6 @@ void __init ehv_pic_init(void)
of_node_put(np2);
}
- ehv_pic->irqhost->host_data = ehv_pic;
ehv_pic->hc_irq = ehv_pic_irq_chip;
ehv_pic->hc_irq.irq_set_affinity = ehv_pic_set_affinity;
ehv_pic->coreint_flag = coreint_flag;
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index ecb5c1946d2..0c01debe963 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -60,7 +60,7 @@ static struct irq_chip fsl_msi_chip = {
.name = "FSL-MSI",
};
-static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
+static int fsl_msi_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct fsl_msi *msi_data = h->host_data;
@@ -74,7 +74,7 @@ static int fsl_msi_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops fsl_msi_host_ops = {
+static const struct irq_domain_ops fsl_msi_host_ops = {
.map = fsl_msi_host_map,
};
@@ -387,8 +387,8 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
}
platform_set_drvdata(dev, msi);
- msi->irqhost = irq_alloc_host(dev->dev.of_node, IRQ_HOST_MAP_LINEAR,
- NR_MSI_IRQS, &fsl_msi_host_ops, 0);
+ msi->irqhost = irq_domain_add_linear(dev->dev.of_node,
+ NR_MSI_IRQS, &fsl_msi_host_ops, msi);
if (msi->irqhost == NULL) {
dev_err(&dev->dev, "No memory for MSI irqhost\n");
@@ -420,8 +420,6 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev)
msi->feature = features->fsl_pic_ip;
- msi->irqhost->host_data = msi;
-
/*
* Remember the phandle, so that we can match with any PCI nodes
* that have an "fsl,msi" property.
diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h
index f6c646a5254..8225f8653f7 100644
--- a/arch/powerpc/sysdev/fsl_msi.h
+++ b/arch/powerpc/sysdev/fsl_msi.h
@@ -26,7 +26,7 @@
#define FSL_PIC_IP_VMPIC 0x00000003
struct fsl_msi {
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
unsigned long cascade_irq;
diff --git a/arch/powerpc/sysdev/i8259.c b/arch/powerpc/sysdev/i8259.c
index d18bb27e4df..997df6a7ab5 100644
--- a/arch/powerpc/sysdev/i8259.c
+++ b/arch/powerpc/sysdev/i8259.c
@@ -25,7 +25,7 @@ static unsigned char cached_8259[2] = { 0xff, 0xff };
static DEFINE_RAW_SPINLOCK(i8259_lock);
-static struct irq_host *i8259_host;
+static struct irq_domain *i8259_host;
/*
* Acknowledge the IRQ using either the PCI host bridge's interrupt
@@ -163,12 +163,12 @@ static struct resource pic_edgectrl_iores = {
.flags = IORESOURCE_BUSY,
};
-static int i8259_host_match(struct irq_host *h, struct device_node *node)
+static int i8259_host_match(struct irq_domain *h, struct device_node *node)
{
return h->of_node == NULL || h->of_node == node;
}
-static int i8259_host_map(struct irq_host *h, unsigned int virq,
+static int i8259_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
pr_debug("i8259_host_map(%d, 0x%lx)\n", virq, hw);
@@ -185,7 +185,7 @@ static int i8259_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
+static int i8259_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
{
@@ -205,13 +205,13 @@ static int i8259_host_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops i8259_host_ops = {
+static struct irq_domain_ops i8259_host_ops = {
.match = i8259_host_match,
.map = i8259_host_map,
.xlate = i8259_host_xlate,
};
-struct irq_host *i8259_get_host(void)
+struct irq_domain *i8259_get_host(void)
{
return i8259_host;
}
@@ -263,8 +263,7 @@ void i8259_init(struct device_node *node, unsigned long intack_addr)
raw_spin_unlock_irqrestore(&i8259_lock, flags);
/* create a legacy host */
- i8259_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY,
- 0, &i8259_host_ops, 0);
+ i8259_host = irq_domain_add_legacy_isa(node, &i8259_host_ops, NULL);
if (i8259_host == NULL) {
printk(KERN_ERR "i8259: failed to allocate irq host !\n");
return;
diff --git a/arch/powerpc/sysdev/ipic.c b/arch/powerpc/sysdev/ipic.c
index 95da897f05a..b50f97811c2 100644
--- a/arch/powerpc/sysdev/ipic.c
+++ b/arch/powerpc/sysdev/ipic.c
@@ -672,13 +672,13 @@ static struct irq_chip ipic_edge_irq_chip = {
.irq_set_type = ipic_set_irq_type,
};
-static int ipic_host_match(struct irq_host *h, struct device_node *node)
+static int ipic_host_match(struct irq_domain *h, struct device_node *node)
{
/* Exact match, unless ipic node is NULL */
return h->of_node == NULL || h->of_node == node;
}
-static int ipic_host_map(struct irq_host *h, unsigned int virq,
+static int ipic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct ipic *ipic = h->host_data;
@@ -692,26 +692,10 @@ static int ipic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int ipic_host_xlate(struct irq_host *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_flags)
-
-{
- /* interrupt sense values coming from the device tree equal either
- * LEVEL_LOW (low assertion) or EDGE_FALLING (high-to-low change)
- */
- *out_hwirq = intspec[0];
- if (intsize > 1)
- *out_flags = intspec[1];
- else
- *out_flags = IRQ_TYPE_NONE;
- return 0;
-}
-
-static struct irq_host_ops ipic_host_ops = {
+static struct irq_domain_ops ipic_host_ops = {
.match = ipic_host_match,
.map = ipic_host_map,
- .xlate = ipic_host_xlate,
+ .xlate = irq_domain_xlate_onetwocell,
};
struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
@@ -728,9 +712,8 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
if (ipic == NULL)
return NULL;
- ipic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
- NR_IPIC_INTS,
- &ipic_host_ops, 0);
+ ipic->irqhost = irq_domain_add_linear(node, NR_IPIC_INTS,
+ &ipic_host_ops, ipic);
if (ipic->irqhost == NULL) {
kfree(ipic);
return NULL;
@@ -738,8 +721,6 @@ struct ipic * __init ipic_init(struct device_node *node, unsigned int flags)
ipic->regs = ioremap(res.start, resource_size(&res));
- ipic->irqhost->host_data = ipic;
-
/* init hw */
ipic_write(ipic->regs, IPIC_SICNR, 0x0);
diff --git a/arch/powerpc/sysdev/ipic.h b/arch/powerpc/sysdev/ipic.h
index 9391c57b0c5..90031d1282e 100644
--- a/arch/powerpc/sysdev/ipic.h
+++ b/arch/powerpc/sysdev/ipic.h
@@ -43,7 +43,7 @@ struct ipic {
volatile u32 __iomem *regs;
/* The remapper for this IPIC */
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
};
struct ipic_info {
diff --git a/arch/powerpc/sysdev/mpc8xx_pic.c b/arch/powerpc/sysdev/mpc8xx_pic.c
index 2ca0a85fcce..d5f5416be31 100644
--- a/arch/powerpc/sysdev/mpc8xx_pic.c
+++ b/arch/powerpc/sysdev/mpc8xx_pic.c
@@ -17,7 +17,7 @@
extern int cpm_get_irq(struct pt_regs *regs);
-static struct irq_host *mpc8xx_pic_host;
+static struct irq_domain *mpc8xx_pic_host;
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
static unsigned long ppc_cached_irq_mask[NR_MASK_WORDS];
static sysconf8xx_t __iomem *siu_reg;
@@ -110,7 +110,7 @@ unsigned int mpc8xx_get_irq(void)
}
-static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
+static int mpc8xx_pic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
pr_debug("mpc8xx_pic_host_map(%d, 0x%lx)\n", virq, hw);
@@ -121,7 +121,7 @@ static int mpc8xx_pic_host_map(struct irq_host *h, unsigned int virq,
}
-static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int mpc8xx_pic_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
{
@@ -142,7 +142,7 @@ static int mpc8xx_pic_host_xlate(struct irq_host *h, struct device_node *ct,
}
-static struct irq_host_ops mpc8xx_pic_host_ops = {
+static struct irq_domain_ops mpc8xx_pic_host_ops = {
.map = mpc8xx_pic_host_map,
.xlate = mpc8xx_pic_host_xlate,
};
@@ -171,8 +171,7 @@ int mpc8xx_pic_init(void)
goto out;
}
- mpc8xx_pic_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
- 64, &mpc8xx_pic_host_ops, 64);
+ mpc8xx_pic_host = irq_domain_add_linear(np, 64, &mpc8xx_pic_host_ops, NULL);
if (mpc8xx_pic_host == NULL) {
printk(KERN_ERR "MPC8xx PIC: failed to allocate irq host!\n");
ret = -ENOMEM;
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 4e9ccb1015d..c83a512fa17 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -965,13 +965,13 @@ static struct irq_chip mpic_irq_ht_chip = {
#endif /* CONFIG_MPIC_U3_HT_IRQS */
-static int mpic_host_match(struct irq_host *h, struct device_node *node)
+static int mpic_host_match(struct irq_domain *h, struct device_node *node)
{
/* Exact match, unless mpic node is NULL */
return h->of_node == NULL || h->of_node == node;
}
-static int mpic_host_map(struct irq_host *h, unsigned int virq,
+static int mpic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct mpic *mpic = h->host_data;
@@ -1041,7 +1041,7 @@ static int mpic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int mpic_host_xlate(struct irq_host *h, struct device_node *ct,
+static int mpic_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
@@ -1121,13 +1121,13 @@ static void mpic_cascade(unsigned int irq, struct irq_desc *desc)
BUG_ON(!(mpic->flags & MPIC_SECONDARY));
virq = mpic_get_one_irq(mpic);
- if (virq != NO_IRQ)
+ if (virq)
generic_handle_irq(virq);
chip->irq_eoi(&desc->irq_data);
}
-static struct irq_host_ops mpic_host_ops = {
+static struct irq_domain_ops mpic_host_ops = {
.match = mpic_host_match,
.map = mpic_host_map,
.xlate = mpic_host_xlate,
@@ -1345,10 +1345,9 @@ struct mpic * __init mpic_alloc(struct device_node *node,
mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
mpic->isu_mask = (1 << mpic->isu_shift) - 1;
- mpic->irqhost = irq_alloc_host(mpic->node, IRQ_HOST_MAP_LINEAR,
+ mpic->irqhost = irq_domain_add_linear(mpic->node,
isu_size ? isu_size : mpic->num_sources,
- &mpic_host_ops,
- flags & MPIC_LARGE_VECTORS ? 2048 : 256);
+ &mpic_host_ops, mpic);
/*
* FIXME: The code leaks the MPIC object and mappings here; this
@@ -1357,8 +1356,6 @@ struct mpic * __init mpic_alloc(struct device_node *node,
if (mpic->irqhost == NULL)
return NULL;
- mpic->irqhost->host_data = mpic;
-
/* Display version */
switch (greg_feature & MPIC_GREG_FEATURE_VERSION_MASK) {
case 1:
diff --git a/arch/powerpc/sysdev/mpic_msi.c b/arch/powerpc/sysdev/mpic_msi.c
index 0f67cd79d48..0622aa91b18 100644
--- a/arch/powerpc/sysdev/mpic_msi.c
+++ b/arch/powerpc/sysdev/mpic_msi.c
@@ -32,7 +32,7 @@ void mpic_msi_reserve_hwirq(struct mpic *mpic, irq_hw_number_t hwirq)
static int mpic_msi_reserve_u3_hwirqs(struct mpic *mpic)
{
irq_hw_number_t hwirq;
- struct irq_host_ops *ops = mpic->irqhost->ops;
+ const struct irq_domain_ops *ops = mpic->irqhost->ops;
struct device_node *np;
int flags, index, i;
struct of_irq oirq;
diff --git a/arch/powerpc/sysdev/mv64x60_pic.c b/arch/powerpc/sysdev/mv64x60_pic.c
index 14d130268e7..8848e99a83f 100644
--- a/arch/powerpc/sysdev/mv64x60_pic.c
+++ b/arch/powerpc/sysdev/mv64x60_pic.c
@@ -70,7 +70,7 @@ static u32 mv64x60_cached_low_mask;
static u32 mv64x60_cached_high_mask = MV64X60_HIGH_GPP_GROUPS;
static u32 mv64x60_cached_gpp_mask;
-static struct irq_host *mv64x60_irq_host;
+static struct irq_domain *mv64x60_irq_host;
/*
* mv64x60_chip_low functions
@@ -208,7 +208,7 @@ static struct irq_chip *mv64x60_chips[] = {
[MV64x60_LEVEL1_GPP] = &mv64x60_chip_gpp,
};
-static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
+static int mv64x60_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hwirq)
{
int level1;
@@ -223,7 +223,7 @@ static int mv64x60_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops mv64x60_host_ops = {
+static struct irq_domain_ops mv64x60_host_ops = {
.map = mv64x60_host_map,
};
@@ -250,9 +250,8 @@ void __init mv64x60_init_irq(void)
paddr = of_translate_address(np, reg);
mv64x60_irq_reg_base = ioremap(paddr, reg[1]);
- mv64x60_irq_host = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR,
- MV64x60_NUM_IRQS,
- &mv64x60_host_ops, MV64x60_NUM_IRQS);
+ mv64x60_irq_host = irq_domain_add_linear(np, MV64x60_NUM_IRQS,
+ &mv64x60_host_ops, NULL);
spin_lock_irqsave(&mv64x60_lock, flags);
out_le32(mv64x60_gpp_reg_base + MV64x60_GPP_INTR_MASK,
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.c b/arch/powerpc/sysdev/qe_lib/qe_ic.c
index 73034bd203c..2fba6ef2f95 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.c
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.c
@@ -245,13 +245,13 @@ static struct irq_chip qe_ic_irq_chip = {
.irq_mask_ack = qe_ic_mask_irq,
};
-static int qe_ic_host_match(struct irq_host *h, struct device_node *node)
+static int qe_ic_host_match(struct irq_domain *h, struct device_node *node)
{
/* Exact match, unless qe_ic node is NULL */
return h->of_node == NULL || h->of_node == node;
}
-static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
+static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct qe_ic *qe_ic = h->host_data;
@@ -272,23 +272,10 @@ static int qe_ic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int qe_ic_host_xlate(struct irq_host *h, struct device_node *ct,
- const u32 * intspec, unsigned int intsize,
- irq_hw_number_t * out_hwirq,
- unsigned int *out_flags)
-{
- *out_hwirq = intspec[0];
- if (intsize > 1)
- *out_flags = intspec[1];
- else
- *out_flags = IRQ_TYPE_NONE;
- return 0;
-}
-
-static struct irq_host_ops qe_ic_host_ops = {
+static struct irq_domain_ops qe_ic_host_ops = {
.match = qe_ic_host_match,
.map = qe_ic_host_map,
- .xlate = qe_ic_host_xlate,
+ .xlate = irq_domain_xlate_onetwocell,
};
/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
@@ -339,8 +326,8 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
if (qe_ic == NULL)
return;
- qe_ic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
- NR_QE_IC_INTS, &qe_ic_host_ops, 0);
+ qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
+ &qe_ic_host_ops, qe_ic);
if (qe_ic->irqhost == NULL) {
kfree(qe_ic);
return;
@@ -348,7 +335,6 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
qe_ic->regs = ioremap(res.start, resource_size(&res));
- qe_ic->irqhost->host_data = qe_ic;
qe_ic->hc_irq = qe_ic_irq_chip;
qe_ic->virq_high = irq_of_parse_and_map(node, 0);
diff --git a/arch/powerpc/sysdev/qe_lib/qe_ic.h b/arch/powerpc/sysdev/qe_lib/qe_ic.h
index c1361d005a8..c327872ed35 100644
--- a/arch/powerpc/sysdev/qe_lib/qe_ic.h
+++ b/arch/powerpc/sysdev/qe_lib/qe_ic.h
@@ -79,7 +79,7 @@ struct qe_ic {
volatile u32 __iomem *regs;
/* The remapper for this QEIC */
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
/* The "linux" controller struct */
struct irq_chip hc_irq;
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 4d18658116e..188012c58f7 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -51,7 +51,7 @@
u32 tsi108_pci_cfg_base;
static u32 tsi108_pci_cfg_phys;
u32 tsi108_csr_vir_base;
-static struct irq_host *pci_irq_host;
+static struct irq_domain *pci_irq_host;
extern u32 get_vir_csrbase(void);
extern u32 tsi108_read_reg(u32 reg_offset);
@@ -376,7 +376,7 @@ static struct irq_chip tsi108_pci_irq = {
.irq_unmask = tsi108_pci_irq_unmask,
};
-static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
+static int pci_irq_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
{
@@ -385,7 +385,7 @@ static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
+static int pci_irq_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{ unsigned int irq;
DBG("%s(%d, 0x%lx)\n", __func__, virq, hw);
@@ -397,7 +397,7 @@ static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops pci_irq_host_ops = {
+static struct irq_domain_ops pci_irq_domain_ops = {
.map = pci_irq_host_map,
.xlate = pci_irq_host_xlate,
};
@@ -419,10 +419,9 @@ void __init tsi108_pci_int_init(struct device_node *node)
{
DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
- pci_irq_host = irq_alloc_host(node, IRQ_HOST_MAP_LEGACY,
- 0, &pci_irq_host_ops, 0);
+ pci_irq_host = irq_domain_add_legacy_isa(node, &pci_irq_domain_ops, NULL);
if (pci_irq_host == NULL) {
- printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n");
+ printk(KERN_ERR "pci_irq_host: failed to allocate irq domain!\n");
return;
}
diff --git a/arch/powerpc/sysdev/uic.c b/arch/powerpc/sysdev/uic.c
index 063c901b126..92033936a8f 100644
--- a/arch/powerpc/sysdev/uic.c
+++ b/arch/powerpc/sysdev/uic.c
@@ -49,7 +49,7 @@ struct uic {
raw_spinlock_t lock;
/* The remapper for this UIC */
- struct irq_host *irqhost;
+ struct irq_domain *irqhost;
};
static void uic_unmask_irq(struct irq_data *d)
@@ -174,7 +174,7 @@ static struct irq_chip uic_irq_chip = {
.irq_set_type = uic_set_irq_type,
};
-static int uic_host_map(struct irq_host *h, unsigned int virq,
+static int uic_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct uic *uic = h->host_data;
@@ -190,21 +190,9 @@ static int uic_host_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int uic_host_xlate(struct irq_host *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq, unsigned int *out_type)
-
-{
- /* UIC intspecs must have 2 cells */
- BUG_ON(intsize != 2);
- *out_hwirq = intspec[0];
- *out_type = intspec[1];
- return 0;
-}
-
-static struct irq_host_ops uic_host_ops = {
+static struct irq_domain_ops uic_host_ops = {
.map = uic_host_map,
- .xlate = uic_host_xlate,
+ .xlate = irq_domain_xlate_twocell,
};
void uic_irq_cascade(unsigned int virq, struct irq_desc *desc)
@@ -270,13 +258,11 @@ static struct uic * __init uic_init_one(struct device_node *node)
}
uic->dcrbase = *dcrreg;
- uic->irqhost = irq_alloc_host(node, IRQ_HOST_MAP_LINEAR,
- NR_UIC_INTS, &uic_host_ops, -1);
+ uic->irqhost = irq_domain_add_linear(node, NR_UIC_INTS, &uic_host_ops,
+ uic);
if (! uic->irqhost)
return NULL; /* FIXME: panic? */
- uic->irqhost->host_data = uic;
-
/* Start with all interrupts disabled, level and non-critical */
mtdcr(uic->dcrbase + UIC_ER, 0);
mtdcr(uic->dcrbase + UIC_CR, 0);
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index d72eda6a4c0..ea5e204e345 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -40,7 +40,7 @@ unsigned int xics_interrupt_server_size = 8;
DEFINE_PER_CPU(struct xics_cppr, xics_cppr);
-struct irq_host *xics_host;
+struct irq_domain *xics_host;
static LIST_HEAD(ics_list);
@@ -212,16 +212,16 @@ void xics_migrate_irqs_away(void)
/* We can't set affinity on ISA interrupts */
if (virq < NUM_ISA_INTERRUPTS)
continue;
- if (!virq_is_host(virq, xics_host))
- continue;
- irq = (unsigned int)virq_to_hw(virq);
- /* We need to get IPIs still. */
- if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
- continue;
desc = irq_to_desc(virq);
/* We only need to migrate enabled IRQS */
if (!desc || !desc->action)
continue;
+ if (desc->irq_data.domain != xics_host)
+ continue;
+ irq = desc->irq_data.hwirq;
+ /* We need to get IPIs still. */
+ if (irq == XICS_IPI || irq == XICS_IRQ_SPURIOUS)
+ continue;
chip = irq_desc_get_chip(desc);
if (!chip || !chip->irq_set_affinity)
continue;
@@ -301,7 +301,7 @@ int xics_get_irq_server(unsigned int virq, const struct cpumask *cpumask,
}
#endif /* CONFIG_SMP */
-static int xics_host_match(struct irq_host *h, struct device_node *node)
+static int xics_host_match(struct irq_domain *h, struct device_node *node)
{
struct ics *ics;
@@ -323,7 +323,7 @@ static struct irq_chip xics_ipi_chip = {
.irq_unmask = xics_ipi_unmask,
};
-static int xics_host_map(struct irq_host *h, unsigned int virq,
+static int xics_host_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct ics *ics;
@@ -351,7 +351,7 @@ static int xics_host_map(struct irq_host *h, unsigned int virq,
return -EINVAL;
}
-static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
+static int xics_host_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq, unsigned int *out_flags)
@@ -366,7 +366,7 @@ static int xics_host_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static struct irq_host_ops xics_host_ops = {
+static struct irq_domain_ops xics_host_ops = {
.match = xics_host_match,
.map = xics_host_map,
.xlate = xics_host_xlate,
@@ -374,8 +374,7 @@ static struct irq_host_ops xics_host_ops = {
static void __init xics_init_host(void)
{
- xics_host = irq_alloc_host(NULL, IRQ_HOST_MAP_TREE, 0, &xics_host_ops,
- XICS_IRQ_SPURIOUS);
+ xics_host = irq_domain_add_tree(NULL, &xics_host_ops, NULL);
BUG_ON(xics_host == NULL);
irq_set_default_host(xics_host);
}
diff --git a/arch/powerpc/sysdev/xilinx_intc.c b/arch/powerpc/sysdev/xilinx_intc.c
index 6183799754a..8d73c3c0bee 100644
--- a/arch/powerpc/sysdev/xilinx_intc.c
+++ b/arch/powerpc/sysdev/xilinx_intc.c
@@ -40,7 +40,7 @@
#define XINTC_IVR 24 /* Interrupt Vector */
#define XINTC_MER 28 /* Master Enable */
-static struct irq_host *master_irqhost;
+static struct irq_domain *master_irqhost;
#define XILINX_INTC_MAXIRQS (32)
@@ -141,7 +141,7 @@ static struct irq_chip xilinx_intc_edge_irqchip = {
/**
* xilinx_intc_xlate - translate virq# from device tree interrupts property
*/
-static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
+static int xilinx_intc_xlate(struct irq_domain *h, struct device_node *ct,
const u32 *intspec, unsigned int intsize,
irq_hw_number_t *out_hwirq,
unsigned int *out_flags)
@@ -161,7 +161,7 @@ static int xilinx_intc_xlate(struct irq_host *h, struct device_node *ct,
return 0;
}
-static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
+static int xilinx_intc_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t irq)
{
irq_set_chip_data(virq, h->host_data);
@@ -177,15 +177,15 @@ static int xilinx_intc_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static struct irq_host_ops xilinx_intc_ops = {
+static struct irq_domain_ops xilinx_intc_ops = {
.map = xilinx_intc_map,
.xlate = xilinx_intc_xlate,
};
-struct irq_host * __init
+struct irq_domain * __init
xilinx_intc_init(struct device_node *np)
{
- struct irq_host * irq;
+ struct irq_domain * irq;
void * regs;
/* Find and map the intc registers */
@@ -200,12 +200,11 @@ xilinx_intc_init(struct device_node *np)
out_be32(regs + XINTC_IAR, ~(u32) 0); /* Acknowledge pending irqs */
out_be32(regs + XINTC_MER, 0x3UL); /* Turn on the Master Enable. */
- /* Allocate and initialize an irq_host structure. */
- irq = irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, XILINX_INTC_MAXIRQS,
- &xilinx_intc_ops, -1);
+ /* Allocate and initialize an irq_domain structure. */
+ irq = irq_domain_add_linear(np, XILINX_INTC_MAXIRQS, &xilinx_intc_ops,
+ regs);
if (!irq)
panic(__FILE__ ": Cannot allocate IRQ host\n");
- irq->host_data = regs;
return irq;
}
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index d1727584230..6d99a5fcc09 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -227,6 +227,9 @@ config COMPAT
config SYSVIPC_COMPAT
def_bool y if COMPAT && SYSVIPC
+config KEYS_COMPAT
+ def_bool y if COMPAT && KEYS
+
config AUDIT_ARCH
def_bool y
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 2e49748b27d..234f1d859ce 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -172,13 +172,6 @@ static inline int is_compat_task(void)
return is_32bit_task();
}
-#else
-
-static inline int is_compat_task(void)
-{
- return 0;
-}
-
#endif
static inline void __user *arch_compat_alloc_user_space(long len)
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S
index 18c51df9fe0..ff605a39cf4 100644
--- a/arch/s390/kernel/compat_wrapper.S
+++ b/arch/s390/kernel/compat_wrapper.S
@@ -662,7 +662,7 @@ ENTRY(sys32_getresuid16_wrapper)
ENTRY(sys32_poll_wrapper)
llgtr %r2,%r2 # struct pollfd *
llgfr %r3,%r3 # unsigned int
- lgfr %r4,%r4 # long
+ lgfr %r4,%r4 # int
jg sys_poll # branch to system call
ENTRY(sys32_setresgid16_wrapper)
diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c
index 39f8fd4438f..c383ce440d9 100644
--- a/arch/s390/kernel/crash_dump.c
+++ b/arch/s390/kernel/crash_dump.c
@@ -11,7 +11,6 @@
#include <linux/module.h>
#include <linux/gfp.h>
#include <linux/slab.h>
-#include <linux/crash_dump.h>
#include <linux/bootmem.h>
#include <linux/elf.h>
#include <asm/ipl.h>
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 3201ae44799..e795933eb2c 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -29,7 +29,6 @@
#include <asm/irq.h>
#include <asm/timer.h>
#include <asm/nmi.h>
-#include <asm/compat.h>
#include <asm/smp.h>
#include "entry.h"
@@ -76,7 +75,6 @@ static void default_idle(void)
if (test_thread_flag(TIF_MCCK_PENDING)) {
local_mcck_enable();
local_irq_enable();
- s390_handle_mcck();
return;
}
trace_hardirqs_on();
@@ -93,10 +91,12 @@ void cpu_idle(void)
for (;;) {
tick_nohz_idle_enter();
rcu_idle_enter();
- while (!need_resched())
+ while (!need_resched() && !test_thread_flag(TIF_MCCK_PENDING))
default_idle();
rcu_idle_exit();
tick_nohz_idle_exit();
+ if (test_thread_flag(TIF_MCCK_PENDING))
+ s390_handle_mcck();
preempt_enable_no_resched();
schedule();
preempt_disable();
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 9d82ed4bcb2..61f95489d70 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -20,8 +20,8 @@
#include <linux/regset.h>
#include <linux/tracehook.h>
#include <linux/seccomp.h>
+#include <linux/compat.h>
#include <trace/syscall.h>
-#include <asm/compat.h>
#include <asm/segment.h>
#include <asm/page.h>
#include <asm/pgtable.h>
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 354de0763ef..3b2efc81f34 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -46,6 +46,7 @@
#include <linux/kexec.h>
#include <linux/crash_dump.h>
#include <linux/memory.h>
+#include <linux/compat.h>
#include <asm/ipl.h>
#include <asm/uaccess.h>
@@ -59,7 +60,6 @@
#include <asm/ptrace.h>
#include <asm/sections.h>
#include <asm/ebcdic.h>
-#include <asm/compat.h>
#include <asm/kvm_virtio.h>
#include <asm/diag.h>
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index a8ba840294f..2d421d90fad 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -30,7 +30,6 @@
#include <asm/ucontext.h>
#include <asm/uaccess.h>
#include <asm/lowcore.h>
-#include <asm/compat.h>
#include "entry.h"
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index fa02f443f5f..14da278febb 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -113,11 +113,14 @@ static void fixup_clock_comparator(unsigned long long delta)
static int s390_next_ktime(ktime_t expires,
struct clock_event_device *evt)
{
+ struct timespec ts;
u64 nsecs;
- nsecs = ktime_to_ns(ktime_sub(expires, ktime_get_monotonic_offset()));
+ ts.tv_sec = ts.tv_nsec = 0;
+ monotonic_to_bootbased(&ts);
+ nsecs = ktime_to_ns(ktime_add(timespec_to_ktime(ts), expires));
do_div(nsecs, 125);
- S390_lowcore.clock_comparator = TOD_UNIX_EPOCH + (nsecs << 9);
+ S390_lowcore.clock_comparator = sched_clock_base_cc + (nsecs << 9);
set_clock_comparator(S390_lowcore.clock_comparator);
return 0;
}
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 354dd39073e..e8fcd928dc7 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -36,7 +36,6 @@
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
-#include <asm/compat.h>
#include "../kernel/entry.h"
#ifndef CONFIG_64BIT
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 5d633019d8f..50236610de8 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -223,16 +223,38 @@ void free_initrd_mem(unsigned long start, unsigned long end)
#ifdef CONFIG_MEMORY_HOTPLUG
int arch_add_memory(int nid, u64 start, u64 size)
{
- struct pglist_data *pgdat;
+ unsigned long zone_start_pfn, zone_end_pfn, nr_pages;
+ unsigned long start_pfn = PFN_DOWN(start);
+ unsigned long size_pages = PFN_DOWN(size);
struct zone *zone;
int rc;
- pgdat = NODE_DATA(nid);
- zone = pgdat->node_zones + ZONE_MOVABLE;
rc = vmem_add_mapping(start, size);
if (rc)
return rc;
- rc = __add_pages(nid, zone, PFN_DOWN(start), PFN_DOWN(size));
+ for_each_zone(zone) {
+ if (zone_idx(zone) != ZONE_MOVABLE) {
+ /* Add range within existing zone limits */
+ zone_start_pfn = zone->zone_start_pfn;
+ zone_end_pfn = zone->zone_start_pfn +
+ zone->spanned_pages;
+ } else {
+ /* Add remaining range to ZONE_MOVABLE */
+ zone_start_pfn = start_pfn;
+ zone_end_pfn = start_pfn + size_pages;
+ }
+ if (start_pfn < zone_start_pfn || start_pfn >= zone_end_pfn)
+ continue;
+ nr_pages = (start_pfn + size_pages > zone_end_pfn) ?
+ zone_end_pfn - start_pfn : size_pages;
+ rc = __add_pages(nid, zone, start_pfn, nr_pages);
+ if (rc)
+ break;
+ start_pfn += nr_pages;
+ size_pages -= nr_pages;
+ if (!size_pages)
+ break;
+ }
if (rc)
vmem_remove_mapping(start, size);
return rc;
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index f09c74881b7..a0155c02e32 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -29,8 +29,8 @@
#include <linux/mman.h>
#include <linux/module.h>
#include <linux/random.h>
+#include <linux/compat.h>
#include <asm/pgalloc.h>
-#include <asm/compat.h>
static unsigned long stack_maxrandom_size(void)
{
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 9a4d02f64f1..51b0738e13d 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -574,7 +574,7 @@ static inline void page_table_free_pgste(unsigned long *table)
page = pfn_to_page(__pa(table) >> PAGE_SHIFT);
mp = (struct gmap_pgtable *) page->index;
BUG_ON(!list_empty(&mp->mapper));
- pgtable_page_ctor(page);
+ pgtable_page_dtor(page);
atomic_set(&page->_mapcount, -1);
kfree(mp);
__free_page(page);
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c
index 0838154dd21..24b1ee410da 100644
--- a/arch/sh/boards/board-sh7757lcr.c
+++ b/arch/sh/boards/board-sh7757lcr.c
@@ -169,6 +169,11 @@ static struct resource sh_eth_giga1_resources[] = {
.end = 0xfee00fff,
.flags = IORESOURCE_MEM,
}, {
+ /* TSU */
+ .start = 0xfee01800,
+ .end = 0xfee01fff,
+ .flags = IORESOURCE_MEM,
+ }, {
.start = 316,
.end = 316,
.flags = IORESOURCE_IRQ,
@@ -210,20 +215,13 @@ static struct resource sh_mmcif_resources[] = {
},
};
-static struct sh_mmcif_dma sh7757lcr_mmcif_dma = {
- .chan_priv_tx = {
- .slave_id = SHDMA_SLAVE_MMCIF_TX,
- },
- .chan_priv_rx = {
- .slave_id = SHDMA_SLAVE_MMCIF_RX,
- }
-};
-
static struct sh_mmcif_plat_data sh_mmcif_plat = {
- .dma = &sh7757lcr_mmcif_dma,
.sup_pclk = 0x0f,
- .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
+ .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA |
+ MMC_CAP_NONREMOVABLE,
.ocr = MMC_VDD_32_33 | MMC_VDD_33_34,
+ .slave_id_tx = SHDMA_SLAVE_MMCIF_TX,
+ .slave_id_rx = SHDMA_SLAVE_MMCIF_RX,
};
static struct platform_device sh_mmcif_device = {
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 6418e95c2b6..ebd0f818a25 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -22,6 +22,7 @@
#include <linux/i2c.h>
#include <linux/smsc911x.h>
#include <linux/gpio.h>
+#include <linux/videodev2.h>
#include <media/ov772x.h>
#include <media/soc_camera.h>
#include <media/soc_camera_platform.h>
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 033ef2ba621..cde7c0085ce 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -29,9 +29,11 @@
#include <linux/input.h>
#include <linux/input/sh_keysc.h>
#include <linux/sh_eth.h>
+#include <linux/videodev2.h>
#include <video/sh_mobile_lcdc.h>
#include <sound/sh_fsi.h>
#include <media/sh_mobile_ceu.h>
+#include <media/soc_camera.h>
#include <media/tw9910.h>
#include <media/mt9t112.h>
#include <asm/heartbeat.h>
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 2a18b06abda..5b382e1afae 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -22,6 +22,7 @@
#include <linux/input/sh_keysc.h>
#include <linux/i2c.h>
#include <linux/usb/r8a66597.h>
+#include <linux/videodev2.h>
#include <media/rj54n1cb0c.h>
#include <media/soc_camera.h>
#include <media/sh_mobile_ceu.h>
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index 68c3d6f4289..d37ba272052 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -21,9 +21,11 @@
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/gpio.h>
+#include <linux/videodev2.h>
#include <video/sh_mobile_lcdc.h>
#include <media/sh_mobile_ceu.h>
#include <media/ov772x.h>
+#include <media/soc_camera.h>
#include <media/tw9910.h>
#include <asm/clock.h>
#include <asm/machvec.h>
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 036fe1adaef..2b07fc01695 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -24,6 +24,7 @@
#include <linux/input/sh_keysc.h>
#include <linux/usb/r8a66597.h>
#include <linux/sh_eth.h>
+#include <linux/videodev2.h>
#include <video/sh_mobile_lcdc.h>
#include <media/sh_mobile_ceu.h>
#include <sound/sh_fsi.h>
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index fa7b978cc72..fb8f1499074 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -74,7 +74,7 @@ struct pci_errors {
{ SH4_PCIINT_MLCK, "master lock error" },
{ SH4_PCIINT_TABT, "target-target abort" },
{ SH4_PCIINT_TRET, "target retry time out" },
- { SH4_PCIINT_MFDE, "master function disable erorr" },
+ { SH4_PCIINT_MFDE, "master function disable error" },
{ SH4_PCIINT_PRTY, "address parity error" },
{ SH4_PCIINT_SERR, "SERR" },
{ SH4_PCIINT_TWDP, "data parity error for target write" },
diff --git a/arch/sh/include/asm/device.h b/arch/sh/include/asm/device.h
index a1c9c0daec1..071bcb4d4bf 100644
--- a/arch/sh/include/asm/device.h
+++ b/arch/sh/include/asm/device.h
@@ -3,9 +3,10 @@
*
* This file is released under the GPLv2
*/
+#ifndef __ASM_SH_DEVICE_H
+#define __ASM_SH_DEVICE_H
-struct dev_archdata {
-};
+#include <asm-generic/device.h>
struct platform_device;
/* allocate contiguous memory chunk and fill in struct resource */
@@ -14,5 +15,4 @@ int platform_resource_setup_memory(struct platform_device *pdev,
void plat_early_device_setup(void);
-struct pdev_archdata {
-};
+#endif /* __ASM_SH_DEVICE_H */
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
index b3c039a5064..70bd96646f4 100644
--- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
+++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c
@@ -343,7 +343,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[HWBLK_CEU1]),
CLKDEV_CON_ID("beu1", &mstp_clks[HWBLK_BEU1]),
CLKDEV_CON_ID("2ddmac0", &mstp_clks[HWBLK_2DDMAC]),
- CLKDEV_CON_ID("spu0", &mstp_clks[HWBLK_SPU]),
+ CLKDEV_DEV_ID("sh_fsi.0", &mstp_clks[HWBLK_SPU]),
CLKDEV_CON_ID("jpu0", &mstp_clks[HWBLK_JPU]),
CLKDEV_DEV_ID("sh-vou.0", &mstp_clks[HWBLK_VOU]),
CLKDEV_CON_ID("beu0", &mstp_clks[HWBLK_BEU0]),
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
index a7b2da6b3a1..2875e8be4f7 100644
--- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
+++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c
@@ -133,7 +133,7 @@ static struct resource spi0_resources[] = {
[0] = {
.start = 0xfe002000,
.end = 0xfe0020ff,
- .flags = IORESOURCE_MEM,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
},
[1] = {
.start = 86,
@@ -661,6 +661,25 @@ static struct platform_device spi0_device = {
.resource = spi0_resources,
};
+static struct resource spi1_resources[] = {
+ {
+ .start = 0xffd8ee70,
+ .end = 0xffd8eeff,
+ .flags = IORESOURCE_MEM | IORESOURCE_MEM_8BIT,
+ },
+ {
+ .start = 54,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device spi1_device = {
+ .name = "sh_spi",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(spi1_resources),
+ .resource = spi1_resources,
+};
+
static struct resource usb_ehci_resources[] = {
[0] = {
.start = 0xfe4f1000,
@@ -720,6 +739,7 @@ static struct platform_device *sh7757_devices[] __initdata = {
&dma2_device,
&dma3_device,
&spi0_device,
+ &spi1_device,
&usb_ehci_device,
&usb_ohci_device,
};
diff --git a/arch/sh/kernel/smp.c b/arch/sh/kernel/smp.c
index 3147a9a6fb8..f624174bf23 100644
--- a/arch/sh/kernel/smp.c
+++ b/arch/sh/kernel/smp.c
@@ -63,7 +63,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
mp_ops->prepare_cpus(max_cpus);
#ifndef CONFIG_HOTPLUG_CPU
- init_cpu_present(&cpu_possible_map);
+ init_cpu_present(cpu_possible_mask);
#endif
}
diff --git a/arch/sh/kernel/topology.c b/arch/sh/kernel/topology.c
index 4649a6ff0cf..772caffba22 100644
--- a/arch/sh/kernel/topology.c
+++ b/arch/sh/kernel/topology.c
@@ -27,7 +27,7 @@ static cpumask_t cpu_coregroup_map(unsigned int cpu)
* Presently all SH-X3 SMP cores are multi-cores, so just keep it
* simple until we have a method for determining topology..
*/
- return cpu_possible_map;
+ return *cpu_possible_mask;
}
const struct cpumask *cpu_coregroup_mask(unsigned int cpu)
diff --git a/arch/sh/mm/cache-sh2a.c b/arch/sh/mm/cache-sh2a.c
index ae08cbbfa56..949e2d3138a 100644
--- a/arch/sh/mm/cache-sh2a.c
+++ b/arch/sh/mm/cache-sh2a.c
@@ -23,6 +23,7 @@
#define MAX_OCACHE_PAGES 32
#define MAX_ICACHE_PAGES 32
+#ifdef CONFIG_CACHE_WRITEBACK
static void sh2a_flush_oc_line(unsigned long v, int way)
{
unsigned long addr = (v & 0x000007f0) | (way << 11);
@@ -34,6 +35,7 @@ static void sh2a_flush_oc_line(unsigned long v, int way)
__raw_writel(data, CACHE_OC_ADDRESS_ARRAY | addr);
}
}
+#endif
static void sh2a_invalidate_line(unsigned long cache_addr, unsigned long v)
{
diff --git a/arch/sparc/include/asm/prom.h b/arch/sparc/include/asm/prom.h
index edd3d3cde46..c2876511070 100644
--- a/arch/sparc/include/asm/prom.h
+++ b/arch/sparc/include/asm/prom.h
@@ -22,6 +22,7 @@
#include <linux/proc_fs.h>
#include <linux/mutex.h>
#include <linux/atomic.h>
+#include <linux/irqdomain.h>
#define OF_ROOT_NODE_ADDR_CELLS_DEFAULT 2
#define OF_ROOT_NODE_SIZE_CELLS_DEFAULT 1
@@ -55,15 +56,6 @@ struct resource;
extern void __iomem *of_ioremap(struct resource *res, unsigned long offset, unsigned long size, char *name);
extern void of_iounmap(struct resource *res, void __iomem *base, unsigned long size);
-/* These routines are here to provide compatibility with how powerpc
- * handles IRQ mapping for OF device nodes. We precompute and permanently
- * register them in the platform_device objects, whereas powerpc computes them
- * on request.
- */
-static inline void irq_dispose_mapping(unsigned int virq)
-{
-}
-
extern struct device_node *of_console_device;
extern char *of_console_path;
extern char *of_console_options;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5bed94e189f..e0829a6a466 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -398,6 +398,7 @@ config X86_INTEL_CE
select X86_REBOOTFIXUPS
select OF
select OF_EARLY_FLATTREE
+ select IRQ_DOMAIN
---help---
Select for the Intel CE media processor (CE4100) SOC.
This option compiles in support for the CE4100 SOC for settop
@@ -2076,6 +2077,7 @@ config OLPC
select GPIOLIB
select OF
select OF_PROMTREE
+ select IRQ_DOMAIN
---help---
Add support for detecting the unique features of the OLPC
XO hardware.
diff --git a/arch/x86/include/asm/i387.h b/arch/x86/include/asm/i387.h
index a850b4d8d14..247904945d3 100644
--- a/arch/x86/include/asm/i387.h
+++ b/arch/x86/include/asm/i387.h
@@ -29,10 +29,11 @@ extern unsigned int sig_xstate_size;
extern void fpu_init(void);
extern void mxcsr_feature_mask_init(void);
extern int init_fpu(struct task_struct *child);
-extern void __math_state_restore(struct task_struct *);
extern void math_state_restore(void);
extern int dump_fpu(struct pt_regs *, struct user_i387_struct *);
+DECLARE_PER_CPU(struct task_struct *, fpu_owner_task);
+
extern user_regset_active_fn fpregs_active, xfpregs_active;
extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get,
xstateregs_get;
@@ -269,6 +270,16 @@ static inline int fpu_restore_checking(struct fpu *fpu)
static inline int restore_fpu_checking(struct task_struct *tsk)
{
+ /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
+ is pending. Clear the x87 state here by setting it to fixed
+ values. "m" is a random variable that should be in L1 */
+ alternative_input(
+ ASM_NOP8 ASM_NOP2,
+ "emms\n\t" /* clear stack tags */
+ "fildl %P[addr]", /* set F?P to defined value */
+ X86_FEATURE_FXSAVE_LEAK,
+ [addr] "m" (tsk->thread.fpu.has_fpu));
+
return fpu_restore_checking(&tsk->thread.fpu);
}
@@ -279,19 +290,21 @@ static inline int restore_fpu_checking(struct task_struct *tsk)
*/
static inline int __thread_has_fpu(struct task_struct *tsk)
{
- return tsk->thread.has_fpu;
+ return tsk->thread.fpu.has_fpu;
}
/* Must be paired with an 'stts' after! */
static inline void __thread_clear_has_fpu(struct task_struct *tsk)
{
- tsk->thread.has_fpu = 0;
+ tsk->thread.fpu.has_fpu = 0;
+ percpu_write(fpu_owner_task, NULL);
}
/* Must be paired with a 'clts' before! */
static inline void __thread_set_has_fpu(struct task_struct *tsk)
{
- tsk->thread.has_fpu = 1;
+ tsk->thread.fpu.has_fpu = 1;
+ percpu_write(fpu_owner_task, tsk);
}
/*
@@ -336,30 +349,36 @@ typedef struct { int preload; } fpu_switch_t;
* We don't do that yet, so "fpu_lazy_restore()" always returns
* false, but some day..
*/
-#define fpu_lazy_restore(tsk) (0)
-#define fpu_lazy_state_intact(tsk) do { } while (0)
+static inline int fpu_lazy_restore(struct task_struct *new, unsigned int cpu)
+{
+ return new == percpu_read_stable(fpu_owner_task) &&
+ cpu == new->thread.fpu.last_cpu;
+}
-static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct task_struct *new)
+static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct task_struct *new, int cpu)
{
fpu_switch_t fpu;
fpu.preload = tsk_used_math(new) && new->fpu_counter > 5;
if (__thread_has_fpu(old)) {
- if (__save_init_fpu(old))
- fpu_lazy_state_intact(old);
- __thread_clear_has_fpu(old);
- old->fpu_counter++;
+ if (!__save_init_fpu(old))
+ cpu = ~0;
+ old->thread.fpu.last_cpu = cpu;
+ old->thread.fpu.has_fpu = 0; /* But leave fpu_owner_task! */
/* Don't change CR0.TS if we just switch! */
if (fpu.preload) {
+ new->fpu_counter++;
__thread_set_has_fpu(new);
prefetch(new->thread.fpu.state);
} else
stts();
} else {
old->fpu_counter = 0;
+ old->thread.fpu.last_cpu = ~0;
if (fpu.preload) {
- if (fpu_lazy_restore(new))
+ new->fpu_counter++;
+ if (fpu_lazy_restore(new, cpu))
fpu.preload = 0;
else
prefetch(new->thread.fpu.state);
@@ -377,8 +396,10 @@ static inline fpu_switch_t switch_fpu_prepare(struct task_struct *old, struct ta
*/
static inline void switch_fpu_finish(struct task_struct *new, fpu_switch_t fpu)
{
- if (fpu.preload)
- __math_state_restore(new);
+ if (fpu.preload) {
+ if (unlikely(restore_fpu_checking(new)))
+ __thread_fpu_end(new);
+ }
}
/*
@@ -451,8 +472,10 @@ static inline void kernel_fpu_begin(void)
__save_init_fpu(me);
__thread_clear_has_fpu(me);
/* We do 'stts()' in kernel_fpu_end() */
- } else
+ } else {
+ percpu_write(fpu_owner_task, NULL);
clts();
+ }
}
static inline void kernel_fpu_end(void)
diff --git a/arch/x86/include/asm/irq_controller.h b/arch/x86/include/asm/irq_controller.h
deleted file mode 100644
index 423bbbddf36..00000000000
--- a/arch/x86/include/asm/irq_controller.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __IRQ_CONTROLLER__
-#define __IRQ_CONTROLLER__
-
-struct irq_domain {
- int (*xlate)(struct irq_domain *h, const u32 *intspec, u32 intsize,
- u32 *out_hwirq, u32 *out_type);
- void *priv;
- struct device_node *controller;
- struct list_head l;
-};
-
-#endif
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 096c975e099..461ce432b1c 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -242,4 +242,12 @@ static inline void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
static inline void perf_events_lapic_init(void) { }
#endif
+#if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD)
+ extern void amd_pmu_enable_virt(void);
+ extern void amd_pmu_disable_virt(void);
+#else
+ static inline void amd_pmu_enable_virt(void) { }
+ static inline void amd_pmu_disable_virt(void) { }
+#endif
+
#endif /* _ASM_X86_PERF_EVENT_H */
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index f7c89e231c6..58545c97d07 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -374,6 +374,8 @@ union thread_xstate {
};
struct fpu {
+ unsigned int last_cpu;
+ unsigned int has_fpu;
union thread_xstate *state;
};
@@ -454,7 +456,6 @@ struct thread_struct {
unsigned long trap_no;
unsigned long error_code;
/* floating point and extended processor state */
- unsigned long has_fpu;
struct fpu fpu;
#ifdef CONFIG_X86_32
/* Virtual 86 mode info */
diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h
index 644dd885f05..60bef663609 100644
--- a/arch/x86/include/asm/prom.h
+++ b/arch/x86/include/asm/prom.h
@@ -21,7 +21,6 @@
#include <asm/irq.h>
#include <linux/atomic.h>
#include <asm/setup.h>
-#include <asm/irq_controller.h>
#ifdef CONFIG_OF
extern int of_ioapic;
@@ -43,15 +42,6 @@ extern char cmd_line[COMMAND_LINE_SIZE];
#define pci_address_to_pio pci_address_to_pio
unsigned long pci_address_to_pio(phys_addr_t addr);
-/**
- * irq_dispose_mapping - Unmap an interrupt
- * @virq: linux virq number of the interrupt to unmap
- *
- * FIXME: We really should implement proper virq handling like power,
- * but that's going to be major surgery.
- */
-static inline void irq_dispose_mapping(unsigned int virq) { }
-
#define HAVE_ARCH_DEVTREE_FIXUPS
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index d43cad74f16..c0f7d68d318 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -1044,6 +1044,9 @@ DEFINE_PER_CPU(char *, irq_stack_ptr) =
DEFINE_PER_CPU(unsigned int, irq_count) = -1;
+DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);
+EXPORT_PER_CPU_SYMBOL(fpu_owner_task);
+
/*
* Special IST stacks which the CPU switches to when it calls
* an IST-marked descriptor entry. Up to 7 stacks (hardware
@@ -1111,6 +1114,8 @@ void debug_stack_reset(void)
DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
EXPORT_PER_CPU_SYMBOL(current_task);
+DEFINE_PER_CPU(struct task_struct *, fpu_owner_task);
+EXPORT_PER_CPU_SYMBOL(fpu_owner_task);
#ifdef CONFIG_CC_STACKPROTECTOR
DEFINE_PER_CPU_ALIGNED(struct stack_canary, stack_canary);
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 6b45e5e7a90..73d08ed98a6 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -326,8 +326,7 @@ static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb)
l3->indices = (max(max3(sc0, sc1, sc2), sc3) << 10) - 1;
}
-static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf,
- int index)
+static void __cpuinit amd_init_l3_cache(struct _cpuid4_info_regs *this_leaf, int index)
{
int node;
@@ -725,14 +724,16 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);
#define CPUID4_INFO_IDX(x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))
#ifdef CONFIG_SMP
-static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+
+static int __cpuinit cache_shared_amd_cpu_map_setup(unsigned int cpu, int index)
{
- struct _cpuid4_info *this_leaf, *sibling_leaf;
- unsigned long num_threads_sharing;
- int index_msb, i, sibling;
+ struct _cpuid4_info *this_leaf;
+ int ret, i, sibling;
struct cpuinfo_x86 *c = &cpu_data(cpu);
- if ((index == 3) && (c->x86_vendor == X86_VENDOR_AMD)) {
+ ret = 0;
+ if (index == 3) {
+ ret = 1;
for_each_cpu(i, cpu_llc_shared_mask(cpu)) {
if (!per_cpu(ici_cpuid4_info, i))
continue;
@@ -743,8 +744,35 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
set_bit(sibling, this_leaf->shared_cpu_map);
}
}
- return;
+ } else if ((c->x86 == 0x15) && ((index == 1) || (index == 2))) {
+ ret = 1;
+ for_each_cpu(i, cpu_sibling_mask(cpu)) {
+ if (!per_cpu(ici_cpuid4_info, i))
+ continue;
+ this_leaf = CPUID4_INFO_IDX(i, index);
+ for_each_cpu(sibling, cpu_sibling_mask(cpu)) {
+ if (!cpu_online(sibling))
+ continue;
+ set_bit(sibling, this_leaf->shared_cpu_map);
+ }
+ }
}
+
+ return ret;
+}
+
+static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
+{
+ struct _cpuid4_info *this_leaf, *sibling_leaf;
+ unsigned long num_threads_sharing;
+ int index_msb, i;
+ struct cpuinfo_x86 *c = &cpu_data(cpu);
+
+ if (c->x86_vendor == X86_VENDOR_AMD) {
+ if (cache_shared_amd_cpu_map_setup(cpu, index))
+ return;
+ }
+
this_leaf = CPUID4_INFO_IDX(cpu, index);
num_threads_sharing = 1 + this_leaf->base.eax.split.num_threads_sharing;
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd.c b/arch/x86/kernel/cpu/mcheck/mce_amd.c
index 786e76a8632..e4eeaaf58a4 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd.c
@@ -528,6 +528,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
sprintf(name, "threshold_bank%i", bank);
+#ifdef CONFIG_SMP
if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */
i = cpumask_first(cpu_llc_shared_mask(cpu));
@@ -553,6 +554,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
goto out;
}
+#endif
b = kzalloc(sizeof(struct threshold_bank), GFP_KERNEL);
if (!b) {
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index 8944062f46e..c30c807ddc7 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -147,7 +147,9 @@ struct cpu_hw_events {
/*
* AMD specific bits
*/
- struct amd_nb *amd_nb;
+ struct amd_nb *amd_nb;
+ /* Inverted mask of bits to clear in the perf_ctr ctrl registers */
+ u64 perf_ctr_virt_mask;
void *kfree_on_online;
};
@@ -417,9 +419,11 @@ void x86_pmu_disable_all(void);
static inline void __x86_pmu_enable_event(struct hw_perf_event *hwc,
u64 enable_mask)
{
+ u64 disable_mask = __this_cpu_read(cpu_hw_events.perf_ctr_virt_mask);
+
if (hwc->extra_reg.reg)
wrmsrl(hwc->extra_reg.reg, hwc->extra_reg.config);
- wrmsrl(hwc->config_base, hwc->config | enable_mask);
+ wrmsrl(hwc->config_base, (hwc->config | enable_mask) & ~disable_mask);
}
void x86_pmu_enable_all(int added);
diff --git a/arch/x86/kernel/cpu/perf_event_amd.c b/arch/x86/kernel/cpu/perf_event_amd.c
index 0397b23be8e..67250a52430 100644
--- a/arch/x86/kernel/cpu/perf_event_amd.c
+++ b/arch/x86/kernel/cpu/perf_event_amd.c
@@ -1,4 +1,5 @@
#include <linux/perf_event.h>
+#include <linux/export.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -357,7 +358,9 @@ static void amd_pmu_cpu_starting(int cpu)
struct amd_nb *nb;
int i, nb_id;
- if (boot_cpu_data.x86_max_cores < 2)
+ cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY;
+
+ if (boot_cpu_data.x86_max_cores < 2 || boot_cpu_data.x86 == 0x15)
return;
nb_id = amd_get_nb_id(cpu);
@@ -587,9 +590,9 @@ static __initconst const struct x86_pmu amd_pmu_f15h = {
.put_event_constraints = amd_put_event_constraints,
.cpu_prepare = amd_pmu_cpu_prepare,
- .cpu_starting = amd_pmu_cpu_starting,
.cpu_dead = amd_pmu_cpu_dead,
#endif
+ .cpu_starting = amd_pmu_cpu_starting,
};
__init int amd_pmu_init(void)
@@ -621,3 +624,33 @@ __init int amd_pmu_init(void)
return 0;
}
+
+void amd_pmu_enable_virt(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+ cpuc->perf_ctr_virt_mask = 0;
+
+ /* Reload all events */
+ x86_pmu_disable_all();
+ x86_pmu_enable_all(0);
+}
+EXPORT_SYMBOL_GPL(amd_pmu_enable_virt);
+
+void amd_pmu_disable_virt(void)
+{
+ struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
+
+ /*
+ * We only mask out the Host-only bit so that host-only counting works
+ * when SVM is disabled. If someone sets up a guest-only counter when
+ * SVM is disabled the Guest-only bits still gets set and the counter
+ * will not count anything.
+ */
+ cpuc->perf_ctr_virt_mask = AMD_PERFMON_EVENTSEL_HOSTONLY;
+
+ /* Reload all events */
+ x86_pmu_disable_all();
+ x86_pmu_enable_all(0);
+}
+EXPORT_SYMBOL_GPL(amd_pmu_disable_virt);
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 52821799a70..3ae2ced4a87 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -4,6 +4,7 @@
#include <linux/bootmem.h>
#include <linux/export.h>
#include <linux/io.h>
+#include <linux/irqdomain.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/of.h>
@@ -17,64 +18,14 @@
#include <linux/initrd.h>
#include <asm/hpet.h>
-#include <asm/irq_controller.h>
#include <asm/apic.h>
#include <asm/pci_x86.h>
__initdata u64 initial_dtb;
char __initdata cmd_line[COMMAND_LINE_SIZE];
-static LIST_HEAD(irq_domains);
-static DEFINE_RAW_SPINLOCK(big_irq_lock);
int __initdata of_ioapic;
-#ifdef CONFIG_X86_IO_APIC
-static void add_interrupt_host(struct irq_domain *ih)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&big_irq_lock, flags);
- list_add(&ih->l, &irq_domains);
- raw_spin_unlock_irqrestore(&big_irq_lock, flags);
-}
-#endif
-
-static struct irq_domain *get_ih_from_node(struct device_node *controller)
-{
- struct irq_domain *ih, *found = NULL;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&big_irq_lock, flags);
- list_for_each_entry(ih, &irq_domains, l) {
- if (ih->controller == controller) {
- found = ih;
- break;
- }
- }
- raw_spin_unlock_irqrestore(&big_irq_lock, flags);
- return found;
-}
-
-unsigned int irq_create_of_mapping(struct device_node *controller,
- const u32 *intspec, unsigned int intsize)
-{
- struct irq_domain *ih;
- u32 virq, type;
- int ret;
-
- ih = get_ih_from_node(controller);
- if (!ih)
- return 0;
- ret = ih->xlate(ih, intspec, intsize, &virq, &type);
- if (ret)
- return 0;
- if (type == IRQ_TYPE_NONE)
- return virq;
- irq_set_irq_type(virq, type);
- return virq;
-}
-EXPORT_SYMBOL_GPL(irq_create_of_mapping);
-
unsigned long pci_address_to_pio(phys_addr_t address)
{
/*
@@ -354,36 +305,43 @@ static struct of_ioapic_type of_ioapic_type[] =
},
};
-static int ioapic_xlate(struct irq_domain *id, const u32 *intspec, u32 intsize,
- u32 *out_hwirq, u32 *out_type)
+static int ioapic_xlate(struct irq_domain *domain,
+ struct device_node *controller,
+ const u32 *intspec, u32 intsize,
+ irq_hw_number_t *out_hwirq, u32 *out_type)
{
- struct mp_ioapic_gsi *gsi_cfg;
struct io_apic_irq_attr attr;
struct of_ioapic_type *it;
- u32 line, idx, type;
+ u32 line, idx;
+ int rc;
- if (intsize < 2)
+ if (WARN_ON(intsize < 2))
return -EINVAL;
- line = *intspec;
- idx = (u32) id->priv;
- gsi_cfg = mp_ioapic_gsi_routing(idx);
- *out_hwirq = line + gsi_cfg->gsi_base;
-
- intspec++;
- type = *intspec;
+ line = intspec[0];
- if (type >= ARRAY_SIZE(of_ioapic_type))
+ if (intspec[1] >= ARRAY_SIZE(of_ioapic_type))
return -EINVAL;
- it = of_ioapic_type + type;
- *out_type = it->out_type;
+ it = &of_ioapic_type[intspec[1]];
+ idx = (u32) domain->host_data;
set_io_apic_irq_attr(&attr, idx, line, it->trigger, it->polarity);
- return io_apic_setup_irq_pin_once(*out_hwirq, cpu_to_node(0), &attr);
+ rc = io_apic_setup_irq_pin_once(irq_find_mapping(domain, line),
+ cpu_to_node(0), &attr);
+ if (rc)
+ return rc;
+
+ *out_hwirq = line;
+ *out_type = it->out_type;
+ return 0;
}
+const struct irq_domain_ops ioapic_irq_domain_ops = {
+ .xlate = ioapic_xlate,
+};
+
static void __init ioapic_add_ofnode(struct device_node *np)
{
struct resource r;
@@ -399,13 +357,14 @@ static void __init ioapic_add_ofnode(struct device_node *np)
for (i = 0; i < nr_ioapics; i++) {
if (r.start == mpc_ioapic_addr(i)) {
struct irq_domain *id;
+ struct mp_ioapic_gsi *gsi_cfg;
+
+ gsi_cfg = mp_ioapic_gsi_routing(i);
- id = kzalloc(sizeof(*id), GFP_KERNEL);
+ id = irq_domain_add_legacy(np, 32, gsi_cfg->gsi_base, 0,
+ &ioapic_irq_domain_ops,
+ (void*)i);
BUG_ON(!id);
- id->controller = np;
- id->xlate = ioapic_xlate;
- id->priv = (void *)i;
- add_interrupt_host(id);
return;
}
}
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 3fe8239fd8f..1333d985177 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -1532,10 +1532,17 @@ ENTRY(nmi)
pushq_cfi %rdx
/*
+ * If %cs was not the kernel segment, then the NMI triggered in user
+ * space, which means it is definitely not nested.
+ */
+ cmpl $__KERNEL_CS, 16(%rsp)
+ jne first_nmi
+
+ /*
* Check the special variable on the stack to see if NMIs are
* executing.
*/
- cmp $1, -8(%rsp)
+ cmpl $1, -8(%rsp)
je nested_nmi
/*
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index ac0417be913..73465aab28f 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -360,7 +360,6 @@ out:
static enum ucode_state
request_microcode_user(int cpu, const void __user *buf, size_t size)
{
- pr_info("AMD microcode update via /dev/cpu/microcode not supported\n");
return UCODE_ERROR;
}
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 80bfe1ab003..c08d1ff12b7 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -214,6 +214,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
task_user_gs(p) = get_user_gs(regs);
+ p->fpu_counter = 0;
p->thread.io_bitmap_ptr = NULL;
tsk = current;
err = -ENOMEM;
@@ -303,7 +304,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
- fpu = switch_fpu_prepare(prev_p, next_p);
+ fpu = switch_fpu_prepare(prev_p, next_p, cpu);
/*
* Reload esp0.
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 1fd94bc4279..cfa5c90c01d 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -286,6 +286,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
set_tsk_thread_flag(p, TIF_FORK);
+ p->fpu_counter = 0;
p->thread.io_bitmap_ptr = NULL;
savesegment(gs, p->thread.gsindex);
@@ -388,7 +389,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
unsigned fsindex, gsindex;
fpu_switch_t fpu;
- fpu = switch_fpu_prepare(prev_p, next_p);
+ fpu = switch_fpu_prepare(prev_p, next_p, cpu);
/*
* Reload esp0, LDT and the page table pointer:
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 77da5b475ad..4bbe04d9674 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -571,37 +571,6 @@ asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void)
}
/*
- * This gets called with the process already owning the
- * FPU state, and with CR0.TS cleared. It just needs to
- * restore the FPU register state.
- */
-void __math_state_restore(struct task_struct *tsk)
-{
- /* We need a safe address that is cheap to find and that is already
- in L1. We've just brought in "tsk->thread.has_fpu", so use that */
-#define safe_address (tsk->thread.has_fpu)
-
- /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
- is pending. Clear the x87 state here by setting it to fixed
- values. safe_address is a random variable that should be in L1 */
- alternative_input(
- ASM_NOP8 ASM_NOP2,
- "emms\n\t" /* clear stack tags */
- "fildl %P[addr]", /* set F?P to defined value */
- X86_FEATURE_FXSAVE_LEAK,
- [addr] "m" (safe_address));
-
- /*
- * Paranoid restore. send a SIGSEGV if we fail to restore the state.
- */
- if (unlikely(restore_fpu_checking(tsk))) {
- __thread_fpu_end(tsk);
- force_sig(SIGSEGV, tsk);
- return;
- }
-}
-
-/*
* 'math_state_restore()' saves the current math information in the
* old math state array, and gets the new ones from the current task
*
@@ -631,7 +600,14 @@ void math_state_restore(void)
}
__thread_fpu_begin(tsk);
- __math_state_restore(tsk);
+ /*
+ * Paranoid restore. send a SIGSEGV if we fail to restore the state.
+ */
+ if (unlikely(restore_fpu_checking(tsk))) {
+ __thread_fpu_end(tsk);
+ force_sig(SIGSEGV, tsk);
+ return;
+ }
tsk->fpu_counter++;
}
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 5fa553babe5..e385214711c 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -29,6 +29,7 @@
#include <linux/ftrace_event.h>
#include <linux/slab.h>
+#include <asm/perf_event.h>
#include <asm/tlbflush.h>
#include <asm/desc.h>
#include <asm/kvm_para.h>
@@ -575,6 +576,8 @@ static void svm_hardware_disable(void *garbage)
wrmsrl(MSR_AMD64_TSC_RATIO, TSC_RATIO_DEFAULT);
cpu_svm_disable();
+
+ amd_pmu_disable_virt();
}
static int svm_hardware_enable(void *garbage)
@@ -622,6 +625,8 @@ static int svm_hardware_enable(void *garbage)
svm_init_erratum_383();
+ amd_pmu_enable_virt();
+
return 0;
}
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 12eb07bfb26..4172af8ceeb 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -1141,7 +1141,9 @@ asmlinkage void __init xen_start_kernel(void)
/* Prevent unwanted bits from being set in PTEs. */
__supported_pte_mask &= ~_PAGE_GLOBAL;
+#if 0
if (!xen_initial_domain())
+#endif
__supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
__supported_pte_mask |= _PAGE_IOMAP;
@@ -1204,10 +1206,6 @@ asmlinkage void __init xen_start_kernel(void)
pgd = (pgd_t *)xen_start_info->pt_base;
- if (!xen_initial_domain())
- __supported_pte_mask &= ~(_PAGE_PWT | _PAGE_PCD);
-
- __supported_pte_mask |= _PAGE_IOMAP;
/* Don't do the full vcpu_info placement stuff until we have a
possible map and a non-dummy shared_info. */
per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 58a0e46c404..95c1cf60c66 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -415,13 +415,13 @@ static pteval_t iomap_pte(pteval_t val)
static pteval_t xen_pte_val(pte_t pte)
{
pteval_t pteval = pte.pte;
-
+#if 0
/* If this is a WC pte, convert back from Xen WC to Linux WC */
if ((pteval & (_PAGE_PAT | _PAGE_PCD | _PAGE_PWT)) == _PAGE_PAT) {
WARN_ON(!pat_enabled);
pteval = (pteval & ~_PAGE_PAT) | _PAGE_PWT;
}
-
+#endif
if (xen_initial_domain() && (pteval & _PAGE_IOMAP))
return pteval;
@@ -463,7 +463,7 @@ void xen_set_pat(u64 pat)
static pte_t xen_make_pte(pteval_t pte)
{
phys_addr_t addr = (pte & PTE_PFN_MASK);
-
+#if 0
/* If Linux is trying to set a WC pte, then map to the Xen WC.
* If _PAGE_PAT is set, then it probably means it is really
* _PAGE_PSE, so avoid fiddling with the PAT mapping and hope
@@ -476,7 +476,7 @@ static pte_t xen_make_pte(pteval_t pte)
if ((pte & (_PAGE_PCD | _PAGE_PWT)) == _PAGE_PWT)
pte = (pte & ~(_PAGE_PCD | _PAGE_PWT)) | _PAGE_PAT;
}
-
+#endif
/*
* Unprivileged domains are allowed to do IOMAPpings for
* PCI passthrough, but not map ISA space. The ISA
diff --git a/block/partitions/ldm.c b/block/partitions/ldm.c
index bd8ae788f68..e507cfbd044 100644
--- a/block/partitions/ldm.c
+++ b/block/partitions/ldm.c
@@ -2,7 +2,7 @@
* ldm - Support for Windows Logical Disk Manager (Dynamic Disks)
*
* Copyright (C) 2001,2002 Richard Russon <ldm@flatcap.org>
- * Copyright (c) 2001-2007 Anton Altaparmakov
+ * Copyright (c) 2001-2012 Anton Altaparmakov
* Copyright (C) 2001,2002 Jakob Kemi <jakob.kemi@telia.com>
*
* Documentation is available at http://www.linux-ntfs.org/doku.php?id=downloads
@@ -1341,20 +1341,17 @@ found:
ldm_error("REC value (%d) exceeds NUM value (%d)", rec, f->num);
return false;
}
-
if (f->map & (1 << rec)) {
ldm_error ("Duplicate VBLK, part %d.", rec);
f->map &= 0x7F; /* Mark the group as broken */
return false;
}
-
f->map |= (1 << rec);
-
+ if (!rec)
+ memcpy(f->data, data, VBLK_SIZE_HEAD);
data += VBLK_SIZE_HEAD;
size -= VBLK_SIZE_HEAD;
-
- memcpy (f->data+rec*(size-VBLK_SIZE_HEAD)+VBLK_SIZE_HEAD, data, size);
-
+ memcpy(f->data + VBLK_SIZE_HEAD + rec * size, data, size);
return true;
}
diff --git a/drivers/amba/bus.c b/drivers/amba/bus.c
index 54eaf96ab21..01c2cf4efcd 100644
--- a/drivers/amba/bus.c
+++ b/drivers/amba/bus.c
@@ -497,37 +497,22 @@ static void amba_device_release(struct device *dev)
}
/**
- * amba_device_register - register an AMBA device
- * @dev: AMBA device to register
- * @parent: parent memory resource
+ * amba_device_add - add a previously allocated AMBA device structure
+ * @dev: AMBA device allocated by amba_device_alloc
+ * @parent: resource parent for this devices resources
*
- * Setup the AMBA device, reading the cell ID if present.
- * Claim the resource, and register the AMBA device with
- * the Linux device manager.
+ * Claim the resource, and read the device cell ID if not already
+ * initialized. Register the AMBA device with the Linux device
+ * manager.
*/
-int amba_device_register(struct amba_device *dev, struct resource *parent)
+int amba_device_add(struct amba_device *dev, struct resource *parent)
{
u32 size;
void __iomem *tmp;
int i, ret;
- device_initialize(&dev->dev);
-
- /*
- * Copy from device_add
- */
- if (dev->dev.init_name) {
- dev_set_name(&dev->dev, "%s", dev->dev.init_name);
- dev->dev.init_name = NULL;
- }
-
- dev->dev.release = amba_device_release;
- dev->dev.bus = &amba_bustype;
- dev->dev.dma_mask = &dev->dma_mask;
- dev->res.name = dev_name(&dev->dev);
-
- if (!dev->dev.coherent_dma_mask && dev->dma_mask)
- dev_warn(&dev->dev, "coherent dma mask is unset\n");
+ WARN_ON(dev->irq[0] == (unsigned int)-1);
+ WARN_ON(dev->irq[1] == (unsigned int)-1);
ret = request_resource(parent, &dev->res);
if (ret)
@@ -582,9 +567,9 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
if (ret)
goto err_release;
- if (dev->irq[0] != NO_IRQ)
+ if (dev->irq[0] && dev->irq[0] != NO_IRQ)
ret = device_create_file(&dev->dev, &dev_attr_irq0);
- if (ret == 0 && dev->irq[1] != NO_IRQ)
+ if (ret == 0 && dev->irq[1] && dev->irq[1] != NO_IRQ)
ret = device_create_file(&dev->dev, &dev_attr_irq1);
if (ret == 0)
return ret;
@@ -596,6 +581,74 @@ int amba_device_register(struct amba_device *dev, struct resource *parent)
err_out:
return ret;
}
+EXPORT_SYMBOL_GPL(amba_device_add);
+
+static void amba_device_initialize(struct amba_device *dev, const char *name)
+{
+ device_initialize(&dev->dev);
+ if (name)
+ dev_set_name(&dev->dev, "%s", name);
+ dev->dev.release = amba_device_release;
+ dev->dev.bus = &amba_bustype;
+ dev->dev.dma_mask = &dev->dma_mask;
+ dev->res.name = dev_name(&dev->dev);
+}
+
+/**
+ * amba_device_alloc - allocate an AMBA device
+ * @name: sysfs name of the AMBA device
+ * @base: base of AMBA device
+ * @size: size of AMBA device
+ *
+ * Allocate and initialize an AMBA device structure. Returns %NULL
+ * on failure.
+ */
+struct amba_device *amba_device_alloc(const char *name, resource_size_t base,
+ size_t size)
+{
+ struct amba_device *dev;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (dev) {
+ amba_device_initialize(dev, name);
+ dev->res.start = base;
+ dev->res.end = base + size - 1;
+ dev->res.flags = IORESOURCE_MEM;
+ }
+
+ return dev;
+}
+EXPORT_SYMBOL_GPL(amba_device_alloc);
+
+/**
+ * amba_device_register - register an AMBA device
+ * @dev: AMBA device to register
+ * @parent: parent memory resource
+ *
+ * Setup the AMBA device, reading the cell ID if present.
+ * Claim the resource, and register the AMBA device with
+ * the Linux device manager.
+ */
+int amba_device_register(struct amba_device *dev, struct resource *parent)
+{
+ amba_device_initialize(dev, dev->dev.init_name);
+ dev->dev.init_name = NULL;
+
+ if (!dev->dev.coherent_dma_mask && dev->dma_mask)
+ dev_warn(&dev->dev, "coherent dma mask is unset\n");
+
+ return amba_device_add(dev, parent);
+}
+
+/**
+ * amba_device_put - put an AMBA device
+ * @dev: AMBA device to put
+ */
+void amba_device_put(struct amba_device *dev)
+{
+ put_device(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(amba_device_put);
/**
* amba_device_unregister - unregister an AMBA device
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c
index 5d1d0764513..e8cd652d201 100644
--- a/drivers/atm/solos-pci.c
+++ b/drivers/atm/solos-pci.c
@@ -1206,9 +1206,9 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
out_unmap_both:
pci_set_drvdata(dev, NULL);
- pci_iounmap(dev, card->config_regs);
- out_unmap_config:
pci_iounmap(dev, card->buffers);
+ out_unmap_config:
+ pci_iounmap(dev, card->config_regs);
out_release_regions:
pci_release_regions(dev);
out:
diff --git a/drivers/block/nvme.c b/drivers/block/nvme.c
index c1dc4d86c22..1f3c1a7d132 100644
--- a/drivers/block/nvme.c
+++ b/drivers/block/nvme.c
@@ -41,6 +41,8 @@
#include <linux/types.h>
#include <linux/version.h>
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
#define NVME_Q_DEPTH 1024
#define SQ_SIZE(depth) (depth * sizeof(struct nvme_command))
#define CQ_SIZE(depth) (depth * sizeof(struct nvme_completion))
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f00f596c102..789c9b579ae 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -102,6 +102,7 @@ static struct usb_device_id btusb_table[] = {
/* Broadcom BCM20702A0 */
{ USB_DEVICE(0x0a5c, 0x21e3) },
+ { USB_DEVICE(0x0a5c, 0x21f3) },
{ USB_DEVICE(0x413c, 0x8197) },
{ } /* Terminating entry */
@@ -726,9 +727,6 @@ static int btusb_send_frame(struct sk_buff *skb)
usb_fill_bulk_urb(urb, data->udev, pipe,
skb->data, skb->len, btusb_tx_complete, skb);
- if (skb->priority >= HCI_PRIO_MAX - 1)
- urb->transfer_flags = URB_ISO_ASAP;
-
hdev->stat.acl_tx++;
break;
diff --git a/drivers/cpuidle/Kconfig b/drivers/cpuidle/Kconfig
index 7dbc4a83c45..78a666d1e5f 100644
--- a/drivers/cpuidle/Kconfig
+++ b/drivers/cpuidle/Kconfig
@@ -1,7 +1,7 @@
config CPU_IDLE
bool "CPU idle PM support"
- default ACPI
+ default y if ACPI || PPC_PSERIES
help
CPU idle is a generic framework for supporting software-controlled
idle processor power management. It includes modular cross-platform
diff --git a/drivers/crypto/mv_cesa.c b/drivers/crypto/mv_cesa.c
index 597235a2f8f..0d40cf66b3c 100644
--- a/drivers/crypto/mv_cesa.c
+++ b/drivers/crypto/mv_cesa.c
@@ -714,6 +714,7 @@ static int mv_hash_final(struct ahash_request *req)
{
struct mv_req_hash_ctx *ctx = ahash_request_ctx(req);
+ ahash_request_set_crypt(req, NULL, req->result, 0);
mv_update_hash_req_ctx(ctx, 1, 0);
return mv_handle_req(&req->base);
}
diff --git a/drivers/edac/i3200_edac.c b/drivers/edac/i3200_edac.c
index aa08497a075..73f55e2008c 100644
--- a/drivers/edac/i3200_edac.c
+++ b/drivers/edac/i3200_edac.c
@@ -15,6 +15,8 @@
#include <linux/io.h>
#include "edac_core.h"
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
#define I3200_REVISION "1.1"
#define EDAC_MOD_STR "i3200_edac"
@@ -101,19 +103,6 @@ struct i3200_priv {
static int nr_channels;
-#ifndef readq
-static inline __u64 readq(const volatile void __iomem *addr)
-{
- const volatile u32 __iomem *p = addr;
- u32 low, high;
-
- low = readl(p);
- high = readl(p + 1);
-
- return low + ((u64)high << 32);
-}
-#endif
-
static int how_many_channels(struct pci_dev *pdev)
{
unsigned char capid0_8b; /* 8th byte of CAPID0 */
diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
index 5cd04b65c55..e6568c19c93 100644
--- a/drivers/gpio/gpio-mpc8xxx.c
+++ b/drivers/gpio/gpio-mpc8xxx.c
@@ -37,7 +37,7 @@ struct mpc8xxx_gpio_chip {
* open drain mode safely
*/
u32 data;
- struct irq_host *irq;
+ struct irq_domain *irq;
void *of_dev_id_data;
};
@@ -281,7 +281,7 @@ static struct irq_chip mpc8xxx_irq_chip = {
.irq_set_type = mpc8xxx_irq_set_type,
};
-static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
+static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int virq,
irq_hw_number_t hw)
{
struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data;
@@ -296,24 +296,9 @@ static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq,
return 0;
}
-static int mpc8xxx_gpio_irq_xlate(struct irq_host *h, struct device_node *ct,
- const u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_flags)
-
-{
- /* interrupt sense values coming from the device tree equal either
- * EDGE_FALLING or EDGE_BOTH
- */
- *out_hwirq = intspec[0];
- *out_flags = intspec[1];
-
- return 0;
-}
-
-static struct irq_host_ops mpc8xxx_gpio_irq_ops = {
+static struct irq_domain_ops mpc8xxx_gpio_irq_ops = {
.map = mpc8xxx_gpio_irq_map,
- .xlate = mpc8xxx_gpio_irq_xlate,
+ .xlate = irq_domain_xlate_twocell,
};
static struct of_device_id mpc8xxx_gpio_ids[] __initdata = {
@@ -364,9 +349,8 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
if (hwirq == NO_IRQ)
goto skip_irq;
- mpc8xxx_gc->irq =
- irq_alloc_host(np, IRQ_HOST_MAP_LINEAR, MPC8XXX_GPIO_PINS,
- &mpc8xxx_gpio_irq_ops, MPC8XXX_GPIO_PINS);
+ mpc8xxx_gc->irq = irq_domain_add_linear(np, MPC8XXX_GPIO_PINS,
+ &mpc8xxx_gpio_irq_ops, mpc8xxx_gc);
if (!mpc8xxx_gc->irq)
goto skip_irq;
@@ -374,8 +358,6 @@ static void __init mpc8xxx_add_controller(struct device_node *np)
if (id)
mpc8xxx_gc->of_dev_id_data = id->data;
- mpc8xxx_gc->irq->host_data = mpc8xxx_gc;
-
/* ack and mask all irqs */
out_be32(mm_gc->regs + GPIO_IER, 0xffffffff);
out_be32(mm_gc->regs + GPIO_IMR, 0);
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index bdc29379159..6f17671260e 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -25,6 +25,7 @@
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/module.h>
+#include <linux/irqdomain.h>
#include <asm/mach/irq.h>
@@ -74,9 +75,10 @@ struct tegra_gpio_bank {
#endif
};
-
+static struct irq_domain *irq_domain;
static void __iomem *regs;
-static struct tegra_gpio_bank tegra_gpio_banks[7];
+static u32 tegra_gpio_bank_count;
+static struct tegra_gpio_bank *tegra_gpio_banks;
static inline void tegra_gpio_writel(u32 val, u32 reg)
{
@@ -139,7 +141,7 @@ static int tegra_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
static int tegra_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
- return TEGRA_GPIO_TO_IRQ(offset);
+ return irq_find_mapping(irq_domain, offset);
}
static struct gpio_chip tegra_gpio_chip = {
@@ -155,28 +157,28 @@ static struct gpio_chip tegra_gpio_chip = {
static void tegra_gpio_irq_ack(struct irq_data *d)
{
- int gpio = d->irq - INT_GPIO_BASE;
+ int gpio = d->hwirq;
tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
}
static void tegra_gpio_irq_mask(struct irq_data *d)
{
- int gpio = d->irq - INT_GPIO_BASE;
+ int gpio = d->hwirq;
tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 0);
}
static void tegra_gpio_irq_unmask(struct irq_data *d)
{
- int gpio = d->irq - INT_GPIO_BASE;
+ int gpio = d->hwirq;
tegra_gpio_mask_write(GPIO_MSK_INT_ENB(gpio), gpio, 1);
}
static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
{
- int gpio = d->irq - INT_GPIO_BASE;
+ int gpio = d->hwirq;
struct tegra_gpio_bank *bank = irq_data_get_irq_chip_data(d);
int port = GPIO_PORT(gpio);
int lvl_type;
@@ -273,7 +275,7 @@ void tegra_gpio_resume(void)
local_irq_save(flags);
- for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+ for (b = 0; b < tegra_gpio_bank_count; b++) {
struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -296,7 +298,7 @@ void tegra_gpio_suspend(void)
int p;
local_irq_save(flags);
- for (b = 0; b < ARRAY_SIZE(tegra_gpio_banks); b++) {
+ for (b = 0; b < tegra_gpio_bank_count; b++) {
struct tegra_gpio_bank *bank = &tegra_gpio_banks[b];
for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
@@ -337,13 +339,44 @@ static struct lock_class_key gpio_lock_class;
static int __devinit tegra_gpio_probe(struct platform_device *pdev)
{
+ int irq_base;
struct resource *res;
struct tegra_gpio_bank *bank;
int gpio;
int i;
int j;
- for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+ for (;;) {
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, tegra_gpio_bank_count);
+ if (!res)
+ break;
+ tegra_gpio_bank_count++;
+ }
+ if (!tegra_gpio_bank_count) {
+ dev_err(&pdev->dev, "Missing IRQ resource\n");
+ return -ENODEV;
+ }
+
+ tegra_gpio_chip.ngpio = tegra_gpio_bank_count * 32;
+
+ tegra_gpio_banks = devm_kzalloc(&pdev->dev,
+ tegra_gpio_bank_count * sizeof(*tegra_gpio_banks),
+ GFP_KERNEL);
+ if (!tegra_gpio_banks) {
+ dev_err(&pdev->dev, "Couldn't allocate bank structure\n");
+ return -ENODEV;
+ }
+
+ irq_base = irq_alloc_descs(-1, 0, tegra_gpio_chip.ngpio, 0);
+ if (irq_base < 0) {
+ dev_err(&pdev->dev, "Couldn't allocate IRQ numbers\n");
+ return -ENODEV;
+ }
+ irq_domain = irq_domain_add_legacy(pdev->dev.of_node,
+ tegra_gpio_chip.ngpio, irq_base, 0,
+ &irq_domain_simple_ops, NULL);
+
+ for (i = 0; i < tegra_gpio_bank_count; i++) {
res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
if (!res) {
dev_err(&pdev->dev, "Missing IRQ resource\n");
@@ -380,8 +413,8 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
gpiochip_add(&tegra_gpio_chip);
- for (gpio = 0; gpio < TEGRA_NR_GPIOS; gpio++) {
- int irq = TEGRA_GPIO_TO_IRQ(gpio);
+ for (gpio = 0; gpio < tegra_gpio_chip.ngpio; gpio++) {
+ int irq = irq_find_mapping(irq_domain, gpio);
/* No validity check; all Tegra GPIOs are valid IRQs */
bank = &tegra_gpio_banks[GPIO_BANK(gpio)];
@@ -393,7 +426,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
set_irq_flags(irq, IRQF_VALID);
}
- for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
+ for (i = 0; i < tegra_gpio_bank_count; i++) {
bank = &tegra_gpio_banks[i];
irq_set_chained_handler(bank->irq, tegra_gpio_irq_handler);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c
index d620b078425..618bd4d87d2 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_connector.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c
@@ -28,6 +28,7 @@
#include "drmP.h"
#include "drm_crtc_helper.h"
+#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h"
@@ -44,8 +45,9 @@ struct exynos_drm_connector {
/* convert exynos_video_timings to drm_display_mode */
static inline void
convert_to_display_mode(struct drm_display_mode *mode,
- struct fb_videomode *timing)
+ struct exynos_drm_panel_info *panel)
{
+ struct fb_videomode *timing = &panel->timing;
DRM_DEBUG_KMS("%s\n", __FILE__);
mode->clock = timing->pixclock / 1000;
@@ -60,6 +62,8 @@ convert_to_display_mode(struct drm_display_mode *mode,
mode->vsync_start = mode->vdisplay + timing->upper_margin;
mode->vsync_end = mode->vsync_start + timing->vsync_len;
mode->vtotal = mode->vsync_end + timing->lower_margin;
+ mode->width_mm = panel->width_mm;
+ mode->height_mm = panel->height_mm;
if (timing->vmode & FB_VMODE_INTERLACED)
mode->flags |= DRM_MODE_FLAG_INTERLACE;
@@ -148,16 +152,18 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
connector->display_info.raw_edid = edid;
} else {
struct drm_display_mode *mode = drm_mode_create(connector->dev);
- struct fb_videomode *timing;
+ struct exynos_drm_panel_info *panel;
- if (display_ops->get_timing)
- timing = display_ops->get_timing(manager->dev);
+ if (display_ops->get_panel)
+ panel = display_ops->get_panel(manager->dev);
else {
drm_mode_destroy(connector->dev, mode);
return 0;
}
- convert_to_display_mode(mode, timing);
+ convert_to_display_mode(mode, panel);
+ connector->display_info.width_mm = mode->width_mm;
+ connector->display_info.height_mm = mode->height_mm;
mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
drm_mode_set_name(mode);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c
index 661a03571d0..d08a55896d5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_core.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_core.c
@@ -193,6 +193,9 @@ int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv)
return err;
}
+ /* setup possible_clones. */
+ exynos_drm_encoder_setup(drm_dev);
+
/*
* if any specific driver such as fimd or hdmi driver called
* exynos_drm_subdrv_register() later than drm_load(),
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index e3861ac4929..de818831a51 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -307,9 +307,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
*/
event->pipe = exynos_crtc->pipe;
- list_add_tail(&event->base.link,
- &dev_priv->pageflip_event_list);
-
ret = drm_vblank_get(dev, exynos_crtc->pipe);
if (ret) {
DRM_DEBUG("failed to acquire vblank counter\n");
@@ -318,6 +315,9 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
goto out;
}
+ list_add_tail(&event->base.link,
+ &dev_priv->pageflip_event_list);
+
crtc->fb = fb;
ret = exynos_drm_crtc_update(crtc);
if (ret) {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 35889ca255e..58820ebd355 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -33,6 +33,7 @@
#include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
+#include "exynos_drm_encoder.h"
#include "exynos_drm_fbdev.h"
#include "exynos_drm_fb.h"
#include "exynos_drm_gem.h"
@@ -99,6 +100,9 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
if (ret)
goto err_vblank;
+ /* setup possible_clones. */
+ exynos_drm_encoder_setup(dev);
+
/*
* create and configure fb helper and also exynos specific
* fbdev object.
@@ -141,16 +145,21 @@ static int exynos_drm_unload(struct drm_device *dev)
}
static void exynos_drm_preclose(struct drm_device *dev,
- struct drm_file *file_priv)
+ struct drm_file *file)
{
- struct exynos_drm_private *dev_priv = dev->dev_private;
+ DRM_DEBUG_DRIVER("%s\n", __FILE__);
- /*
- * drm framework frees all events at release time,
- * so private event list should be cleared.
- */
- if (!list_empty(&dev_priv->pageflip_event_list))
- INIT_LIST_HEAD(&dev_priv->pageflip_event_list);
+}
+
+static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
+{
+ DRM_DEBUG_DRIVER("%s\n", __FILE__);
+
+ if (!file->driver_priv)
+ return;
+
+ kfree(file->driver_priv);
+ file->driver_priv = NULL;
}
static void exynos_drm_lastclose(struct drm_device *dev)
@@ -195,6 +204,7 @@ static struct drm_driver exynos_drm_driver = {
.unload = exynos_drm_unload,
.preclose = exynos_drm_preclose,
.lastclose = exynos_drm_lastclose,
+ .postclose = exynos_drm_postclose,
.get_vblank_counter = drm_vblank_count,
.enable_vblank = exynos_drm_crtc_enable_vblank,
.disable_vblank = exynos_drm_crtc_disable_vblank,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index e685e1e3305..13540de90bf 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -136,7 +136,7 @@ struct exynos_drm_overlay {
* @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
* @is_connected: check for that display is connected or not.
* @get_edid: get edid modes from display driver.
- * @get_timing: get timing object from display driver.
+ * @get_panel: get panel object from display driver.
* @check_timing: check if timing is valid or not.
* @power_on: display device on or off.
*/
@@ -145,7 +145,7 @@ struct exynos_drm_display_ops {
bool (*is_connected)(struct device *dev);
int (*get_edid)(struct device *dev, struct drm_connector *connector,
u8 *edid, int len);
- void *(*get_timing)(struct device *dev);
+ void *(*get_panel)(struct device *dev);
int (*check_timing)(struct device *dev, void *timing);
int (*power_on)(struct device *dev, int mode);
};
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 86b93dde219..ef4754f1519 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -195,6 +195,40 @@ static struct drm_encoder_funcs exynos_encoder_funcs = {
.destroy = exynos_drm_encoder_destroy,
};
+static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder)
+{
+ struct drm_encoder *clone;
+ struct drm_device *dev = encoder->dev;
+ struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder);
+ struct exynos_drm_display_ops *display_ops =
+ exynos_encoder->manager->display_ops;
+ unsigned int clone_mask = 0;
+ int cnt = 0;
+
+ list_for_each_entry(clone, &dev->mode_config.encoder_list, head) {
+ switch (display_ops->type) {
+ case EXYNOS_DISPLAY_TYPE_LCD:
+ case EXYNOS_DISPLAY_TYPE_HDMI:
+ clone_mask |= (1 << (cnt++));
+ break;
+ default:
+ continue;
+ }
+ }
+
+ return clone_mask;
+}
+
+void exynos_drm_encoder_setup(struct drm_device *dev)
+{
+ struct drm_encoder *encoder;
+
+ DRM_DEBUG_KMS("%s\n", __FILE__);
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+ encoder->possible_clones = exynos_drm_encoder_clones(encoder);
+}
+
struct drm_encoder *
exynos_drm_encoder_create(struct drm_device *dev,
struct exynos_drm_manager *manager,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
index 97b087a51cb..eb7d2316847 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
@@ -30,6 +30,7 @@
struct exynos_drm_manager;
+void exynos_drm_encoder_setup(struct drm_device *dev);
struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev,
struct exynos_drm_manager *mgr,
unsigned int possible_crtcs);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index d7ae29d2f3d..3508700e529 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -195,66 +195,6 @@ out:
return ret;
}
-static bool
-exynos_drm_fbdev_is_samefb(struct drm_framebuffer *fb,
- struct drm_fb_helper_surface_size *sizes)
-{
- if (fb->width != sizes->surface_width)
- return false;
- if (fb->height != sizes->surface_height)
- return false;
- if (fb->bits_per_pixel != sizes->surface_bpp)
- return false;
- if (fb->depth != sizes->surface_depth)
- return false;
-
- return true;
-}
-
-static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper,
- struct drm_fb_helper_surface_size *sizes)
-{
- struct drm_device *dev = helper->dev;
- struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper);
- struct exynos_drm_gem_obj *exynos_gem_obj;
- struct drm_framebuffer *fb = helper->fb;
- struct drm_mode_fb_cmd2 mode_cmd = { 0 };
- unsigned long size;
-
- DRM_DEBUG_KMS("%s\n", __FILE__);
-
- if (exynos_drm_fbdev_is_samefb(fb, sizes))
- return 0;
-
- mode_cmd.width = sizes->surface_width;
- mode_cmd.height = sizes->surface_height;
- mode_cmd.pitches[0] = sizes->surface_width * (sizes->surface_bpp >> 3);
- mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
- sizes->surface_depth);
-
- if (exynos_fbdev->exynos_gem_obj)
- exynos_drm_gem_destroy(exynos_fbdev->exynos_gem_obj);
-
- if (fb->funcs->destroy)
- fb->funcs->destroy(fb);
-
- size = mode_cmd.pitches[0] * mode_cmd.height;
- exynos_gem_obj = exynos_drm_gem_create(dev, size);
- if (IS_ERR(exynos_gem_obj))
- return PTR_ERR(exynos_gem_obj);
-
- exynos_fbdev->exynos_gem_obj = exynos_gem_obj;
-
- helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd,
- &exynos_gem_obj->base);
- if (IS_ERR_OR_NULL(helper->fb)) {
- DRM_ERROR("failed to create drm framebuffer.\n");
- return PTR_ERR(helper->fb);
- }
-
- return exynos_drm_fbdev_update(helper, helper->fb);
-}
-
static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes)
{
@@ -262,6 +202,10 @@ static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
DRM_DEBUG_KMS("%s\n", __FILE__);
+ /*
+ * with !helper->fb, it means that this funcion is called first time
+ * and after that, the helper->fb would be used as clone mode.
+ */
if (!helper->fb) {
ret = exynos_drm_fbdev_create(helper, sizes);
if (ret < 0) {
@@ -274,12 +218,6 @@ static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper,
* because register_framebuffer() should be called.
*/
ret = 1;
- } else {
- ret = exynos_drm_fbdev_recreate(helper, sizes);
- if (ret < 0) {
- DRM_ERROR("failed to reconfigure fbdev\n");
- return ret;
- }
}
return ret;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index b6a737d196a..360adf2bba0 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -89,7 +89,7 @@ struct fimd_context {
bool suspended;
struct mutex lock;
- struct fb_videomode *timing;
+ struct exynos_drm_panel_info *panel;
};
static bool fimd_display_is_connected(struct device *dev)
@@ -101,13 +101,13 @@ static bool fimd_display_is_connected(struct device *dev)
return true;
}
-static void *fimd_get_timing(struct device *dev)
+static void *fimd_get_panel(struct device *dev)
{
struct fimd_context *ctx = get_fimd_context(dev);
DRM_DEBUG_KMS("%s\n", __FILE__);
- return ctx->timing;
+ return ctx->panel;
}
static int fimd_check_timing(struct device *dev, void *timing)
@@ -131,7 +131,7 @@ static int fimd_display_power_on(struct device *dev, int mode)
static struct exynos_drm_display_ops fimd_display_ops = {
.type = EXYNOS_DISPLAY_TYPE_LCD,
.is_connected = fimd_display_is_connected,
- .get_timing = fimd_get_timing,
+ .get_panel = fimd_get_panel,
.check_timing = fimd_check_timing,
.power_on = fimd_display_power_on,
};
@@ -193,7 +193,8 @@ static void fimd_apply(struct device *subdrv_dev)
static void fimd_commit(struct device *dev)
{
struct fimd_context *ctx = get_fimd_context(dev);
- struct fb_videomode *timing = ctx->timing;
+ struct exynos_drm_panel_info *panel = ctx->panel;
+ struct fb_videomode *timing = &panel->timing;
u32 val;
if (ctx->suspended)
@@ -604,7 +605,12 @@ static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
}
if (is_checked) {
- drm_vblank_put(drm_dev, crtc);
+ /*
+ * call drm_vblank_put only in case that drm_vblank_get was
+ * called.
+ */
+ if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0)
+ drm_vblank_put(drm_dev, crtc);
/*
* don't off vblank if vblank_disable_allowed is 1,
@@ -781,7 +787,7 @@ static int __devinit fimd_probe(struct platform_device *pdev)
struct fimd_context *ctx;
struct exynos_drm_subdrv *subdrv;
struct exynos_drm_fimd_pdata *pdata;
- struct fb_videomode *timing;
+ struct exynos_drm_panel_info *panel;
struct resource *res;
int win;
int ret = -EINVAL;
@@ -794,9 +800,9 @@ static int __devinit fimd_probe(struct platform_device *pdev)
return -EINVAL;
}
- timing = &pdata->timing;
- if (!timing) {
- dev_err(dev, "timing is null.\n");
+ panel = &pdata->panel;
+ if (!panel) {
+ dev_err(dev, "panel is null.\n");
return -EINVAL;
}
@@ -858,16 +864,16 @@ static int __devinit fimd_probe(struct platform_device *pdev)
goto err_req_irq;
}
- ctx->clkdiv = fimd_calc_clkdiv(ctx, timing);
+ ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing);
ctx->vidcon0 = pdata->vidcon0;
ctx->vidcon1 = pdata->vidcon1;
ctx->default_win = pdata->default_win;
- ctx->timing = timing;
+ ctx->panel = panel;
- timing->pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv;
+ panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv;
DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n",
- timing->pixclock, ctx->clkdiv);
+ panel->timing.pixclock, ctx->clkdiv);
subdrv = &ctx->subdrv;
diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c
index ac24cff3977..93846e810e3 100644
--- a/drivers/gpu/drm/exynos/exynos_mixer.c
+++ b/drivers/gpu/drm/exynos/exynos_mixer.c
@@ -712,7 +712,12 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc)
}
if (is_checked)
- drm_vblank_put(drm_dev, crtc);
+ /*
+ * call drm_vblank_put only in case that drm_vblank_get was
+ * called.
+ */
+ if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0)
+ drm_vblank_put(drm_dev, crtc);
spin_unlock_irqrestore(&drm_dev->event_lock, flags);
}
@@ -779,15 +784,15 @@ static void mixer_win_reset(struct mixer_context *ctx)
mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
MXR_STATUS_BURST_MASK);
- /* setting default layer priority: layer1 > video > layer0
+ /* setting default layer priority: layer1 > layer0 > video
* because typical usage scenario would be
+ * layer1 - OSD
* layer0 - framebuffer
* video - video overlay
- * layer1 - OSD
*/
- val = MXR_LAYER_CFG_GRP0_VAL(1);
- val |= MXR_LAYER_CFG_VP_VAL(2);
- val |= MXR_LAYER_CFG_GRP1_VAL(3);
+ val = MXR_LAYER_CFG_GRP1_VAL(3);
+ val |= MXR_LAYER_CFG_GRP0_VAL(2);
+ val |= MXR_LAYER_CFG_VP_VAL(1);
mixer_reg_write(res, MXR_LAYER_CFG, val);
/* setting background color */
@@ -1044,7 +1049,7 @@ static int mixer_remove(struct platform_device *pdev)
platform_get_drvdata(pdev);
struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx;
- dev_info(dev, "remove sucessful\n");
+ dev_info(dev, "remove successful\n");
mixer_resource_poweroff(ctx);
mixer_resources_cleanup(ctx);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c3afb783cb9..03c53fcf865 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3028,6 +3028,20 @@
#define DISP_TILE_SURFACE_SWIZZLING (1<<13)
#define DISP_FBC_WM_DIS (1<<15)
+/* GEN7 chicken */
+#define GEN7_COMMON_SLICE_CHICKEN1 0x7010
+# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26))
+
+#define GEN7_L3CNTLREG1 0xB01C
+#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C
+
+#define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030
+#define GEN7_WA_L3_CHICKEN_MODE 0x20000000
+
+/* WaCatErrorRejectionIssue */
+#define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG 0x9030
+#define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11)
+
/* PCH */
/* south display engine interrupt */
@@ -3618,6 +3632,7 @@
#define GT_FIFO_NUM_RESERVED_ENTRIES 20
#define GEN6_UCGCTL2 0x9404
+# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13)
# define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12)
# define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 00fbff5ddd8..f851db7be2c 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -4680,8 +4680,17 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane,
crtc = intel_get_crtc_for_plane(dev, plane);
clock = crtc->mode.clock;
+ if (!clock) {
+ *sprite_wm = 0;
+ return false;
+ }
line_time_us = (sprite_width * 1000) / clock;
+ if (!line_time_us) {
+ *sprite_wm = 0;
+ return false;
+ }
+
line_count = (latency_ns / line_time_us + 1000) / 1000;
line_size = sprite_width * pixel_size;
@@ -6175,7 +6184,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
int i;
/* The clocks have to be on to load the palette. */
- if (!crtc->enabled)
+ if (!crtc->enabled || !intel_crtc->active)
return;
/* use legacy palette for Ironlake */
@@ -6561,7 +6570,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
mode_cmd.height = mode->vdisplay;
mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
bpp);
- mode_cmd.pixel_format = 0;
+ mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth);
return intel_framebuffer_create(dev, &mode_cmd, obj);
}
@@ -8184,8 +8193,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */
if (intel_enable_rc6(dev_priv->dev))
- rc6_mask = GEN6_RC_CTL_RC6p_ENABLE |
- GEN6_RC_CTL_RC6_ENABLE;
+ rc6_mask = GEN6_RC_CTL_RC6_ENABLE |
+ ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0);
I915_WRITE(GEN6_RC_CONTROL,
rc6_mask |
@@ -8463,12 +8472,32 @@ static void ivybridge_init_clock_gating(struct drm_device *dev)
I915_WRITE(WM2_LP_ILK, 0);
I915_WRITE(WM1_LP_ILK, 0);
+ /* According to the spec, bit 13 (RCZUNIT) must be set on IVB.
+ * This implements the WaDisableRCZUnitClockGating workaround.
+ */
+ I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE);
+
I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE);
I915_WRITE(IVB_CHICKEN3,
CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE |
CHICKEN3_DGMG_DONE_FIX_DISABLE);
+ /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */
+ I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1,
+ GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
+
+ /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */
+ I915_WRITE(GEN7_L3CNTLREG1,
+ GEN7_WA_FOR_GEN7_L3_CONTROL);
+ I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER,
+ GEN7_WA_L3_CHICKEN_MODE);
+
+ /* This is required by WaCatErrorRejectionIssue */
+ I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG,
+ I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) |
+ GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB);
+
for_each_pipe(pipe) {
I915_WRITE(DSPCNTR(pipe),
I915_READ(DSPCNTR(pipe)) |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 1ab842c6032..536191540b0 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -301,7 +301,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)
I915_WRITE_CTL(ring,
((ring->size - PAGE_SIZE) & RING_NR_PAGES)
- | RING_REPORT_64K | RING_VALID);
+ | RING_VALID);
/* If the head is still not zero, the ring is dead */
if ((I915_READ_CTL(ring) & RING_VALID) == 0 ||
@@ -1132,18 +1132,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long end;
- u32 head;
-
- /* If the reported head position has wrapped or hasn't advanced,
- * fallback to the slow and accurate path.
- */
- head = intel_read_status_page(ring, 4);
- if (head > ring->head) {
- ring->head = head;
- ring->space = ring_space(ring);
- if (ring->space >= n)
- return 0;
- }
trace_i915_ring_wait_begin(ring);
if (drm_core_check_feature(dev, DRIVER_GEM))
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c
index 9be353b894c..f58254a3fb0 100644
--- a/drivers/gpu/drm/radeon/evergreen.c
+++ b/drivers/gpu/drm/radeon/evergreen.c
@@ -3223,6 +3223,7 @@ int evergreen_resume(struct radeon_device *rdev)
r = evergreen_startup(rdev);
if (r) {
DRM_ERROR("evergreen startup failed on resume\n");
+ rdev->accel_working = false;
return r;
}
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
index db09065e68f..2509c505acb 100644
--- a/drivers/gpu/drm/radeon/ni.c
+++ b/drivers/gpu/drm/radeon/ni.c
@@ -1547,6 +1547,7 @@ int cayman_resume(struct radeon_device *rdev)
r = cayman_startup(rdev);
if (r) {
DRM_ERROR("cayman startup failed on resume\n");
+ rdev->accel_working = false;
return r;
}
return r;
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 18cd84fae99..333cde9d4e7 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -3928,6 +3928,8 @@ static int r100_startup(struct radeon_device *rdev)
int r100_resume(struct radeon_device *rdev)
{
+ int r;
+
/* Make sur GART are not working */
if (rdev->flags & RADEON_IS_PCI)
r100_pci_gart_disable(rdev);
@@ -3947,7 +3949,11 @@ int r100_resume(struct radeon_device *rdev)
radeon_surface_init(rdev);
rdev->accel_working = true;
- return r100_startup(rdev);
+ r = r100_startup(rdev);
+ if (r) {
+ rdev->accel_working = false;
+ }
+ return r;
}
int r100_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c
index 3fc0d29a5f3..6829638cca4 100644
--- a/drivers/gpu/drm/radeon/r300.c
+++ b/drivers/gpu/drm/radeon/r300.c
@@ -1431,6 +1431,8 @@ static int r300_startup(struct radeon_device *rdev)
int r300_resume(struct radeon_device *rdev)
{
+ int r;
+
/* Make sur GART are not working */
if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev);
@@ -1452,7 +1454,11 @@ int r300_resume(struct radeon_device *rdev)
radeon_surface_init(rdev);
rdev->accel_working = true;
- return r300_startup(rdev);
+ r = r300_startup(rdev);
+ if (r) {
+ rdev->accel_working = false;
+ }
+ return r;
}
int r300_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c
index 666e28fe509..b14323053ba 100644
--- a/drivers/gpu/drm/radeon/r420.c
+++ b/drivers/gpu/drm/radeon/r420.c
@@ -291,6 +291,8 @@ static int r420_startup(struct radeon_device *rdev)
int r420_resume(struct radeon_device *rdev)
{
+ int r;
+
/* Make sur GART are not working */
if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev);
@@ -316,7 +318,11 @@ int r420_resume(struct radeon_device *rdev)
radeon_surface_init(rdev);
rdev->accel_working = true;
- return r420_startup(rdev);
+ r = r420_startup(rdev);
+ if (r) {
+ rdev->accel_working = false;
+ }
+ return r;
}
int r420_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c
index 4ae1615e752..25084e824db 100644
--- a/drivers/gpu/drm/radeon/r520.c
+++ b/drivers/gpu/drm/radeon/r520.c
@@ -218,6 +218,8 @@ static int r520_startup(struct radeon_device *rdev)
int r520_resume(struct radeon_device *rdev)
{
+ int r;
+
/* Make sur GART are not working */
if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev);
@@ -237,7 +239,11 @@ int r520_resume(struct radeon_device *rdev)
radeon_surface_init(rdev);
rdev->accel_working = true;
- return r520_startup(rdev);
+ r = r520_startup(rdev);
+ if (r) {
+ rdev->accel_working = false;
+ }
+ return r;
}
int r520_init(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c
index 4f08e5e6ee9..fbcd84803b6 100644
--- a/drivers/gpu/drm/radeon/r600.c
+++ b/drivers/gpu/drm/radeon/r600.c
@@ -2529,6 +2529,7 @@ int r600_resume(struct radeon_device *rdev)
r = r600_startup(rdev);
if (r) {
DRM_ERROR("r600 startup failed on resume\n");
+ rdev->accel_working = false;
return r;
}
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 38ce5d0427e..387fcc9f03e 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -1304,6 +1304,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
h0 = G_038004_TEX_HEIGHT(word1) + 1;
d0 = G_038004_TEX_DEPTH(word1);
nfaces = 1;
+ array = 0;
switch (G_038000_DIM(word0)) {
case V_038000_SQ_TEX_DIM_1D:
case V_038000_SQ_TEX_DIM_2D:
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c
index 9e72daeeddc..1f53ae74ada 100644
--- a/drivers/gpu/drm/radeon/radeon_atombios.c
+++ b/drivers/gpu/drm/radeon/radeon_atombios.c
@@ -3020,6 +3020,9 @@ radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on)
struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
uint32_t bios_2_scratch;
+ if (ASIC_IS_DCE4(rdev))
+ return;
+
if (rdev->family >= CHIP_R600)
bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH);
else
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index e7cb3ab0924..8b3d8ed52ff 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1117,13 +1117,23 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
struct drm_display_mode *mode;
- if (!radeon_dig_connector->edp_on)
- atombios_set_edp_panel_power(connector,
- ATOM_TRANSMITTER_ACTION_POWER_ON);
- ret = radeon_ddc_get_modes(radeon_connector);
- if (!radeon_dig_connector->edp_on)
- atombios_set_edp_panel_power(connector,
- ATOM_TRANSMITTER_ACTION_POWER_OFF);
+ if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
+ if (!radeon_dig_connector->edp_on)
+ atombios_set_edp_panel_power(connector,
+ ATOM_TRANSMITTER_ACTION_POWER_ON);
+ ret = radeon_ddc_get_modes(radeon_connector);
+ if (!radeon_dig_connector->edp_on)
+ atombios_set_edp_panel_power(connector,
+ ATOM_TRANSMITTER_ACTION_POWER_OFF);
+ } else {
+ /* need to setup ddc on the bridge */
+ if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) !=
+ ENCODER_OBJECT_ID_NONE) {
+ if (encoder)
+ radeon_atom_ext_encoder_setup_ddc(encoder);
+ }
+ ret = radeon_ddc_get_modes(radeon_connector);
+ }
if (ret > 0) {
if (encoder) {
@@ -1134,7 +1144,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
return ret;
}
- encoder = radeon_best_single_encoder(connector);
if (!encoder)
return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c
index 435a3d970ab..e64bec488ed 100644
--- a/drivers/gpu/drm/radeon/radeon_cs.c
+++ b/drivers/gpu/drm/radeon/radeon_cs.c
@@ -453,6 +453,10 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
int r;
radeon_mutex_lock(&rdev->cs_mutex);
+ if (!rdev->accel_working) {
+ radeon_mutex_unlock(&rdev->cs_mutex);
+ return -EBUSY;
+ }
/* initialize parser */
memset(&parser, 0, sizeof(struct radeon_cs_parser));
parser.filp = filp;
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c
index 010dad8b66a..c58a036233f 100644
--- a/drivers/gpu/drm/radeon/radeon_gart.c
+++ b/drivers/gpu/drm/radeon/radeon_gart.c
@@ -597,13 +597,13 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
if (bo_va == NULL)
return 0;
- list_del(&bo_va->bo_list);
mutex_lock(&vm->mutex);
radeon_mutex_lock(&rdev->cs_mutex);
radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
radeon_mutex_unlock(&rdev->cs_mutex);
list_del(&bo_va->vm_list);
mutex_unlock(&vm->mutex);
+ list_del(&bo_va->bo_list);
kfree(bo_va);
return 0;
diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c
index 30a4c5014c8..92c9ea4751f 100644
--- a/drivers/gpu/drm/radeon/radeon_ring.c
+++ b/drivers/gpu/drm/radeon/radeon_ring.c
@@ -500,8 +500,11 @@ static char radeon_debugfs_ib_names[RADEON_IB_POOL_SIZE][32];
int radeon_debugfs_ring_init(struct radeon_device *rdev)
{
#if defined(CONFIG_DEBUG_FS)
- return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list,
- ARRAY_SIZE(radeon_debugfs_ring_info_list));
+ if (rdev->family >= CHIP_CAYMAN)
+ return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list,
+ ARRAY_SIZE(radeon_debugfs_ring_info_list));
+ else
+ return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1);
#else
return 0;
#endif
diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c
index b0ce84a20a6..866a05be75f 100644
--- a/drivers/gpu/drm/radeon/rs400.c
+++ b/drivers/gpu/drm/radeon/rs400.c
@@ -442,6 +442,8 @@ static int rs400_startup(struct radeon_device *rdev)
int rs400_resume(struct radeon_device *rdev)
{
+ int r;
+
/* Make sur GART are not working */
rs400_gart_disable(rdev);
/* Resume clock before doing reset */
@@ -462,7 +464,11 @@ int rs400_resume(struct radeon_device *rdev)
radeon_surface_init(rdev);
rdev->accel_working = true;
- return rs400_startup(rdev);
+ r = rs400_startup(rdev);
+ if (r) {
+ rdev->accel_working = false;
+ }
+ return r;
}
int rs400_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index c05865e5521..4fc700684dc 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -876,6 +876,8 @@ static int rs600_startup(struct radeon_device *rdev)
int rs600_resume(struct radeon_device *rdev)
{
+ int r;
+
/* Make sur GART are not working */
rs600_gart_disable(rdev);
/* Resume clock before doing reset */
@@ -894,7 +896,11 @@ int rs600_resume(struct radeon_device *rdev)
radeon_surface_init(rdev);
rdev->accel_working = true;
- return rs600_startup(rdev);
+ r = rs600_startup(rdev);
+ if (r) {
+ rdev->accel_working = false;
+ }
+ return r;
}
int rs600_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c
index 4f24a0fa8c8..f68dff2fadc 100644
--- a/drivers/gpu/drm/radeon/rs690.c
+++ b/drivers/gpu/drm/radeon/rs690.c
@@ -659,6 +659,8 @@ static int rs690_startup(struct radeon_device *rdev)
int rs690_resume(struct radeon_device *rdev)
{
+ int r;
+
/* Make sur GART are not working */
rs400_gart_disable(rdev);
/* Resume clock before doing reset */
@@ -677,7 +679,11 @@ int rs690_resume(struct radeon_device *rdev)
radeon_surface_init(rdev);
rdev->accel_working = true;
- return rs690_startup(rdev);
+ r = rs690_startup(rdev);
+ if (r) {
+ rdev->accel_working = false;
+ }
+ return r;
}
int rs690_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c
index 880637fd194..959bf4483be 100644
--- a/drivers/gpu/drm/radeon/rv515.c
+++ b/drivers/gpu/drm/radeon/rv515.c
@@ -424,6 +424,8 @@ static int rv515_startup(struct radeon_device *rdev)
int rv515_resume(struct radeon_device *rdev)
{
+ int r;
+
/* Make sur GART are not working */
if (rdev->flags & RADEON_IS_PCIE)
rv370_pcie_gart_disable(rdev);
@@ -443,7 +445,11 @@ int rv515_resume(struct radeon_device *rdev)
radeon_surface_init(rdev);
rdev->accel_working = true;
- return rv515_startup(rdev);
+ r = rv515_startup(rdev);
+ if (r) {
+ rdev->accel_working = false;
+ }
+ return r;
}
int rv515_suspend(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c
index a1668b659dd..c049c0c5184 100644
--- a/drivers/gpu/drm/radeon/rv770.c
+++ b/drivers/gpu/drm/radeon/rv770.c
@@ -1139,6 +1139,7 @@ int rv770_resume(struct radeon_device *rdev)
r = rv770_startup(rdev);
if (r) {
DRM_ERROR("r600 startup failed on resume\n");
+ rdev->accel_working = false;
return r;
}
diff --git a/drivers/hwmon/ads1015.c b/drivers/hwmon/ads1015.c
index eedca3cf996..dd87ae96c26 100644
--- a/drivers/hwmon/ads1015.c
+++ b/drivers/hwmon/ads1015.c
@@ -271,7 +271,7 @@ static int ads1015_probe(struct i2c_client *client,
continue;
err = device_create_file(&client->dev, &ads1015_in[k].dev_attr);
if (err)
- goto exit_free;
+ goto exit_remove;
}
data->hwmon_dev = hwmon_device_register(&client->dev);
@@ -285,7 +285,6 @@ static int ads1015_probe(struct i2c_client *client,
exit_remove:
for (k = 0; k < ADS1015_CHANNELS; ++k)
device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
-exit_free:
kfree(data);
exit:
return err;
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c
index f609b5727ba..6aa5a9fad87 100644
--- a/drivers/hwmon/f75375s.c
+++ b/drivers/hwmon/f75375s.c
@@ -178,6 +178,16 @@ static inline void f75375_write16(struct i2c_client *client, u8 reg,
i2c_smbus_write_byte_data(client, reg + 1, (value & 0xFF));
}
+static void f75375_write_pwm(struct i2c_client *client, int nr)
+{
+ struct f75375_data *data = i2c_get_clientdata(client);
+ if (data->kind == f75387)
+ f75375_write16(client, F75375_REG_FAN_EXP(nr), data->pwm[nr]);
+ else
+ f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
+ data->pwm[nr]);
+}
+
static struct f75375_data *f75375_update_device(struct device *dev)
{
struct i2c_client *client = to_i2c_client(dev);
@@ -254,6 +264,36 @@ static inline u16 rpm_to_reg(int rpm)
return 1500000 / rpm;
}
+static bool duty_mode_enabled(u8 pwm_enable)
+{
+ switch (pwm_enable) {
+ case 0: /* Manual, duty mode (full speed) */
+ case 1: /* Manual, duty mode */
+ case 4: /* Auto, duty mode */
+ return true;
+ case 2: /* Auto, speed mode */
+ case 3: /* Manual, speed mode */
+ return false;
+ default:
+ BUG();
+ }
+}
+
+static bool auto_mode_enabled(u8 pwm_enable)
+{
+ switch (pwm_enable) {
+ case 0: /* Manual, duty mode (full speed) */
+ case 1: /* Manual, duty mode */
+ case 3: /* Manual, speed mode */
+ return false;
+ case 2: /* Auto, speed mode */
+ case 4: /* Auto, duty mode */
+ return true;
+ default:
+ BUG();
+ }
+}
+
static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
@@ -287,6 +327,11 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *attr,
if (err < 0)
return err;
+ if (auto_mode_enabled(data->pwm_enable[nr]))
+ return -EINVAL;
+ if (data->kind == f75387 && duty_mode_enabled(data->pwm_enable[nr]))
+ return -EINVAL;
+
mutex_lock(&data->update_lock);
data->fan_target[nr] = rpm_to_reg(val);
f75375_write16(client, F75375_REG_FAN_EXP(nr), data->fan_target[nr]);
@@ -307,9 +352,13 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
if (err < 0)
return err;
+ if (auto_mode_enabled(data->pwm_enable[nr]) ||
+ !duty_mode_enabled(data->pwm_enable[nr]))
+ return -EINVAL;
+
mutex_lock(&data->update_lock);
data->pwm[nr] = SENSORS_LIMIT(val, 0, 255);
- f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), data->pwm[nr]);
+ f75375_write_pwm(client, nr);
mutex_unlock(&data->update_lock);
return count;
}
@@ -327,11 +376,15 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
struct f75375_data *data = i2c_get_clientdata(client);
u8 fanmode;
- if (val < 0 || val > 3)
+ if (val < 0 || val > 4)
return -EINVAL;
fanmode = f75375_read8(client, F75375_REG_FAN_TIMER);
if (data->kind == f75387) {
+ /* For now, deny dangerous toggling of duty mode */
+ if (duty_mode_enabled(data->pwm_enable[nr]) !=
+ duty_mode_enabled(val))
+ return -EOPNOTSUPP;
/* clear each fanX_mode bit before setting them properly */
fanmode &= ~(1 << F75387_FAN_DUTY_MODE(nr));
fanmode &= ~(1 << F75387_FAN_MANU_MODE(nr));
@@ -340,19 +393,19 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
data->pwm[nr] = 255;
- f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
- data->pwm[nr]);
break;
case 1: /* PWM */
fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
break;
- case 2: /* AUTOMATIC*/
- fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
+ case 2: /* Automatic, speed mode */
break;
case 3: /* fan speed */
fanmode |= (1 << F75387_FAN_MANU_MODE(nr));
break;
+ case 4: /* Automatic, pwm */
+ fanmode |= (1 << F75387_FAN_DUTY_MODE(nr));
+ break;
}
} else {
/* clear each fanX_mode bit before setting them properly */
@@ -361,8 +414,6 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
case 0: /* full speed */
fanmode |= (3 << FAN_CTRL_MODE(nr));
data->pwm[nr] = 255;
- f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
- data->pwm[nr]);
break;
case 1: /* PWM */
fanmode |= (3 << FAN_CTRL_MODE(nr));
@@ -372,11 +423,15 @@ static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val)
break;
case 3: /* fan speed */
break;
+ case 4: /* Automatic pwm */
+ return -EINVAL;
}
}
f75375_write8(client, F75375_REG_FAN_TIMER, fanmode);
data->pwm_enable[nr] = val;
+ if (val == 0)
+ f75375_write_pwm(client, nr);
return 0;
}
@@ -727,14 +782,17 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
manu = ((mode >> F75387_FAN_MANU_MODE(nr)) & 1);
duty = ((mode >> F75387_FAN_DUTY_MODE(nr)) & 1);
- if (manu && duty)
- /* speed */
+ if (!manu && duty)
+ /* auto, pwm */
+ data->pwm_enable[nr] = 4;
+ else if (manu && !duty)
+ /* manual, speed */
data->pwm_enable[nr] = 3;
- else if (!manu && duty)
- /* automatic */
+ else if (!manu && !duty)
+ /* automatic, speed */
data->pwm_enable[nr] = 2;
else
- /* manual */
+ /* manual, pwm */
data->pwm_enable[nr] = 1;
} else {
if (!(conf & (1 << F75375_FAN_CTRL_LINEAR(nr))))
@@ -759,9 +817,11 @@ static void f75375_init(struct i2c_client *client, struct f75375_data *data,
set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]);
set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]);
for (nr = 0; nr < 2; nr++) {
+ if (auto_mode_enabled(f75375s_pdata->pwm_enable[nr]) ||
+ !duty_mode_enabled(f75375s_pdata->pwm_enable[nr]))
+ continue;
data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255);
- f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr),
- data->pwm[nr]);
+ f75375_write_pwm(client, nr);
}
}
@@ -788,7 +848,7 @@ static int f75375_probe(struct i2c_client *client,
if (err)
goto exit_free;
- if (data->kind == f75375) {
+ if (data->kind != f75373) {
err = sysfs_chmod_file(&client->dev.kobj,
&sensor_dev_attr_pwm1_mode.dev_attr.attr,
S_IRUGO | S_IWUSR);
diff --git a/drivers/hwmon/max6639.c b/drivers/hwmon/max6639.c
index e10a092c603..a6760bacd91 100644
--- a/drivers/hwmon/max6639.c
+++ b/drivers/hwmon/max6639.c
@@ -72,8 +72,8 @@ static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END };
static const int rpm_ranges[] = { 2000, 4000, 8000, 16000 };
-#define FAN_FROM_REG(val, div, rpm_range) ((val) == 0 ? -1 : \
- (val) == 255 ? 0 : (rpm_ranges[rpm_range] * 30) / ((div + 1) * (val)))
+#define FAN_FROM_REG(val, rpm_range) ((val) == 0 || (val) == 255 ? \
+ 0 : (rpm_ranges[rpm_range] * 30) / (val))
#define TEMP_LIMIT_TO_REG(val) SENSORS_LIMIT((val) / 1000, 0, 255)
/*
@@ -333,7 +333,7 @@ static ssize_t show_fan_input(struct device *dev,
return PTR_ERR(data);
return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index],
- data->ppr, data->rpm_range));
+ data->rpm_range));
}
static ssize_t show_alarm(struct device *dev,
@@ -429,9 +429,9 @@ static int max6639_init_client(struct i2c_client *client)
struct max6639_data *data = i2c_get_clientdata(client);
struct max6639_platform_data *max6639_info =
client->dev.platform_data;
- int i = 0;
+ int i;
int rpm_range = 1; /* default: 4000 RPM */
- int err = 0;
+ int err;
/* Reset chip to default values, see below for GCONFIG setup */
err = i2c_smbus_write_byte_data(client, MAX6639_REG_GCONFIG,
@@ -446,11 +446,6 @@ static int max6639_init_client(struct i2c_client *client)
else
data->ppr = 2;
data->ppr -= 1;
- err = i2c_smbus_write_byte_data(client,
- MAX6639_REG_FAN_PPR(i),
- data->ppr << 5);
- if (err)
- goto exit;
if (max6639_info)
rpm_range = rpm_range_to_reg(max6639_info->rpm_range);
@@ -458,6 +453,13 @@ static int max6639_init_client(struct i2c_client *client)
for (i = 0; i < 2; i++) {
+ /* Set Fan pulse per revolution */
+ err = i2c_smbus_write_byte_data(client,
+ MAX6639_REG_FAN_PPR(i),
+ data->ppr << 6);
+ if (err)
+ goto exit;
+
/* Fans config PWM, RPM */
err = i2c_smbus_write_byte_data(client,
MAX6639_REG_FAN_CONFIG1(i),
diff --git a/drivers/hwmon/pmbus/max34440.c b/drivers/hwmon/pmbus/max34440.c
index beaf5a8d9c4..9b97a5b3cf3 100644
--- a/drivers/hwmon/pmbus/max34440.c
+++ b/drivers/hwmon/pmbus/max34440.c
@@ -82,7 +82,7 @@ static int max34440_write_word_data(struct i2c_client *client, int page,
case PMBUS_VIRT_RESET_TEMP_HISTORY:
ret = pmbus_write_word_data(client, page,
MAX34440_MFR_TEMPERATURE_PEAK,
- 0xffff);
+ 0x8000);
break;
default:
ret = -ENODATA;
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 58832e578ff..8d1ab6fa88e 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -196,7 +196,7 @@ static int i2c_imx_start(struct imx_i2c_struct *i2c_imx)
dev_dbg(&i2c_imx->adapter.dev, "<%s>\n", __func__);
- clk_enable(i2c_imx->clk);
+ clk_prepare_enable(i2c_imx->clk);
writeb(i2c_imx->ifdr, i2c_imx->base + IMX_I2C_IFDR);
/* Enable I2C controller */
writeb(0, i2c_imx->base + IMX_I2C_I2SR);
@@ -245,7 +245,7 @@ static void i2c_imx_stop(struct imx_i2c_struct *i2c_imx)
/* Disable I2C controller */
writeb(0, i2c_imx->base + IMX_I2C_I2CR);
- clk_disable(i2c_imx->clk);
+ clk_disable_unprepare(i2c_imx->clk);
}
static void __init i2c_imx_set_clk(struct imx_i2c_struct *i2c_imx,
diff --git a/drivers/i2c/busses/i2c-mxs.c b/drivers/i2c/busses/i2c-mxs.c
index 7e78f7c8785..3d471d56bf1 100644
--- a/drivers/i2c/busses/i2c-mxs.c
+++ b/drivers/i2c/busses/i2c-mxs.c
@@ -72,6 +72,7 @@
#define MXS_I2C_QUEUESTAT (0x70)
#define MXS_I2C_QUEUESTAT_RD_QUEUE_EMPTY 0x00002000
+#define MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK 0x0000001F
#define MXS_I2C_QUEUECMD (0x80)
@@ -219,14 +220,14 @@ static int mxs_i2c_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg,
int ret;
int flags;
- init_completion(&i2c->cmd_complete);
-
dev_dbg(i2c->dev, "addr: 0x%04x, len: %d, flags: 0x%x, stop: %d\n",
msg->addr, msg->len, msg->flags, stop);
if (msg->len == 0)
return -EINVAL;
+ init_completion(&i2c->cmd_complete);
+
flags = stop ? MXS_I2C_CTRL0_POST_SEND_STOP : 0;
if (msg->flags & I2C_M_RD)
@@ -286,6 +287,7 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
{
struct mxs_i2c_dev *i2c = dev_id;
u32 stat = readl(i2c->regs + MXS_I2C_CTRL1) & MXS_I2C_IRQ_MASK;
+ bool is_last_cmd;
if (!stat)
return IRQ_NONE;
@@ -300,9 +302,14 @@ static irqreturn_t mxs_i2c_isr(int this_irq, void *dev_id)
else
i2c->cmd_err = 0;
- complete(&i2c->cmd_complete);
+ is_last_cmd = (readl(i2c->regs + MXS_I2C_QUEUESTAT) &
+ MXS_I2C_QUEUESTAT_WRITE_QUEUE_CNT_MASK) == 0;
+
+ if (is_last_cmd || i2c->cmd_err)
+ complete(&i2c->cmd_complete);
writel(stat, i2c->regs + MXS_I2C_CTRL1_CLR);
+
return IRQ_HANDLED;
}
diff --git a/drivers/iommu/omap-iommu-debug.c b/drivers/iommu/omap-iommu-debug.c
index 288da5c1499..103dbd92e25 100644
--- a/drivers/iommu/omap-iommu-debug.c
+++ b/drivers/iommu/omap-iommu-debug.c
@@ -44,7 +44,8 @@ static ssize_t debug_read_ver(struct file *file, char __user *userbuf,
static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
- struct omap_iommu *obj = file->private_data;
+ struct device *dev = file->private_data;
+ struct omap_iommu *obj = dev_to_omap_iommu(dev);
char *p, *buf;
ssize_t bytes;
@@ -67,7 +68,8 @@ static ssize_t debug_read_regs(struct file *file, char __user *userbuf,
static ssize_t debug_read_tlb(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
- struct omap_iommu *obj = file->private_data;
+ struct device *dev = file->private_data;
+ struct omap_iommu *obj = dev_to_omap_iommu(dev);
char *p, *buf;
ssize_t bytes, rest;
@@ -97,7 +99,8 @@ static ssize_t debug_write_pagetable(struct file *file,
struct iotlb_entry e;
struct cr_regs cr;
int err;
- struct omap_iommu *obj = file->private_data;
+ struct device *dev = file->private_data;
+ struct omap_iommu *obj = dev_to_omap_iommu(dev);
char buf[MAXCOLUMN], *p = buf;
count = min(count, sizeof(buf));
@@ -184,7 +187,8 @@ out:
static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
- struct omap_iommu *obj = file->private_data;
+ struct device *dev = file->private_data;
+ struct omap_iommu *obj = dev_to_omap_iommu(dev);
char *p, *buf;
size_t bytes;
@@ -212,7 +216,8 @@ static ssize_t debug_read_pagetable(struct file *file, char __user *userbuf,
static ssize_t debug_read_mmap(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
- struct omap_iommu *obj = file->private_data;
+ struct device *dev = file->private_data;
+ struct omap_iommu *obj = dev_to_omap_iommu(dev);
char *p, *buf;
struct iovm_struct *tmp;
int uninitialized_var(i);
@@ -254,7 +259,7 @@ static ssize_t debug_read_mmap(struct file *file, char __user *userbuf,
static ssize_t debug_read_mem(struct file *file, char __user *userbuf,
size_t count, loff_t *ppos)
{
- struct omap_iommu *obj = file->private_data;
+ struct device *dev = file->private_data;
char *p, *buf;
struct iovm_struct *area;
ssize_t bytes;
@@ -268,8 +273,8 @@ static ssize_t debug_read_mem(struct file *file, char __user *userbuf,
mutex_lock(&iommu_debug_lock);
- area = omap_find_iovm_area(obj, (u32)ppos);
- if (IS_ERR(area)) {
+ area = omap_find_iovm_area(dev, (u32)ppos);
+ if (!area) {
bytes = -EINVAL;
goto err_out;
}
@@ -287,7 +292,7 @@ err_out:
static ssize_t debug_write_mem(struct file *file, const char __user *userbuf,
size_t count, loff_t *ppos)
{
- struct omap_iommu *obj = file->private_data;
+ struct device *dev = file->private_data;
struct iovm_struct *area;
char *p, *buf;
@@ -305,8 +310,8 @@ static ssize_t debug_write_mem(struct file *file, const char __user *userbuf,
goto err_out;
}
- area = omap_find_iovm_area(obj, (u32)ppos);
- if (IS_ERR(area)) {
+ area = omap_find_iovm_area(dev, (u32)ppos);
+ if (!area) {
count = -EINVAL;
goto err_out;
}
@@ -350,7 +355,7 @@ DEBUG_FOPS(mem);
{ \
struct dentry *dent; \
dent = debugfs_create_file(#attr, mode, parent, \
- obj, &debug_##attr##_fops); \
+ dev, &debug_##attr##_fops); \
if (!dent) \
return -ENOMEM; \
}
@@ -362,20 +367,29 @@ static int iommu_debug_register(struct device *dev, void *data)
{
struct platform_device *pdev = to_platform_device(dev);
struct omap_iommu *obj = platform_get_drvdata(pdev);
+ struct omap_iommu_arch_data *arch_data;
struct dentry *d, *parent;
if (!obj || !obj->dev)
return -EINVAL;
+ arch_data = kzalloc(sizeof(*arch_data), GFP_KERNEL);
+ if (!arch_data)
+ return -ENOMEM;
+
+ arch_data->iommu_dev = obj;
+
+ dev->archdata.iommu = arch_data;
+
d = debugfs_create_dir(obj->name, iommu_debug_root);
if (!d)
- return -ENOMEM;
+ goto nomem;
parent = d;
d = debugfs_create_u8("nr_tlb_entries", 400, parent,
(u8 *)&obj->nr_tlb_entries);
if (!d)
- return -ENOMEM;
+ goto nomem;
DEBUG_ADD_FILE_RO(ver);
DEBUG_ADD_FILE_RO(regs);
@@ -385,6 +399,22 @@ static int iommu_debug_register(struct device *dev, void *data)
DEBUG_ADD_FILE(mem);
return 0;
+
+nomem:
+ kfree(arch_data);
+ return -ENOMEM;
+}
+
+static int iommu_debug_unregister(struct device *dev, void *data)
+{
+ if (!dev->archdata.iommu)
+ return 0;
+
+ kfree(dev->archdata.iommu);
+
+ dev->archdata.iommu = NULL;
+
+ return 0;
}
static int __init iommu_debug_init(void)
@@ -411,6 +441,7 @@ module_init(iommu_debug_init)
static void __exit iommu_debugfs_exit(void)
{
debugfs_remove_recursive(iommu_debug_root);
+ omap_foreach_iommu_device(NULL, iommu_debug_unregister);
}
module_exit(iommu_debugfs_exit)
diff --git a/drivers/iommu/omap-iommu.c b/drivers/iommu/omap-iommu.c
index d8edd979d01..6899dcd02df 100644
--- a/drivers/iommu/omap-iommu.c
+++ b/drivers/iommu/omap-iommu.c
@@ -1223,7 +1223,8 @@ static int __init omap_iommu_init(void)
return platform_driver_register(&omap_iommu_driver);
}
-module_init(omap_iommu_init);
+/* must be ready before omap3isp is probed */
+subsys_initcall(omap_iommu_init);
static void __exit omap_iommu_exit(void)
{
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
index 86b28579f0c..ea1e6545df3 100644
--- a/drivers/media/radio/wl128x/Kconfig
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -4,8 +4,8 @@
menu "Texas Instruments WL128x FM driver (ST based)"
config RADIO_WL128X
tristate "Texas Instruments WL128x FM Radio"
- depends on VIDEO_V4L2 && RFKILL
- select TI_ST if NET && GPIOLIB
+ depends on VIDEO_V4L2 && RFKILL && GPIOLIB
+ select TI_ST if NET
help
Choose Y here if you have this FM radio chip.
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index 3aeb29a7ce1..7f26fdf2e54 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -47,7 +47,7 @@
#define MOD_AUTHOR "Jarod Wilson <jarod@wilsonet.com>"
#define MOD_DESC "Driver for SoundGraph iMON MultiMedia IR/Display"
#define MOD_NAME "imon"
-#define MOD_VERSION "0.9.3"
+#define MOD_VERSION "0.9.4"
#define DISPLAY_MINOR_BASE 144
#define DEVICE_NAME "lcd%d"
@@ -1658,9 +1658,17 @@ static void usb_rx_callback_intf0(struct urb *urb)
return;
ictx = (struct imon_context *)urb->context;
- if (!ictx || !ictx->dev_present_intf0)
+ if (!ictx)
return;
+ /*
+ * if we get a callback before we're done configuring the hardware, we
+ * can't yet process the data, as there's nowhere to send it, but we
+ * still need to submit a new rx URB to avoid wedging the hardware
+ */
+ if (!ictx->dev_present_intf0)
+ goto out;
+
switch (urb->status) {
case -ENOENT: /* usbcore unlink successful! */
return;
@@ -1678,6 +1686,7 @@ static void usb_rx_callback_intf0(struct urb *urb)
break;
}
+out:
usb_submit_urb(ictx->rx_urb_intf0, GFP_ATOMIC);
}
@@ -1690,9 +1699,17 @@ static void usb_rx_callback_intf1(struct urb *urb)
return;
ictx = (struct imon_context *)urb->context;
- if (!ictx || !ictx->dev_present_intf1)
+ if (!ictx)
return;
+ /*
+ * if we get a callback before we're done configuring the hardware, we
+ * can't yet process the data, as there's nowhere to send it, but we
+ * still need to submit a new rx URB to avoid wedging the hardware
+ */
+ if (!ictx->dev_present_intf1)
+ goto out;
+
switch (urb->status) {
case -ENOENT: /* usbcore unlink successful! */
return;
@@ -1710,6 +1727,7 @@ static void usb_rx_callback_intf1(struct urb *urb)
break;
}
+out:
usb_submit_urb(ictx->rx_urb_intf1, GFP_ATOMIC);
}
@@ -2242,7 +2260,7 @@ find_endpoint_failed:
mutex_unlock(&ictx->lock);
usb_free_urb(rx_urb);
rx_urb_alloc_failed:
- dev_err(ictx->dev, "unable to initialize intf0, err %d\n", ret);
+ dev_err(ictx->dev, "unable to initialize intf1, err %d\n", ret);
return NULL;
}
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index e5eb56a5b61..6510110f53d 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -154,10 +154,20 @@ static int device_authorization(struct hdpvr_device *dev)
}
#endif
+ dev->fw_ver = dev->usbc_buf[1];
+
v4l2_info(&dev->v4l2_dev, "firmware version 0x%x dated %s\n",
- dev->usbc_buf[1], &dev->usbc_buf[2]);
+ dev->fw_ver, &dev->usbc_buf[2]);
+
+ if (dev->fw_ver > 0x15) {
+ dev->options.brightness = 0x80;
+ dev->options.contrast = 0x40;
+ dev->options.hue = 0xf;
+ dev->options.saturation = 0x40;
+ dev->options.sharpness = 0x80;
+ }
- switch (dev->usbc_buf[1]) {
+ switch (dev->fw_ver) {
case HDPVR_FIRMWARE_VERSION:
dev->flags &= ~HDPVR_FLAG_AC3_CAP;
break;
@@ -169,7 +179,7 @@ static int device_authorization(struct hdpvr_device *dev)
default:
v4l2_info(&dev->v4l2_dev, "untested firmware, the driver might"
" not work.\n");
- if (dev->usbc_buf[1] >= HDPVR_FIRMWARE_VERSION_AC3)
+ if (dev->fw_ver >= HDPVR_FIRMWARE_VERSION_AC3)
dev->flags |= HDPVR_FLAG_AC3_CAP;
else
dev->flags &= ~HDPVR_FLAG_AC3_CAP;
@@ -270,6 +280,8 @@ static const struct hdpvr_options hdpvr_default_options = {
.bitrate_mode = HDPVR_CONSTANT,
.gop_mode = HDPVR_SIMPLE_IDR_GOP,
.audio_codec = V4L2_MPEG_AUDIO_ENCODING_AAC,
+ /* original picture controls for firmware version <= 0x15 */
+ /* updated in device_authorization() for newer firmware */
.brightness = 0x86,
.contrast = 0x80,
.hue = 0x80,
diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c
index 087f7c08cb8..11ffe9cc178 100644
--- a/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/drivers/media/video/hdpvr/hdpvr-video.c
@@ -283,12 +283,13 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
+ dev->status = STATUS_STREAMING;
+
INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
queue_work(dev->workqueue, &dev->worker);
v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
"streaming started\n");
- dev->status = STATUS_STREAMING;
return 0;
}
@@ -722,21 +723,39 @@ static const s32 supported_v4l2_ctrls[] = {
};
static int fill_queryctrl(struct hdpvr_options *opt, struct v4l2_queryctrl *qc,
- int ac3)
+ int ac3, int fw_ver)
{
int err;
+ if (fw_ver > 0x15) {
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x40);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0x1e, 1, 0xf);
+ case V4L2_CID_SHARPNESS:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ }
+ } else {
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
+ case V4L2_CID_CONTRAST:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_SATURATION:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ case V4L2_CID_SHARPNESS:
+ return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
+ }
+ }
+
switch (qc->id) {
- case V4L2_CID_BRIGHTNESS:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x86);
- case V4L2_CID_CONTRAST:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- case V4L2_CID_SATURATION:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- case V4L2_CID_HUE:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
- case V4L2_CID_SHARPNESS:
- return v4l2_ctrl_query_fill(qc, 0x0, 0xff, 1, 0x80);
case V4L2_CID_MPEG_AUDIO_ENCODING:
return v4l2_ctrl_query_fill(
qc, V4L2_MPEG_AUDIO_ENCODING_AAC,
@@ -794,7 +813,8 @@ static int vidioc_queryctrl(struct file *file, void *private_data,
if (qc->id == supported_v4l2_ctrls[i])
return fill_queryctrl(&dev->options, qc,
- dev->flags & HDPVR_FLAG_AC3_CAP);
+ dev->flags & HDPVR_FLAG_AC3_CAP,
+ dev->fw_ver);
if (qc->id < supported_v4l2_ctrls[i])
break;
diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h
index d6439db1d18..fea3c692699 100644
--- a/drivers/media/video/hdpvr/hdpvr.h
+++ b/drivers/media/video/hdpvr/hdpvr.h
@@ -113,6 +113,7 @@ struct hdpvr_device {
/* usb control transfer buffer and lock */
struct mutex usbc_mutex;
u8 *usbc_buf;
+ u8 fw_ver;
};
static inline struct hdpvr_device *to_hdpvr_dev(struct v4l2_device *v4l2_dev)
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index a74a79701d3..eaabc27f0fa 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1407,7 +1407,7 @@ static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
{
struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
- struct video_device *vdev = &ccdc->subdev.devnode;
+ struct video_device *vdev = ccdc->subdev.devnode;
struct v4l2_event event;
memset(&event, 0, sizeof(event));
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f147395bac9..1489c3540f9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -201,6 +201,7 @@ config MENELAUS
config TWL4030_CORE
bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
depends on I2C=y && GENERIC_HARDIRQS
+ select IRQ_DOMAIN
help
Say yes here if you have TWL4030 / TWL6030 family chip on your board.
This core driver provides register access and IRQ handling
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 8ce3959c691..4970d43952d 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -149,7 +149,7 @@
#define TWL_MODULE_LAST TWL4030_MODULE_LAST
-#define TWL4030_NR_IRQS 8
+#define TWL4030_NR_IRQS 34 /* core:8, power:8, gpio: 18 */
#define TWL6030_NR_IRQS 20
/* Base Address defns for twl4030_map[] */
@@ -263,10 +263,6 @@ struct twl_client {
static struct twl_client twl_modules[TWL_NUM_SLAVES];
-#ifdef CONFIG_IRQ_DOMAIN
-static struct irq_domain domain;
-#endif
-
/* mapping the module id to slave id and base address */
struct twl_mapping {
unsigned char sid; /* Slave ID */
@@ -1227,14 +1223,8 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
pdata->irq_base = status;
pdata->irq_end = pdata->irq_base + nr_irqs;
-
-#ifdef CONFIG_IRQ_DOMAIN
- domain.irq_base = pdata->irq_base;
- domain.nr_irq = nr_irqs;
- domain.of_node = of_node_get(node);
- domain.ops = &irq_domain_simple_ops;
- irq_domain_add(&domain);
-#endif
+ irq_domain_add_legacy(node, nr_irqs, pdata->irq_base, 0,
+ &irq_domain_simple_ops, NULL);
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
dev_dbg(&client->dev, "can't talk I2C?\n");
@@ -1315,11 +1305,10 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
}
-#ifdef CONFIG_OF_DEVICE
+ status = -ENODEV;
if (node)
status = of_platform_populate(node, NULL, NULL, &client->dev);
- else
-#endif
+ if (status)
status = add_children(pdata, id->driver_data);
fail:
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index 947faa5d2ce..efdb81d21c4 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -86,7 +86,6 @@ static inline int at91mci_is_mci1rev2xx(void)
{
return ( cpu_is_at91sam9260()
|| cpu_is_at91sam9263()
- || cpu_is_at91cap9()
|| cpu_is_at91sam9rl()
|| cpu_is_at91sam9g10()
|| cpu_is_at91sam9g20()
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index 0d955ffaf44..304f2f98b68 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1325,7 +1325,7 @@ static int __devinit mmci_probe(struct amba_device *dev,
if (ret)
goto unmap;
- if (dev->irq[1] == NO_IRQ)
+ if (dev->irq[1] == NO_IRQ || !dev->irq[1])
host->singleirq = true;
else {
ret = request_irq(dev->irq[1], mmci_pio_irq, IRQF_SHARED,
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index d601e41af28..f4e82d45caf 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -463,7 +463,7 @@ static int __devinit sdhci_esdhc_imx_probe(struct platform_device *pdev)
err = PTR_ERR(clk);
goto err_clk_get;
}
- clk_enable(clk);
+ clk_prepare_enable(clk);
pltfm_host->clk = clk;
if (!is_imx25_esdhc(imx_data))
@@ -558,7 +558,7 @@ no_card_detect_irq:
gpio_free(boarddata->wp_gpio);
no_card_detect_pin:
no_board_data:
- clk_disable(pltfm_host->clk);
+ clk_disable_unprepare(pltfm_host->clk);
clk_put(pltfm_host->clk);
err_clk_get:
kfree(imx_data);
@@ -585,7 +585,7 @@ static int __devexit sdhci_esdhc_imx_remove(struct platform_device *pdev)
gpio_free(boarddata->cd_gpio);
}
- clk_disable(pltfm_host->clk);
+ clk_disable_unprepare(pltfm_host->clk);
clk_put(pltfm_host->clk);
kfree(imx_data);
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 068c3563e00..88bbd8ffa7f 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -190,8 +190,10 @@ static struct devprobe2 isa_probes[] __initdata = {
{seeq8005_probe, 0},
#endif
#ifdef CONFIG_CS89x0
+#ifndef CONFIG_CS89x0_PLATFORM
{cs89x0_probe, 0},
#endif
+#endif
#ifdef CONFIG_AT1700
{at1700_probe, 0},
#endif
diff --git a/drivers/net/can/sja1000/sja1000.c b/drivers/net/can/sja1000/sja1000.c
index 04a3f1b756a..192b0d118df 100644
--- a/drivers/net/can/sja1000/sja1000.c
+++ b/drivers/net/can/sja1000/sja1000.c
@@ -95,11 +95,16 @@ static void sja1000_write_cmdreg(struct sja1000_priv *priv, u8 val)
spin_unlock_irqrestore(&priv->cmdreg_lock, flags);
}
+static int sja1000_is_absent(struct sja1000_priv *priv)
+{
+ return (priv->read_reg(priv, REG_MOD) == 0xFF);
+}
+
static int sja1000_probe_chip(struct net_device *dev)
{
struct sja1000_priv *priv = netdev_priv(dev);
- if (priv->reg_base && (priv->read_reg(priv, 0) == 0xFF)) {
+ if (priv->reg_base && sja1000_is_absent(priv)) {
printk(KERN_INFO "%s: probing @0x%lX failed\n",
DRV_NAME, dev->base_addr);
return 0;
@@ -493,6 +498,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
while ((isrc = priv->read_reg(priv, REG_IR)) && (n < SJA1000_MAX_IRQ)) {
n++;
status = priv->read_reg(priv, REG_SR);
+ /* check for absent controller due to hw unplug */
+ if (status == 0xFF && sja1000_is_absent(priv))
+ return IRQ_NONE;
if (isrc & IRQ_WUI)
dev_warn(dev->dev.parent, "wakeup interrupt\n");
@@ -509,6 +517,9 @@ irqreturn_t sja1000_interrupt(int irq, void *dev_id)
while (status & SR_RBS) {
sja1000_rx(dev);
status = priv->read_reg(priv, REG_SR);
+ /* check for absent controller */
+ if (status == 0xFF && sja1000_is_absent(priv))
+ return IRQ_NONE;
}
}
if (isrc & (IRQ_DOI | IRQ_EI | IRQ_BEI | IRQ_EPI | IRQ_ALI)) {
diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
index b8591246eb4..1ff3c6df35a 100644
--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
@@ -2244,10 +2244,6 @@ static netdev_tx_t atl1c_xmit_frame(struct sk_buff *skb,
dev_info(&adapter->pdev->dev, "tx locked\n");
return NETDEV_TX_LOCKED;
}
- if (skb->mark == 0x01)
- type = atl1c_trans_high;
- else
- type = atl1c_trans_normal;
if (atl1c_tpd_avail(adapter, type) < tpd_req) {
/* no enough descriptor, just stop queue */
diff --git a/drivers/net/ethernet/broadcom/b44.c b/drivers/net/ethernet/broadcom/b44.c
index 3fb66d09ece..cab87456a34 100644
--- a/drivers/net/ethernet/broadcom/b44.c
+++ b/drivers/net/ethernet/broadcom/b44.c
@@ -2339,7 +2339,7 @@ static inline int __init b44_pci_init(void)
return err;
}
-static inline void __exit b44_pci_exit(void)
+static inline void b44_pci_exit(void)
{
#ifdef CONFIG_B44_PCI
ssb_pcihost_unregister(&b44_pci_driver);
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index dd3a0a232ea..818a573669e 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -3584,7 +3584,11 @@ static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr,
fl6.flowi6_oif = dst_addr->sin6_scope_id;
*dst = ip6_route_output(&init_net, NULL, &fl6);
- if (*dst)
+ if ((*dst)->error) {
+ dst_release(*dst);
+ *dst = NULL;
+ return -ENETUNREACH;
+ } else
return 0;
#endif
diff --git a/drivers/net/ethernet/cirrus/Kconfig b/drivers/net/ethernet/cirrus/Kconfig
index 1f8648f099c..8388e36cf08 100644
--- a/drivers/net/ethernet/cirrus/Kconfig
+++ b/drivers/net/ethernet/cirrus/Kconfig
@@ -5,8 +5,7 @@
config NET_VENDOR_CIRRUS
bool "Cirrus devices"
default y
- depends on ISA || EISA || MACH_IXDP2351 || ARCH_IXDP2X01 \
- || MACH_MX31ADS || MACH_QQ2440 || (ARM && ARCH_EP93XX) || MAC
+ depends on ISA || EISA || ARM || MAC
---help---
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
@@ -21,8 +20,7 @@ if NET_VENDOR_CIRRUS
config CS89x0
tristate "CS89x0 support"
- depends on (ISA || EISA || MACH_IXDP2351 \
- || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440)
+ depends on ISA || EISA || ARM
---help---
Support for CS89x0 chipset based Ethernet cards. If you have a
network (Ethernet) card of this type, say Y and read the
@@ -33,10 +31,15 @@ config CS89x0
To compile this driver as a module, choose M here. The module
will be called cs89x0.
-config CS89x0_NONISA_IRQ
- def_bool y
- depends on CS89x0 != n
- depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440
+config CS89x0_PLATFORM
+ bool "CS89x0 platform driver support"
+ depends on CS89x0
+ help
+ Say Y to compile the cs89x0 driver as a platform driver. This
+ makes this driver suitable for use on certain evaluation boards
+ such as the iMX21ADS.
+
+ If you are unsure, say N.
config EP93XX_ETH
tristate "EP93xx Ethernet support"
diff --git a/drivers/net/ethernet/cirrus/cs89x0.c b/drivers/net/ethernet/cirrus/cs89x0.c
index f328da24c8f..7202ca951bf 100644
--- a/drivers/net/ethernet/cirrus/cs89x0.c
+++ b/drivers/net/ethernet/cirrus/cs89x0.c
@@ -100,9 +100,6 @@
*/
-/* Always include 'config.h' first in case the user wants to turn on
- or override something. */
-#include <linux/module.h>
/*
* Set this to zero to disable DMA code
@@ -131,9 +128,12 @@
*/
+#include <linux/module.h>
+#include <linux/printk.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
@@ -151,6 +151,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
+#include <linux/atomic.h>
#if ALLOW_DMA
#include <asm/dma.h>
#endif
@@ -174,26 +175,20 @@ static char version[] __initdata =
them to system IRQ numbers. This mapping is card specific and is set to
the configuration of the Cirrus Eval board for this chip. */
#if defined(CONFIG_MACH_IXDP2351)
+#define CS89x0_NONISA_IRQ
static unsigned int netcard_portlist[] __used __initdata = {IXDP2351_VIRT_CS8900_BASE, 0};
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2351_CS8900, 0, 0, 0};
#elif defined(CONFIG_ARCH_IXDP2X01)
+#define CS89x0_NONISA_IRQ
static unsigned int netcard_portlist[] __used __initdata = {IXDP2X01_CS8900_VIRT_BASE, 0};
static unsigned int cs8900_irq_map[] = {IRQ_IXDP2X01_CS8900, 0, 0, 0};
-#elif defined(CONFIG_MACH_QQ2440)
-#include <mach/qq2440.h>
-static unsigned int netcard_portlist[] __used __initdata = { QQ2440_CS8900_VIRT_BASE + 0x300, 0 };
-static unsigned int cs8900_irq_map[] = { QQ2440_CS8900_IRQ, 0, 0, 0 };
-#elif defined(CONFIG_MACH_MX31ADS)
-#include <mach/board-mx31ads.h>
-static unsigned int netcard_portlist[] __used __initdata = {
- PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300, 0
-};
-static unsigned cs8900_irq_map[] = {EXPIO_INT_ENET_INT, 0, 0, 0};
#else
+#ifndef CONFIG_CS89x0_PLATFORM
static unsigned int netcard_portlist[] __used __initdata =
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
static unsigned int cs8900_irq_map[] = {10,11,12,5};
#endif
+#endif
#if DEBUGGING
static unsigned int net_debug = DEBUGGING;
@@ -236,11 +231,16 @@ struct net_local {
unsigned char *end_dma_buff; /* points to the end of the buffer */
unsigned char *rx_dma_ptr; /* points to the next packet */
#endif
+#ifdef CONFIG_CS89x0_PLATFORM
+ void __iomem *virt_addr;/* Virtual address for accessing the CS89x0. */
+ unsigned long phys_addr;/* Physical address for accessing the CS89x0. */
+ unsigned long size; /* Length of CS89x0 memory region. */
+#endif
};
/* Index to functions, as function prototypes. */
-static int cs89x0_probe1(struct net_device *dev, int ioaddr, int modular);
+static int cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular);
static int net_open(struct net_device *dev);
static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t net_interrupt(int irq, void *dev_id);
@@ -294,6 +294,7 @@ static int __init media_fn(char *str)
__setup("cs89x0_media=", media_fn);
+#ifndef CONFIG_CS89x0_PLATFORM
/* Check for a network adaptor of this type, and return '0' iff one exists.
If dev->base_addr == 0, probe all likely locations.
If dev->base_addr == 1, always return failure.
@@ -343,6 +344,7 @@ out:
return ERR_PTR(err);
}
#endif
+#endif
#if defined(CONFIG_MACH_IXDP2351)
static u16
@@ -504,7 +506,7 @@ static const struct net_device_ops net_ops = {
*/
static int __init
-cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
+cs89x0_probe1(struct net_device *dev, unsigned long ioaddr, int modular)
{
struct net_local *lp = netdev_priv(dev);
static unsigned version_printed;
@@ -529,15 +531,12 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
lp->force = g_cs89x0_media__force;
#endif
-#if defined(CONFIG_MACH_QQ2440)
- lp->force |= FORCE_RJ45 | FORCE_FULL;
-#endif
}
/* Grab the region so we can find another board if autoIRQ fails. */
/* WTF is going on here? */
if (!request_region(ioaddr & ~3, NETCARD_IO_EXTENT, DRV_NAME)) {
- printk(KERN_ERR "%s: request_region(0x%x, 0x%x) failed\n",
+ printk(KERN_ERR "%s: request_region(0x%lx, 0x%x) failed\n",
DRV_NAME, ioaddr, NETCARD_IO_EXTENT);
retval = -EBUSY;
goto out1;
@@ -549,7 +548,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
will skip the test for the ADD_PORT. */
if (ioaddr & 1) {
if (net_debug > 1)
- printk(KERN_INFO "%s: odd ioaddr 0x%x\n", dev->name, ioaddr);
+ printk(KERN_INFO "%s: odd ioaddr 0x%lx\n", dev->name, ioaddr);
if ((ioaddr & 2) != 2)
if ((readword(ioaddr & ~3, ADD_PORT) & ADD_MASK) != ADD_SIG) {
printk(KERN_ERR "%s: bad signature 0x%x\n",
@@ -560,13 +559,13 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
}
ioaddr &= ~3;
- printk(KERN_DEBUG "PP_addr at %x[%x]: 0x%x\n",
+ printk(KERN_DEBUG "PP_addr at %lx[%x]: 0x%x\n",
ioaddr, ADD_PORT, readword(ioaddr, ADD_PORT));
writeword(ioaddr, ADD_PORT, PP_ChipID);
tmp = readword(ioaddr, DATA_PORT);
if (tmp != CHIP_EISA_ID_SIG) {
- printk(KERN_DEBUG "%s: incorrect signature at %x[%x]: 0x%x!="
+ printk(KERN_DEBUG "%s: incorrect signature at %lx[%x]: 0x%x!="
CHIP_EISA_ID_SIG_STR "\n",
dev->name, ioaddr, DATA_PORT, tmp);
retval = -ENODEV;
@@ -736,8 +735,9 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
dev->irq = i;
} else {
i = lp->isa_config & INT_NO_MASK;
+#ifndef CONFIG_CS89x0_PLATFORM
if (lp->chip_type == CS8900) {
-#ifdef CONFIG_CS89x0_NONISA_IRQ
+#ifdef CS89x0_NONISA_IRQ
i = cs8900_irq_map[0];
#else
/* Translate the IRQ using the IRQ mapping table. */
@@ -758,6 +758,7 @@ cs89x0_probe1(struct net_device *dev, int ioaddr, int modular)
}
#endif
}
+#endif
if (!dev->irq)
dev->irq = i;
}
@@ -1168,6 +1169,7 @@ write_irq(struct net_device *dev, int chip_type, int irq)
int i;
if (chip_type == CS8900) {
+#ifndef CONFIG_CS89x0_PLATFORM
/* Search the mapping table for the corresponding IRQ pin. */
for (i = 0; i != ARRAY_SIZE(cs8900_irq_map); i++)
if (cs8900_irq_map[i] == irq)
@@ -1175,6 +1177,10 @@ write_irq(struct net_device *dev, int chip_type, int irq)
/* Not found */
if (i == ARRAY_SIZE(cs8900_irq_map))
i = 3;
+#else
+ /* INTRQ0 pin is used for interrupt generation. */
+ i = 0;
+#endif
writereg(dev, PP_CS8900_ISAINT, i);
} else {
writereg(dev, PP_CS8920_ISAINT, irq);
@@ -1228,7 +1234,7 @@ net_open(struct net_device *dev)
}
else
{
-#ifndef CONFIG_CS89x0_NONISA_IRQ
+#if !defined(CS89x0_NONISA_IRQ) && !defined(CONFIG_CS89x0_PLATFORM)
if (((1 << dev->irq) & lp->irq_map) == 0) {
printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
dev->name, dev->irq, lp->irq_map);
@@ -1746,7 +1752,7 @@ static int set_mac_address(struct net_device *dev, void *p)
return 0;
}
-#ifdef MODULE
+#if defined(MODULE) && !defined(CONFIG_CS89x0_PLATFORM)
static struct net_device *dev_cs89x0;
@@ -1900,7 +1906,97 @@ cleanup_module(void)
release_region(dev_cs89x0->base_addr, NETCARD_IO_EXTENT);
free_netdev(dev_cs89x0);
}
-#endif /* MODULE */
+#endif /* MODULE && !CONFIG_CS89x0_PLATFORM */
+
+#ifdef CONFIG_CS89x0_PLATFORM
+static int __init cs89x0_platform_probe(struct platform_device *pdev)
+{
+ struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
+ struct net_local *lp;
+ struct resource *mem_res;
+ int err;
+
+ if (!dev)
+ return -ENOMEM;
+
+ lp = netdev_priv(dev);
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ dev->irq = platform_get_irq(pdev, 0);
+ if (mem_res == NULL || dev->irq <= 0) {
+ dev_warn(&dev->dev, "memory/interrupt resource missing.\n");
+ err = -ENXIO;
+ goto free;
+ }
+
+ lp->phys_addr = mem_res->start;
+ lp->size = resource_size(mem_res);
+ if (!request_mem_region(lp->phys_addr, lp->size, DRV_NAME)) {
+ dev_warn(&dev->dev, "request_mem_region() failed.\n");
+ err = -EBUSY;
+ goto free;
+ }
+
+ lp->virt_addr = ioremap(lp->phys_addr, lp->size);
+ if (!lp->virt_addr) {
+ dev_warn(&dev->dev, "ioremap() failed.\n");
+ err = -ENOMEM;
+ goto release;
+ }
+
+ err = cs89x0_probe1(dev, (unsigned long)lp->virt_addr, 0);
+ if (err) {
+ dev_warn(&dev->dev, "no cs8900 or cs8920 detected.\n");
+ goto unmap;
+ }
+
+ platform_set_drvdata(pdev, dev);
+ return 0;
+
+unmap:
+ iounmap(lp->virt_addr);
+release:
+ release_mem_region(lp->phys_addr, lp->size);
+free:
+ free_netdev(dev);
+ return err;
+}
+
+static int cs89x0_platform_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct net_local *lp = netdev_priv(dev);
+
+ unregister_netdev(dev);
+ iounmap(lp->virt_addr);
+ release_mem_region(lp->phys_addr, lp->size);
+ free_netdev(dev);
+ return 0;
+}
+
+static struct platform_driver cs89x0_driver = {
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .remove = cs89x0_platform_remove,
+};
+
+static int __init cs89x0_init(void)
+{
+ return platform_driver_probe(&cs89x0_driver, cs89x0_platform_probe);
+}
+
+module_init(cs89x0_init);
+
+static void __exit cs89x0_cleanup(void)
+{
+ platform_driver_unregister(&cs89x0_driver);
+}
+
+module_exit(cs89x0_cleanup);
+
+#endif /* CONFIG_CS89x0_PLATFORM */
/*
* Local variables:
diff --git a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
index c2c0680a114..ac37cacc613 100644
--- a/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
+++ b/drivers/net/ethernet/cisco/enic/cq_enet_desc.h
@@ -157,7 +157,7 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc,
CQ_ENET_RQ_DESC_FCOE_FC_CRC_OK) ? 1 : 0;
*fcoe_enc_error = (desc->flags &
CQ_ENET_RQ_DESC_FCOE_ENC_ERROR) ? 1 : 0;
- *fcoe_eof = (u8)((desc->checksum_fcoe >>
+ *fcoe_eof = (u8)((le16_to_cpu(desc->checksum_fcoe) >>
CQ_ENET_RQ_DESC_FCOE_EOF_SHIFT) &
CQ_ENET_RQ_DESC_FCOE_EOF_MASK);
*checksum = 0;
diff --git a/drivers/net/ethernet/cisco/enic/enic_pp.c b/drivers/net/ethernet/cisco/enic/enic_pp.c
index 22bf03a1829..c347b6236f8 100644
--- a/drivers/net/ethernet/cisco/enic/enic_pp.c
+++ b/drivers/net/ethernet/cisco/enic/enic_pp.c
@@ -72,7 +72,7 @@ static int enic_set_port_profile(struct enic *enic, int vf)
struct enic_port_profile *pp;
struct vic_provinfo *vp;
const u8 oui[3] = VIC_PROVINFO_CISCO_OUI;
- const u16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
+ const __be16 os_type = htons(VIC_GENERIC_PROV_OS_TYPE_LINUX);
char uuid_str[38];
char client_mac_str[18];
u8 *client_mac;
diff --git a/drivers/net/ethernet/jme.c b/drivers/net/ethernet/jme.c
index 27d651a80f3..55cbf65512c 100644
--- a/drivers/net/ethernet/jme.c
+++ b/drivers/net/ethernet/jme.c
@@ -2328,19 +2328,11 @@ jme_change_mtu(struct net_device *netdev, int new_mtu)
((new_mtu) < IPV6_MIN_MTU))
return -EINVAL;
- if (new_mtu > 4000) {
- jme->reg_rxcs &= ~RXCS_FIFOTHNP;
- jme->reg_rxcs |= RXCS_FIFOTHNP_64QW;
- jme_restart_rx_engine(jme);
- } else {
- jme->reg_rxcs &= ~RXCS_FIFOTHNP;
- jme->reg_rxcs |= RXCS_FIFOTHNP_128QW;
- jme_restart_rx_engine(jme);
- }
netdev->mtu = new_mtu;
netdev_update_features(netdev);
+ jme_restart_rx_engine(jme);
jme_reset_link(jme);
return 0;
diff --git a/drivers/net/ethernet/jme.h b/drivers/net/ethernet/jme.h
index 4304072bd3c..3efc897c991 100644
--- a/drivers/net/ethernet/jme.h
+++ b/drivers/net/ethernet/jme.h
@@ -730,7 +730,7 @@ enum jme_rxcs_values {
RXCS_RETRYCNT_60 = 0x00000F00,
RXCS_DEFAULT = RXCS_FIFOTHTP_128T |
- RXCS_FIFOTHNP_128QW |
+ RXCS_FIFOTHNP_16QW |
RXCS_DMAREQSZ_128B |
RXCS_RETRYGAP_256ns |
RXCS_RETRYCNT_32,
diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c
index 8fa41f3082c..9129ace0256 100644
--- a/drivers/net/ethernet/mellanox/mlx4/eq.c
+++ b/drivers/net/ethernet/mellanox/mlx4/eq.c
@@ -1036,7 +1036,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
struct mlx4_priv *priv = mlx4_priv(dev);
int vec = 0, err = 0, i;
- spin_lock(&priv->msix_ctl.pool_lock);
+ mutex_lock(&priv->msix_ctl.pool_lock);
for (i = 0; !vec && i < dev->caps.comp_pool; i++) {
if (~priv->msix_ctl.pool_bm & 1ULL << i) {
priv->msix_ctl.pool_bm |= 1ULL << i;
@@ -1058,7 +1058,7 @@ int mlx4_assign_eq(struct mlx4_dev *dev, char* name, int * vector)
eq_set_ci(&priv->eq_table.eq[vec], 1);
}
}
- spin_unlock(&priv->msix_ctl.pool_lock);
+ mutex_unlock(&priv->msix_ctl.pool_lock);
if (vec) {
*vector = vec;
@@ -1079,13 +1079,13 @@ void mlx4_release_eq(struct mlx4_dev *dev, int vec)
if (likely(i >= 0)) {
/*sanity check , making sure were not trying to free irq's
Belonging to a legacy EQ*/
- spin_lock(&priv->msix_ctl.pool_lock);
+ mutex_lock(&priv->msix_ctl.pool_lock);
if (priv->msix_ctl.pool_bm & 1ULL << i) {
free_irq(priv->eq_table.eq[vec].irq,
&priv->eq_table.eq[vec]);
priv->msix_ctl.pool_bm &= ~(1ULL << i);
}
- spin_unlock(&priv->msix_ctl.pool_lock);
+ mutex_unlock(&priv->msix_ctl.pool_lock);
}
}
diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c
index 8a21e10952e..9ea7cabcaf3 100644
--- a/drivers/net/ethernet/mellanox/mlx4/fw.c
+++ b/drivers/net/ethernet/mellanox/mlx4/fw.c
@@ -685,7 +685,7 @@ int mlx4_QUERY_PORT_wrapper(struct mlx4_dev *dev, int slave,
return err;
}
-static int mlx4_QUERY_PORT(struct mlx4_dev *dev, void *ptr, u8 port)
+int mlx4_QUERY_PORT(struct mlx4_dev *dev, void *ptr, u8 port)
{
struct mlx4_cmd_mailbox *outbox = ptr;
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index 678558b502f..d498f049c74 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -531,15 +531,14 @@ int mlx4_change_port_types(struct mlx4_dev *dev,
for (port = 0; port < dev->caps.num_ports; port++) {
/* Change the port type only if the new type is different
* from the current, and not set to Auto */
- if (port_types[port] != dev->caps.port_type[port + 1]) {
+ if (port_types[port] != dev->caps.port_type[port + 1])
change = 1;
- dev->caps.port_type[port + 1] = port_types[port];
- }
}
if (change) {
mlx4_unregister_device(dev);
for (port = 1; port <= dev->caps.num_ports; port++) {
mlx4_CLOSE_PORT(dev, port);
+ dev->caps.port_type[port] = port_types[port - 1];
err = mlx4_SET_PORT(dev, port);
if (err) {
mlx4_err(dev, "Failed to set port %d, "
@@ -986,6 +985,9 @@ static int map_bf_area(struct mlx4_dev *dev)
resource_size_t bf_len;
int err = 0;
+ if (!dev->caps.bf_reg_size)
+ return -ENXIO;
+
bf_start = pci_resource_start(dev->pdev, 2) +
(dev->caps.num_uars << PAGE_SHIFT);
bf_len = pci_resource_len(dev->pdev, 2) -
@@ -1825,7 +1827,7 @@ slave_start:
goto err_master_mfunc;
priv->msix_ctl.pool_bm = 0;
- spin_lock_init(&priv->msix_ctl.pool_lock);
+ mutex_init(&priv->msix_ctl.pool_lock);
mlx4_enable_msi_x(dev);
if ((mlx4_is_mfunc(dev)) &&
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
index c92269f8c05..28f8251561f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h
+++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h
@@ -697,7 +697,7 @@ struct mlx4_sense {
struct mlx4_msix_ctl {
u64 pool_bm;
- spinlock_t pool_lock;
+ struct mutex pool_lock;
};
struct mlx4_steer {
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c
index 8deeef98280..25a80d71fb2 100644
--- a/drivers/net/ethernet/mellanox/mlx4/mr.c
+++ b/drivers/net/ethernet/mellanox/mlx4/mr.c
@@ -304,7 +304,7 @@ static int mlx4_HW2SW_MPT(struct mlx4_dev *dev, struct mlx4_cmd_mailbox *mailbox
MLX4_CMD_TIME_CLASS_B, MLX4_CMD_WRAPPED);
}
-static int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align,
+int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align,
u32 *base_mridx)
{
struct mlx4_priv *priv = mlx4_priv(dev);
@@ -320,14 +320,14 @@ static int mlx4_mr_reserve_range(struct mlx4_dev *dev, int cnt, int align,
}
EXPORT_SYMBOL_GPL(mlx4_mr_reserve_range);
-static void mlx4_mr_release_range(struct mlx4_dev *dev, u32 base_mridx, int cnt)
+void mlx4_mr_release_range(struct mlx4_dev *dev, u32 base_mridx, int cnt)
{
struct mlx4_priv *priv = mlx4_priv(dev);
mlx4_bitmap_free_range(&priv->mr_table.mpt_bitmap, base_mridx, cnt);
}
EXPORT_SYMBOL_GPL(mlx4_mr_release_range);
-static int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd,
+int mlx4_mr_alloc_reserved(struct mlx4_dev *dev, u32 mridx, u32 pd,
u64 iova, u64 size, u32 access, int npages,
int page_shift, struct mlx4_mr *mr)
{
@@ -457,7 +457,7 @@ int mlx4_mr_alloc(struct mlx4_dev *dev, u32 pd, u64 iova, u64 size, u32 access,
}
EXPORT_SYMBOL_GPL(mlx4_mr_alloc);
-static void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr)
+void mlx4_mr_free_reserved(struct mlx4_dev *dev, struct mlx4_mr *mr)
{
int err;
@@ -852,7 +852,7 @@ err_free:
}
EXPORT_SYMBOL_GPL(mlx4_fmr_alloc);
-static int mlx4_fmr_alloc_reserved(struct mlx4_dev *dev, u32 mridx,
+int mlx4_fmr_alloc_reserved(struct mlx4_dev *dev, u32 mridx,
u32 pd, u32 access, int max_pages,
int max_maps, u8 page_shift, struct mlx4_fmr *fmr)
{
@@ -954,7 +954,7 @@ int mlx4_fmr_free(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
}
EXPORT_SYMBOL_GPL(mlx4_fmr_free);
-static int mlx4_fmr_free_reserved(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
+int mlx4_fmr_free_reserved(struct mlx4_dev *dev, struct mlx4_fmr *fmr)
{
if (fmr->maps)
return -EBUSY;
diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c
index 231176fcd2b..2784bc706f1 100644
--- a/drivers/net/ethernet/micrel/ks8851_mll.c
+++ b/drivers/net/ethernet/micrel/ks8851_mll.c
@@ -1545,7 +1545,7 @@ static int __devinit ks8851_probe(struct platform_device *pdev)
netdev->irq = platform_get_irq(pdev, 0);
- if (netdev->irq < 0) {
+ if ((int)netdev->irq < 0) {
err = netdev->irq;
goto err_get_irq;
}
diff --git a/drivers/net/ethernet/sfc/rx.c b/drivers/net/ethernet/sfc/rx.c
index aca34986176..fc52fca7419 100644
--- a/drivers/net/ethernet/sfc/rx.c
+++ b/drivers/net/ethernet/sfc/rx.c
@@ -156,11 +156,10 @@ static int efx_init_rx_buffers_skb(struct efx_rx_queue *rx_queue)
if (unlikely(!skb))
return -ENOMEM;
- /* Adjust the SKB for padding and checksum */
+ /* Adjust the SKB for padding */
skb_reserve(skb, NET_IP_ALIGN);
rx_buf->len = skb_len - NET_IP_ALIGN;
rx_buf->is_page = false;
- skb->ip_summed = CHECKSUM_UNNECESSARY;
rx_buf->dma_addr = pci_map_single(efx->pci_dev,
skb->data, rx_buf->len,
@@ -496,6 +495,7 @@ static void efx_rx_packet_gro(struct efx_channel *channel,
EFX_BUG_ON_PARANOID(!checksummed);
rx_buf->u.skb = NULL;
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
gro_result = napi_gro_receive(napi, skb);
}
diff --git a/drivers/net/ethernet/ti/davinci_emac.c b/drivers/net/ethernet/ti/davinci_emac.c
index 4fa0bcb25df..4b2f54565f6 100644
--- a/drivers/net/ethernet/ti/davinci_emac.c
+++ b/drivers/net/ethernet/ti/davinci_emac.c
@@ -1009,7 +1009,7 @@ static void emac_rx_handler(void *token, int len, int status)
int ret;
/* free and bail if we are shutting down */
- if (unlikely(!netif_running(ndev) || !netif_carrier_ok(ndev))) {
+ if (unlikely(!netif_running(ndev))) {
dev_kfree_skb_any(skb);
return;
}
@@ -1038,7 +1038,9 @@ static void emac_rx_handler(void *token, int len, int status)
recycle:
ret = cpdma_chan_submit(priv->rxchan, skb, skb->data,
skb_tailroom(skb), GFP_KERNEL);
- if (WARN_ON(ret < 0))
+
+ WARN_ON(ret == -ENOMEM);
+ if (unlikely(ret < 0))
dev_kfree_skb_any(skb);
}
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index c81f136ae67..0856e1b7a84 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -30,16 +30,16 @@
#include <asm/irq.h>
#include <asm/uaccess.h>
-MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IC1001 PHY drivers");
+MODULE_DESCRIPTION("ICPlus IP175C/IP101A/IP101G/IC1001 PHY drivers");
MODULE_AUTHOR("Michael Barkowski");
MODULE_LICENSE("GPL");
-/* IP101A/IP1001 */
-#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */
-#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */
-#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */
-#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
-#define IP101A_APS_ON 2 /* IP101A APS Mode bit */
+/* IP101A/G - IP1001 */
+#define IP10XX_SPEC_CTRL_STATUS 16 /* Spec. Control Register */
+#define IP1001_SPEC_CTRL_STATUS_2 20 /* IP1001 Spec. Control Reg 2 */
+#define IP1001_PHASE_SEL_MASK 3 /* IP1001 RX/TXPHASE_SEL */
+#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
+#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */
static int ip175c_config_init(struct phy_device *phydev)
{
@@ -98,20 +98,24 @@ static int ip175c_config_init(struct phy_device *phydev)
static int ip1xx_reset(struct phy_device *phydev)
{
- int err, bmcr;
+ int bmcr;
/* Software Reset PHY */
bmcr = phy_read(phydev, MII_BMCR);
+ if (bmcr < 0)
+ return bmcr;
bmcr |= BMCR_RESET;
- err = phy_write(phydev, MII_BMCR, bmcr);
- if (err < 0)
- return err;
+ bmcr = phy_write(phydev, MII_BMCR, bmcr);
+ if (bmcr < 0)
+ return bmcr;
do {
bmcr = phy_read(phydev, MII_BMCR);
+ if (bmcr < 0)
+ return bmcr;
} while (bmcr & BMCR_RESET);
- return err;
+ return 0;
}
static int ip1001_config_init(struct phy_device *phydev)
@@ -124,7 +128,10 @@ static int ip1001_config_init(struct phy_device *phydev)
/* Enable Auto Power Saving mode */
c = phy_read(phydev, IP1001_SPEC_CTRL_STATUS_2);
+ if (c < 0)
+ return c;
c |= IP1001_APS_ON;
+ c = phy_write(phydev, IP1001_SPEC_CTRL_STATUS_2, c);
if (c < 0)
return c;
@@ -132,14 +139,19 @@ static int ip1001_config_init(struct phy_device *phydev)
/* Additional delay (2ns) used to adjust RX clock phase
* at RGMII interface */
c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
+ if (c < 0)
+ return c;
+
c |= IP1001_PHASE_SEL_MASK;
c = phy_write(phydev, IP10XX_SPEC_CTRL_STATUS, c);
+ if (c < 0)
+ return c;
}
- return c;
+ return 0;
}
-static int ip101a_config_init(struct phy_device *phydev)
+static int ip101a_g_config_init(struct phy_device *phydev)
{
int c;
@@ -149,7 +161,7 @@ static int ip101a_config_init(struct phy_device *phydev)
/* Enable Auto Power Saving mode */
c = phy_read(phydev, IP10XX_SPEC_CTRL_STATUS);
- c |= IP101A_APS_ON;
+ c |= IP101A_G_APS_ON;
return c;
}
@@ -191,6 +203,7 @@ static struct phy_driver ip1001_driver = {
.phy_id_mask = 0x0ffffff0,
.features = PHY_GBIT_FEATURES | SUPPORTED_Pause |
SUPPORTED_Asym_Pause,
+ .flags = PHY_HAS_INTERRUPT,
.config_init = &ip1001_config_init,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
@@ -199,13 +212,14 @@ static struct phy_driver ip1001_driver = {
.driver = { .owner = THIS_MODULE,},
};
-static struct phy_driver ip101a_driver = {
+static struct phy_driver ip101a_g_driver = {
.phy_id = 0x02430c54,
- .name = "ICPlus IP101A",
+ .name = "ICPlus IP101A/G",
.phy_id_mask = 0x0ffffff0,
.features = PHY_BASIC_FEATURES | SUPPORTED_Pause |
SUPPORTED_Asym_Pause,
- .config_init = &ip101a_config_init,
+ .flags = PHY_HAS_INTERRUPT,
+ .config_init = &ip101a_g_config_init,
.config_aneg = &genphy_config_aneg,
.read_status = &genphy_read_status,
.suspend = genphy_suspend,
@@ -221,7 +235,7 @@ static int __init icplus_init(void)
if (ret < 0)
return -ENODEV;
- ret = phy_driver_register(&ip101a_driver);
+ ret = phy_driver_register(&ip101a_g_driver);
if (ret < 0)
return -ENODEV;
@@ -231,7 +245,7 @@ static int __init icplus_init(void)
static void __exit icplus_exit(void)
{
phy_driver_unregister(&ip1001_driver);
- phy_driver_unregister(&ip101a_driver);
+ phy_driver_unregister(&ip101a_g_driver);
phy_driver_unregister(&ip175c_driver);
}
@@ -241,6 +255,7 @@ module_exit(icplus_exit);
static struct mdio_device_id __maybe_unused icplus_tbl[] = {
{ 0x02430d80, 0x0ffffff0 },
{ 0x02430d90, 0x0ffffff0 },
+ { 0x02430c54, 0x0ffffff0 },
{ }
};
diff --git a/drivers/net/phy/mdio-gpio.c b/drivers/net/phy/mdio-gpio.c
index 50e8e5e7446..7189adf54bd 100644
--- a/drivers/net/phy/mdio-gpio.c
+++ b/drivers/net/phy/mdio-gpio.c
@@ -255,13 +255,13 @@ static inline int __init mdio_ofgpio_init(void)
return platform_driver_register(&mdio_ofgpio_driver);
}
-static inline void __exit mdio_ofgpio_exit(void)
+static inline void mdio_ofgpio_exit(void)
{
platform_driver_unregister(&mdio_ofgpio_driver);
}
#else
static inline int __init mdio_ofgpio_init(void) { return 0; }
-static inline void __exit mdio_ofgpio_exit(void) { }
+static inline void mdio_ofgpio_exit(void) { }
#endif /* CONFIG_OF_GPIO */
static struct platform_driver mdio_gpio_driver = {
diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
index edfa15d2e79..486b4048850 100644
--- a/drivers/net/ppp/ppp_generic.c
+++ b/drivers/net/ppp/ppp_generic.c
@@ -2024,14 +2024,22 @@ ppp_mp_reconstruct(struct ppp *ppp)
continue;
}
if (PPP_MP_CB(p)->sequence != seq) {
+ u32 oldseq;
/* Fragment `seq' is missing. If it is after
minseq, it might arrive later, so stop here. */
if (seq_after(seq, minseq))
break;
/* Fragment `seq' is lost, keep going. */
lost = 1;
+ oldseq = seq;
seq = seq_before(minseq, PPP_MP_CB(p)->sequence)?
minseq + 1: PPP_MP_CB(p)->sequence;
+
+ if (ppp->debug & 1)
+ netdev_printk(KERN_DEBUG, ppp->dev,
+ "lost frag %u..%u\n",
+ oldseq, seq-1);
+
goto again;
}
@@ -2076,6 +2084,10 @@ ppp_mp_reconstruct(struct ppp *ppp)
struct sk_buff *tmp2;
skb_queue_reverse_walk_from_safe(list, p, tmp2) {
+ if (ppp->debug & 1)
+ netdev_printk(KERN_DEBUG, ppp->dev,
+ "discarding frag %u\n",
+ PPP_MP_CB(p)->sequence);
__skb_unlink(p, list);
kfree_skb(p);
}
@@ -2091,6 +2103,17 @@ ppp_mp_reconstruct(struct ppp *ppp)
/* If we have discarded any fragments,
signal a receive error. */
if (PPP_MP_CB(head)->sequence != ppp->nextseq) {
+ skb_queue_walk_safe(list, p, tmp) {
+ if (p == head)
+ break;
+ if (ppp->debug & 1)
+ netdev_printk(KERN_DEBUG, ppp->dev,
+ "discarding frag %u\n",
+ PPP_MP_CB(p)->sequence);
+ __skb_unlink(p, list);
+ kfree_skb(p);
+ }
+
if (ppp->debug & 1)
netdev_printk(KERN_DEBUG, ppp->dev,
" missed pkts %u..%u\n",
diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 41a61efc331..90a30026a93 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -573,6 +573,13 @@ static const struct usb_device_id products [] = {
.driver_info = 0,
},
+/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
+{
+ USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = 0,
+},
+
/*
* WHITELIST!!!
*
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 304fe78ff60..e1324b4a0f6 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1632,7 +1632,7 @@ static int hso_get_count(struct tty_struct *tty,
struct hso_serial *serial = get_serial_by_tty(tty);
struct hso_tiocmget *tiocmget = serial->tiocmget;
- memset(&icount, 0, sizeof(struct serial_icounter_struct));
+ memset(icount, 0, sizeof(struct serial_icounter_struct));
if (!tiocmget)
return -ENOENT;
diff --git a/drivers/net/usb/zaurus.c b/drivers/net/usb/zaurus.c
index f701d412708..c3197ce0e2a 100644
--- a/drivers/net/usb/zaurus.c
+++ b/drivers/net/usb/zaurus.c
@@ -316,6 +316,11 @@ static const struct usb_device_id products [] = {
ZAURUS_MASTER_INTERFACE,
.driver_info = ZAURUS_PXA_INFO,
}, {
+ /* C-750/C-760/C-860/SL-C3000 PDA in MDLM mode */
+ USB_DEVICE_AND_INTERFACE_INFO(0x04DD, 0x9031, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &bogus_mdlm_info,
+}, {
.match_flags = USB_DEVICE_ID_MATCH_INT_INFO
| USB_DEVICE_ID_MATCH_DEVICE,
.idVendor = 0x04DD,
@@ -349,6 +354,13 @@ static const struct usb_device_id products [] = {
ZAURUS_MASTER_INTERFACE,
.driver_info = OLYMPUS_MXL_INFO,
},
+
+/* Logitech Harmony 900 - uses the pseudo-MDLM (BLAN) driver */
+{
+ USB_DEVICE_AND_INTERFACE_INFO(0x046d, 0xc11f, USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_MDLM, USB_CDC_PROTO_NONE),
+ .driver_info = (unsigned long) &bogus_mdlm_info,
+},
{ }, // END
};
MODULE_DEVICE_TABLE(usb, products);
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c
index de7fc345148..3dcd3857a36 100644
--- a/drivers/net/vmxnet3/vmxnet3_drv.c
+++ b/drivers/net/vmxnet3/vmxnet3_drv.c
@@ -843,8 +843,8 @@ vmxnet3_parse_and_copy_hdr(struct sk_buff *skb, struct vmxnet3_tx_queue *tq,
/* for simplicity, don't copy L4 headers */
ctx->l4_hdr_size = 0;
}
- ctx->copy_size = ctx->eth_ip_hdr_size +
- ctx->l4_hdr_size;
+ ctx->copy_size = min(ctx->eth_ip_hdr_size +
+ ctx->l4_hdr_size, skb->len);
} else {
ctx->eth_ip_hdr_size = 0;
ctx->l4_hdr_size = 0;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 635b592ad96..a427a16bb73 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -1346,7 +1346,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
fc = hdr->frame_control;
for (i = 0; i < sc->hw->max_rates; i++) {
struct ieee80211_tx_rate *rate = &tx_info->status.rates[i];
- if (!rate->count)
+ if (rate->idx < 0 || !rate->count)
break;
final_ts_idx = i;
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c3b6c4652cd..5b2972b43b0 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -841,7 +841,12 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
ret = mwifiex_set_rf_channel(priv, channel,
priv->adapter->channel_type);
- ret = mwifiex_set_encode(priv, NULL, 0, 0, 1); /* Disable keys */
+ /* As this is new association, clear locally stored
+ * keys and security related flags */
+ priv->sec_info.wpa_enabled = false;
+ priv->sec_info.wpa2_enabled = false;
+ priv->wep_key_curr_index = 0;
+ ret = mwifiex_set_encode(priv, NULL, 0, 0, 1);
if (mode == NL80211_IFTYPE_ADHOC) {
/* "privacy" is set only for ad-hoc mode */
@@ -886,6 +891,7 @@ mwifiex_cfg80211_assoc(struct mwifiex_private *priv, size_t ssid_len, u8 *ssid,
dev_dbg(priv->adapter->dev,
"info: setting wep encryption"
" with key len %d\n", sme->key_len);
+ priv->wep_key_curr_index = sme->key_idx;
ret = mwifiex_set_encode(priv, sme->key, sme->key_len,
sme->key_idx, 0);
}
diff --git a/drivers/of/platform.c b/drivers/of/platform.c
index 63b3ec48c20..343ad29e211 100644
--- a/drivers/of/platform.c
+++ b/drivers/of/platform.c
@@ -55,7 +55,7 @@ EXPORT_SYMBOL(of_find_device_by_node);
#include <asm/dcr.h>
#endif
-#if !defined(CONFIG_SPARC)
+#ifdef CONFIG_OF_ADDRESS
/*
* The following routines scan a subtree and registers a device for
* each applicable node.
@@ -253,7 +253,7 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
if (!of_device_is_available(node))
return NULL;
- dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ dev = amba_device_alloc(NULL, 0, 0);
if (!dev)
return NULL;
@@ -283,14 +283,14 @@ static struct amba_device *of_amba_device_create(struct device_node *node,
if (ret)
goto err_free;
- ret = amba_device_register(dev, &iomem_resource);
+ ret = amba_device_add(dev, &iomem_resource);
if (ret)
goto err_free;
return dev;
err_free:
- kfree(dev);
+ amba_device_put(dev);
return NULL;
}
#else /* CONFIG_ARM_AMBA */
@@ -462,4 +462,4 @@ int of_platform_populate(struct device_node *root,
of_node_put(root);
return rc;
}
-#endif /* !CONFIG_SPARC */
+#endif /* CONFIG_OF_ADDRESS */
diff --git a/drivers/parisc/iommu-helpers.h b/drivers/parisc/iommu-helpers.h
index a9c46cc2db3..8c33491b21f 100644
--- a/drivers/parisc/iommu-helpers.h
+++ b/drivers/parisc/iommu-helpers.h
@@ -1,3 +1,5 @@
+#include <linux/prefetch.h>
+
/**
* iommu_fill_pdir - Insert coalesced scatter/gather chunks into the I/O Pdir.
* @ioc: The I/O Controller.
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index a87e2728b2c..64d433ec4fc 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -328,21 +328,15 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev)
goto err1;
}
- if (ret) {
- while (--i >= 0)
- soc_pcmcia_remove_one(&sinfo->skt[i]);
- kfree(sinfo);
- clk_put(clk);
- } else {
- pxa2xx_configure_sockets(&dev->dev);
- dev_set_drvdata(&dev->dev, sinfo);
- }
+ pxa2xx_configure_sockets(&dev->dev);
+ dev_set_drvdata(&dev->dev, sinfo);
return 0;
err1:
while (--i >= 0)
soc_pcmcia_remove_one(&sinfo->skt[i]);
+ clk_put(clk);
kfree(sinfo);
err0:
return ret;
diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c
index 42a7d603c87..7481146a5b4 100644
--- a/drivers/platform/x86/ibm_rtl.c
+++ b/drivers/platform/x86/ibm_rtl.c
@@ -33,6 +33,8 @@
#include <linux/mutex.h>
#include <asm/bios_ebda.h>
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
@@ -83,19 +85,6 @@ static void __iomem *rtl_cmd_addr;
static u8 rtl_cmd_type;
static u8 rtl_cmd_width;
-#ifndef readq
-static inline __u64 readq(const volatile void __iomem *addr)
-{
- const volatile u32 __iomem *p = addr;
- u32 low, high;
-
- low = readl(p);
- high = readl(p + 1);
-
- return low + ((u64)high << 32);
-}
-#endif
-
static void __iomem *rtl_port_map(phys_addr_t addr, unsigned long len)
{
if (rtl_cmd_type == RTL_ADDR_TYPE_MMIO)
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c
index 809a3ae943c..88a98cff5a4 100644
--- a/drivers/platform/x86/intel_ips.c
+++ b/drivers/platform/x86/intel_ips.c
@@ -77,6 +77,8 @@
#include <asm/processor.h>
#include "intel_ips.h"
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
#define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32
/*
@@ -344,19 +346,6 @@ struct ips_driver {
static bool
ips_gpu_turbo_enabled(struct ips_driver *ips);
-#ifndef readq
-static inline __u64 readq(const volatile void __iomem *addr)
-{
- const volatile u32 __iomem *p = addr;
- u32 low, high;
-
- low = readl(p);
- high = readl(p + 1);
-
- return low + ((u64)high << 32);
-}
-#endif
-
/**
* ips_cpu_busy - is CPU busy?
* @ips: IPS driver struct
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index df33530cec4..28b81ae4cf7 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -196,7 +196,7 @@ static const unsigned int LDO12_suspend_table[] = {
};
static const unsigned int LDO13_table[] = {
- 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0, 0,
+ 1200000, 1300000, 1800000, 2000000, 2500000, 2800000, 3000000, 0,
};
static const unsigned int LDO13_suspend_table[] = {
@@ -389,10 +389,10 @@ static struct pm8607_regulator_info pm8607_regulator_info[] = {
PM8607_LDO( 7, LDO7, 0, 3, SUPPLIES_EN12, 1),
PM8607_LDO( 8, LDO8, 0, 3, SUPPLIES_EN12, 2),
PM8607_LDO( 9, LDO9, 0, 3, SUPPLIES_EN12, 3),
- PM8607_LDO(10, LDO10, 0, 3, SUPPLIES_EN12, 4),
+ PM8607_LDO(10, LDO10, 0, 4, SUPPLIES_EN12, 4),
PM8607_LDO(12, LDO12, 0, 4, SUPPLIES_EN12, 5),
PM8607_LDO(13, VIBRATOR_SET, 1, 3, VIBRATOR_SET, 0),
- PM8607_LDO(14, LDO14, 0, 4, SUPPLIES_EN12, 6),
+ PM8607_LDO(14, LDO14, 0, 3, SUPPLIES_EN12, 6),
};
static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 7a61b17ddd0..740f468ba65 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -74,14 +74,6 @@ config REGULATOR_GPIO
and the platform has to provide a mapping of GPIO-states
to target volts/amps.
-config REGULATOR_BQ24022
- tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
- help
- This driver controls a TI bq24022 Charger attached via
- GPIOs. The provided current regulator can enable/disable
- charging select between 100 mA and 500 mA charging current
- limit.
-
config REGULATOR_MAX1586
tristate "Maxim 1586/1587 voltage regulator"
depends on I2C
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 503bac87715..f53cf8082c6 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_GPIO) += gpio-regulator.o
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
-obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
diff --git a/drivers/regulator/bq24022.c b/drivers/regulator/bq24022.c
deleted file mode 100644
index 9fab6d1bbe8..00000000000
--- a/drivers/regulator/bq24022.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/*
- * Support for TI bq24022 (bqTINY-II) Dual Input (USB/AC Adpater)
- * 1-Cell Li-Ion Charger connected via GPIOs.
- *
- * Copyright (c) 2008 Philipp Zabel
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/regulator/bq24022.h>
-#include <linux/regulator/driver.h>
-
-
-static int bq24022_set_current_limit(struct regulator_dev *rdev,
- int min_uA, int max_uA)
-{
- struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
- dev_dbg(rdev_get_dev(rdev), "setting current limit to %s mA\n",
- max_uA >= 500000 ? "500" : "100");
-
- /* REVISIT: maybe return error if min_uA != 0 ? */
- gpio_set_value(pdata->gpio_iset2, max_uA >= 500000);
- return 0;
-}
-
-static int bq24022_get_current_limit(struct regulator_dev *rdev)
-{
- struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
- return gpio_get_value(pdata->gpio_iset2) ? 500000 : 100000;
-}
-
-static int bq24022_enable(struct regulator_dev *rdev)
-{
- struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
- dev_dbg(rdev_get_dev(rdev), "enabling charger\n");
-
- gpio_set_value(pdata->gpio_nce, 0);
- return 0;
-}
-
-static int bq24022_disable(struct regulator_dev *rdev)
-{
- struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
- dev_dbg(rdev_get_dev(rdev), "disabling charger\n");
-
- gpio_set_value(pdata->gpio_nce, 1);
- return 0;
-}
-
-static int bq24022_is_enabled(struct regulator_dev *rdev)
-{
- struct bq24022_mach_info *pdata = rdev_get_drvdata(rdev);
-
- return !gpio_get_value(pdata->gpio_nce);
-}
-
-static struct regulator_ops bq24022_ops = {
- .set_current_limit = bq24022_set_current_limit,
- .get_current_limit = bq24022_get_current_limit,
- .enable = bq24022_enable,
- .disable = bq24022_disable,
- .is_enabled = bq24022_is_enabled,
-};
-
-static struct regulator_desc bq24022_desc = {
- .name = "bq24022",
- .ops = &bq24022_ops,
- .type = REGULATOR_CURRENT,
- .owner = THIS_MODULE,
-};
-
-static int __init bq24022_probe(struct platform_device *pdev)
-{
- struct bq24022_mach_info *pdata = pdev->dev.platform_data;
- struct regulator_dev *bq24022;
- int ret;
-
- if (!pdata || !pdata->gpio_nce || !pdata->gpio_iset2)
- return -EINVAL;
-
- ret = gpio_request(pdata->gpio_nce, "ncharge_en");
- if (ret) {
- dev_dbg(&pdev->dev, "couldn't request nCE GPIO: %d\n",
- pdata->gpio_nce);
- goto err_ce;
- }
- ret = gpio_request(pdata->gpio_iset2, "charge_mode");
- if (ret) {
- dev_dbg(&pdev->dev, "couldn't request ISET2 GPIO: %d\n",
- pdata->gpio_iset2);
- goto err_iset2;
- }
- ret = gpio_direction_output(pdata->gpio_iset2, 0);
- ret = gpio_direction_output(pdata->gpio_nce, 1);
-
- bq24022 = regulator_register(&bq24022_desc, &pdev->dev,
- pdata->init_data, pdata, NULL);
- if (IS_ERR(bq24022)) {
- dev_dbg(&pdev->dev, "couldn't register regulator\n");
- ret = PTR_ERR(bq24022);
- goto err_reg;
- }
- platform_set_drvdata(pdev, bq24022);
- dev_dbg(&pdev->dev, "registered regulator\n");
-
- return 0;
-err_reg:
- gpio_free(pdata->gpio_iset2);
-err_iset2:
- gpio_free(pdata->gpio_nce);
-err_ce:
- return ret;
-}
-
-static int __devexit bq24022_remove(struct platform_device *pdev)
-{
- struct bq24022_mach_info *pdata = pdev->dev.platform_data;
- struct regulator_dev *bq24022 = platform_get_drvdata(pdev);
-
- regulator_unregister(bq24022);
- gpio_free(pdata->gpio_iset2);
- gpio_free(pdata->gpio_nce);
-
- return 0;
-}
-
-static struct platform_driver bq24022_driver = {
- .driver = {
- .name = "bq24022",
- },
- .remove = __devexit_p(bq24022_remove),
-};
-
-static int __init bq24022_init(void)
-{
- return platform_driver_probe(&bq24022_driver, bq24022_probe);
-}
-
-static void __exit bq24022_exit(void)
-{
- platform_driver_unregister(&bq24022_driver);
-}
-
-module_init(bq24022_init);
-module_exit(bq24022_exit);
-
-MODULE_AUTHOR("Philipp Zabel");
-MODULE_DESCRIPTION("TI bq24022 Li-Ion Charger driver");
-MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 3a125b83554..59efc63c4e4 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -773,8 +773,8 @@ config RTC_DRV_EP93XX
will be called rtc-ep93xx.
config RTC_DRV_SA1100
- tristate "SA11x0/PXA2xx"
- depends on ARCH_SA1100 || ARCH_PXA
+ tristate "SA11x0/PXA2xx/PXA910"
+ depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP
help
If you say Y here you will get access to the real time clock
built into your SA11x0 or PXA2xx CPU.
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c
index aef40bd2957..78951866f8a 100644
--- a/drivers/rtc/rtc-s3c.c
+++ b/drivers/rtc/rtc-s3c.c
@@ -35,6 +35,8 @@
enum s3c_cpu_type {
TYPE_S3C2410,
+ TYPE_S3C2416,
+ TYPE_S3C2443,
TYPE_S3C64XX,
};
@@ -132,6 +134,7 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
struct platform_device *pdev = to_platform_device(dev);
struct rtc_device *rtc_dev = platform_get_drvdata(pdev);
unsigned int tmp = 0;
+ int val;
if (!is_power_of_2(freq))
return -EINVAL;
@@ -139,12 +142,22 @@ static int s3c_rtc_setfreq(struct device *dev, int freq)
clk_enable(rtc_clk);
spin_lock_irq(&s3c_rtc_pie_lock);
- if (s3c_rtc_cpu_type == TYPE_S3C2410) {
+ if (s3c_rtc_cpu_type != TYPE_S3C64XX) {
tmp = readb(s3c_rtc_base + S3C2410_TICNT);
tmp &= S3C2410_TICNT_ENABLE;
}
- tmp |= (rtc_dev->max_user_freq / freq)-1;
+ val = (rtc_dev->max_user_freq / freq) - 1;
+
+ if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) {
+ tmp |= S3C2443_TICNT_PART(val);
+ writel(S3C2443_TICNT1_PART(val), s3c_rtc_base + S3C2443_TICNT1);
+
+ if (s3c_rtc_cpu_type == TYPE_S3C2416)
+ writel(S3C2416_TICNT2_PART(val), s3c_rtc_base + S3C2416_TICNT2);
+ } else {
+ tmp |= val;
+ }
writel(tmp, s3c_rtc_base + S3C2410_TICNT);
spin_unlock_irq(&s3c_rtc_pie_lock);
@@ -371,7 +384,7 @@ static void s3c_rtc_enable(struct platform_device *pdev, int en)
tmp &= ~S3C2410_RTCCON_RTCEN;
writew(tmp, base + S3C2410_RTCCON);
- if (s3c_rtc_cpu_type == TYPE_S3C2410) {
+ if (s3c_rtc_cpu_type != TYPE_S3C64XX) {
tmp = readb(base + S3C2410_TICNT);
tmp &= ~S3C2410_TICNT_ENABLE;
writeb(tmp, base + S3C2410_TICNT);
@@ -428,12 +441,27 @@ static int __devexit s3c_rtc_remove(struct platform_device *dev)
return 0;
}
+static const struct of_device_id s3c_rtc_dt_match[];
+
+static inline int s3c_rtc_get_driver_data(struct platform_device *pdev)
+{
+#ifdef CONFIG_OF
+ if (pdev->dev.of_node) {
+ const struct of_device_id *match;
+ match = of_match_node(s3c_rtc_dt_match, pdev->dev.of_node);
+ return match->data;
+ }
+#endif
+ return platform_get_device_id(pdev)->driver_data;
+}
+
static int __devinit s3c_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
struct rtc_time rtc_tm;
struct resource *res;
int ret;
+ int tmp;
pr_debug("%s: probe=%p\n", __func__, pdev);
@@ -508,13 +536,7 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
goto err_nortc;
}
-#ifdef CONFIG_OF
- if (pdev->dev.of_node)
- s3c_rtc_cpu_type = of_device_is_compatible(pdev->dev.of_node,
- "samsung,s3c6410-rtc") ? TYPE_S3C64XX : TYPE_S3C2410;
- else
-#endif
- s3c_rtc_cpu_type = platform_get_device_id(pdev)->driver_data;
+ s3c_rtc_cpu_type = s3c_rtc_get_driver_data(pdev);
/* Check RTC Time */
@@ -533,11 +555,17 @@ static int __devinit s3c_rtc_probe(struct platform_device *pdev)
dev_warn(&pdev->dev, "warning: invalid RTC value so initializing it\n");
}
- if (s3c_rtc_cpu_type == TYPE_S3C64XX)
+ if (s3c_rtc_cpu_type != TYPE_S3C2410)
rtc->max_user_freq = 32768;
else
rtc->max_user_freq = 128;
+ if (s3c_rtc_cpu_type == TYPE_S3C2416 || s3c_rtc_cpu_type == TYPE_S3C2443) {
+ tmp = readw(s3c_rtc_base + S3C2410_RTCCON);
+ tmp |= S3C2443_RTCCON_TICSEL;
+ writew(tmp, s3c_rtc_base + S3C2410_RTCCON);
+ }
+
platform_set_drvdata(pdev, rtc);
s3c_rtc_setfreq(&pdev->dev, 1);
@@ -638,8 +666,19 @@ static int s3c_rtc_resume(struct platform_device *pdev)
#ifdef CONFIG_OF
static const struct of_device_id s3c_rtc_dt_match[] = {
- { .compatible = "samsung,s3c2410-rtc" },
- { .compatible = "samsung,s3c6410-rtc" },
+ {
+ .compatible = "samsung,s3c2410-rtc"
+ .data = TYPE_S3C2410,
+ }, {
+ .compatible = "samsung,s3c2416-rtc"
+ .data = TYPE_S3C2416,
+ }, {
+ .compatible = "samsung,s3c2443-rtc"
+ .data = TYPE_S3C2443,
+ }, {
+ .compatible = "samsung,s3c6410-rtc"
+ .data = TYPE_S3C64XX,
+ },
{},
};
MODULE_DEVICE_TABLE(of, s3c_rtc_dt_match);
@@ -652,6 +691,12 @@ static struct platform_device_id s3c_rtc_driver_ids[] = {
.name = "s3c2410-rtc",
.driver_data = TYPE_S3C2410,
}, {
+ .name = "s3c2416-rtc",
+ .driver_data = TYPE_S3C2416,
+ }, {
+ .name = "s3c2443-rtc",
+ .driver_data = TYPE_S3C2443,
+ }, {
.name = "s3c64xx-rtc",
.driver_data = TYPE_S3C64XX,
},
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c
index cb9a585312c..e443b7850ed 100644
--- a/drivers/rtc/rtc-sa1100.c
+++ b/drivers/rtc/rtc-sa1100.c
@@ -23,94 +23,44 @@
#include <linux/platform_device.h>
#include <linux/module.h>
+#include <linux/clk.h>
#include <linux/rtc.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
+#include <linux/slab.h>
#include <linux/string.h>
+#include <linux/of.h>
#include <linux/pm.h>
#include <linux/bitops.h>
#include <mach/hardware.h>
#include <asm/irq.h>
-#ifdef CONFIG_ARCH_PXA
+#if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)
#include <mach/regs-rtc.h>
#endif
#define RTC_DEF_DIVIDER (32768 - 1)
#define RTC_DEF_TRIM 0
-
-static const unsigned long RTC_FREQ = 1024;
-static struct rtc_time rtc_alarm;
-static DEFINE_SPINLOCK(sa1100_rtc_lock);
-
-static inline int rtc_periodic_alarm(struct rtc_time *tm)
-{
- return (tm->tm_year == -1) ||
- ((unsigned)tm->tm_mon >= 12) ||
- ((unsigned)(tm->tm_mday - 1) >= 31) ||
- ((unsigned)tm->tm_hour > 23) ||
- ((unsigned)tm->tm_min > 59) ||
- ((unsigned)tm->tm_sec > 59);
-}
-
-/*
- * Calculate the next alarm time given the requested alarm time mask
- * and the current time.
- */
-static void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now,
- struct rtc_time *alrm)
-{
- unsigned long next_time;
- unsigned long now_time;
-
- next->tm_year = now->tm_year;
- next->tm_mon = now->tm_mon;
- next->tm_mday = now->tm_mday;
- next->tm_hour = alrm->tm_hour;
- next->tm_min = alrm->tm_min;
- next->tm_sec = alrm->tm_sec;
-
- rtc_tm_to_time(now, &now_time);
- rtc_tm_to_time(next, &next_time);
-
- if (next_time < now_time) {
- /* Advance one day */
- next_time += 60 * 60 * 24;
- rtc_time_to_tm(next_time, next);
- }
-}
-
-static int rtc_update_alarm(struct rtc_time *alrm)
-{
- struct rtc_time alarm_tm, now_tm;
- unsigned long now, time;
- int ret;
-
- do {
- now = RCNR;
- rtc_time_to_tm(now, &now_tm);
- rtc_next_alarm_time(&alarm_tm, &now_tm, alrm);
- ret = rtc_tm_to_time(&alarm_tm, &time);
- if (ret != 0)
- break;
-
- RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
- RTAR = time;
- } while (now != RCNR);
-
- return ret;
-}
+#define RTC_FREQ 1024
+
+struct sa1100_rtc {
+ spinlock_t lock;
+ int irq_1hz;
+ int irq_alarm;
+ struct rtc_device *rtc;
+ struct clk *clk;
+};
static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
{
- struct platform_device *pdev = to_platform_device(dev_id);
- struct rtc_device *rtc = platform_get_drvdata(pdev);
+ struct sa1100_rtc *info = dev_get_drvdata(dev_id);
+ struct rtc_device *rtc = info->rtc;
unsigned int rtsr;
unsigned long events = 0;
- spin_lock(&sa1100_rtc_lock);
+ spin_lock(&info->lock);
rtsr = RTSR;
/* clear interrupt sources */
@@ -146,30 +96,30 @@ static irqreturn_t sa1100_rtc_interrupt(int irq, void *dev_id)
rtc_update_irq(rtc, 1, events);
- if (rtsr & RTSR_AL && rtc_periodic_alarm(&rtc_alarm))
- rtc_update_alarm(&rtc_alarm);
-
- spin_unlock(&sa1100_rtc_lock);
+ spin_unlock(&info->lock);
return IRQ_HANDLED;
}
static int sa1100_rtc_open(struct device *dev)
{
+ struct sa1100_rtc *info = dev_get_drvdata(dev);
+ struct rtc_device *rtc = info->rtc;
int ret;
- struct platform_device *plat_dev = to_platform_device(dev);
- struct rtc_device *rtc = platform_get_drvdata(plat_dev);
- ret = request_irq(IRQ_RTC1Hz, sa1100_rtc_interrupt, IRQF_DISABLED,
+ ret = clk_prepare_enable(info->clk);
+ if (ret)
+ goto fail_clk;
+ ret = request_irq(info->irq_1hz, sa1100_rtc_interrupt, IRQF_DISABLED,
"rtc 1Hz", dev);
if (ret) {
- dev_err(dev, "IRQ %d already in use.\n", IRQ_RTC1Hz);
+ dev_err(dev, "IRQ %d already in use.\n", info->irq_1hz);
goto fail_ui;
}
- ret = request_irq(IRQ_RTCAlrm, sa1100_rtc_interrupt, IRQF_DISABLED,
+ ret = request_irq(info->irq_alarm, sa1100_rtc_interrupt, IRQF_DISABLED,
"rtc Alrm", dev);
if (ret) {
- dev_err(dev, "IRQ %d already in use.\n", IRQ_RTCAlrm);
+ dev_err(dev, "IRQ %d already in use.\n", info->irq_alarm);
goto fail_ai;
}
rtc->max_user_freq = RTC_FREQ;
@@ -178,29 +128,36 @@ static int sa1100_rtc_open(struct device *dev)
return 0;
fail_ai:
- free_irq(IRQ_RTC1Hz, dev);
+ free_irq(info->irq_1hz, dev);
fail_ui:
+ clk_disable_unprepare(info->clk);
+ fail_clk:
return ret;
}
static void sa1100_rtc_release(struct device *dev)
{
- spin_lock_irq(&sa1100_rtc_lock);
+ struct sa1100_rtc *info = dev_get_drvdata(dev);
+
+ spin_lock_irq(&info->lock);
RTSR = 0;
- spin_unlock_irq(&sa1100_rtc_lock);
+ spin_unlock_irq(&info->lock);
- free_irq(IRQ_RTCAlrm, dev);
- free_irq(IRQ_RTC1Hz, dev);
+ free_irq(info->irq_alarm, dev);
+ free_irq(info->irq_1hz, dev);
+ clk_disable_unprepare(info->clk);
}
static int sa1100_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
{
- spin_lock_irq(&sa1100_rtc_lock);
+ struct sa1100_rtc *info = dev_get_drvdata(dev);
+
+ spin_lock_irq(&info->lock);
if (enabled)
RTSR |= RTSR_ALE;
else
RTSR &= ~RTSR_ALE;
- spin_unlock_irq(&sa1100_rtc_lock);
+ spin_unlock_irq(&info->lock);
return 0;
}
@@ -225,7 +182,6 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
u32 rtsr;
- memcpy(&alrm->time, &rtc_alarm, sizeof(struct rtc_time));
rtsr = RTSR;
alrm->enabled = (rtsr & RTSR_ALE) ? 1 : 0;
alrm->pending = (rtsr & RTSR_AL) ? 1 : 0;
@@ -234,17 +190,22 @@ static int sa1100_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
static int sa1100_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
+ struct sa1100_rtc *info = dev_get_drvdata(dev);
+ unsigned long time;
int ret;
- spin_lock_irq(&sa1100_rtc_lock);
- ret = rtc_update_alarm(&alrm->time);
- if (ret == 0) {
- if (alrm->enabled)
- RTSR |= RTSR_ALE;
- else
- RTSR &= ~RTSR_ALE;
- }
- spin_unlock_irq(&sa1100_rtc_lock);
+ spin_lock_irq(&info->lock);
+ ret = rtc_tm_to_time(&alrm->time, &time);
+ if (ret != 0)
+ goto out;
+ RTSR = RTSR & (RTSR_HZE|RTSR_ALE|RTSR_AL);
+ RTAR = time;
+ if (alrm->enabled)
+ RTSR |= RTSR_ALE;
+ else
+ RTSR &= ~RTSR_ALE;
+out:
+ spin_unlock_irq(&info->lock);
return ret;
}
@@ -271,6 +232,27 @@ static const struct rtc_class_ops sa1100_rtc_ops = {
static int sa1100_rtc_probe(struct platform_device *pdev)
{
struct rtc_device *rtc;
+ struct sa1100_rtc *info;
+ int irq_1hz, irq_alarm, ret = 0;
+
+ irq_1hz = platform_get_irq_byname(pdev, "rtc 1Hz");
+ irq_alarm = platform_get_irq_byname(pdev, "rtc alarm");
+ if (irq_1hz < 0 || irq_alarm < 0)
+ return -ENODEV;
+
+ info = kzalloc(sizeof(struct sa1100_rtc), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+ info->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(info->clk)) {
+ dev_err(&pdev->dev, "failed to find rtc clock source\n");
+ ret = PTR_ERR(info->clk);
+ goto err_clk;
+ }
+ info->irq_1hz = irq_1hz;
+ info->irq_alarm = irq_alarm;
+ spin_lock_init(&info->lock);
+ platform_set_drvdata(pdev, info);
/*
* According to the manual we should be able to let RTTR be zero
@@ -292,10 +274,11 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
rtc = rtc_device_register(pdev->name, &pdev->dev, &sa1100_rtc_ops,
THIS_MODULE);
- if (IS_ERR(rtc))
- return PTR_ERR(rtc);
-
- platform_set_drvdata(pdev, rtc);
+ if (IS_ERR(rtc)) {
+ ret = PTR_ERR(rtc);
+ goto err_dev;
+ }
+ info->rtc = rtc;
/* Fix for a nasty initialization problem the in SA11xx RTSR register.
* See also the comments in sa1100_rtc_interrupt().
@@ -322,14 +305,24 @@ static int sa1100_rtc_probe(struct platform_device *pdev)
RTSR = RTSR_AL | RTSR_HZ;
return 0;
+err_dev:
+ platform_set_drvdata(pdev, NULL);
+ clk_put(info->clk);
+err_clk:
+ kfree(info);
+ return ret;
}
static int sa1100_rtc_remove(struct platform_device *pdev)
{
- struct rtc_device *rtc = platform_get_drvdata(pdev);
+ struct sa1100_rtc *info = platform_get_drvdata(pdev);
- if (rtc)
- rtc_device_unregister(rtc);
+ if (info) {
+ rtc_device_unregister(info->rtc);
+ clk_put(info->clk);
+ platform_set_drvdata(pdev, NULL);
+ kfree(info);
+ }
return 0;
}
@@ -337,15 +330,17 @@ static int sa1100_rtc_remove(struct platform_device *pdev)
#ifdef CONFIG_PM
static int sa1100_rtc_suspend(struct device *dev)
{
+ struct sa1100_rtc *info = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
- enable_irq_wake(IRQ_RTCAlrm);
+ enable_irq_wake(info->irq_alarm);
return 0;
}
static int sa1100_rtc_resume(struct device *dev)
{
+ struct sa1100_rtc *info = dev_get_drvdata(dev);
if (device_may_wakeup(dev))
- disable_irq_wake(IRQ_RTCAlrm);
+ disable_irq_wake(info->irq_alarm);
return 0;
}
@@ -355,6 +350,13 @@ static const struct dev_pm_ops sa1100_rtc_pm_ops = {
};
#endif
+static struct of_device_id sa1100_rtc_dt_ids[] = {
+ { .compatible = "mrvl,sa1100-rtc", },
+ { .compatible = "mrvl,mmp-rtc", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, sa1100_rtc_dt_ids);
+
static struct platform_driver sa1100_rtc_driver = {
.probe = sa1100_rtc_probe,
.remove = sa1100_rtc_remove,
@@ -363,6 +365,7 @@ static struct platform_driver sa1100_rtc_driver = {
#ifdef CONFIG_PM
.pm = &sa1100_rtc_pm_ops,
#endif
+ .of_match_table = sa1100_rtc_dt_ids,
},
};
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
index 70880be2601..2617b1ed470 100644
--- a/drivers/s390/block/dasd_eckd.c
+++ b/drivers/s390/block/dasd_eckd.c
@@ -18,12 +18,12 @@
#include <linux/hdreg.h> /* HDIO_GETGEO */
#include <linux/bio.h>
#include <linux/module.h>
+#include <linux/compat.h>
#include <linux/init.h>
#include <asm/debug.h>
#include <asm/idals.h>
#include <asm/ebcdic.h>
-#include <asm/compat.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/cio.h>
diff --git a/drivers/s390/block/dasd_ioctl.c b/drivers/s390/block/dasd_ioctl.c
index f1a2016829f..792c69e78fe 100644
--- a/drivers/s390/block/dasd_ioctl.c
+++ b/drivers/s390/block/dasd_ioctl.c
@@ -13,6 +13,7 @@
#define KMSG_COMPONENT "dasd"
#include <linux/interrupt.h>
+#include <linux/compat.h>
#include <linux/major.h>
#include <linux/fs.h>
#include <linux/blkpg.h>
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index 934458ad55e..e71a50d4b22 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -87,6 +87,7 @@ struct raw3215_info {
struct tty_struct *tty; /* pointer to tty structure if present */
struct raw3215_req *queued_read; /* pointer to queued read requests */
struct raw3215_req *queued_write;/* pointer to queued write requests */
+ struct tasklet_struct tlet; /* tasklet to invoke tty_wakeup */
wait_queue_head_t empty_wait; /* wait queue for flushing */
struct timer_list timer; /* timer for delayed output */
int line_pos; /* position on the line (for tabs) */
@@ -334,19 +335,23 @@ static inline void raw3215_try_io(struct raw3215_info *raw)
}
/*
+ * Call tty_wakeup from tasklet context
+ */
+static void raw3215_wakeup(unsigned long data)
+{
+ struct raw3215_info *raw = (struct raw3215_info *) data;
+ tty_wakeup(raw->tty);
+}
+
+/*
* Try to start the next IO and wake up processes waiting on the tty.
*/
static void raw3215_next_io(struct raw3215_info *raw)
{
- struct tty_struct *tty;
-
raw3215_mk_write_req(raw);
raw3215_try_io(raw);
- tty = raw->tty;
- if (tty != NULL &&
- RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE) {
- tty_wakeup(tty);
- }
+ if (raw->tty && RAW3215_BUFFER_SIZE - raw->count >= RAW3215_MIN_SPACE)
+ tasklet_schedule(&raw->tlet);
}
/*
@@ -682,6 +687,7 @@ static int raw3215_probe (struct ccw_device *cdev)
return -ENOMEM;
}
init_waitqueue_head(&raw->empty_wait);
+ tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
dev_set_drvdata(&cdev->dev, raw);
cdev->handler = raw3215_irq;
@@ -901,6 +907,7 @@ static int __init con3215_init(void)
raw->flags |= RAW3215_FIXED;
init_waitqueue_head(&raw->empty_wait);
+ tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw);
/* Request the console irq */
if (raw3215_startup(raw) != 0) {
@@ -966,6 +973,7 @@ static void tty3215_close(struct tty_struct *tty, struct file * filp)
tty->closing = 1;
/* Shutdown the terminal */
raw3215_shutdown(raw);
+ tasklet_kill(&raw->tlet);
tty->closing = 0;
raw->tty = NULL;
}
diff --git a/drivers/s390/char/fs3270.c b/drivers/s390/char/fs3270.c
index e71298158f9..911704571b9 100644
--- a/drivers/s390/char/fs3270.c
+++ b/drivers/s390/char/fs3270.c
@@ -11,6 +11,7 @@
#include <linux/console.h>
#include <linux/init.h>
#include <linux/interrupt.h>
+#include <linux/compat.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/slab.h>
diff --git a/drivers/s390/char/vmcp.c b/drivers/s390/char/vmcp.c
index 75bde6a8b7d..89c03e6b1c0 100644
--- a/drivers/s390/char/vmcp.c
+++ b/drivers/s390/char/vmcp.c
@@ -13,6 +13,7 @@
#include <linux/fs.h>
#include <linux/init.h>
+#include <linux/compat.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/slab.h>
diff --git a/drivers/s390/cio/chsc_sch.c b/drivers/s390/cio/chsc_sch.c
index 0c87b0fc771..8f9a1a38449 100644
--- a/drivers/s390/cio/chsc_sch.c
+++ b/drivers/s390/cio/chsc_sch.c
@@ -8,6 +8,7 @@
*/
#include <linux/slab.h>
+#include <linux/compat.h>
#include <linux/device.h>
#include <linux/module.h>
#include <linux/uaccess.h>
diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c
index 303dde09d29..fab2c2592a9 100644
--- a/drivers/s390/scsi/zfcp_cfdc.c
+++ b/drivers/s390/scsi/zfcp_cfdc.c
@@ -11,6 +11,7 @@
#define KMSG_COMPONENT "zfcp"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+#include <linux/compat.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/miscdevice.h>
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 53a31c753cb..20c4557f5ab 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -364,10 +364,7 @@ static void release_controller(struct kref *kref)
struct rdac_controller *ctlr;
ctlr = container_of(kref, struct rdac_controller, kref);
- flush_workqueue(kmpath_rdacd);
- spin_lock(&list_lock);
list_del(&ctlr->node);
- spin_unlock(&list_lock);
kfree(ctlr);
}
@@ -376,20 +373,17 @@ static struct rdac_controller *get_controller(int index, char *array_name,
{
struct rdac_controller *ctlr, *tmp;
- spin_lock(&list_lock);
-
list_for_each_entry(tmp, &ctlr_list, node) {
if ((memcmp(tmp->array_id, array_id, UNIQUE_ID_LEN) == 0) &&
(tmp->index == index) &&
(tmp->host == sdev->host)) {
kref_get(&tmp->kref);
- spin_unlock(&list_lock);
return tmp;
}
}
ctlr = kmalloc(sizeof(*ctlr), GFP_ATOMIC);
if (!ctlr)
- goto done;
+ return NULL;
/* initialize fields of controller */
memcpy(ctlr->array_id, array_id, UNIQUE_ID_LEN);
@@ -405,8 +399,7 @@ static struct rdac_controller *get_controller(int index, char *array_name,
INIT_WORK(&ctlr->ms_work, send_mode_select);
INIT_LIST_HEAD(&ctlr->ms_head);
list_add(&ctlr->node, &ctlr_list);
-done:
- spin_unlock(&list_lock);
+
return ctlr;
}
@@ -517,9 +510,12 @@ static int initialize_controller(struct scsi_device *sdev,
index = 0;
else
index = 1;
+
+ spin_lock(&list_lock);
h->ctlr = get_controller(index, array_name, array_id, sdev);
if (!h->ctlr)
err = SCSI_DH_RES_TEMP_UNAVAIL;
+ spin_unlock(&list_lock);
}
return err;
}
@@ -906,7 +902,9 @@ static int rdac_bus_attach(struct scsi_device *sdev)
return 0;
clean_ctlr:
+ spin_lock(&list_lock);
kref_put(&h->ctlr->kref, release_controller);
+ spin_unlock(&list_lock);
failed:
kfree(scsi_dh_data);
@@ -921,14 +919,19 @@ static void rdac_bus_detach( struct scsi_device *sdev )
struct rdac_dh_data *h;
unsigned long flags;
- spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
scsi_dh_data = sdev->scsi_dh_data;
+ h = (struct rdac_dh_data *) scsi_dh_data->buf;
+ if (h->ctlr && h->ctlr->ms_queued)
+ flush_workqueue(kmpath_rdacd);
+
+ spin_lock_irqsave(sdev->request_queue->queue_lock, flags);
sdev->scsi_dh_data = NULL;
spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags);
- h = (struct rdac_dh_data *) scsi_dh_data->buf;
+ spin_lock(&list_lock);
if (h->ctlr)
kref_put(&h->ctlr->kref, release_controller);
+ spin_unlock(&list_lock);
kfree(scsi_dh_data);
module_put(THIS_MODULE);
sdev_printk(KERN_NOTICE, sdev, "%s: Detached\n", RDAC_NAME);
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 67b169b7a5b..b538f0883fd 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -4613,11 +4613,13 @@ static int __ipr_eh_host_reset(struct scsi_cmnd * scsi_cmd)
ENTER;
ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata;
- dev_err(&ioa_cfg->pdev->dev,
- "Adapter being reset as a result of error recovery.\n");
+ if (!ioa_cfg->in_reset_reload) {
+ dev_err(&ioa_cfg->pdev->dev,
+ "Adapter being reset as a result of error recovery.\n");
- if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
- ioa_cfg->sdt_state = GET_DUMP;
+ if (WAIT_FOR_DUMP == ioa_cfg->sdt_state)
+ ioa_cfg->sdt_state = GET_DUMP;
+ }
rc = ipr_reset_reload(ioa_cfg, IPR_SHUTDOWN_ABBREV);
@@ -4907,7 +4909,7 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
struct ipr_ioa_cfg *ioa_cfg;
struct ipr_resource_entry *res;
struct ipr_cmd_pkt *cmd_pkt;
- u32 ioasc;
+ u32 ioasc, int_reg;
int op_found = 0;
ENTER;
@@ -4920,7 +4922,17 @@ static int ipr_cancel_op(struct scsi_cmnd * scsi_cmd)
*/
if (ioa_cfg->in_reset_reload || ioa_cfg->ioa_is_dead)
return FAILED;
- if (!res || !ipr_is_gscsi(res))
+ if (!res)
+ return FAILED;
+
+ /*
+ * If we are aborting a timed out op, chances are that the timeout was caused
+ * by a still not detected EEH error. In such cases, reading a register will
+ * trigger the EEH recovery infrastructure.
+ */
+ int_reg = readl(ioa_cfg->regs.sense_interrupt_reg);
+
+ if (!ipr_is_gscsi(res))
return FAILED;
list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
diff --git a/drivers/scsi/isci/host.c b/drivers/scsi/isci/host.c
index 1a65d651423..418391b1c36 100644
--- a/drivers/scsi/isci/host.c
+++ b/drivers/scsi/isci/host.c
@@ -1848,9 +1848,11 @@ static enum sci_status sci_oem_parameters_set(struct isci_host *ihost)
if (state == SCIC_RESET ||
state == SCIC_INITIALIZING ||
state == SCIC_INITIALIZED) {
+ u8 oem_version = pci_info->orom ? pci_info->orom->hdr.version :
+ ISCI_ROM_VER_1_0;
if (sci_oem_parameters_validate(&ihost->oem_parameters,
- pci_info->orom->hdr.version))
+ oem_version))
return SCI_FAILURE_INVALID_PARAMETER_VALUE;
return SCI_SUCCESS;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c
index 0b2c9558366..a78036f5e1a 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.c
@@ -4548,7 +4548,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
printk(MPT2SAS_ERR_FMT "%s: pci error recovery reset\n",
ioc->name, __func__);
r = 0;
- goto out;
+ goto out_unlocked;
}
if (mpt2sas_fwfault_debug)
@@ -4604,6 +4604,7 @@ mpt2sas_base_hard_reset_handler(struct MPT2SAS_ADAPTER *ioc, int sleep_flag,
spin_unlock_irqrestore(&ioc->ioc_reset_in_progress_lock, flags);
mutex_unlock(&ioc->reset_in_progress_mutex);
+ out_unlocked:
dtmprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: exit\n", ioc->name,
__func__));
return r;
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c
index b31a8e3841d..d4ed9eb5265 100644
--- a/drivers/scsi/osd/osd_uld.c
+++ b/drivers/scsi/osd/osd_uld.c
@@ -69,10 +69,10 @@
#ifndef SCSI_OSD_MAJOR
# define SCSI_OSD_MAJOR 260
#endif
-#define SCSI_OSD_MAX_MINOR 64
+#define SCSI_OSD_MAX_MINOR MINORMASK
static const char osd_name[] = "osd";
-static const char *osd_version_string = "open-osd 0.2.0";
+static const char *osd_version_string = "open-osd 0.2.1";
MODULE_AUTHOR("Boaz Harrosh <bharrosh@panasas.com>");
MODULE_DESCRIPTION("open-osd Upper-Layer-Driver osd.ko");
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c
index a2f1b3043df..9f41b3b4358 100644
--- a/drivers/scsi/qla2xxx/qla_attr.c
+++ b/drivers/scsi/qla2xxx/qla_attr.c
@@ -1036,8 +1036,7 @@ qla2x00_link_state_show(struct device *dev, struct device_attribute *attr,
vha->device_flags & DFLG_NO_CABLE)
len = snprintf(buf, PAGE_SIZE, "Link Down\n");
else if (atomic_read(&vha->loop_state) != LOOP_READY ||
- test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+ qla2x00_reset_active(vha))
len = snprintf(buf, PAGE_SIZE, "Unknown Link State\n");
else {
len = snprintf(buf, PAGE_SIZE, "Link Up - ");
@@ -1359,8 +1358,7 @@ qla2x00_thermal_temp_show(struct device *dev,
return snprintf(buf, PAGE_SIZE, "\n");
temp = frac = 0;
- if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+ if (qla2x00_reset_active(vha))
ql_log(ql_log_warn, vha, 0x707b,
"ISP reset active.\n");
else if (!vha->hw->flags.eeh_busy)
@@ -1379,8 +1377,7 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
int rval = QLA_FUNCTION_FAILED;
uint16_t state[5];
- if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags))
+ if (qla2x00_reset_active(vha))
ql_log(ql_log_warn, vha, 0x707c,
"ISP reset active.\n");
else if (!vha->hw->flags.eeh_busy)
@@ -1693,9 +1690,7 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost)
if (IS_FWI2_CAPABLE(ha)) {
rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma);
} else if (atomic_read(&base_vha->loop_state) == LOOP_READY &&
- !test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) &&
- !test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) &&
- !ha->dpc_active) {
+ !qla2x00_reset_active(vha) && !ha->dpc_active) {
/* Must be in a 'READY' state for statistics retrieval. */
rval = qla2x00_get_link_status(base_vha, base_vha->loop_id,
stats, stats_dma);
diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c
index b1d0f936bf2..1682e2e4201 100644
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -108,13 +108,6 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
goto exit_fcp_prio_cfg;
}
- if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
- test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
- ret = -EBUSY;
- goto exit_fcp_prio_cfg;
- }
-
/* Get the sub command */
oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
@@ -646,13 +639,6 @@ qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
dma_addr_t rsp_data_dma;
uint32_t rsp_data_len;
- if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
- test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
- ql_log(ql_log_warn, vha, 0x7018, "Abort active or needed.\n");
- return -EBUSY;
- }
-
if (!vha->flags.online) {
ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
return -EIO;
@@ -874,13 +860,6 @@ qla84xx_reset(struct fc_bsg_job *bsg_job)
int rval = 0;
uint32_t flag;
- if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
- test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
- ql_log(ql_log_warn, vha, 0x702e, "Abort active or needed.\n");
- return -EBUSY;
- }
-
if (!IS_QLA84XX(ha)) {
ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
return -EINVAL;
@@ -922,11 +901,6 @@ qla84xx_updatefw(struct fc_bsg_job *bsg_job)
uint32_t flag;
uint32_t fw_ver;
- if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
- test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_RETRY, &vha->dpc_flags))
- return -EBUSY;
-
if (!IS_QLA84XX(ha)) {
ql_dbg(ql_dbg_user, vha, 0x7032,
"Not 84xx, exiting.\n");
@@ -1036,14 +1010,6 @@ qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
uint32_t data_len = 0;
uint32_t dma_direction = DMA_NONE;
- if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
- test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
- ql_log(ql_log_warn, vha, 0x7039,
- "Abort active or needed.\n");
- return -EBUSY;
- }
-
if (!IS_QLA84XX(ha)) {
ql_log(ql_log_warn, vha, 0x703a,
"Not 84xx, exiting.\n");
@@ -1246,13 +1212,6 @@ qla24xx_iidma(struct fc_bsg_job *bsg_job)
bsg_job->reply->reply_payload_rcv_len = 0;
- if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
- test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
- test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
- ql_log(ql_log_warn, vha, 0x7045, "abort active or needed.\n");
- return -EBUSY;
- }
-
if (!IS_IIDMA_CAPABLE(vha->hw)) {
ql_log(ql_log_info, vha, 0x7046, "iiDMA not supported.\n");
return -EINVAL;
@@ -1668,6 +1627,15 @@ qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
vha = shost_priv(host);
}
+ if (qla2x00_reset_active(vha)) {
+ ql_dbg(ql_dbg_user, vha, 0x709f,
+ "BSG: ISP abort active/needed -- cmd=%d.\n",
+ bsg_job->request->msgcode);
+ bsg_job->reply->result = (DID_ERROR << 16);
+ bsg_job->job_done(bsg_job);
+ return -EBUSY;
+ }
+
ql_dbg(ql_dbg_user, vha, 0x7000,
"Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode);
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
index 7c54624b5b1..45cbf0ba624 100644
--- a/drivers/scsi/qla2xxx/qla_dbg.c
+++ b/drivers/scsi/qla2xxx/qla_dbg.c
@@ -19,7 +19,8 @@
* | DPC Thread | 0x401c | |
* | Async Events | 0x5057 | 0x5052 |
* | Timer Routines | 0x6011 | 0x600e,0x600f |
- * | User Space Interactions | 0x709e | |
+ * | User Space Interactions | 0x709e | 0x7018,0x702e |
+ * | | | 0x7039,0x7045 |
* | Task Management | 0x803c | 0x8025-0x8026 |
* | | | 0x800b,0x8039 |
* | AER/EEH | 0x900f | |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
index a6a4eebce4a..af1003f9de1 100644
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -44,6 +44,7 @@
* ISP2100 HBAs.
*/
#define MAILBOX_REGISTER_COUNT_2100 8
+#define MAILBOX_REGISTER_COUNT_2200 24
#define MAILBOX_REGISTER_COUNT 32
#define QLA2200A_RISC_ROM_VER 4
diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
index 9902834e0b7..7cc4f36cd53 100644
--- a/drivers/scsi/qla2xxx/qla_inline.h
+++ b/drivers/scsi/qla2xxx/qla_inline.h
@@ -131,3 +131,16 @@ qla2x00_hba_err_chk_enabled(srb_t *sp)
}
return 0;
}
+
+static inline int
+qla2x00_reset_active(scsi_qla_host_t *vha)
+{
+ scsi_qla_host_t *base_vha = pci_get_drvdata(vha->hw->pdev);
+
+ /* Test appropriate base-vha and vha flags. */
+ return test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) ||
+ test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) ||
+ test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) ||
+ test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
+ test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
+}
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index e804585cc59..349843ea32f 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -2090,7 +2090,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
break;
case CT_IOCB_TYPE:
qla24xx_els_ct_entry(vha, rsp->req, pkt, CT_IOCB_TYPE);
- clear_bit(MBX_INTERRUPT, &vha->hw->mbx_cmd_flags);
break;
case ELS_IOCB_TYPE:
qla24xx_els_ct_entry(vha, rsp->req, pkt, ELS_IOCB_TYPE);
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
index 34344d3f865..08f1d01bdc1 100644
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -342,6 +342,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
+ /* Allow next mbx cmd to come in. */
+ complete(&ha->mbx_cmd_comp);
if (ha->isp_ops->abort_isp(vha)) {
/* Failed. retry later. */
set_bit(ISP_ABORT_NEEDED,
@@ -350,6 +352,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp)
clear_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags);
ql_dbg(ql_dbg_mbx, base_vha, 0x101f,
"Finished abort_isp.\n");
+ goto mbx_done;
}
}
}
@@ -358,6 +361,7 @@ premature_exit:
/* Allow next mbx cmd to come in. */
complete(&ha->mbx_cmd_comp);
+mbx_done:
if (rval) {
ql_dbg(ql_dbg_mbx, base_vha, 0x1020,
"**** Failed mbx[0]=%x, mb[1]=%x, mb[2]=%x, cmd=%x ****.\n",
@@ -2581,7 +2585,8 @@ qla2x00_stop_firmware(scsi_qla_host_t *vha)
ql_dbg(ql_dbg_mbx, vha, 0x10a1, "Entered %s.\n", __func__);
mcp->mb[0] = MBC_STOP_FIRMWARE;
- mcp->out_mb = MBX_0;
+ mcp->mb[1] = 0;
+ mcp->out_mb = MBX_1|MBX_0;
mcp->in_mb = MBX_0;
mcp->tov = 5;
mcp->flags = 0;
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c
index 1cd46cd7ff9..270ba3130fd 100644
--- a/drivers/scsi/qla2xxx/qla_nx.c
+++ b/drivers/scsi/qla2xxx/qla_nx.c
@@ -1165,19 +1165,6 @@ qla82xx_pinit_from_rom(scsi_qla_host_t *vha)
qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xfeffffff);
else
qla82xx_wr_32(ha, QLA82XX_ROMUSB_GLB_SW_RESET, 0xffffffff);
-
- /* reset ms */
- val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
- val |= (1 << 1);
- qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
- msleep(20);
-
- /* unreset ms */
- val = qla82xx_rd_32(ha, QLA82XX_CRB_QDR_NET + 0xe4);
- val &= ~(1 << 1);
- qla82xx_wr_32(ha, QLA82XX_CRB_QDR_NET + 0xe4, val);
- msleep(20);
-
qla82xx_rom_unlock(ha);
/* Read the signature value from the flash.
@@ -3392,7 +3379,7 @@ void qla82xx_watchdog(scsi_qla_host_t *vha)
QLA82XX_CRB_PEG_NET_3 + 0x3c),
qla82xx_rd_32(ha,
QLA82XX_CRB_PEG_NET_4 + 0x3c));
- if (LSW(MSB(halt_status)) == 0x67)
+ if (((halt_status & 0x1fffff00) >> 8) == 0x67)
ql_log(ql_log_warn, vha, 0xb052,
"Firmware aborted with "
"error code 0x00006700. Device is "
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 4ed1e4a96b9..036030c9533 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -625,6 +625,12 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
cmd->result = DID_NO_CONNECT << 16;
goto qc24_fail_command;
}
+
+ if (!fcport) {
+ cmd->result = DID_NO_CONNECT << 16;
+ goto qc24_fail_command;
+ }
+
if (atomic_read(&fcport->state) != FCS_ONLINE) {
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
atomic_read(&base_vha->loop_state) == LOOP_DEAD) {
@@ -877,6 +883,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (ha->isp_ops->abort_command(sp)) {
+ ret = FAILED;
ql_dbg(ql_dbg_taskm, vha, 0x8003,
"Abort command mbx failed cmd=%p.\n", cmd);
} else {
@@ -1124,7 +1131,6 @@ static int
qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
{
scsi_qla_host_t *vha = shost_priv(cmd->device->host);
- fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
struct qla_hw_data *ha = vha->hw;
int ret = FAILED;
unsigned int id, lun;
@@ -1133,15 +1139,6 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
id = cmd->device->id;
lun = cmd->device->lun;
- if (!fcport) {
- return ret;
- }
-
- ret = fc_block_scsi_eh(cmd);
- if (ret != 0)
- return ret;
- ret = FAILED;
-
ql_log(ql_log_info, vha, 0x8018,
"ADAPTER RESET ISSUED nexus=%ld:%d:%d.\n", vha->host_no, id, lun);
@@ -2047,7 +2044,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ha->nvram_data_off = ~0;
ha->isp_ops = &qla2100_isp_ops;
} else if (IS_QLA2200(ha)) {
- ha->mbx_count = MAILBOX_REGISTER_COUNT;
+ ha->mbx_count = MAILBOX_REGISTER_COUNT_2200;
req_length = REQUEST_ENTRY_CNT_2200;
rsp_length = RESPONSE_ENTRY_CNT_2100;
ha->max_loop_id = SNS_LAST_LOOP_ID_2100;
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h
index 23f33a6d52d..29d780c3804 100644
--- a/drivers/scsi/qla2xxx/qla_version.h
+++ b/drivers/scsi/qla2xxx/qla_version.h
@@ -7,7 +7,7 @@
/*
* Driver version
*/
-#define QLA2XXX_VERSION "8.03.07.12-k"
+#define QLA2XXX_VERSION "8.03.07.13-k"
#define QLA_DRIVER_MAJOR_VER 8
#define QLA_DRIVER_MINOR_VER 3
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 78f1111158d..65253dfbe96 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -10,6 +10,8 @@
#include "ql4_def.h"
#include "ql4_glbl.h"
+#include <asm-generic/io-64-nonatomic-lo-hi.h>
+
#define MASK(n) DMA_BIT_MASK(n)
#define MN_WIN(addr) (((addr & 0x1fc0000) >> 1) | ((addr >> 25) & 0x3ff))
#define OCM_WIN(addr) (((addr & 0x1ff0000) >> 1) | ((addr >> 25) & 0x3ff))
@@ -655,27 +657,6 @@ static int qla4_8xxx_pci_is_same_window(struct scsi_qla_host *ha,
return 0;
}
-#ifndef readq
-static inline __u64 readq(const volatile void __iomem *addr)
-{
- const volatile u32 __iomem *p = addr;
- u32 low, high;
-
- low = readl(p);
- high = readl(p + 1);
-
- return low + ((u64)high << 32);
-}
-#endif
-
-#ifndef writeq
-static inline void writeq(__u64 val, volatile void __iomem *addr)
-{
- writel(val, addr);
- writel(val >> 32, addr+4);
-}
-#endif
-
static int qla4_8xxx_pci_mem_read_direct(struct scsi_qla_host *ha,
u64 off, void *data, int size)
{
diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c
index bf8bf79e6a1..c4670642d02 100644
--- a/drivers/scsi/scsi_pm.c
+++ b/drivers/scsi/scsi_pm.c
@@ -7,6 +7,7 @@
#include <linux/pm_runtime.h>
#include <linux/export.h>
+#include <linux/async.h>
#include <scsi/scsi.h>
#include <scsi/scsi_device.h>
@@ -92,6 +93,19 @@ static int scsi_bus_resume_common(struct device *dev)
return err;
}
+static int scsi_bus_prepare(struct device *dev)
+{
+ if (scsi_is_sdev_device(dev)) {
+ /* sd probing uses async_schedule. Wait until it finishes. */
+ async_synchronize_full();
+
+ } else if (scsi_is_host_device(dev)) {
+ /* Wait until async scanning is finished */
+ scsi_complete_async_scans();
+ }
+ return 0;
+}
+
static int scsi_bus_suspend(struct device *dev)
{
return scsi_bus_suspend_common(dev, PMSG_SUSPEND);
@@ -110,6 +124,7 @@ static int scsi_bus_poweroff(struct device *dev)
#else /* CONFIG_PM_SLEEP */
#define scsi_bus_resume_common NULL
+#define scsi_bus_prepare NULL
#define scsi_bus_suspend NULL
#define scsi_bus_freeze NULL
#define scsi_bus_poweroff NULL
@@ -218,6 +233,7 @@ void scsi_autopm_put_host(struct Scsi_Host *shost)
#endif /* CONFIG_PM_RUNTIME */
const struct dev_pm_ops scsi_bus_pm_ops = {
+ .prepare = scsi_bus_prepare,
.suspend = scsi_bus_suspend,
.resume = scsi_bus_resume_common,
.freeze = scsi_bus_freeze,
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 68eadd1c67f..be4fa6d179b 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -109,6 +109,7 @@ extern void scsi_exit_procfs(void);
#endif /* CONFIG_PROC_FS */
/* scsi_scan.c */
+extern int scsi_complete_async_scans(void);
extern int scsi_scan_host_selected(struct Scsi_Host *, unsigned int,
unsigned int, unsigned int, int);
extern void scsi_forget_host(struct Scsi_Host *);
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 89da43f73c0..29c4c048097 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -1815,6 +1815,7 @@ static void scsi_finish_async_scan(struct async_scan_data *data)
}
spin_unlock(&async_scan_lock);
+ scsi_autopm_put_host(shost);
scsi_host_put(shost);
kfree(data);
}
@@ -1841,7 +1842,6 @@ static int do_scan_async(void *_data)
do_scsi_scan_host(shost);
scsi_finish_async_scan(data);
- scsi_autopm_put_host(shost);
return 0;
}
@@ -1869,7 +1869,7 @@ void scsi_scan_host(struct Scsi_Host *shost)
p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
if (IS_ERR(p))
do_scan_async(data);
- /* scsi_autopm_put_host(shost) is called in do_scan_async() */
+ /* scsi_autopm_put_host(shost) is called in scsi_finish_async_scan() */
}
EXPORT_SYMBOL(scsi_scan_host);
diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c
index 45fee368b09..92d314a73f6 100644
--- a/drivers/sh/clk/cpg.c
+++ b/drivers/sh/clk/cpg.c
@@ -190,7 +190,7 @@ static int __init sh_clk_init_parent(struct clk *clk)
return -EINVAL;
}
- clk->parent = clk->parent_table[val];
+ clk_reparent(clk, clk->parent_table[val]);
if (!clk->parent) {
pr_err("sh_clk_init_parent: unable to set parent");
return -EINVAL;
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 0b7fed746b2..e7feceeebc2 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -1508,7 +1508,7 @@ static int serial_imx_probe(struct platform_device *pdev)
ret = PTR_ERR(sport->clk);
goto unmap;
}
- clk_enable(sport->clk);
+ clk_prepare_enable(sport->clk);
sport->port.uartclk = clk_get_rate(sport->clk);
@@ -1531,8 +1531,8 @@ deinit:
if (pdata && pdata->exit)
pdata->exit(pdev);
clkput:
+ clk_disable_unprepare(sport->clk);
clk_put(sport->clk);
- clk_disable(sport->clk);
unmap:
iounmap(sport->port.membase);
free:
@@ -1552,11 +1552,10 @@ static int serial_imx_remove(struct platform_device *pdev)
if (sport) {
uart_remove_one_port(&imx_reg, &sport->port);
+ clk_disable_unprepare(sport->clk);
clk_put(sport->clk);
}
- clk_disable(sport->clk);
-
if (pdata && pdata->exit)
pdata->exit(pdev);
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index d136b8f4c8a..81e2c0d9c17 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -187,7 +187,10 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV;
dev->current_state = PCI_D0;
- if (!dev->irq) {
+ /* The xHCI driver supports MSI and MSI-X,
+ * so don't fail if the BIOS doesn't provide a legacy IRQ.
+ */
+ if (!dev->irq && (driver->flags & HCD_MASK) != HCD_USB3) {
dev_err(&dev->dev,
"Found HC with no IRQ. Check BIOS/PCI %s setup!\n",
pci_name(dev));
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index eb19cba34ac..e1282328fc2 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -2447,8 +2447,10 @@ int usb_add_hcd(struct usb_hcd *hcd,
&& device_can_wakeup(&hcd->self.root_hub->dev))
dev_dbg(hcd->self.controller, "supports USB remote wakeup\n");
- /* enable irqs just before we start the controller */
- if (usb_hcd_is_primary_hcd(hcd)) {
+ /* enable irqs just before we start the controller,
+ * if the BIOS provides legacy PCI irqs.
+ */
+ if (usb_hcd_is_primary_hcd(hcd) && irqnum) {
retval = usb_hcd_request_irqs(hcd, irqnum, irqflags);
if (retval)
goto err_request_irq;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index a0613d8f9be..265c2f675d0 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -705,10 +705,26 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type)
if (type == HUB_INIT3)
goto init3;
- /* After a resume, port power should still be on.
+ /* The superspeed hub except for root hub has to use Hub Depth
+ * value as an offset into the route string to locate the bits
+ * it uses to determine the downstream port number. So hub driver
+ * should send a set hub depth request to superspeed hub after
+ * the superspeed hub is set configuration in initialization or
+ * reset procedure.
+ *
+ * After a resume, port power should still be on.
* For any other type of activation, turn it on.
*/
if (type != HUB_RESUME) {
+ if (hdev->parent && hub_is_superspeed(hdev)) {
+ ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
+ HUB_SET_DEPTH, USB_RT_HUB,
+ hdev->level - 1, 0, NULL, 0,
+ USB_CTRL_SET_TIMEOUT);
+ if (ret < 0)
+ dev_err(hub->intfdev,
+ "set hub depth failed\n");
+ }
/* Speed up system boot by using a delayed_work for the
* hub's initial power-up delays. This is pretty awkward
@@ -987,18 +1003,6 @@ static int hub_configure(struct usb_hub *hub,
goto fail;
}
- if (hub_is_superspeed(hdev) && (hdev->parent != NULL)) {
- ret = usb_control_msg(hdev, usb_sndctrlpipe(hdev, 0),
- HUB_SET_DEPTH, USB_RT_HUB,
- hdev->level - 1, 0, NULL, 0,
- USB_CTRL_SET_TIMEOUT);
-
- if (ret < 0) {
- message = "can't set hub depth";
- goto fail;
- }
- }
-
/* Request the entire hub descriptor.
* hub->descriptor can handle USB_MAXCHILDREN ports,
* but the hub can/will return fewer bytes here.
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index 7ecb68a6741..85ae4b46bb6 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -137,7 +137,7 @@ choice
config USB_AT91
tristate "Atmel AT91 USB Device Port"
- depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91CAP9 && !ARCH_AT91SAM9G45
+ depends on ARCH_AT91 && !ARCH_AT91SAM9RL && !ARCH_AT91SAM9G45
help
Many Atmel AT91 processors (such as the AT91RM2000) have a
full speed USB Device Port with support for five configurable
@@ -150,7 +150,7 @@ config USB_AT91
config USB_ATMEL_USBA
tristate "Atmel USBA"
select USB_GADGET_DUALSPEED
- depends on AVR32 || ARCH_AT91CAP9 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
+ depends on AVR32 || ARCH_AT91SAM9RL || ARCH_AT91SAM9G45
help
USBA is the integrated high-speed USB Device controller on
the AT32AP700x, some AT91SAM9 and AT91CAP9 processors from Atmel.
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index ac53a662a6a..7732d69e49e 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -872,7 +872,17 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
*/
if (pdev->vendor == 0x184e) /* vendor Netlogic */
return;
+ if (pdev->class != PCI_CLASS_SERIAL_USB_UHCI &&
+ pdev->class != PCI_CLASS_SERIAL_USB_OHCI &&
+ pdev->class != PCI_CLASS_SERIAL_USB_EHCI &&
+ pdev->class != PCI_CLASS_SERIAL_USB_XHCI)
+ return;
+ if (pci_enable_device(pdev) < 0) {
+ dev_warn(&pdev->dev, "Can't enable PCI device, "
+ "BIOS handoff failed.\n");
+ return;
+ }
if (pdev->class == PCI_CLASS_SERIAL_USB_UHCI)
quirk_usb_handoff_uhci(pdev);
else if (pdev->class == PCI_CLASS_SERIAL_USB_OHCI)
@@ -881,5 +891,6 @@ static void __devinit quirk_usb_early_handoff(struct pci_dev *pdev)
quirk_usb_disable_ehci(pdev);
else if (pdev->class == PCI_CLASS_SERIAL_USB_XHCI)
quirk_usb_handoff_xhci(pdev);
+ pci_disable_device(pdev);
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_usb_early_handoff);
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index 35e257f79c7..557b6f32db8 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -93,7 +93,7 @@ static void xhci_usb2_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
*/
memset(port_removable, 0, sizeof(port_removable));
for (i = 0; i < ports; i++) {
- portsc = xhci_readl(xhci, xhci->usb3_ports[i]);
+ portsc = xhci_readl(xhci, xhci->usb2_ports[i]);
/* If a device is removable, PORTSC reports a 0, same as in the
* hub descriptor DeviceRemovable bits.
*/
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 36cbe2226a4..383fc857491 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1126,26 +1126,42 @@ static unsigned int xhci_parse_exponent_interval(struct usb_device *udev,
}
/*
- * Convert bInterval expressed in frames (in 1-255 range) to exponent of
+ * Convert bInterval expressed in microframes (in 1-255 range) to exponent of
* microframes, rounded down to nearest power of 2.
*/
-static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
- struct usb_host_endpoint *ep)
+static unsigned int xhci_microframes_to_exponent(struct usb_device *udev,
+ struct usb_host_endpoint *ep, unsigned int desc_interval,
+ unsigned int min_exponent, unsigned int max_exponent)
{
unsigned int interval;
- interval = fls(8 * ep->desc.bInterval) - 1;
- interval = clamp_val(interval, 3, 10);
- if ((1 << interval) != 8 * ep->desc.bInterval)
+ interval = fls(desc_interval) - 1;
+ interval = clamp_val(interval, min_exponent, max_exponent);
+ if ((1 << interval) != desc_interval)
dev_warn(&udev->dev,
"ep %#x - rounding interval to %d microframes, ep desc says %d microframes\n",
ep->desc.bEndpointAddress,
1 << interval,
- 8 * ep->desc.bInterval);
+ desc_interval);
return interval;
}
+static unsigned int xhci_parse_microframe_interval(struct usb_device *udev,
+ struct usb_host_endpoint *ep)
+{
+ return xhci_microframes_to_exponent(udev, ep,
+ ep->desc.bInterval, 0, 15);
+}
+
+
+static unsigned int xhci_parse_frame_interval(struct usb_device *udev,
+ struct usb_host_endpoint *ep)
+{
+ return xhci_microframes_to_exponent(udev, ep,
+ ep->desc.bInterval * 8, 3, 10);
+}
+
/* Return the polling or NAK interval.
*
* The polling interval is expressed in "microframes". If xHCI's Interval field
@@ -1164,7 +1180,7 @@ static unsigned int xhci_get_endpoint_interval(struct usb_device *udev,
/* Max NAK rate */
if (usb_endpoint_xfer_control(&ep->desc) ||
usb_endpoint_xfer_bulk(&ep->desc)) {
- interval = ep->desc.bInterval;
+ interval = xhci_parse_microframe_interval(udev, ep);
break;
}
/* Fall through - SS and HS isoc/int have same decoding */
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 6bbe3c3a711..c939f5fdef9 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -352,6 +352,11 @@ static int xhci_try_enable_msi(struct usb_hcd *hcd)
/* hcd->irq is -1, we have MSI */
return 0;
+ if (!pdev->irq) {
+ xhci_err(xhci, "No msi-x/msi found and no IRQ in BIOS\n");
+ return -EINVAL;
+ }
+
/* fall back to legacy interrupt*/
ret = request_irq(pdev->irq, &usb_hcd_irq, IRQF_SHARED,
hcd->irq_descr, hcd);
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 8dbf51a43c4..08a5575724c 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -136,6 +136,8 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x16DC, 0x0011) }, /* W-IE-NE-R Plein & Baus GmbH RCM Remote Control for MARATON Power Supply */
{ USB_DEVICE(0x16DC, 0x0012) }, /* W-IE-NE-R Plein & Baus GmbH MPOD Multi Channel Power Supply */
{ USB_DEVICE(0x16DC, 0x0015) }, /* W-IE-NE-R Plein & Baus GmbH CML Control, Monitoring and Data Logger */
+ { USB_DEVICE(0x17A8, 0x0001) }, /* Kamstrup Optical Eye/3-wire */
+ { USB_DEVICE(0x17A8, 0x0005) }, /* Kamstrup M-Bus Master MultiPort 250D */
{ USB_DEVICE(0x17F4, 0xAAAA) }, /* Wavesense Jazz blood glucose meter */
{ USB_DEVICE(0x1843, 0x0200) }, /* Vaisala USB Instrument Cable */
{ USB_DEVICE(0x18EF, 0xE00F) }, /* ELV USB-I2C-Interface */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 39ed1f46cec..b54afceb961 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -788,7 +788,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0012, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0013, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0016, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0017, 0xff, 0xff, 0xff),
@@ -803,7 +802,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0024, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0025, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
- /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0026, 0xff, 0xff, 0xff) }, */
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0028, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0029, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0030, 0xff, 0xff, 0xff) },
@@ -828,7 +826,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0051, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0052, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
- /* { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0053, 0xff, 0xff, 0xff) }, */
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0054, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0055, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
@@ -836,7 +833,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0057, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0058, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0061, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0062, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0063, 0xff, 0xff, 0xff),
@@ -846,7 +842,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0066, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0067, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0069, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0076, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0077, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0078, 0xff, 0xff, 0xff) },
@@ -865,8 +860,6 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0095, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0096, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0097, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0098, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0099, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0104, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0105, 0xff, 0xff, 0xff) },
@@ -887,28 +880,18 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0144, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0145, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0146, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0148, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0149, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0150, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0151, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0153, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0155, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0160, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0164, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
@@ -1083,127 +1066,27 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1403, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1404, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1405, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1406, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1407, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1408, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1409, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1410, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1411, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1412, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1413, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1414, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1415, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1416, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1417, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1418, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1419, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1420, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1421, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1422, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1423, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1427, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1428, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1429, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1430, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1431, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1432, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1433, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1434, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1435, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1436, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1437, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1438, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1439, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1440, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1441, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1442, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1443, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1444, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1445, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1446, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1447, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1448, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1449, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1450, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1451, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1452, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1453, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1454, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1455, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1456, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1457, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1458, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1459, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1460, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1461, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1462, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1463, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1464, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1465, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1466, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1467, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1468, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1469, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1470, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1471, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1472, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1473, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1474, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1475, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1476, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1477, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1478, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1479, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1480, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1481, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1482, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1483, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1484, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1485, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1486, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1487, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1488, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1489, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1490, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1491, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1492, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1493, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1494, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1495, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1496, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1497, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1498, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1499, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1500, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1501, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1502, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1503, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1504, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1505, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1506, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1507, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1508, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1509, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1510, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
+ 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0014, 0xff, 0xff, 0xff) }, /* ZTE CDMA products */
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0027, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0059, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0060, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
- 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
- { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) },
+
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC2726, 0xff, 0xff, 0xff) },
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 8468eb769a2..75b838eff17 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -165,7 +165,7 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[14+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -179,6 +179,7 @@ static struct usb_device_id ti_id_table_3410[13+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
+ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
};
static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
@@ -188,7 +189,7 @@ static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_combined[18+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
{ USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
@@ -206,6 +207,7 @@ static struct usb_device_id ti_id_table_combined[17+2*TI_EXTRA_VID_PID_COUNT+1]
{ USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) },
{ USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) },
+ { USB_DEVICE(ABBOTT_VENDOR_ID, ABBOTT_PRODUCT_ID) },
{ }
};
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index 2aac1953993..f140f1b9d5c 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -49,6 +49,10 @@
#define MTS_MT9234ZBA_PRODUCT_ID 0xF115
#define MTS_MT9234ZBAOLD_PRODUCT_ID 0x0319
+/* Abbott Diabetics vendor and product ids */
+#define ABBOTT_VENDOR_ID 0x1a61
+#define ABBOTT_PRODUCT_ID 0x3410
+
/* Commands */
#define TI_GET_VERSION 0x01
#define TI_GET_PORT_STATUS 0x02
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 3dd7da9fd50..db51ba16dc0 100644
--- a/drivers/usb/storage/usb.c
+++ b/drivers/usb/storage/usb.c
@@ -788,15 +788,19 @@ static void quiesce_and_remove_host(struct us_data *us)
struct Scsi_Host *host = us_to_host(us);
/* If the device is really gone, cut short reset delays */
- if (us->pusb_dev->state == USB_STATE_NOTATTACHED)
+ if (us->pusb_dev->state == USB_STATE_NOTATTACHED) {
set_bit(US_FLIDX_DISCONNECTING, &us->dflags);
+ wake_up(&us->delay_wait);
+ }
- /* Prevent SCSI-scanning (if it hasn't started yet)
- * and wait for the SCSI-scanning thread to stop.
+ /* Prevent SCSI scanning (if it hasn't started yet)
+ * or wait for the SCSI-scanning routine to stop.
*/
- set_bit(US_FLIDX_DONT_SCAN, &us->dflags);
- wake_up(&us->delay_wait);
- wait_for_completion(&us->scanning_done);
+ cancel_delayed_work_sync(&us->scan_dwork);
+
+ /* Balance autopm calls if scanning was cancelled */
+ if (test_bit(US_FLIDX_SCAN_PENDING, &us->dflags))
+ usb_autopm_put_interface_no_suspend(us->pusb_intf);
/* Removing the host will perform an orderly shutdown: caches
* synchronized, disks spun down, etc.
@@ -823,53 +827,28 @@ static void release_everything(struct us_data *us)
scsi_host_put(us_to_host(us));
}
-/* Thread to carry out delayed SCSI-device scanning */
-static int usb_stor_scan_thread(void * __us)
+/* Delayed-work routine to carry out SCSI-device scanning */
+static void usb_stor_scan_dwork(struct work_struct *work)
{
- struct us_data *us = (struct us_data *)__us;
+ struct us_data *us = container_of(work, struct us_data,
+ scan_dwork.work);
struct device *dev = &us->pusb_intf->dev;
- dev_dbg(dev, "device found\n");
-
- set_freezable();
+ dev_dbg(dev, "starting scan\n");
- /*
- * Wait for the timeout to expire or for a disconnect
- *
- * We can't freeze in this thread or we risk causing khubd to
- * fail to freeze, but we can't be non-freezable either. Nor can
- * khubd freeze while waiting for scanning to complete as it may
- * hold the device lock, causing a hang when suspending devices.
- * So instead of using wait_event_freezable(), explicitly test
- * for (DONT_SCAN || freezing) in interruptible wait and proceed
- * if any of DONT_SCAN, freezing or timeout has happened.
- */
- if (delay_use > 0) {
- dev_dbg(dev, "waiting for device to settle "
- "before scanning\n");
- wait_event_interruptible_timeout(us->delay_wait,
- test_bit(US_FLIDX_DONT_SCAN, &us->dflags) ||
- freezing(current), delay_use * HZ);
+ /* For bulk-only devices, determine the max LUN value */
+ if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) {
+ mutex_lock(&us->dev_mutex);
+ us->max_lun = usb_stor_Bulk_max_lun(us);
+ mutex_unlock(&us->dev_mutex);
}
+ scsi_scan_host(us_to_host(us));
+ dev_dbg(dev, "scan complete\n");
- /* If the device is still connected, perform the scanning */
- if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) {
-
- /* For bulk-only devices, determine the max LUN value */
- if (us->protocol == USB_PR_BULK &&
- !(us->fflags & US_FL_SINGLE_LUN)) {
- mutex_lock(&us->dev_mutex);
- us->max_lun = usb_stor_Bulk_max_lun(us);
- mutex_unlock(&us->dev_mutex);
- }
- scsi_scan_host(us_to_host(us));
- dev_dbg(dev, "scan complete\n");
-
- /* Should we unbind if no devices were detected? */
- }
+ /* Should we unbind if no devices were detected? */
usb_autopm_put_interface(us->pusb_intf);
- complete_and_exit(&us->scanning_done, 0);
+ clear_bit(US_FLIDX_SCAN_PENDING, &us->dflags);
}
static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf)
@@ -916,7 +895,7 @@ int usb_stor_probe1(struct us_data **pus,
init_completion(&us->cmnd_ready);
init_completion(&(us->notify));
init_waitqueue_head(&us->delay_wait);
- init_completion(&us->scanning_done);
+ INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork);
/* Associate the us_data structure with the USB device */
result = associate_dev(us, intf);
@@ -947,7 +926,6 @@ EXPORT_SYMBOL_GPL(usb_stor_probe1);
/* Second part of general USB mass-storage probing */
int usb_stor_probe2(struct us_data *us)
{
- struct task_struct *th;
int result;
struct device *dev = &us->pusb_intf->dev;
@@ -988,20 +966,14 @@ int usb_stor_probe2(struct us_data *us)
goto BadDevice;
}
- /* Start up the thread for delayed SCSI-device scanning */
- th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan");
- if (IS_ERR(th)) {
- dev_warn(dev,
- "Unable to start the device-scanning thread\n");
- complete(&us->scanning_done);
- quiesce_and_remove_host(us);
- result = PTR_ERR(th);
- goto BadDevice;
- }
-
+ /* Submit the delayed_work for SCSI-device scanning */
usb_autopm_get_interface_no_resume(us->pusb_intf);
- wake_up_process(th);
+ set_bit(US_FLIDX_SCAN_PENDING, &us->dflags);
+ if (delay_use > 0)
+ dev_dbg(dev, "waiting for device to settle before scanning\n");
+ queue_delayed_work(system_freezable_wq, &us->scan_dwork,
+ delay_use * HZ);
return 0;
/* We come here if there are any problems */
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
index 7b0f2113632..75f70f04f37 100644
--- a/drivers/usb/storage/usb.h
+++ b/drivers/usb/storage/usb.h
@@ -47,6 +47,7 @@
#include <linux/blkdev.h>
#include <linux/completion.h>
#include <linux/mutex.h>
+#include <linux/workqueue.h>
#include <scsi/scsi_host.h>
struct us_data;
@@ -72,7 +73,7 @@ struct us_unusual_dev {
#define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */
#define US_FLIDX_RESETTING 4 /* device reset in progress */
#define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */
-#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */
+#define US_FLIDX_SCAN_PENDING 6 /* scanning not yet done */
#define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */
#define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */
@@ -147,8 +148,8 @@ struct us_data {
/* mutual exclusion and synchronization structures */
struct completion cmnd_ready; /* to sleep thread on */
struct completion notify; /* thread begin/end */
- wait_queue_head_t delay_wait; /* wait during scan, reset */
- struct completion scanning_done; /* wait for scan thread */
+ wait_queue_head_t delay_wait; /* wait during reset */
+ struct delayed_work scan_dwork; /* for async scanning */
/* subdriver information */
void *extra; /* Any extra data */
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 74d29b55290..408a9927be9 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -12,7 +12,7 @@ config PANEL_GENERIC_DPI
config PANEL_DVI
tristate "DVI output"
- depends on OMAP2_DSS_DPI
+ depends on OMAP2_DSS_DPI && I2C
help
Driver for external monitors, connected via DVI. The driver uses i2c
to read EDID information from the monitor.
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 052dc874cd3..87b3e25294c 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1276,6 +1276,9 @@ int dss_ovl_enable(struct omap_overlay *ovl)
spin_unlock_irqrestore(&data_lock, flags);
+ /* wait for overlay to be enabled */
+ wait_pending_extra_info_updates();
+
mutex_unlock(&apply_lock);
return 0;
@@ -1313,6 +1316,9 @@ int dss_ovl_disable(struct omap_overlay *ovl)
spin_unlock_irqrestore(&data_lock, flags);
+ /* wait for the overlay to be disabled */
+ wait_pending_extra_info_updates();
+
mutex_unlock(&apply_lock);
return 0;
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index d7aa3b05652..a36b934b2db 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -165,9 +165,25 @@ static int hdmi_runtime_get(void)
DSSDBG("hdmi_runtime_get\n");
+ /*
+ * HACK: Add dss_runtime_get() to ensure DSS clock domain is enabled.
+ * This should be removed later.
+ */
+ r = dss_runtime_get();
+ if (r < 0)
+ goto err_get_dss;
+
r = pm_runtime_get_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
- return r < 0 ? r : 0;
+ if (r < 0)
+ goto err_get_hdmi;
+
+ return 0;
+
+err_get_hdmi:
+ dss_runtime_put();
+err_get_dss:
+ return r;
}
static void hdmi_runtime_put(void)
@@ -178,6 +194,12 @@ static void hdmi_runtime_put(void)
r = pm_runtime_put_sync(&hdmi.pdev->dev);
WARN_ON(r < 0);
+
+ /*
+ * HACK: This is added to complement the dss_runtime_get() call in
+ * hdmi_runtime_get(). This should be removed later.
+ */
+ dss_runtime_put();
}
int hdmi_init_display(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index 2d72334ca3d..6847a478b45 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -479,14 +479,7 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
{
- int r;
-
- void __iomem *base = hdmi_core_sys_base(ip_data);
-
- /* HPD */
- r = REG_GET(base, HDMI_CORE_SYS_SYS_STAT, 1, 1);
-
- return r == 1;
+ return gpio_get_value(ip_data->hpd_gpio);
}
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index f9975100d56..3a3fdc62c75 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -1061,7 +1061,7 @@ static struct pvr2_board {
int (*init)(void);
void (*exit)(void);
char name[16];
-} board_driver[] = {
+} board_driver[] __refdata = {
#ifdef CONFIG_SH_DREAMCAST
{ pvr2fb_dc_init, pvr2fb_dc_exit, "Sega DC PVR2" },
#endif
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index d5aaca9cfa7..8497727d66d 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -1810,7 +1810,11 @@ static void hw_init(void)
break;
}
+ /* magic required on VX900 for correct modesetting on IGA1 */
+ via_write_reg_mask(VIACR, 0x45, 0x00, 0x01);
+
/* probably this should go to the scaling code one day */
+ via_write_reg_mask(VIACR, 0xFD, 0, 0x80); /* VX900 hw scale on IGA2 */
viafb_write_regx(scaling_parameters, ARRAY_SIZE(scaling_parameters));
/* Fill VPIT Parameters */
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 95aeedf198f..958e5129c60 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -367,29 +367,45 @@ static void __devexit virtballoon_remove(struct virtio_device *vdev)
#ifdef CONFIG_PM
static int virtballoon_freeze(struct virtio_device *vdev)
{
+ struct virtio_balloon *vb = vdev->priv;
+
/*
* The kthread is already frozen by the PM core before this
* function is called.
*/
+ while (vb->num_pages)
+ leak_balloon(vb, vb->num_pages);
+ update_balloon_size(vb);
+
/* Ensure we don't get any more requests from the host */
vdev->config->reset(vdev);
vdev->config->del_vqs(vdev);
return 0;
}
+static int restore_common(struct virtio_device *vdev)
+{
+ struct virtio_balloon *vb = vdev->priv;
+ int ret;
+
+ ret = init_vqs(vdev->priv);
+ if (ret)
+ return ret;
+
+ fill_balloon(vb, towards_target(vb));
+ update_balloon_size(vb);
+ return 0;
+}
+
static int virtballoon_thaw(struct virtio_device *vdev)
{
- return init_vqs(vdev->priv);
+ return restore_common(vdev);
}
static int virtballoon_restore(struct virtio_device *vdev)
{
struct virtio_balloon *vb = vdev->priv;
- struct page *page, *page2;
-
- /* We're starting from a clean slate */
- vb->num_pages = 0;
/*
* If a request wasn't complete at the time of freezing, this
@@ -397,12 +413,7 @@ static int virtballoon_restore(struct virtio_device *vdev)
*/
vb->need_stats_update = 0;
- /* We don't have these pages in the balloon anymore! */
- list_for_each_entry_safe(page, page2, &vb->pages, lru) {
- list_del(&page->lru);
- totalram_pages++;
- }
- return init_vqs(vdev->priv);
+ return restore_common(vdev);
}
#endif
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index 877b107f77a..df9e8f0e327 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1098,7 +1098,7 @@ config BOOKE_WDT_DEFAULT_TIMEOUT
For Freescale Book-E processors, this is a number between 0 and 63.
For other Book-E processors, this is a number between 0 and 3.
- The value can be overidden by the wdt_period command-line parameter.
+ The value can be overridden by the wdt_period command-line parameter.
# PPC64 Architecture
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c
index 337265b4730..7c0fdfca264 100644
--- a/drivers/watchdog/booke_wdt.c
+++ b/drivers/watchdog/booke_wdt.c
@@ -198,9 +198,13 @@ static long booke_wdt_ioctl(struct file *file,
booke_wdt_period = tmp;
#endif
booke_wdt_set();
- return 0;
+ /* Fall */
case WDIOC_GETTIMEOUT:
+#ifdef CONFIG_FSL_BOOKE
+ return put_user(period_to_sec(booke_wdt_period), p);
+#else
return put_user(booke_wdt_period, p);
+#endif
default:
return -ENOTTY;
}
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 8464ea1c36a..3c166d3f4e5 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -231,7 +231,7 @@ static int __devinit cru_detect(unsigned long map_entry,
cmn_regs.u1.reax = CRU_BIOS_SIGNATURE_VALUE;
- set_memory_x((unsigned long)bios32_entrypoint, (2 * PAGE_SIZE));
+ set_memory_x((unsigned long)bios32_map, 2);
asminline_call(&cmn_regs, bios32_entrypoint);
if (cmn_regs.u1.ral != 0) {
@@ -250,7 +250,8 @@ static int __devinit cru_detect(unsigned long map_entry,
cru_rom_addr =
ioremap(cru_physical_address, cru_length);
if (cru_rom_addr) {
- set_memory_x((unsigned long)cru_rom_addr, cru_length);
+ set_memory_x((unsigned long)cru_rom_addr & PAGE_MASK,
+ (cru_length + PAGE_SIZE - 1) >> PAGE_SHIFT);
retval = 0;
}
}
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c
index 8e210aafdfd..dfae030a7ef 100644
--- a/drivers/watchdog/pnx4008_wdt.c
+++ b/drivers/watchdog/pnx4008_wdt.c
@@ -264,7 +264,7 @@ static int __devinit pnx4008_wdt_probe(struct platform_device *pdev)
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");
+ "failed to get memory region resource\n");
return -ENOENT;
}
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c
index 4bc3744e14e..404172f02c9 100644
--- a/drivers/watchdog/s3c2410_wdt.c
+++ b/drivers/watchdog/s3c2410_wdt.c
@@ -312,18 +312,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
dev = &pdev->dev;
wdt_dev = &pdev->dev;
- /* get the memory region for the watchdog timer */
-
wdt_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (wdt_mem == NULL) {
dev_err(dev, "no memory resource specified\n");
return -ENOENT;
}
+ wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (wdt_irq == NULL) {
+ dev_err(dev, "no irq resource specified\n");
+ ret = -ENOENT;
+ goto err;
+ }
+
+ /* get the memory region for the watchdog timer */
+
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;
+ ret = -EBUSY;
+ goto err;
}
wdt_base = ioremap(wdt_mem->start, size);
@@ -335,29 +343,17 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
DBG("probe: mapped wdt_base=%p\n", wdt_base);
- wdt_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
- if (wdt_irq == NULL) {
- dev_err(dev, "no irq resource specified\n");
- ret = -ENOENT;
- goto err_map;
- }
-
- ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
- if (ret != 0) {
- dev_err(dev, "failed to install irq (%d)\n", ret);
- goto err_map;
- }
-
wdt_clock = clk_get(&pdev->dev, "watchdog");
if (IS_ERR(wdt_clock)) {
dev_err(dev, "failed to find watchdog clock source\n");
ret = PTR_ERR(wdt_clock);
- goto err_irq;
+ goto err_map;
}
clk_enable(wdt_clock);
- if (s3c2410wdt_cpufreq_register() < 0) {
+ ret = s3c2410wdt_cpufreq_register();
+ if (ret < 0) {
printk(KERN_ERR PFX "failed to register cpufreq\n");
goto err_clk;
}
@@ -378,12 +374,18 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
"cannot start\n");
}
+ ret = request_irq(wdt_irq->start, s3c2410wdt_irq, 0, pdev->name, pdev);
+ if (ret != 0) {
+ dev_err(dev, "failed to install irq (%d)\n", ret);
+ goto err_cpufreq;
+ }
+
watchdog_set_nowayout(&s3c2410_wdd, nowayout);
ret = watchdog_register_device(&s3c2410_wdd);
if (ret) {
dev_err(dev, "cannot register watchdog (%d)\n", ret);
- goto err_cpufreq;
+ goto err_irq;
}
if (tmr_atboot && started == 0) {
@@ -408,23 +410,26 @@ static int __devinit s3c2410wdt_probe(struct platform_device *pdev)
return 0;
+ err_irq:
+ free_irq(wdt_irq->start, pdev);
+
err_cpufreq:
s3c2410wdt_cpufreq_deregister();
err_clk:
clk_disable(wdt_clock);
clk_put(wdt_clock);
-
- err_irq:
- free_irq(wdt_irq->start, pdev);
+ wdt_clock = NULL;
err_map:
iounmap(wdt_base);
err_req:
release_mem_region(wdt_mem->start, size);
- wdt_mem = NULL;
+ err:
+ wdt_irq = NULL;
+ wdt_mem = NULL;
return ret;
}
@@ -432,18 +437,18 @@ static int __devexit s3c2410wdt_remove(struct platform_device *dev)
{
watchdog_unregister_device(&s3c2410_wdd);
+ free_irq(wdt_irq->start, dev);
+
s3c2410wdt_cpufreq_deregister();
clk_disable(wdt_clock);
clk_put(wdt_clock);
wdt_clock = NULL;
- free_irq(wdt_irq->start, dev);
- wdt_irq = NULL;
-
iounmap(wdt_base);
release_mem_region(wdt_mem->start, resource_size(wdt_mem));
+ wdt_irq = NULL;
wdt_mem = NULL;
return 0;
}
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h
index d8d8e7ba6a1..eb1cc92cd67 100644
--- a/fs/autofs4/autofs_i.h
+++ b/fs/autofs4/autofs_i.h
@@ -110,6 +110,7 @@ struct autofs_sb_info {
int sub_version;
int min_proto;
int max_proto;
+ int compat_daemon;
unsigned long exp_timeout;
unsigned int type;
int reghost_enabled;
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c
index 76741d8d778..85f1fcdb30e 100644
--- a/fs/autofs4/dev-ioctl.c
+++ b/fs/autofs4/dev-ioctl.c
@@ -385,6 +385,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
sbi->pipefd = pipefd;
sbi->pipe = pipe;
sbi->catatonic = 0;
+ sbi->compat_daemon = is_compat_task();
}
out:
mutex_unlock(&sbi->wq_mutex);
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c
index 450f529a4ea..1feb68ecef9 100644
--- a/fs/autofs4/expire.c
+++ b/fs/autofs4/expire.c
@@ -124,6 +124,7 @@ start:
/* Negative dentry - try next */
if (!simple_positive(q)) {
spin_unlock(&p->d_lock);
+ lock_set_subclass(&q->d_lock.dep_map, 0, _RET_IP_);
p = q;
goto again;
}
@@ -186,6 +187,7 @@ again:
/* Negative dentry - try next */
if (!simple_positive(ret)) {
spin_unlock(&p->d_lock);
+ lock_set_subclass(&ret->d_lock.dep_map, 0, _RET_IP_);
p = ret;
goto again;
}
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c
index e16980b00b8..06858d95512 100644
--- a/fs/autofs4/inode.c
+++ b/fs/autofs4/inode.c
@@ -19,6 +19,7 @@
#include <linux/parser.h>
#include <linux/bitops.h>
#include <linux/magic.h>
+#include <linux/compat.h>
#include "autofs_i.h"
#include <linux/module.h>
@@ -224,6 +225,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent)
set_autofs_type_indirect(&sbi->type);
sbi->min_proto = 0;
sbi->max_proto = 0;
+ sbi->compat_daemon = is_compat_task();
mutex_init(&sbi->wq_mutex);
mutex_init(&sbi->pipe_mutex);
spin_lock_init(&sbi->fs_lock);
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index da8876d38a7..9c098db4334 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -91,7 +91,24 @@ static int autofs4_write(struct autofs_sb_info *sbi,
return (bytes > 0);
}
-
+
+/*
+ * The autofs_v5 packet was misdesigned.
+ *
+ * The packets are identical on x86-32 and x86-64, but have different
+ * alignment. Which means that 'sizeof()' will give different results.
+ * Fix it up for the case of running 32-bit user mode on a 64-bit kernel.
+ */
+static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi)
+{
+ size_t pktsz = sizeof(struct autofs_v5_packet);
+#if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT)
+ if (sbi->compat_daemon > 0)
+ pktsz -= 4;
+#endif
+ return pktsz;
+}
+
static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
struct autofs_wait_queue *wq,
int type)
@@ -155,8 +172,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
{
struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet;
- pktsz = sizeof(*packet);
-
+ pktsz = autofs_v5_packet_size(sbi);
packet->wait_queue_token = wq->wait_queue_token;
packet->len = wq->name.len;
memcpy(packet->name, wq->name.name, wq->name.len);
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index bcb884e2d61..07d096c4992 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1421,7 +1421,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t,
for (i = 1; i < view->n; ++i) {
const struct user_regset *regset = &view->regsets[i];
do_thread_regset_writeback(t->task, regset);
- if (regset->core_note_type &&
+ if (regset->core_note_type && regset->get &&
(!regset->active || regset->active(t->task, regset))) {
int ret;
size_t size = regset->n * regset->size;
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index 633c701a287..98f6bf10bbd 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -892,6 +892,8 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
if (eb != eb_in)
free_extent_buffer(eb);
ret = inode_ref_info(parent, 0, fs_root, path, &found_key);
+ if (ret > 0)
+ ret = -ENOENT;
if (ret)
break;
next_inum = found_key.offset;
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index b669a7d8e49..d986824bb2b 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -644,7 +644,7 @@ static struct btrfsic_dev_state *btrfsic_dev_state_hashtable_lookup(
static int btrfsic_process_superblock(struct btrfsic_state *state,
struct btrfs_fs_devices *fs_devices)
{
- int ret;
+ int ret = 0;
struct btrfs_super_block *selected_super;
struct list_head *dev_head = &fs_devices->devices;
struct btrfs_device *device;
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 14f1c5a0b2d..d02c27cd14c 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -588,6 +588,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
page_offset(bio->bi_io_vec->bv_page),
PAGE_CACHE_SIZE);
read_unlock(&em_tree->lock);
+ if (!em)
+ return -EIO;
compressed_len = em->block_len;
cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 27ebe61d3cc..80b6486fd5e 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -886,7 +886,7 @@ struct btrfs_block_rsv {
u64 reserved;
struct btrfs_space_info *space_info;
spinlock_t lock;
- unsigned int full:1;
+ unsigned int full;
};
/*
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 811d9f918b1..534266fe505 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2260,6 +2260,12 @@ int open_ctree(struct super_block *sb,
goto fail_sb_buffer;
}
+ if (sectorsize < PAGE_SIZE) {
+ printk(KERN_WARNING "btrfs: Incompatible sector size "
+ "found on %s\n", sb->s_id);
+ goto fail_sb_buffer;
+ }
+
mutex_lock(&fs_info->chunk_mutex);
ret = btrfs_read_sys_array(tree_root);
mutex_unlock(&fs_info->chunk_mutex);
@@ -2301,6 +2307,12 @@ int open_ctree(struct super_block *sb,
btrfs_close_extra_devices(fs_devices);
+ if (!fs_devices->latest_bdev) {
+ printk(KERN_CRIT "btrfs: failed to read devices on %s\n",
+ sb->s_id);
+ goto fail_tree_roots;
+ }
+
retry_root_backup:
blocksize = btrfs_level_size(tree_root,
btrfs_super_root_level(disk_super));
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 283af7a676a..37e0a800d34 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3312,7 +3312,8 @@ commit_trans:
}
data_sinfo->bytes_may_use += bytes;
trace_btrfs_space_reservation(root->fs_info, "space_info",
- (u64)data_sinfo, bytes, 1);
+ (u64)(unsigned long)data_sinfo,
+ bytes, 1);
spin_unlock(&data_sinfo->lock);
return 0;
@@ -3333,7 +3334,8 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes)
spin_lock(&data_sinfo->lock);
data_sinfo->bytes_may_use -= bytes;
trace_btrfs_space_reservation(root->fs_info, "space_info",
- (u64)data_sinfo, bytes, 0);
+ (u64)(unsigned long)data_sinfo,
+ bytes, 0);
spin_unlock(&data_sinfo->lock);
}
@@ -3611,12 +3613,15 @@ static int may_commit_transaction(struct btrfs_root *root,
if (space_info != delayed_rsv->space_info)
return -ENOSPC;
+ spin_lock(&space_info->lock);
spin_lock(&delayed_rsv->lock);
- if (delayed_rsv->size < bytes) {
+ if (space_info->bytes_pinned + delayed_rsv->size < bytes) {
spin_unlock(&delayed_rsv->lock);
+ spin_unlock(&space_info->lock);
return -ENOSPC;
}
spin_unlock(&delayed_rsv->lock);
+ spin_unlock(&space_info->lock);
commit:
trans = btrfs_join_transaction(root);
@@ -3695,9 +3700,9 @@ again:
if (used + orig_bytes <= space_info->total_bytes) {
space_info->bytes_may_use += orig_bytes;
trace_btrfs_space_reservation(root->fs_info,
- "space_info",
- (u64)space_info,
- orig_bytes, 1);
+ "space_info",
+ (u64)(unsigned long)space_info,
+ orig_bytes, 1);
ret = 0;
} else {
/*
@@ -3766,9 +3771,9 @@ again:
if (used + num_bytes < space_info->total_bytes + avail) {
space_info->bytes_may_use += orig_bytes;
trace_btrfs_space_reservation(root->fs_info,
- "space_info",
- (u64)space_info,
- orig_bytes, 1);
+ "space_info",
+ (u64)(unsigned long)space_info,
+ orig_bytes, 1);
ret = 0;
} else {
wait_ordered = true;
@@ -3913,8 +3918,8 @@ static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
spin_lock(&space_info->lock);
space_info->bytes_may_use -= num_bytes;
trace_btrfs_space_reservation(fs_info, "space_info",
- (u64)space_info,
- num_bytes, 0);
+ (u64)(unsigned long)space_info,
+ num_bytes, 0);
space_info->reservation_progress++;
spin_unlock(&space_info->lock);
}
@@ -4105,7 +4110,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info)
num_bytes += div64_u64(data_used + meta_used, 50);
if (num_bytes * 3 > meta_used)
- num_bytes = div64_u64(meta_used, 3);
+ num_bytes = div64_u64(meta_used, 3) * 2;
return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10);
}
@@ -4132,14 +4137,14 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
block_rsv->reserved += num_bytes;
sinfo->bytes_may_use += num_bytes;
trace_btrfs_space_reservation(fs_info, "space_info",
- (u64)sinfo, num_bytes, 1);
+ (u64)(unsigned long)sinfo, num_bytes, 1);
}
if (block_rsv->reserved >= block_rsv->size) {
num_bytes = block_rsv->reserved - block_rsv->size;
sinfo->bytes_may_use -= num_bytes;
trace_btrfs_space_reservation(fs_info, "space_info",
- (u64)sinfo, num_bytes, 0);
+ (u64)(unsigned long)sinfo, num_bytes, 0);
sinfo->reservation_progress++;
block_rsv->reserved = block_rsv->size;
block_rsv->full = 1;
@@ -4192,7 +4197,8 @@ void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
if (!trans->bytes_reserved)
return;
- trace_btrfs_space_reservation(root->fs_info, "transaction", (u64)trans,
+ trace_btrfs_space_reservation(root->fs_info, "transaction",
+ (u64)(unsigned long)trans,
trans->bytes_reserved, 0);
btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
trans->bytes_reserved = 0;
@@ -4710,9 +4716,9 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
space_info->bytes_reserved += num_bytes;
if (reserve == RESERVE_ALLOC) {
trace_btrfs_space_reservation(cache->fs_info,
- "space_info",
- (u64)space_info,
- num_bytes, 0);
+ "space_info",
+ (u64)(unsigned long)space_info,
+ num_bytes, 0);
space_info->bytes_may_use -= num_bytes;
}
}
@@ -7886,9 +7892,16 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range)
u64 start;
u64 end;
u64 trimmed = 0;
+ u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy);
int ret = 0;
- cache = btrfs_lookup_block_group(fs_info, range->start);
+ /*
+ * try to trim all FS space, our block group may start from non-zero.
+ */
+ if (range->len == total_bytes)
+ cache = btrfs_lookup_first_block_group(fs_info, range->start);
+ else
+ cache = btrfs_lookup_block_group(fs_info, range->start);
while (cache) {
if (cache->key.objectid >= (range->start + range->len)) {
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index fcf77e1ded4..a55fbe6252d 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -513,6 +513,15 @@ hit_next:
WARN_ON(state->end < start);
last_end = state->end;
+ if (state->end < end && !need_resched())
+ next_node = rb_next(&state->rb_node);
+ else
+ next_node = NULL;
+
+ /* the state doesn't have the wanted bits, go ahead */
+ if (!(state->state & bits))
+ goto next;
+
/*
* | ---- desired range ---- |
* | state | or
@@ -565,20 +574,15 @@ hit_next:
goto out;
}
- if (state->end < end && prealloc && !need_resched())
- next_node = rb_next(&state->rb_node);
- else
- next_node = NULL;
-
set |= clear_state_bit(tree, state, &bits, wake);
+next:
if (last_end == (u64)-1)
goto out;
start = last_end + 1;
if (start <= end && next_node) {
state = rb_entry(next_node, struct extent_state,
rb_node);
- if (state->start == start)
- goto hit_next;
+ goto hit_next;
}
goto search_again;
@@ -961,8 +965,6 @@ hit_next:
set_state_bits(tree, state, &bits);
clear_state_bit(tree, state, &clear_bits, 0);
-
- merge_state(tree, state);
if (last_end == (u64)-1)
goto out;
@@ -1007,7 +1009,6 @@ hit_next:
if (state->end <= end) {
set_state_bits(tree, state, &bits);
clear_state_bit(tree, state, &clear_bits, 0);
- merge_state(tree, state);
if (last_end == (u64)-1)
goto out;
start = last_end + 1;
@@ -1068,8 +1069,6 @@ hit_next:
set_state_bits(tree, prealloc, &bits);
clear_state_bit(tree, prealloc, &clear_bits, 0);
-
- merge_state(tree, prealloc);
prealloc = NULL;
goto out;
}
@@ -2154,13 +2153,46 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
"this_mirror=%d, num_copies=%d, in_validation=%d\n", read_mode,
failrec->this_mirror, num_copies, failrec->in_validation);
- tree->ops->submit_bio_hook(inode, read_mode, bio, failrec->this_mirror,
- failrec->bio_flags, 0);
- return 0;
+ ret = tree->ops->submit_bio_hook(inode, read_mode, bio,
+ failrec->this_mirror,
+ failrec->bio_flags, 0);
+ return ret;
}
/* lots and lots of room for performance fixes in the end_bio funcs */
+int end_extent_writepage(struct page *page, int err, u64 start, u64 end)
+{
+ int uptodate = (err == 0);
+ struct extent_io_tree *tree;
+ int ret;
+
+ tree = &BTRFS_I(page->mapping->host)->io_tree;
+
+ if (tree->ops && tree->ops->writepage_end_io_hook) {
+ ret = tree->ops->writepage_end_io_hook(page, start,
+ end, NULL, uptodate);
+ if (ret)
+ uptodate = 0;
+ }
+
+ if (!uptodate && tree->ops &&
+ tree->ops->writepage_io_failed_hook) {
+ ret = tree->ops->writepage_io_failed_hook(NULL, page,
+ start, end, NULL);
+ /* Writeback already completed */
+ if (ret == 0)
+ return 1;
+ }
+
+ if (!uptodate) {
+ clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS);
+ ClearPageUptodate(page);
+ SetPageError(page);
+ }
+ return 0;
+}
+
/*
* after a writepage IO is done, we need to:
* clear the uptodate bits on error
@@ -2172,13 +2204,11 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page,
*/
static void end_bio_extent_writepage(struct bio *bio, int err)
{
- int uptodate = err == 0;
struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
struct extent_io_tree *tree;
u64 start;
u64 end;
int whole_page;
- int ret;
do {
struct page *page = bvec->bv_page;
@@ -2195,28 +2225,9 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
if (--bvec >= bio->bi_io_vec)
prefetchw(&bvec->bv_page->flags);
- if (tree->ops && tree->ops->writepage_end_io_hook) {
- ret = tree->ops->writepage_end_io_hook(page, start,
- end, NULL, uptodate);
- if (ret)
- uptodate = 0;
- }
-
- if (!uptodate && tree->ops &&
- tree->ops->writepage_io_failed_hook) {
- ret = tree->ops->writepage_io_failed_hook(bio, page,
- start, end, NULL);
- if (ret == 0) {
- uptodate = (err == 0);
- continue;
- }
- }
- if (!uptodate) {
- clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS);
- ClearPageUptodate(page);
- SetPageError(page);
- }
+ if (end_extent_writepage(page, err, start, end))
+ continue;
if (whole_page)
end_page_writeback(page);
@@ -2779,9 +2790,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
delalloc_start = delalloc_end + 1;
continue;
}
- tree->ops->fill_delalloc(inode, page, delalloc_start,
- delalloc_end, &page_started,
- &nr_written);
+ ret = tree->ops->fill_delalloc(inode, page,
+ delalloc_start,
+ delalloc_end,
+ &page_started,
+ &nr_written);
+ BUG_ON(ret);
/*
* delalloc_end is already one less than the total
* length, so we don't subtract one from
@@ -2818,8 +2832,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc,
if (tree->ops && tree->ops->writepage_start_hook) {
ret = tree->ops->writepage_start_hook(page, start,
page_end);
- if (ret == -EAGAIN) {
- redirty_page_for_writepage(wbc, page);
+ if (ret) {
+ /* Fixup worker will requeue */
+ if (ret == -EBUSY)
+ wbc->pages_skipped++;
+ else
+ redirty_page_for_writepage(wbc, page);
update_nr_written(page, wbc, nr_written);
unlock_page(page);
ret = 0;
@@ -3289,7 +3307,7 @@ int try_release_extent_mapping(struct extent_map_tree *map,
len = end - start + 1;
write_lock(&map->lock);
em = lookup_extent_mapping(map, start, len);
- if (IS_ERR_OR_NULL(em)) {
+ if (!em) {
write_unlock(&map->lock);
break;
}
@@ -3853,10 +3871,9 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
num_pages = num_extent_pages(eb->start, eb->len);
clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
- if (eb_straddles_pages(eb)) {
- clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
- cached_state, GFP_NOFS);
- }
+ clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
+ cached_state, GFP_NOFS);
+
for (i = 0; i < num_pages; i++) {
page = extent_buffer_page(eb, i);
if (page)
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index bc6a042cb6f..cecc3518c12 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -319,4 +319,5 @@ struct btrfs_mapping_tree;
int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start,
u64 length, u64 logical, struct page *page,
int mirror_num);
+int end_extent_writepage(struct page *page, int err, u64 start, u64 end);
#endif
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h
index 33a7890b1f4..1195f09761f 100644
--- a/fs/btrfs/extent_map.h
+++ b/fs/btrfs/extent_map.h
@@ -26,8 +26,8 @@ struct extent_map {
unsigned long flags;
struct block_device *bdev;
atomic_t refs;
- unsigned int in_tree:1;
- unsigned int compress_type:4;
+ unsigned int in_tree;
+ unsigned int compress_type;
};
struct extent_map_tree {
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
index 859ba2dd889..e8d06b6b919 100644
--- a/fs/btrfs/file.c
+++ b/fs/btrfs/file.c
@@ -1605,6 +1605,14 @@ static long btrfs_fallocate(struct file *file, int mode,
return -EOPNOTSUPP;
/*
+ * Make sure we have enough space before we do the
+ * allocation.
+ */
+ ret = btrfs_check_data_free_space(inode, len);
+ if (ret)
+ return ret;
+
+ /*
* wait for ordered IO before we have any locks. We'll loop again
* below with the locks held.
*/
@@ -1667,27 +1675,12 @@ static long btrfs_fallocate(struct file *file, int mode,
if (em->block_start == EXTENT_MAP_HOLE ||
(cur_offset >= inode->i_size &&
!test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
-
- /*
- * Make sure we have enough space before we do the
- * allocation.
- */
- ret = btrfs_check_data_free_space(inode, last_byte -
- cur_offset);
- if (ret) {
- free_extent_map(em);
- break;
- }
-
ret = btrfs_prealloc_file_range(inode, mode, cur_offset,
last_byte - cur_offset,
1 << inode->i_blkbits,
offset + len,
&alloc_hint);
- /* Let go of our reservation. */
- btrfs_free_reserved_data_space(inode, last_byte -
- cur_offset);
if (ret < 0) {
free_extent_map(em);
break;
@@ -1715,6 +1708,8 @@ static long btrfs_fallocate(struct file *file, int mode,
&cached_state, GFP_NOFS);
out:
mutex_unlock(&inode->i_mutex);
+ /* Let go of our reservation. */
+ btrfs_free_reserved_data_space(inode, len);
return ret;
}
@@ -1761,7 +1756,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
start - root->sectorsize,
root->sectorsize, 0);
if (IS_ERR(em)) {
- ret = -ENXIO;
+ ret = PTR_ERR(em);
goto out;
}
last_end = em->start + em->len;
@@ -1773,7 +1768,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
while (1) {
em = btrfs_get_extent_fiemap(inode, NULL, 0, start, len, 0);
if (IS_ERR(em)) {
- ret = -ENXIO;
+ ret = PTR_ERR(em);
break;
}
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
index c2f20594c9f..710ea380c7e 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
@@ -777,6 +777,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info,
spin_lock(&block_group->lock);
if (block_group->disk_cache_state != BTRFS_DC_WRITTEN) {
spin_unlock(&block_group->lock);
+ btrfs_free_path(path);
goto out;
}
spin_unlock(&block_group->lock);
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c
index 213ffa86ce1..ee15d88b33d 100644
--- a/fs/btrfs/inode-map.c
+++ b/fs/btrfs/inode-map.c
@@ -438,7 +438,8 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
trans->bytes_reserved);
if (ret)
goto out;
- trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
+ trace_btrfs_space_reservation(root->fs_info, "ino_cache",
+ (u64)(unsigned long)trans,
trans->bytes_reserved, 1);
again:
inode = lookup_free_ino_inode(root, path);
@@ -500,7 +501,8 @@ again:
out_put:
iput(inode);
out_release:
- trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans,
+ trace_btrfs_space_reservation(root->fs_info, "ino_cache",
+ (u64)(unsigned long)trans,
trans->bytes_reserved, 0);
btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved);
out:
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 32214fe0f7e..892b34785cc 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1555,6 +1555,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
struct inode *inode;
u64 page_start;
u64 page_end;
+ int ret;
fixup = container_of(work, struct btrfs_writepage_fixup, work);
page = fixup->page;
@@ -1582,12 +1583,21 @@ again:
page_end, &cached_state, GFP_NOFS);
unlock_page(page);
btrfs_start_ordered_extent(inode, ordered, 1);
+ btrfs_put_ordered_extent(ordered);
goto again;
}
- BUG();
+ ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
+ if (ret) {
+ mapping_set_error(page->mapping, ret);
+ end_extent_writepage(page, ret, page_start, page_end);
+ ClearPageChecked(page);
+ goto out;
+ }
+
btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state);
ClearPageChecked(page);
+ set_page_dirty(page);
out:
unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
&cached_state, GFP_NOFS);
@@ -1630,7 +1640,7 @@ static int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end)
fixup->work.func = btrfs_writepage_fixup_worker;
fixup->page = page;
btrfs_queue_worker(&root->fs_info->fixup_workers, &fixup->work);
- return -EAGAIN;
+ return -EBUSY;
}
static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
@@ -4575,7 +4585,8 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
ret = btrfs_insert_dir_item(trans, root, name, name_len,
parent_inode, &key,
btrfs_inode_type(inode), index);
- BUG_ON(ret);
+ if (ret)
+ goto fail_dir_item;
btrfs_i_size_write(parent_inode, parent_inode->i_size +
name_len * 2);
@@ -4583,6 +4594,23 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
ret = btrfs_update_inode(trans, root, parent_inode);
}
return ret;
+
+fail_dir_item:
+ if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) {
+ u64 local_index;
+ int err;
+ err = btrfs_del_root_ref(trans, root->fs_info->tree_root,
+ key.objectid, root->root_key.objectid,
+ parent_ino, &local_index, name, name_len);
+
+ } else if (add_backref) {
+ u64 local_index;
+ int err;
+
+ err = btrfs_del_inode_ref(trans, root, name, name_len,
+ ino, parent_ino, &local_index);
+ }
+ return ret;
}
static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
@@ -6696,8 +6724,10 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans,
int err;
u64 index = 0;
- inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid,
- new_dirid, S_IFDIR | 0700, &index);
+ inode = btrfs_new_inode(trans, new_root, NULL, "..", 2,
+ new_dirid, new_dirid,
+ S_IFDIR | (~current_umask() & S_IRWXUGO),
+ &index);
if (IS_ERR(inode))
return PTR_ERR(inode);
inode->i_op = &btrfs_dir_inode_operations;
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 03bb62a9ee2..d8b54715c2d 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -861,6 +861,7 @@ static int cluster_pages_for_defrag(struct inode *inode,
int i_done;
struct btrfs_ordered_extent *ordered;
struct extent_state *cached_state = NULL;
+ struct extent_io_tree *tree;
gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
if (isize == 0)
@@ -871,18 +872,34 @@ static int cluster_pages_for_defrag(struct inode *inode,
num_pages << PAGE_CACHE_SHIFT);
if (ret)
return ret;
-again:
- ret = 0;
i_done = 0;
+ tree = &BTRFS_I(inode)->io_tree;
/* step one, lock all the pages */
for (i = 0; i < num_pages; i++) {
struct page *page;
+again:
page = find_or_create_page(inode->i_mapping,
- start_index + i, mask);
+ start_index + i, mask);
if (!page)
break;
+ page_start = page_offset(page);
+ page_end = page_start + PAGE_CACHE_SIZE - 1;
+ while (1) {
+ lock_extent(tree, page_start, page_end, GFP_NOFS);
+ ordered = btrfs_lookup_ordered_extent(inode,
+ page_start);
+ unlock_extent(tree, page_start, page_end, GFP_NOFS);
+ if (!ordered)
+ break;
+
+ unlock_page(page);
+ btrfs_start_ordered_extent(inode, ordered, 1);
+ btrfs_put_ordered_extent(ordered);
+ lock_page(page);
+ }
+
if (!PageUptodate(page)) {
btrfs_readpage(NULL, page);
lock_page(page);
@@ -893,15 +910,22 @@ again:
break;
}
}
+
isize = i_size_read(inode);
file_end = (isize - 1) >> PAGE_CACHE_SHIFT;
- if (!isize || page->index > file_end ||
- page->mapping != inode->i_mapping) {
+ if (!isize || page->index > file_end) {
/* whoops, we blew past eof, skip this page */
unlock_page(page);
page_cache_release(page);
break;
}
+
+ if (page->mapping != inode->i_mapping) {
+ unlock_page(page);
+ page_cache_release(page);
+ goto again;
+ }
+
pages[i] = page;
i_done++;
}
@@ -924,25 +948,6 @@ again:
lock_extent_bits(&BTRFS_I(inode)->io_tree,
page_start, page_end - 1, 0, &cached_state,
GFP_NOFS);
- ordered = btrfs_lookup_first_ordered_extent(inode, page_end - 1);
- if (ordered &&
- ordered->file_offset + ordered->len > page_start &&
- ordered->file_offset < page_end) {
- btrfs_put_ordered_extent(ordered);
- unlock_extent_cached(&BTRFS_I(inode)->io_tree,
- page_start, page_end - 1,
- &cached_state, GFP_NOFS);
- for (i = 0; i < i_done; i++) {
- unlock_page(pages[i]);
- page_cache_release(pages[i]);
- }
- btrfs_wait_ordered_range(inode, page_start,
- page_end - page_start);
- goto again;
- }
- if (ordered)
- btrfs_put_ordered_extent(ordered);
-
clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start,
page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
@@ -1327,6 +1332,12 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file,
goto out;
}
+ if (name[0] == '.' &&
+ (namelen == 1 || (name[1] == '.' && namelen == 2))) {
+ ret = -EEXIST;
+ goto out;
+ }
+
if (subvol) {
ret = btrfs_mksubvol(&file->f_path, name, namelen,
NULL, transid, readonly);
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index 9770cc5bfb7..abc0fbffa51 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1367,7 +1367,8 @@ out:
}
static noinline_for_stack int scrub_chunk(struct scrub_dev *sdev,
- u64 chunk_tree, u64 chunk_objectid, u64 chunk_offset, u64 length)
+ u64 chunk_tree, u64 chunk_objectid, u64 chunk_offset, u64 length,
+ u64 dev_offset)
{
struct btrfs_mapping_tree *map_tree =
&sdev->dev->dev_root->fs_info->mapping_tree;
@@ -1391,7 +1392,8 @@ static noinline_for_stack int scrub_chunk(struct scrub_dev *sdev,
goto out;
for (i = 0; i < map->num_stripes; ++i) {
- if (map->stripes[i].dev == sdev->dev) {
+ if (map->stripes[i].dev == sdev->dev &&
+ map->stripes[i].physical == dev_offset) {
ret = scrub_stripe(sdev, map, i, chunk_offset, length);
if (ret)
goto out;
@@ -1487,7 +1489,7 @@ int scrub_enumerate_chunks(struct scrub_dev *sdev, u64 start, u64 end)
break;
}
ret = scrub_chunk(sdev, chunk_tree, chunk_objectid,
- chunk_offset, length);
+ chunk_offset, length, found_key.offset);
btrfs_put_block_group(cache);
if (ret)
break;
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 287a6728b1a..04b77e3ceb7 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -327,7 +327,8 @@ again:
if (num_bytes) {
trace_btrfs_space_reservation(root->fs_info, "transaction",
- (u64)h, num_bytes, 1);
+ (u64)(unsigned long)h,
+ num_bytes, 1);
h->block_rsv = &root->fs_info->trans_block_rsv;
h->bytes_reserved = num_bytes;
}
@@ -915,7 +916,11 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
dentry->d_name.name, dentry->d_name.len,
parent_inode, &key,
BTRFS_FT_DIR, index);
- BUG_ON(ret);
+ if (ret) {
+ pending->error = -EEXIST;
+ dput(parent);
+ goto fail;
+ }
btrfs_i_size_write(parent_inode, parent_inode->i_size +
dentry->d_name.len * 2);
@@ -993,12 +998,9 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
{
struct btrfs_pending_snapshot *pending;
struct list_head *head = &trans->transaction->pending_snapshots;
- int ret;
- list_for_each_entry(pending, head, list) {
- ret = create_pending_snapshot(trans, fs_info, pending);
- BUG_ON(ret);
- }
+ list_for_each_entry(pending, head, list)
+ create_pending_snapshot(trans, fs_info, pending);
return 0;
}
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 0b4e2af7954..ef41f285a47 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -459,12 +459,23 @@ int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices)
{
struct btrfs_device *device, *next;
+ struct block_device *latest_bdev = NULL;
+ u64 latest_devid = 0;
+ u64 latest_transid = 0;
+
mutex_lock(&uuid_mutex);
again:
/* This is the initialized path, it is safe to release the devices. */
list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) {
- if (device->in_fs_metadata)
+ if (device->in_fs_metadata) {
+ if (!latest_transid ||
+ device->generation > latest_transid) {
+ latest_devid = device->devid;
+ latest_transid = device->generation;
+ latest_bdev = device->bdev;
+ }
continue;
+ }
if (device->bdev) {
blkdev_put(device->bdev, device->mode);
@@ -487,6 +498,10 @@ again:
goto again;
}
+ fs_devices->latest_bdev = latest_bdev;
+ fs_devices->latest_devid = latest_devid;
+ fs_devices->latest_trans = latest_transid;
+
mutex_unlock(&uuid_mutex);
return 0;
}
@@ -1953,7 +1968,7 @@ static int btrfs_relocate_chunk(struct btrfs_root *root,
em = lookup_extent_mapping(em_tree, chunk_offset, 1);
read_unlock(&em_tree->lock);
- BUG_ON(em->start > chunk_offset ||
+ BUG_ON(!em || em->start > chunk_offset ||
em->start + em->len < chunk_offset);
map = (struct map_lookup *)em->bdev;
@@ -4356,6 +4371,20 @@ int btrfs_read_sys_array(struct btrfs_root *root)
return -ENOMEM;
btrfs_set_buffer_uptodate(sb);
btrfs_set_buffer_lockdep_class(root->root_key.objectid, sb, 0);
+ /*
+ * The sb extent buffer is artifical and just used to read the system array.
+ * btrfs_set_buffer_uptodate() call does not properly mark all it's
+ * pages up-to-date when the page is larger: extent does not cover the
+ * whole page and consequently check_page_uptodate does not find all
+ * the page's extents up-to-date (the hole beyond sb),
+ * write_extent_buffer then triggers a WARN_ON.
+ *
+ * Regular short extents go through mark_extent_buffer_dirty/writeback cycle,
+ * but sb spans only this function. Add an explicit SetPageUptodate call
+ * to silence the warning eg. on PowerPC 64.
+ */
+ if (PAGE_CACHE_SIZE > BTRFS_SUPER_INFO_SIZE)
+ SetPageUptodate(sb->first_page);
write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE);
array_size = btrfs_super_sys_array_size(super_copy);
diff --git a/fs/compat.c b/fs/compat.c
index fa9d721ecfe..07880bae28a 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -131,41 +131,35 @@ asmlinkage long compat_sys_utimes(const char __user *filename, struct compat_tim
static int cp_compat_stat(struct kstat *stat, struct compat_stat __user *ubuf)
{
- compat_ino_t ino = stat->ino;
- typeof(ubuf->st_uid) uid = 0;
- typeof(ubuf->st_gid) gid = 0;
- int err;
+ struct compat_stat tmp;
- SET_UID(uid, stat->uid);
- SET_GID(gid, stat->gid);
+ if (!old_valid_dev(stat->dev) || !old_valid_dev(stat->rdev))
+ return -EOVERFLOW;
- if ((u64) stat->size > MAX_NON_LFS ||
- !old_valid_dev(stat->dev) ||
- !old_valid_dev(stat->rdev))
+ memset(&tmp, 0, sizeof(tmp));
+ tmp.st_dev = old_encode_dev(stat->dev);
+ tmp.st_ino = stat->ino;
+ if (sizeof(tmp.st_ino) < sizeof(stat->ino) && tmp.st_ino != stat->ino)
return -EOVERFLOW;
- if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino)
+ tmp.st_mode = stat->mode;
+ tmp.st_nlink = stat->nlink;
+ if (tmp.st_nlink != stat->nlink)
return -EOVERFLOW;
-
- if (clear_user(ubuf, sizeof(*ubuf)))
- return -EFAULT;
-
- err = __put_user(old_encode_dev(stat->dev), &ubuf->st_dev);
- err |= __put_user(ino, &ubuf->st_ino);
- err |= __put_user(stat->mode, &ubuf->st_mode);
- err |= __put_user(stat->nlink, &ubuf->st_nlink);
- err |= __put_user(uid, &ubuf->st_uid);
- err |= __put_user(gid, &ubuf->st_gid);
- err |= __put_user(old_encode_dev(stat->rdev), &ubuf->st_rdev);
- err |= __put_user(stat->size, &ubuf->st_size);
- err |= __put_user(stat->atime.tv_sec, &ubuf->st_atime);
- err |= __put_user(stat->atime.tv_nsec, &ubuf->st_atime_nsec);
- err |= __put_user(stat->mtime.tv_sec, &ubuf->st_mtime);
- err |= __put_user(stat->mtime.tv_nsec, &ubuf->st_mtime_nsec);
- err |= __put_user(stat->ctime.tv_sec, &ubuf->st_ctime);
- err |= __put_user(stat->ctime.tv_nsec, &ubuf->st_ctime_nsec);
- err |= __put_user(stat->blksize, &ubuf->st_blksize);
- err |= __put_user(stat->blocks, &ubuf->st_blocks);
- return err;
+ SET_UID(tmp.st_uid, stat->uid);
+ SET_GID(tmp.st_gid, stat->gid);
+ tmp.st_rdev = old_encode_dev(stat->rdev);
+ if ((u64) stat->size > MAX_NON_LFS)
+ return -EOVERFLOW;
+ tmp.st_size = stat->size;
+ tmp.st_atime = stat->atime.tv_sec;
+ tmp.st_atime_nsec = stat->atime.tv_nsec;
+ tmp.st_mtime = stat->mtime.tv_sec;
+ tmp.st_mtime_nsec = stat->mtime.tv_nsec;
+ tmp.st_ctime = stat->ctime.tv_sec;
+ tmp.st_ctime_nsec = stat->ctime.tv_nsec;
+ tmp.st_blocks = stat->blocks;
+ tmp.st_blksize = stat->blksize;
+ return copy_to_user(ubuf, &tmp, sizeof(tmp)) ? -EFAULT : 0;
}
asmlinkage long compat_sys_newstat(const char __user * filename,
diff --git a/fs/dcache.c b/fs/dcache.c
index 16a53cc2cc0..138be96e25b 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -104,7 +104,7 @@ static unsigned int d_hash_shift __read_mostly;
static struct hlist_bl_head *dentry_hashtable __read_mostly;
-static inline struct hlist_bl_head *d_hash(struct dentry *parent,
+static inline struct hlist_bl_head *d_hash(const struct dentry *parent,
unsigned long hash)
{
hash += ((unsigned long) parent ^ GOLDEN_RATIO_PRIME) / L1_CACHE_BYTES;
@@ -1717,8 +1717,9 @@ EXPORT_SYMBOL(d_add_ci);
* child is looked up. Thus, an interlocking stepping of sequence lock checks
* is formed, giving integrity down the path walk.
*/
-struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
- unsigned *seq, struct inode **inode)
+struct dentry *__d_lookup_rcu(const struct dentry *parent,
+ const struct qstr *name,
+ unsigned *seqp, struct inode **inode)
{
unsigned int len = name->len;
unsigned int hash = name->hash;
@@ -1748,6 +1749,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
* See Documentation/filesystems/path-lookup.txt for more details.
*/
hlist_bl_for_each_entry_rcu(dentry, node, b, d_hash) {
+ unsigned seq;
struct inode *i;
const char *tname;
int tlen;
@@ -1756,7 +1758,7 @@ struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
continue;
seqretry:
- *seq = read_seqcount_begin(&dentry->d_seq);
+ seq = read_seqcount_begin(&dentry->d_seq);
if (dentry->d_parent != parent)
continue;
if (d_unhashed(dentry))
@@ -1771,7 +1773,7 @@ seqretry:
* edge of memory when walking. If we could load this
* atomically some other way, we could drop this check.
*/
- if (read_seqcount_retry(&dentry->d_seq, *seq))
+ if (read_seqcount_retry(&dentry->d_seq, seq))
goto seqretry;
if (unlikely(parent->d_flags & DCACHE_OP_COMPARE)) {
if (parent->d_op->d_compare(parent, *inode,
@@ -1788,6 +1790,7 @@ seqretry:
* order to do anything useful with the returned dentry
* anyway.
*/
+ *seqp = seq;
*inode = i;
return dentry;
}
@@ -2968,7 +2971,7 @@ __setup("dhash_entries=", set_dhash_entries);
static void __init dcache_init_early(void)
{
- int loop;
+ unsigned int loop;
/* If hashes are distributed across NUMA nodes, defer
* hash allocation until vmalloc space is available.
@@ -2986,13 +2989,13 @@ static void __init dcache_init_early(void)
&d_hash_mask,
0);
- for (loop = 0; loop < (1 << d_hash_shift); loop++)
+ for (loop = 0; loop < (1U << d_hash_shift); loop++)
INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
}
static void __init dcache_init(void)
{
- int loop;
+ unsigned int loop;
/*
* A constructor could be added for stable state like the lists,
@@ -3016,7 +3019,7 @@ static void __init dcache_init(void)
&d_hash_mask,
0);
- for (loop = 0; loop < (1 << d_hash_shift); loop++)
+ for (loop = 0; loop < (1U << d_hash_shift); loop++)
INIT_HLIST_BL_HEAD(dentry_hashtable + loop);
}
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 4a588dbd11b..f4aadd15b61 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -173,7 +173,7 @@ void inode_dio_wait(struct inode *inode)
if (atomic_read(&inode->i_dio_count))
__inode_dio_wait(inode);
}
-EXPORT_SYMBOL_GPL(inode_dio_wait);
+EXPORT_SYMBOL(inode_dio_wait);
/*
* inode_dio_done - signal finish of a direct I/O requests
@@ -187,7 +187,7 @@ void inode_dio_done(struct inode *inode)
if (atomic_dec_and_test(&inode->i_dio_count))
wake_up_bit(&inode->i_state, __I_DIO_WAKEUP);
}
-EXPORT_SYMBOL_GPL(inode_dio_done);
+EXPORT_SYMBOL(inode_dio_done);
/*
* How many pages are in the queue?
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c
index 349209dc6a9..3a06f4043df 100644
--- a/fs/ecryptfs/miscdev.c
+++ b/fs/ecryptfs/miscdev.c
@@ -429,7 +429,7 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf,
goto memdup;
} else if (count < MIN_MSG_PKT_SIZE || count > MAX_MSG_PKT_SIZE) {
printk(KERN_WARNING "%s: Acceptable packet size range is "
- "[%d-%lu], but amount of data written is [%zu].",
+ "[%d-%zu], but amount of data written is [%zu].",
__func__, MIN_MSG_PKT_SIZE, MAX_MSG_PKT_SIZE, count);
return -EINVAL;
}
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index aabdfc38cf2..ea54cdef04d 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -320,6 +320,11 @@ static inline int ep_is_linked(struct list_head *p)
return !list_empty(p);
}
+static inline struct eppoll_entry *ep_pwq_from_wait(wait_queue_t *p)
+{
+ return container_of(p, struct eppoll_entry, wait);
+}
+
/* Get the "struct epitem" from a wait queue pointer */
static inline struct epitem *ep_item_from_wait(wait_queue_t *p)
{
@@ -467,6 +472,18 @@ static void ep_poll_safewake(wait_queue_head_t *wq)
put_cpu();
}
+static void ep_remove_wait_queue(struct eppoll_entry *pwq)
+{
+ wait_queue_head_t *whead;
+
+ rcu_read_lock();
+ /* If it is cleared by POLLFREE, it should be rcu-safe */
+ whead = rcu_dereference(pwq->whead);
+ if (whead)
+ remove_wait_queue(whead, &pwq->wait);
+ rcu_read_unlock();
+}
+
/*
* This function unregisters poll callbacks from the associated file
* descriptor. Must be called with "mtx" held (or "epmutex" if called from
@@ -481,7 +498,7 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi)
pwq = list_first_entry(lsthead, struct eppoll_entry, llink);
list_del(&pwq->llink);
- remove_wait_queue(pwq->whead, &pwq->wait);
+ ep_remove_wait_queue(pwq);
kmem_cache_free(pwq_cache, pwq);
}
}
@@ -842,6 +859,17 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k
struct epitem *epi = ep_item_from_wait(wait);
struct eventpoll *ep = epi->ep;
+ if ((unsigned long)key & POLLFREE) {
+ ep_pwq_from_wait(wait)->whead = NULL;
+ /*
+ * whead = NULL above can race with ep_remove_wait_queue()
+ * which can do another remove_wait_queue() after us, so we
+ * can't use __remove_wait_queue(). whead->lock is held by
+ * the caller.
+ */
+ list_del_init(&wait->task_list);
+ }
+
spin_lock_irqsave(&ep->lock, flags);
/*
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 376816fcd04..351a3e79778 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -167,14 +167,19 @@ void gfs2_glock_add_to_lru(struct gfs2_glock *gl)
spin_unlock(&lru_lock);
}
-static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
+static void __gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
{
- spin_lock(&lru_lock);
if (!list_empty(&gl->gl_lru)) {
list_del_init(&gl->gl_lru);
atomic_dec(&lru_count);
clear_bit(GLF_LRU, &gl->gl_flags);
}
+}
+
+static void gfs2_glock_remove_from_lru(struct gfs2_glock *gl)
+{
+ spin_lock(&lru_lock);
+ __gfs2_glock_remove_from_lru(gl);
spin_unlock(&lru_lock);
}
@@ -217,11 +222,12 @@ void gfs2_glock_put(struct gfs2_glock *gl)
struct gfs2_sbd *sdp = gl->gl_sbd;
struct address_space *mapping = gfs2_glock2aspace(gl);
- if (atomic_dec_and_test(&gl->gl_ref)) {
+ if (atomic_dec_and_lock(&gl->gl_ref, &lru_lock)) {
+ __gfs2_glock_remove_from_lru(gl);
+ spin_unlock(&lru_lock);
spin_lock_bucket(gl->gl_hash);
hlist_bl_del_rcu(&gl->gl_list);
spin_unlock_bucket(gl->gl_hash);
- gfs2_glock_remove_from_lru(gl);
GLOCK_BUG_ON(gl, !list_empty(&gl->gl_holders));
GLOCK_BUG_ON(gl, mapping && mapping->nrpages);
trace_gfs2_glock_put(gl);
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index a7d611b93f0..56987460cda 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -391,10 +391,6 @@ static int alloc_dinode(struct gfs2_inode *dip, u64 *no_addr, u64 *generation)
int error;
int dblocks = 1;
- error = gfs2_rindex_update(sdp);
- if (error)
- fs_warn(sdp, "rindex update returns %d\n", error);
-
error = gfs2_inplace_reserve(dip, RES_DINODE);
if (error)
goto out;
@@ -1043,6 +1039,7 @@ static int gfs2_unlink(struct inode *dir, struct dentry *dentry)
rgd = gfs2_blk2rgrpd(sdp, ip->i_no_addr);
if (!rgd)
goto out_inodes;
+
gfs2_holder_init(rgd->rd_gl, LM_ST_EXCLUSIVE, 0, ghs + 2);
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index 6aacf3f230a..24f609c9ef9 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -800,6 +800,11 @@ static int init_inodes(struct gfs2_sbd *sdp, int undo)
fs_err(sdp, "can't get quota file inode: %d\n", error);
goto fail_rindex;
}
+
+ error = gfs2_rindex_update(sdp);
+ if (error)
+ goto fail_qinode;
+
return 0;
fail_qinode:
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 981bfa32121..49ada95209d 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -683,16 +683,21 @@ int gfs2_rindex_update(struct gfs2_sbd *sdp)
struct gfs2_glock *gl = ip->i_gl;
struct gfs2_holder ri_gh;
int error = 0;
+ int unlock_required = 0;
/* Read new copy from disk if we don't have the latest */
if (!sdp->sd_rindex_uptodate) {
mutex_lock(&sdp->sd_rindex_mutex);
- error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh);
- if (error)
- return error;
+ if (!gfs2_glock_is_locked_by_me(gl)) {
+ error = gfs2_glock_nq_init(gl, LM_ST_SHARED, 0, &ri_gh);
+ if (error)
+ return error;
+ unlock_required = 1;
+ }
if (!sdp->sd_rindex_uptodate)
error = gfs2_ri_update(ip);
- gfs2_glock_dq_uninit(&ri_gh);
+ if (unlock_required)
+ gfs2_glock_dq_uninit(&ri_gh);
mutex_unlock(&sdp->sd_rindex_mutex);
}
diff --git a/fs/inode.c b/fs/inode.c
index fb10d86ffad..d3ebdbe723d 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1651,7 +1651,7 @@ __setup("ihash_entries=", set_ihash_entries);
*/
void __init inode_init_early(void)
{
- int loop;
+ unsigned int loop;
/* If hashes are distributed across NUMA nodes, defer
* hash allocation until vmalloc space is available.
@@ -1669,13 +1669,13 @@ void __init inode_init_early(void)
&i_hash_mask,
0);
- for (loop = 0; loop < (1 << i_hash_shift); loop++)
+ for (loop = 0; loop < (1U << i_hash_shift); loop++)
INIT_HLIST_HEAD(&inode_hashtable[loop]);
}
void __init inode_init(void)
{
- int loop;
+ unsigned int loop;
/* inode slab cache */
inode_cachep = kmem_cache_create("inode_cache",
@@ -1699,7 +1699,7 @@ void __init inode_init(void)
&i_hash_mask,
0);
- for (loop = 0; loop < (1 << i_hash_shift); loop++)
+ for (loop = 0; loop < (1U << i_hash_shift); loop++)
INIT_HLIST_HEAD(&inode_hashtable[loop]);
}
diff --git a/fs/namei.c b/fs/namei.c
index 208c6aa4a98..e2ba62820a0 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1095,8 +1095,10 @@ static struct dentry *d_inode_lookup(struct dentry *parent, struct dentry *dentr
struct dentry *old;
/* Don't create child dentry for a dead directory. */
- if (unlikely(IS_DEADDIR(inode)))
+ if (unlikely(IS_DEADDIR(inode))) {
+ dput(dentry);
return ERR_PTR(-ENOENT);
+ }
old = inode->i_op->lookup(inode, dentry, nd);
if (unlikely(old)) {
@@ -1372,6 +1374,34 @@ static inline int can_lookup(struct inode *inode)
return 1;
}
+unsigned int full_name_hash(const unsigned char *name, unsigned int len)
+{
+ unsigned long hash = init_name_hash();
+ while (len--)
+ hash = partial_name_hash(*name++, hash);
+ return end_name_hash(hash);
+}
+EXPORT_SYMBOL(full_name_hash);
+
+/*
+ * We know there's a real path component here of at least
+ * one character.
+ */
+static inline unsigned long hash_name(const char *name, unsigned int *hashp)
+{
+ unsigned long hash = init_name_hash();
+ unsigned long len = 0, c;
+
+ c = (unsigned char)*name;
+ do {
+ len++;
+ hash = partial_name_hash(c, hash);
+ c = (unsigned char)name[len];
+ } while (c && c != '/');
+ *hashp = end_name_hash(hash);
+ return len;
+}
+
/*
* Name resolution.
* This is the basic name resolution function, turning a pathname into
@@ -1392,31 +1422,22 @@ static int link_path_walk(const char *name, struct nameidata *nd)
/* At this point we know we have a real path component. */
for(;;) {
- unsigned long hash;
struct qstr this;
- unsigned int c;
+ long len;
int type;
err = may_lookup(nd);
if (err)
break;
+ len = hash_name(name, &this.hash);
this.name = name;
- c = *(const unsigned char *)name;
-
- hash = init_name_hash();
- do {
- name++;
- hash = partial_name_hash(c, hash);
- c = *(const unsigned char *)name;
- } while (c && (c != '/'));
- this.len = name - (const char *) this.name;
- this.hash = end_name_hash(hash);
+ this.len = len;
type = LAST_NORM;
- if (this.name[0] == '.') switch (this.len) {
+ if (name[0] == '.') switch (len) {
case 2:
- if (this.name[1] == '.') {
+ if (name[1] == '.') {
type = LAST_DOTDOT;
nd->flags |= LOOKUP_JUMPED;
}
@@ -1435,12 +1456,18 @@ static int link_path_walk(const char *name, struct nameidata *nd)
}
}
- /* remove trailing slashes? */
- if (!c)
+ if (!name[len])
goto last_component;
- while (*++name == '/');
- if (!*name)
+ /*
+ * If it wasn't NUL, we know it was '/'. Skip that
+ * slash, and continue until no more slashes.
+ */
+ do {
+ len++;
+ } while (unlikely(name[len] == '/'));
+ if (!name[len])
goto last_component;
+ name += len;
err = walk_component(nd, &next, &this, type, LOOKUP_FOLLOW);
if (err < 0)
@@ -1773,24 +1800,21 @@ static struct dentry *lookup_hash(struct nameidata *nd)
struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
{
struct qstr this;
- unsigned long hash;
unsigned int c;
WARN_ON_ONCE(!mutex_is_locked(&base->d_inode->i_mutex));
this.name = name;
this.len = len;
+ this.hash = full_name_hash(name, len);
if (!len)
return ERR_PTR(-EACCES);
- hash = init_name_hash();
while (len--) {
c = *(const unsigned char *)name++;
if (c == '/' || c == '\0')
return ERR_PTR(-EACCES);
- hash = partial_name_hash(c, hash);
}
- this.hash = end_name_hash(hash);
/*
* See if the low-level filesystem might want
* to use its own hash..
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index f0c849c98fe..ec9f6ef6c5d 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3575,8 +3575,8 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
}
if (npages > 1) {
/* for decoding across pages */
- args.acl_scratch = alloc_page(GFP_KERNEL);
- if (!args.acl_scratch)
+ res.acl_scratch = alloc_page(GFP_KERNEL);
+ if (!res.acl_scratch)
goto out_free;
}
args.acl_len = npages * PAGE_SIZE;
@@ -3612,8 +3612,8 @@ out_free:
for (i = 0; i < npages; i++)
if (pages[i])
__free_page(pages[i]);
- if (args.acl_scratch)
- __free_page(args.acl_scratch);
+ if (res.acl_scratch)
+ __free_page(res.acl_scratch);
return ret;
}
@@ -4883,8 +4883,10 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
clp->cl_rpcclient->cl_auth->au_flavor);
res.server_scope = kzalloc(sizeof(struct server_scope), GFP_KERNEL);
- if (unlikely(!res.server_scope))
- return -ENOMEM;
+ if (unlikely(!res.server_scope)) {
+ status = -ENOMEM;
+ goto out;
+ }
status = rpc_call_sync(clp->cl_rpcclient, &msg, RPC_TASK_TIMEOUT);
if (!status)
@@ -4901,12 +4903,13 @@ int nfs4_proc_exchange_id(struct nfs_client *clp, struct rpc_cred *cred)
clp->server_scope = NULL;
}
- if (!clp->server_scope)
+ if (!clp->server_scope) {
clp->server_scope = res.server_scope;
- else
- kfree(res.server_scope);
+ goto out;
+ }
}
-
+ kfree(res.server_scope);
+out:
dprintk("<-- %s status= %d\n", __func__, status);
return status;
}
@@ -5008,37 +5011,53 @@ int nfs4_proc_get_lease_time(struct nfs_client *clp, struct nfs_fsinfo *fsinfo)
return status;
}
+static struct nfs4_slot *nfs4_alloc_slots(u32 max_slots, gfp_t gfp_flags)
+{
+ return kcalloc(max_slots, sizeof(struct nfs4_slot), gfp_flags);
+}
+
+static void nfs4_add_and_init_slots(struct nfs4_slot_table *tbl,
+ struct nfs4_slot *new,
+ u32 max_slots,
+ u32 ivalue)
+{
+ struct nfs4_slot *old = NULL;
+ u32 i;
+
+ spin_lock(&tbl->slot_tbl_lock);
+ if (new) {
+ old = tbl->slots;
+ tbl->slots = new;
+ tbl->max_slots = max_slots;
+ }
+ tbl->highest_used_slotid = -1; /* no slot is currently used */
+ for (i = 0; i < tbl->max_slots; i++)
+ tbl->slots[i].seq_nr = ivalue;
+ spin_unlock(&tbl->slot_tbl_lock);
+ kfree(old);
+}
+
/*
- * Reset a slot table
+ * (re)Initialise a slot table
*/
-static int nfs4_reset_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
- int ivalue)
+static int nfs4_realloc_slot_table(struct nfs4_slot_table *tbl, u32 max_reqs,
+ u32 ivalue)
{
struct nfs4_slot *new = NULL;
- int i;
- int ret = 0;
+ int ret = -ENOMEM;
dprintk("--> %s: max_reqs=%u, tbl->max_slots %d\n", __func__,
max_reqs, tbl->max_slots);
/* Does the newly negotiated max_reqs match the existing slot table? */
if (max_reqs != tbl->max_slots) {
- ret = -ENOMEM;
- new = kmalloc(max_reqs * sizeof(struct nfs4_slot),
- GFP_NOFS);
+ new = nfs4_alloc_slots(max_reqs, GFP_NOFS);
if (!new)
goto out;
- ret = 0;
- kfree(tbl->slots);
}
- spin_lock(&tbl->slot_tbl_lock);
- if (new) {
- tbl->slots = new;
- tbl->max_slots = max_reqs;
- }
- for (i = 0; i < tbl->max_slots; ++i)
- tbl->slots[i].seq_nr = ivalue;
- spin_unlock(&tbl->slot_tbl_lock);
+ ret = 0;
+
+ nfs4_add_and_init_slots(tbl, new, max_reqs, ivalue);
dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
tbl, tbl->slots, tbl->max_slots);
out:
@@ -5061,36 +5080,6 @@ static void nfs4_destroy_slot_tables(struct nfs4_session *session)
}
/*
- * Initialize slot table
- */
-static int nfs4_init_slot_table(struct nfs4_slot_table *tbl,
- int max_slots, int ivalue)
-{
- struct nfs4_slot *slot;
- int ret = -ENOMEM;
-
- BUG_ON(max_slots > NFS4_MAX_SLOT_TABLE);
-
- dprintk("--> %s: max_reqs=%u\n", __func__, max_slots);
-
- slot = kcalloc(max_slots, sizeof(struct nfs4_slot), GFP_NOFS);
- if (!slot)
- goto out;
- ret = 0;
-
- spin_lock(&tbl->slot_tbl_lock);
- tbl->max_slots = max_slots;
- tbl->slots = slot;
- tbl->highest_used_slotid = -1; /* no slot is currently used */
- spin_unlock(&tbl->slot_tbl_lock);
- dprintk("%s: tbl=%p slots=%p max_slots=%d\n", __func__,
- tbl, tbl->slots, tbl->max_slots);
-out:
- dprintk("<-- %s: return %d\n", __func__, ret);
- return ret;
-}
-
-/*
* Initialize or reset the forechannel and backchannel tables
*/
static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
@@ -5101,25 +5090,16 @@ static int nfs4_setup_session_slot_tables(struct nfs4_session *ses)
dprintk("--> %s\n", __func__);
/* Fore channel */
tbl = &ses->fc_slot_table;
- if (tbl->slots == NULL) {
- status = nfs4_init_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
- if (status) /* -ENOMEM */
- return status;
- } else {
- status = nfs4_reset_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
- if (status)
- return status;
- }
+ status = nfs4_realloc_slot_table(tbl, ses->fc_attrs.max_reqs, 1);
+ if (status) /* -ENOMEM */
+ return status;
/* Back channel */
tbl = &ses->bc_slot_table;
- if (tbl->slots == NULL) {
- status = nfs4_init_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
- if (status)
- /* Fore and back channel share a connection so get
- * both slot tables or neither */
- nfs4_destroy_slot_tables(ses);
- } else
- status = nfs4_reset_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
+ status = nfs4_realloc_slot_table(tbl, ses->bc_attrs.max_reqs, 0);
+ if (status && tbl->slots == NULL)
+ /* Fore and back channel share a connection so get
+ * both slot tables or neither */
+ nfs4_destroy_slot_tables(ses);
return status;
}
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index a53f33b4ac3..45392032e7b 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1132,6 +1132,8 @@ void nfs4_schedule_stateid_recovery(const struct nfs_server *server, struct nfs4
{
struct nfs_client *clp = server->nfs_client;
+ if (test_and_clear_bit(NFS_DELEGATED_STATE, &state->flags))
+ nfs_async_inode_return_delegation(state->inode, &state->stateid);
nfs4_state_mark_reclaim_nograce(clp, state);
nfs4_schedule_state_manager(clp);
}
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 95e92e43840..33bd8d0f745 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -2522,7 +2522,6 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr,
xdr_inline_pages(&req->rq_rcv_buf, replen << 2,
args->acl_pages, args->acl_pgbase, args->acl_len);
- xdr_set_scratch_buffer(xdr, page_address(args->acl_scratch), PAGE_SIZE);
encode_nops(&hdr);
}
@@ -6032,6 +6031,10 @@ nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
struct compound_hdr hdr;
int status;
+ if (res->acl_scratch != NULL) {
+ void *p = page_address(res->acl_scratch);
+ xdr_set_scratch_buffer(xdr, p, PAGE_SIZE);
+ }
status = decode_compound_hdr(xdr, &hdr);
if (status)
goto out;
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index f14fde2b03d..e0281992ddc 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1,7 +1,7 @@
/**
* attrib.c - NTFS attribute operations. Part of the Linux-NTFS project.
*
- * Copyright (c) 2001-2007 Anton Altaparmakov
+ * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
@@ -345,10 +345,10 @@ LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,
unsigned long flags;
bool is_retry = false;
+ BUG_ON(!ni);
ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",
ni->mft_no, (unsigned long long)vcn,
write_locked ? "write" : "read");
- BUG_ON(!ni);
BUG_ON(!NInoNonResident(ni));
BUG_ON(vcn < 0);
if (!ni->runlist.rl) {
@@ -469,9 +469,9 @@ runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,
int err = 0;
bool is_retry = false;
+ BUG_ON(!ni);
ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, with%s ctx.",
ni->mft_no, (unsigned long long)vcn, ctx ? "" : "out");
- BUG_ON(!ni);
BUG_ON(!NInoNonResident(ni));
BUG_ON(vcn < 0);
if (!ni->runlist.rl) {
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 382857f9c7d..3014a36a255 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -1,7 +1,7 @@
/**
* mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.
*
- * Copyright (c) 2001-2011 Anton Altaparmakov and Tuxera Inc.
+ * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
@@ -1367,7 +1367,7 @@ static int ntfs_mft_bitmap_extend_allocation_nolock(ntfs_volume *vol)
ntfs_error(vol->sb, "Failed to merge runlists for mft "
"bitmap.");
if (ntfs_cluster_free_from_rl(vol, rl2)) {
- ntfs_error(vol->sb, "Failed to dealocate "
+ ntfs_error(vol->sb, "Failed to deallocate "
"allocated cluster.%s", es);
NVolSetErrors(vol);
}
@@ -1805,7 +1805,7 @@ static int ntfs_mft_data_extend_allocation_nolock(ntfs_volume *vol)
ntfs_error(vol->sb, "Failed to merge runlists for mft data "
"attribute.");
if (ntfs_cluster_free_from_rl(vol, rl2)) {
- ntfs_error(vol->sb, "Failed to dealocate clusters "
+ ntfs_error(vol->sb, "Failed to deallocate clusters "
"from the mft data attribute.%s", es);
NVolSetErrors(vol);
}
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 5a4a8af5c40..f907611cca7 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1,7 +1,7 @@
/*
* super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.
*
- * Copyright (c) 2001-2011 Anton Altaparmakov and Tuxera Inc.
+ * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
* Copyright (c) 2001,2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
@@ -1239,7 +1239,6 @@ static int check_windows_hibernation_status(ntfs_volume *vol)
{
MFT_REF mref;
struct inode *vi;
- ntfs_inode *ni;
struct page *page;
u32 *kaddr, *kend;
ntfs_name *name = NULL;
@@ -1290,7 +1289,6 @@ static int check_windows_hibernation_status(ntfs_volume *vol)
"is not the system volume.", i_size_read(vi));
goto iput_out;
}
- ni = NTFS_I(vi);
page = ntfs_map_page(vi->i_mapping, 0);
if (IS_ERR(page)) {
ntfs_error(vol->sb, "Failed to read from hiberfil.sys.");
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index be244692550..a9856e3eaaf 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -1053,7 +1053,7 @@ static int ocfs2_rename(struct inode *old_dir,
handle_t *handle = NULL;
struct buffer_head *old_dir_bh = NULL;
struct buffer_head *new_dir_bh = NULL;
- nlink_t old_dir_nlink = old_dir->i_nlink;
+ u32 old_dir_nlink = old_dir->i_nlink;
struct ocfs2_dinode *old_di;
struct ocfs2_dir_lookup_result old_inode_dot_dot_res = { NULL, };
struct ocfs2_dir_lookup_result target_lookup_res = { NULL, };
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 7898cd688a0..fc2c4388d12 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -292,11 +292,26 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
}
}
+/* Return 1 if 'cmd' will block on frozen filesystem */
+static int quotactl_cmd_write(int cmd)
+{
+ switch (cmd) {
+ case Q_GETFMT:
+ case Q_GETINFO:
+ case Q_SYNC:
+ case Q_XGETQSTAT:
+ case Q_XGETQUOTA:
+ case Q_XQUOTASYNC:
+ return 0;
+ }
+ return 1;
+}
+
/*
* look up a superblock on which quota ops will be performed
* - use the name of a block device to find the superblock thereon
*/
-static struct super_block *quotactl_block(const char __user *special)
+static struct super_block *quotactl_block(const char __user *special, int cmd)
{
#ifdef CONFIG_BLOCK
struct block_device *bdev;
@@ -309,7 +324,10 @@ static struct super_block *quotactl_block(const char __user *special)
putname(tmp);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
- sb = get_super(bdev);
+ if (quotactl_cmd_write(cmd))
+ sb = get_super_thawed(bdev);
+ else
+ sb = get_super(bdev);
bdput(bdev);
if (!sb)
return ERR_PTR(-ENODEV);
@@ -361,7 +379,7 @@ SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
pathp = &path;
}
- sb = quotactl_block(special);
+ sb = quotactl_block(special, cmds);
if (IS_ERR(sb)) {
ret = PTR_ERR(sb);
goto out;
diff --git a/fs/select.c b/fs/select.c
index d33418fdc85..e782258d0de 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -912,7 +912,7 @@ static long do_restart_poll(struct restart_block *restart_block)
}
SYSCALL_DEFINE3(poll, struct pollfd __user *, ufds, unsigned int, nfds,
- long, timeout_msecs)
+ int, timeout_msecs)
{
struct timespec end_time, *to = NULL;
int ret;
diff --git a/fs/signalfd.c b/fs/signalfd.c
index 492465b451d..7ae2a574cb2 100644
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -30,6 +30,21 @@
#include <linux/signalfd.h>
#include <linux/syscalls.h>
+void signalfd_cleanup(struct sighand_struct *sighand)
+{
+ wait_queue_head_t *wqh = &sighand->signalfd_wqh;
+ /*
+ * The lockless check can race with remove_wait_queue() in progress,
+ * but in this case its caller should run under rcu_read_lock() and
+ * sighand_cachep is SLAB_DESTROY_BY_RCU, we can safely return.
+ */
+ if (likely(!waitqueue_active(wqh)))
+ return;
+
+ /* wait_queue_t->func(POLLFREE) should do remove_wait_queue() */
+ wake_up_poll(wqh, POLLHUP | POLLFREE);
+}
+
struct signalfd_ctx {
sigset_t sigmask;
};
diff --git a/fs/super.c b/fs/super.c
index 6015c02296b..6277ec6cb60 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -634,6 +634,28 @@ rescan:
EXPORT_SYMBOL(get_super);
/**
+ * get_super_thawed - get thawed superblock of a device
+ * @bdev: device to get the superblock for
+ *
+ * Scans the superblock list and finds the superblock of the file system
+ * mounted on the device. The superblock is returned once it is thawed
+ * (or immediately if it was not frozen). %NULL is returned if no match
+ * is found.
+ */
+struct super_block *get_super_thawed(struct block_device *bdev)
+{
+ while (1) {
+ struct super_block *s = get_super(bdev);
+ if (!s || s->s_frozen == SB_UNFROZEN)
+ return s;
+ up_read(&s->s_umount);
+ vfs_check_frozen(s, SB_FREEZE_WRITE);
+ put_super(s);
+ }
+}
+EXPORT_SYMBOL(get_super_thawed);
+
+/**
* get_active_super - get an active reference to the superblock of a device
* @bdev: device to get the superblock for
*
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index cbcb7bea38e..53db20ee3e7 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -139,10 +139,10 @@ xfs_qm_adjust_dqtimers(
if (!d->d_btimer) {
if ((d->d_blk_softlimit &&
- (be64_to_cpu(d->d_bcount) >=
+ (be64_to_cpu(d->d_bcount) >
be64_to_cpu(d->d_blk_softlimit))) ||
(d->d_blk_hardlimit &&
- (be64_to_cpu(d->d_bcount) >=
+ (be64_to_cpu(d->d_bcount) >
be64_to_cpu(d->d_blk_hardlimit)))) {
d->d_btimer = cpu_to_be32(get_seconds() +
mp->m_quotainfo->qi_btimelimit);
@@ -151,10 +151,10 @@ xfs_qm_adjust_dqtimers(
}
} else {
if ((!d->d_blk_softlimit ||
- (be64_to_cpu(d->d_bcount) <
+ (be64_to_cpu(d->d_bcount) <=
be64_to_cpu(d->d_blk_softlimit))) &&
(!d->d_blk_hardlimit ||
- (be64_to_cpu(d->d_bcount) <
+ (be64_to_cpu(d->d_bcount) <=
be64_to_cpu(d->d_blk_hardlimit)))) {
d->d_btimer = 0;
}
@@ -162,10 +162,10 @@ xfs_qm_adjust_dqtimers(
if (!d->d_itimer) {
if ((d->d_ino_softlimit &&
- (be64_to_cpu(d->d_icount) >=
+ (be64_to_cpu(d->d_icount) >
be64_to_cpu(d->d_ino_softlimit))) ||
(d->d_ino_hardlimit &&
- (be64_to_cpu(d->d_icount) >=
+ (be64_to_cpu(d->d_icount) >
be64_to_cpu(d->d_ino_hardlimit)))) {
d->d_itimer = cpu_to_be32(get_seconds() +
mp->m_quotainfo->qi_itimelimit);
@@ -174,10 +174,10 @@ xfs_qm_adjust_dqtimers(
}
} else {
if ((!d->d_ino_softlimit ||
- (be64_to_cpu(d->d_icount) <
+ (be64_to_cpu(d->d_icount) <=
be64_to_cpu(d->d_ino_softlimit))) &&
(!d->d_ino_hardlimit ||
- (be64_to_cpu(d->d_icount) <
+ (be64_to_cpu(d->d_icount) <=
be64_to_cpu(d->d_ino_hardlimit)))) {
d->d_itimer = 0;
}
@@ -185,10 +185,10 @@ xfs_qm_adjust_dqtimers(
if (!d->d_rtbtimer) {
if ((d->d_rtb_softlimit &&
- (be64_to_cpu(d->d_rtbcount) >=
+ (be64_to_cpu(d->d_rtbcount) >
be64_to_cpu(d->d_rtb_softlimit))) ||
(d->d_rtb_hardlimit &&
- (be64_to_cpu(d->d_rtbcount) >=
+ (be64_to_cpu(d->d_rtbcount) >
be64_to_cpu(d->d_rtb_hardlimit)))) {
d->d_rtbtimer = cpu_to_be32(get_seconds() +
mp->m_quotainfo->qi_rtbtimelimit);
@@ -197,10 +197,10 @@ xfs_qm_adjust_dqtimers(
}
} else {
if ((!d->d_rtb_softlimit ||
- (be64_to_cpu(d->d_rtbcount) <
+ (be64_to_cpu(d->d_rtbcount) <=
be64_to_cpu(d->d_rtb_softlimit))) &&
(!d->d_rtb_hardlimit ||
- (be64_to_cpu(d->d_rtbcount) <
+ (be64_to_cpu(d->d_rtbcount) <=
be64_to_cpu(d->d_rtb_hardlimit)))) {
d->d_rtbtimer = 0;
}
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 15ff5392fb6..0ed9ee77937 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -1981,7 +1981,7 @@ xfs_qm_dqcheck(
if (!errs && ddq->d_id) {
if (ddq->d_blk_softlimit &&
- be64_to_cpu(ddq->d_bcount) >=
+ be64_to_cpu(ddq->d_bcount) >
be64_to_cpu(ddq->d_blk_softlimit)) {
if (!ddq->d_btimer) {
if (flags & XFS_QMOPT_DOWARN)
@@ -1992,7 +1992,7 @@ xfs_qm_dqcheck(
}
}
if (ddq->d_ino_softlimit &&
- be64_to_cpu(ddq->d_icount) >=
+ be64_to_cpu(ddq->d_icount) >
be64_to_cpu(ddq->d_ino_softlimit)) {
if (!ddq->d_itimer) {
if (flags & XFS_QMOPT_DOWARN)
@@ -2003,7 +2003,7 @@ xfs_qm_dqcheck(
}
}
if (ddq->d_rtb_softlimit &&
- be64_to_cpu(ddq->d_rtbcount) >=
+ be64_to_cpu(ddq->d_rtbcount) >
be64_to_cpu(ddq->d_rtb_softlimit)) {
if (!ddq->d_rtbtimer) {
if (flags & XFS_QMOPT_DOWARN)
diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
index eafbcff81f3..711a86e39ff 100644
--- a/fs/xfs/xfs_qm_syscalls.c
+++ b/fs/xfs/xfs_qm_syscalls.c
@@ -813,11 +813,11 @@ xfs_qm_export_dquot(
(XFS_IS_OQUOTA_ENFORCED(mp) &&
(dst->d_flags & (FS_PROJ_QUOTA | FS_GROUP_QUOTA)))) &&
dst->d_id != 0) {
- if (((int) dst->d_bcount >= (int) dst->d_blk_softlimit) &&
+ if (((int) dst->d_bcount > (int) dst->d_blk_softlimit) &&
(dst->d_blk_softlimit > 0)) {
ASSERT(dst->d_btimer != 0);
}
- if (((int) dst->d_icount >= (int) dst->d_ino_softlimit) &&
+ if (((int) dst->d_icount > (int) dst->d_ino_softlimit) &&
(dst->d_ino_softlimit > 0)) {
ASSERT(dst->d_itimer != 0);
}
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c
index 329b06aba1c..7adcdf15ae0 100644
--- a/fs/xfs/xfs_trans.c
+++ b/fs/xfs/xfs_trans.c
@@ -1151,8 +1151,8 @@ xfs_trans_add_item(
{
struct xfs_log_item_desc *lidp;
- ASSERT(lip->li_mountp = tp->t_mountp);
- ASSERT(lip->li_ailp = tp->t_mountp->m_ail);
+ ASSERT(lip->li_mountp == tp->t_mountp);
+ ASSERT(lip->li_ailp == tp->t_mountp->m_ail);
lidp = kmem_zone_zalloc(xfs_log_item_desc_zone, KM_SLEEP | KM_NOFS);
diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
index 4d00ee67792..c4ba366d24e 100644
--- a/fs/xfs/xfs_trans_dquot.c
+++ b/fs/xfs/xfs_trans_dquot.c
@@ -649,12 +649,12 @@ xfs_trans_dqresv(
* nblks.
*/
if (hardlimit > 0ULL &&
- hardlimit <= nblks + *resbcountp) {
+ hardlimit < nblks + *resbcountp) {
xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
goto error_return;
}
if (softlimit > 0ULL &&
- softlimit <= nblks + *resbcountp) {
+ softlimit < nblks + *resbcountp) {
if ((timer != 0 && get_seconds() > timer) ||
(warns != 0 && warns >= warnlimit)) {
xfs_quota_warn(mp, dqp,
@@ -677,11 +677,13 @@ xfs_trans_dqresv(
if (!softlimit)
softlimit = q->qi_isoftlimit;
- if (hardlimit > 0ULL && count >= hardlimit) {
+ if (hardlimit > 0ULL &&
+ hardlimit < ninos + count) {
xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
goto error_return;
}
- if (softlimit > 0ULL && count >= softlimit) {
+ if (softlimit > 0ULL &&
+ softlimit < ninos + count) {
if ((timer != 0 && get_seconds() > timer) ||
(warns != 0 && warns >= warnlimit)) {
xfs_quota_warn(mp, dqp,
diff --git a/include/asm-generic/io-64-nonatomic-hi-lo.h b/include/asm-generic/io-64-nonatomic-hi-lo.h
new file mode 100644
index 00000000000..a6806a94250
--- /dev/null
+++ b/include/asm-generic/io-64-nonatomic-hi-lo.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_IO_64_NONATOMIC_HI_LO_H_
+#define _ASM_IO_64_NONATOMIC_HI_LO_H_
+
+#include <linux/io.h>
+#include <asm-generic/int-ll64.h>
+
+#ifndef readq
+static inline __u64 readq(const volatile void __iomem *addr)
+{
+ const volatile u32 __iomem *p = addr;
+ u32 low, high;
+
+ high = readl(p + 1);
+ low = readl(p);
+
+ return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(__u64 val, volatile void __iomem *addr)
+{
+ writel(val >> 32, addr + 4);
+ writel(val, addr);
+}
+#endif
+
+#endif /* _ASM_IO_64_NONATOMIC_HI_LO_H_ */
diff --git a/include/asm-generic/io-64-nonatomic-lo-hi.h b/include/asm-generic/io-64-nonatomic-lo-hi.h
new file mode 100644
index 00000000000..ca546b1ff8b
--- /dev/null
+++ b/include/asm-generic/io-64-nonatomic-lo-hi.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_IO_64_NONATOMIC_LO_HI_H_
+#define _ASM_IO_64_NONATOMIC_LO_HI_H_
+
+#include <linux/io.h>
+#include <asm-generic/int-ll64.h>
+
+#ifndef readq
+static inline __u64 readq(const volatile void __iomem *addr)
+{
+ const volatile u32 __iomem *p = addr;
+ u32 low, high;
+
+ low = readl(p);
+ high = readl(p + 1);
+
+ return low + ((u64)high << 32);
+}
+#endif
+
+#ifndef writeq
+static inline void writeq(__u64 val, volatile void __iomem *addr)
+{
+ writel(val, addr);
+ writel(val >> 32, addr + 4);
+}
+#endif
+
+#endif /* _ASM_IO_64_NONATOMIC_LO_HI_H_ */
diff --git a/include/asm-generic/iomap.h b/include/asm-generic/iomap.h
index 8a3d4fde260..6afd7d6a989 100644
--- a/include/asm-generic/iomap.h
+++ b/include/asm-generic/iomap.h
@@ -70,7 +70,7 @@ extern void ioport_unmap(void __iomem *);
/* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev;
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
-#else
+#elif defined(CONFIG_GENERIC_IOMAP)
struct pci_dev;
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
{ }
diff --git a/include/asm-generic/pci_iomap.h b/include/asm-generic/pci_iomap.h
index e58fcf89137..ce37349860f 100644
--- a/include/asm-generic/pci_iomap.h
+++ b/include/asm-generic/pci_iomap.h
@@ -25,7 +25,7 @@ extern void __iomem *__pci_ioport_map(struct pci_dev *dev, unsigned long port,
#define __pci_ioport_map(dev, port, nr) ioport_map((port), (nr))
#endif
-#else
+#elif defined(CONFIG_GENERIC_PCI_IOMAP)
static inline void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
{
return NULL;
diff --git a/include/asm-generic/poll.h b/include/asm-generic/poll.h
index 44bce836d35..9ce7f44aebd 100644
--- a/include/asm-generic/poll.h
+++ b/include/asm-generic/poll.h
@@ -28,6 +28,8 @@
#define POLLRDHUP 0x2000
#endif
+#define POLLFREE 0x4000 /* currently only for epoll */
+
struct pollfd {
int fd;
short events;
diff --git a/include/drm/Kbuild b/include/drm/Kbuild
index a5c0e10fd47..1e38a19d68f 100644
--- a/include/drm/Kbuild
+++ b/include/drm/Kbuild
@@ -2,6 +2,7 @@ header-y += drm.h
header-y += drm_fourcc.h
header-y += drm_mode.h
header-y += drm_sarea.h
+header-y += exynos_drm.h
header-y += i810_drm.h
header-y += i915_drm.h
header-y += mga_drm.h
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h
index 5e120f1c5cd..1ed3aae893a 100644
--- a/include/drm/exynos_drm.h
+++ b/include/drm/exynos_drm.h
@@ -97,15 +97,30 @@ struct drm_exynos_plane_set_zpos {
#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
+#ifdef __KERNEL__
+
/**
- * Platform Specific Structure for DRM based FIMD.
+ * A structure for lcd panel information.
*
* @timing: default video mode for initializing
+ * @width_mm: physical size of lcd width.
+ * @height_mm: physical size of lcd height.
+ */
+struct exynos_drm_panel_info {
+ struct fb_videomode timing;
+ u32 width_mm;
+ u32 height_mm;
+};
+
+/**
+ * Platform Specific Structure for DRM based FIMD.
+ *
+ * @panel: default panel info for initializing
* @default_win: default window layer number to be used for UI.
* @bpp: default bit per pixel.
*/
struct exynos_drm_fimd_pdata {
- struct fb_videomode timing;
+ struct exynos_drm_panel_info panel;
u32 vidcon0;
u32 vidcon1;
unsigned int default_win;
@@ -139,4 +154,5 @@ struct exynos_drm_hdmi_pdata {
unsigned int bpp;
};
-#endif
+#endif /* __KERNEL__ */
+#endif /* _EXYNOS_DRM_H_ */
diff --git a/include/linux/amba/bus.h b/include/linux/amba/bus.h
index 724c69c40bb..a9fab831caf 100644
--- a/include/linux/amba/bus.h
+++ b/include/linux/amba/bus.h
@@ -60,6 +60,9 @@ extern struct bus_type amba_bustype;
int amba_driver_register(struct amba_driver *);
void amba_driver_unregister(struct amba_driver *);
+struct amba_device *amba_device_alloc(const char *, resource_size_t, size_t);
+void amba_device_put(struct amba_device *);
+int amba_device_add(struct amba_device *, struct resource *);
int amba_device_register(struct amba_device *, struct resource *);
void amba_device_unregister(struct amba_device *);
struct amba_device *amba_find_device(const char *, struct device *, unsigned int, unsigned int);
@@ -89,4 +92,37 @@ void amba_release_regions(struct amba_device *);
#define amba_manf(d) AMBA_MANF_BITS((d)->periphid)
#define amba_part(d) AMBA_PART_BITS((d)->periphid)
+#define __AMBA_DEV(busid, data, mask) \
+ { \
+ .coherent_dma_mask = mask, \
+ .init_name = busid, \
+ .platform_data = data, \
+ }
+
+/*
+ * APB devices do not themselves have the ability to address memory,
+ * so DMA masks should be zero (much like USB peripheral devices.)
+ * The DMA controller DMA masks should be used instead (much like
+ * USB host controllers in conventional PCs.)
+ */
+#define AMBA_APB_DEVICE(name, busid, id, base, irqs, data) \
+struct amba_device name##_device = { \
+ .dev = __AMBA_DEV(busid, data, 0), \
+ .res = DEFINE_RES_MEM(base, SZ_4K), \
+ .irq = irqs, \
+ .periphid = id, \
+}
+
+/*
+ * AHB devices are DMA capable, so set their DMA masks
+ */
+#define AMBA_AHB_DEVICE(name, busid, id, base, irqs, data) \
+struct amba_device name##_device = { \
+ .dev = __AMBA_DEV(busid, data, ~0ULL), \
+ .res = DEFINE_RES_MEM(base, SZ_4K), \
+ .dma_mask = ~0ULL, \
+ .irq = irqs, \
+ .periphid = id, \
+}
+
#endif
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 41c9f6515f4..7e05fcee75a 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -561,5 +561,9 @@ asmlinkage ssize_t compat_sys_process_vm_writev(compat_pid_t pid,
unsigned long liovcnt, const struct compat_iovec __user *rvec,
unsigned long riovcnt, unsigned long flags);
+#else
+
+#define is_compat_task() (0)
+
#endif /* CONFIG_COMPAT */
#endif /* _LINUX_COMPAT_H */
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index d64a55b23af..4270bedd230 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -54,18 +54,17 @@ extern struct dentry_stat_t dentry_stat;
static inline int dentry_cmp(const unsigned char *cs, size_t scount,
const unsigned char *ct, size_t tcount)
{
- int ret;
if (scount != tcount)
return 1;
+
do {
- ret = (*cs != *ct);
- if (ret)
- break;
+ if (*cs != *ct)
+ return 1;
cs++;
ct++;
tcount--;
} while (tcount);
- return ret;
+ return 0;
}
/* Name hashing routines. Initial hash value */
@@ -89,14 +88,7 @@ static inline unsigned long end_name_hash(unsigned long hash)
}
/* Compute the hash for a name string. */
-static inline unsigned int
-full_name_hash(const unsigned char *name, unsigned int len)
-{
- unsigned long hash = init_name_hash();
- while (len--)
- hash = partial_name_hash(*name++, hash);
- return end_name_hash(hash);
-}
+extern unsigned int full_name_hash(const unsigned char *, unsigned int);
/*
* Try to keep struct dentry aligned on 64 byte cachelines (this will
@@ -309,7 +301,8 @@ extern struct dentry *d_ancestor(struct dentry *, struct dentry *);
extern struct dentry *d_lookup(struct dentry *, struct qstr *);
extern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *);
extern struct dentry *__d_lookup(struct dentry *, struct qstr *);
-extern struct dentry *__d_lookup_rcu(struct dentry *parent, struct qstr *name,
+extern struct dentry *__d_lookup_rcu(const struct dentry *parent,
+ const struct qstr *name,
unsigned *seq, struct inode **inode);
/**
diff --git a/include/linux/digsig.h b/include/linux/digsig.h
index b01558b1581..6f85a070bb4 100644
--- a/include/linux/digsig.h
+++ b/include/linux/digsig.h
@@ -30,7 +30,7 @@ enum digest_algo {
struct pubkey_hdr {
uint8_t version; /* key format version */
- time_t timestamp; /* key made, always 0 for now */
+ uint32_t timestamp; /* key made, always 0 for now */
uint8_t algo;
uint8_t nmpi;
char mpi[0];
@@ -38,7 +38,7 @@ struct pubkey_hdr {
struct signature_hdr {
uint8_t version; /* signature format version */
- time_t timestamp; /* signature made */
+ uint32_t timestamp; /* signature made */
uint8_t algo;
uint8_t hash;
uint8_t keyid[8];
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 386da09f229..69cd5bb640f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2496,6 +2496,7 @@ extern void get_filesystem(struct file_system_type *fs);
extern void put_filesystem(struct file_system_type *fs);
extern struct file_system_type *get_fs_type(const char *name);
extern struct super_block *get_super(struct block_device *);
+extern struct super_block *get_super_thawed(struct block_device *);
extern struct super_block *get_active_super(struct block_device *bdev);
extern void drop_super(struct super_block *sb);
extern void iterate_supers(void (*)(struct super_block *, void *), void *);
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index c52d4b5f872..4b24ff453ae 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -137,6 +137,7 @@ enum {
IFLA_AF_SPEC,
IFLA_GROUP, /* Group the device belongs to */
IFLA_NET_NS_FD,
+ IFLA_EXT_MASK, /* Extended info mask, VFs, etc */
__IFLA_MAX
};
diff --git a/include/linux/irqdomain.h b/include/linux/irqdomain.h
index bd4272b61a1..ead4a421579 100644
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -9,99 +9,182 @@
* representation into a hardware irq number that can be mapped back to a
* Linux irq number without any extra platform support code.
*
- * irq_domain is expected to be embedded in an interrupt controller's private
- * data structure.
+ * Interrupt controller "domain" data structure. This could be defined as a
+ * irq domain controller. That is, it handles the mapping between hardware
+ * and virtual interrupt numbers for a given interrupt domain. The domain
+ * structure is generally created by the PIC code for a given PIC instance
+ * (though a domain can cover more than one PIC if they have a flat number
+ * model). It's the domain callbacks that are responsible for setting the
+ * irq_chip on a given irq_desc after it's been mapped.
+ *
+ * The host code and data structures are agnostic to whether or not
+ * we use an open firmware device-tree. We do have references to struct
+ * device_node in two places: in irq_find_host() to find the host matching
+ * a given interrupt controller node, and of course as an argument to its
+ * counterpart domain->ops->match() callback. However, those are treated as
+ * generic pointers by the core and the fact that it's actually a device-node
+ * pointer is purely a convention between callers and implementation. This
+ * code could thus be used on other architectures by replacing those two
+ * by some sort of arch-specific void * "token" used to identify interrupt
+ * controllers.
*/
+
#ifndef _LINUX_IRQDOMAIN_H
#define _LINUX_IRQDOMAIN_H
-#include <linux/irq.h>
-#include <linux/mod_devicetable.h>
+#include <linux/types.h>
+#include <linux/radix-tree.h>
-#ifdef CONFIG_IRQ_DOMAIN
struct device_node;
struct irq_domain;
+struct of_device_id;
+
+/* Number of irqs reserved for a legacy isa controller */
+#define NUM_ISA_INTERRUPTS 16
+
+/* This type is the placeholder for a hardware interrupt number. It has to
+ * be big enough to enclose whatever representation is used by a given
+ * platform.
+ */
+typedef unsigned long irq_hw_number_t;
/**
* struct irq_domain_ops - Methods for irq_domain objects
- * @to_irq: (optional) given a local hardware irq number, return the linux
- * irq number. If to_irq is not implemented, then the irq_domain
- * will use this translation: irq = (domain->irq_base + hwirq)
- * @dt_translate: Given a device tree node and interrupt specifier, decode
- * the hardware irq number and linux irq type value.
+ * @match: Match an interrupt controller device node to a host, returns
+ * 1 on a match
+ * @map: Create or update a mapping between a virtual irq number and a hw
+ * irq number. This is called only once for a given mapping.
+ * @unmap: Dispose of such a mapping
+ * @xlate: Given a device tree node and interrupt specifier, decode
+ * the hardware irq number and linux irq type value.
+ *
+ * Functions below are provided by the driver and called whenever a new mapping
+ * is created or an old mapping is disposed. The driver can then proceed to
+ * whatever internal data structures management is required. It also needs
+ * to setup the irq_desc when returning from map().
*/
struct irq_domain_ops {
- unsigned int (*to_irq)(struct irq_domain *d, unsigned long hwirq);
-
-#ifdef CONFIG_OF
- int (*dt_translate)(struct irq_domain *d, struct device_node *node,
- const u32 *intspec, unsigned int intsize,
- unsigned long *out_hwirq, unsigned int *out_type);
-#endif /* CONFIG_OF */
+ int (*match)(struct irq_domain *d, struct device_node *node);
+ int (*map)(struct irq_domain *d, unsigned int virq, irq_hw_number_t hw);
+ void (*unmap)(struct irq_domain *d, unsigned int virq);
+ int (*xlate)(struct irq_domain *d, struct device_node *node,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq, unsigned int *out_type);
};
/**
* struct irq_domain - Hardware interrupt number translation object
- * @list: Element in global irq_domain list.
+ * @link: Element in global irq_domain list.
+ * @revmap_type: Method used for reverse mapping hwirq numbers to linux irq. This
+ * will be one of the IRQ_DOMAIN_MAP_* values.
+ * @revmap_data: Revmap method specific data.
+ * @ops: pointer to irq_domain methods
+ * @host_data: private data pointer for use by owner. Not touched by irq_domain
+ * core code.
* @irq_base: Start of irq_desc range assigned to the irq_domain. The creator
* of the irq_domain is responsible for allocating the array of
* irq_desc structures.
* @nr_irq: Number of irqs managed by the irq domain
* @hwirq_base: Starting number for hwirqs managed by the irq domain
- * @ops: pointer to irq_domain methods
- * @priv: private data pointer for use by owner. Not touched by irq_domain
- * core code.
* @of_node: (optional) Pointer to device tree nodes associated with the
* irq_domain. Used when decoding device tree interrupt specifiers.
*/
struct irq_domain {
- struct list_head list;
- unsigned int irq_base;
- unsigned int nr_irq;
- unsigned int hwirq_base;
+ struct list_head link;
+
+ /* type of reverse mapping_technique */
+ unsigned int revmap_type;
+ union {
+ struct {
+ unsigned int size;
+ unsigned int first_irq;
+ irq_hw_number_t first_hwirq;
+ } legacy;
+ struct {
+ unsigned int size;
+ unsigned int *revmap;
+ } linear;
+ struct radix_tree_root tree;
+ } revmap_data;
const struct irq_domain_ops *ops;
- void *priv;
+ void *host_data;
+ irq_hw_number_t inval_irq;
+
+ /* Optional device node pointer */
struct device_node *of_node;
};
-/**
- * irq_domain_to_irq() - Translate from a hardware irq to a linux irq number
- *
- * Returns the linux irq number associated with a hardware irq. By default,
- * the mapping is irq == domain->irq_base + hwirq, but this mapping can
- * be overridden if the irq_domain implements a .to_irq() hook.
- */
-static inline unsigned int irq_domain_to_irq(struct irq_domain *d,
- unsigned long hwirq)
+#ifdef CONFIG_IRQ_DOMAIN
+struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+ unsigned int size,
+ unsigned int first_irq,
+ irq_hw_number_t first_hwirq,
+ const struct irq_domain_ops *ops,
+ void *host_data);
+struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+ unsigned int size,
+ const struct irq_domain_ops *ops,
+ void *host_data);
+struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+ const struct irq_domain_ops *ops,
+ void *host_data);
+struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+ const struct irq_domain_ops *ops,
+ void *host_data);
+
+extern struct irq_domain *irq_find_host(struct device_node *node);
+extern void irq_set_default_host(struct irq_domain *host);
+extern void irq_set_virq_count(unsigned int count);
+
+static inline struct irq_domain *irq_domain_add_legacy_isa(
+ struct device_node *of_node,
+ const struct irq_domain_ops *ops,
+ void *host_data)
{
- if (d->ops->to_irq)
- return d->ops->to_irq(d, hwirq);
- if (WARN_ON(hwirq < d->hwirq_base))
- return 0;
- return d->irq_base + hwirq - d->hwirq_base;
+ return irq_domain_add_legacy(of_node, NUM_ISA_INTERRUPTS, 0, 0, ops,
+ host_data);
}
+extern struct irq_domain *irq_find_host(struct device_node *node);
+extern void irq_set_default_host(struct irq_domain *host);
+extern void irq_set_virq_count(unsigned int count);
-#define irq_domain_for_each_hwirq(d, hw) \
- for (hw = d->hwirq_base; hw < d->hwirq_base + d->nr_irq; hw++)
-#define irq_domain_for_each_irq(d, hw, irq) \
- for (hw = d->hwirq_base, irq = irq_domain_to_irq(d, hw); \
- hw < d->hwirq_base + d->nr_irq; \
- hw++, irq = irq_domain_to_irq(d, hw))
+extern unsigned int irq_create_mapping(struct irq_domain *host,
+ irq_hw_number_t hwirq);
+extern void irq_dispose_mapping(unsigned int virq);
+extern unsigned int irq_find_mapping(struct irq_domain *host,
+ irq_hw_number_t hwirq);
+extern unsigned int irq_create_direct_mapping(struct irq_domain *host);
+extern void irq_radix_revmap_insert(struct irq_domain *host, unsigned int virq,
+ irq_hw_number_t hwirq);
+extern unsigned int irq_radix_revmap_lookup(struct irq_domain *host,
+ irq_hw_number_t hwirq);
+extern unsigned int irq_linear_revmap(struct irq_domain *host,
+ irq_hw_number_t hwirq);
-extern void irq_domain_add(struct irq_domain *domain);
-extern void irq_domain_del(struct irq_domain *domain);
+extern const struct irq_domain_ops irq_domain_simple_ops;
-extern struct irq_domain_ops irq_domain_simple_ops;
-#endif /* CONFIG_IRQ_DOMAIN */
+/* stock xlate functions */
+int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq, unsigned int *out_type);
+int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq, unsigned int *out_type);
+int irq_domain_xlate_onetwocell(struct irq_domain *d, struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq, unsigned int *out_type);
-#if defined(CONFIG_IRQ_DOMAIN) && defined(CONFIG_OF_IRQ)
-extern void irq_domain_add_simple(struct device_node *controller, int irq_base);
+#if defined(CONFIG_OF_IRQ)
extern void irq_domain_generate_simple(const struct of_device_id *match,
u64 phys_base, unsigned int irq_start);
-#else /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
+#else /* CONFIG_OF_IRQ */
static inline void irq_domain_generate_simple(const struct of_device_id *match,
u64 phys_base, unsigned int irq_start) { }
-#endif /* CONFIG_IRQ_DOMAIN && CONFIG_OF_IRQ */
+#endif /* !CONFIG_OF_IRQ */
+
+#else /* CONFIG_IRQ_DOMAIN */
+static inline void irq_dispose_mapping(unsigned int virq) { }
+#endif /* !CONFIG_IRQ_DOMAIN */
#endif /* _LINUX_IRQDOMAIN_H */
diff --git a/include/linux/netfilter_bridge/ebtables.h b/include/linux/netfilter_bridge/ebtables.h
index 8797ed16feb..4dd5bd6994a 100644
--- a/include/linux/netfilter_bridge/ebtables.h
+++ b/include/linux/netfilter_bridge/ebtables.h
@@ -285,8 +285,8 @@ struct ebt_table {
struct module *me;
};
-#define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_replace)-1)) & \
- ~(__alignof__(struct ebt_replace)-1))
+#define EBT_ALIGN(s) (((s) + (__alignof__(struct _xt_align)-1)) & \
+ ~(__alignof__(struct _xt_align)-1))
extern struct ebt_table *ebt_register_table(struct net *net,
const struct ebt_table *table);
extern void ebt_unregister_table(struct net *net, struct ebt_table *table);
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index a764cef06b7..d6ba9a12591 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -614,7 +614,6 @@ struct nfs_getaclargs {
size_t acl_len;
unsigned int acl_pgbase;
struct page ** acl_pages;
- struct page * acl_scratch;
struct nfs4_sequence_args seq_args;
};
@@ -624,6 +623,7 @@ struct nfs_getaclres {
size_t acl_len;
size_t acl_data_offset;
int acl_flags;
+ struct page * acl_scratch;
struct nfs4_sequence_res seq_res;
};
diff --git a/include/linux/of_address.h b/include/linux/of_address.h
index 3118623c2c1..01b925ad8d7 100644
--- a/include/linux/of_address.h
+++ b/include/linux/of_address.h
@@ -4,6 +4,7 @@
#include <linux/errno.h>
#include <linux/of.h>
+#ifdef CONFIG_OF_ADDRESS
extern u64 of_translate_address(struct device_node *np, const __be32 *addr);
extern int of_address_to_resource(struct device_node *dev, int index,
struct resource *r);
@@ -25,12 +26,37 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
#define pci_address_to_pio pci_address_to_pio
#endif
-#ifdef CONFIG_PCI
+#else /* CONFIG_OF_ADDRESS */
+static inline int of_address_to_resource(struct device_node *dev, int index,
+ struct resource *r)
+{
+ return -EINVAL;
+}
+static inline struct device_node *of_find_matching_node_by_address(
+ struct device_node *from,
+ const struct of_device_id *matches,
+ u64 base_address)
+{
+ return NULL;
+}
+static inline void __iomem *of_iomap(struct device_node *device, int index)
+{
+ return NULL;
+}
+static inline const u32 *of_get_address(struct device_node *dev, int index,
+ u64 *size, unsigned int *flags)
+{
+ return NULL;
+}
+#endif /* CONFIG_OF_ADDRESS */
+
+
+#if defined(CONFIG_OF_ADDRESS) && defined(CONFIG_PCI)
extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no,
u64 *size, unsigned int *flags);
extern int of_pci_address_to_resource(struct device_node *dev, int bar,
struct resource *r);
-#else /* CONFIG_PCI */
+#else /* CONFIG_OF_ADDRESS && CONFIG_PCI */
static inline int of_pci_address_to_resource(struct device_node *dev, int bar,
struct resource *r)
{
@@ -42,8 +68,7 @@ static inline const __be32 *of_get_pci_address(struct device_node *dev,
{
return NULL;
}
-#endif /* CONFIG_PCI */
-
+#endif /* CONFIG_OF_ADDRESS && CONFIG_PCI */
#endif /* __OF_ADDRESS_H */
diff --git a/include/linux/of_irq.h b/include/linux/of_irq.h
index d0307eed20c..d229ad3edee 100644
--- a/include/linux/of_irq.h
+++ b/include/linux/of_irq.h
@@ -6,6 +6,7 @@ struct of_irq;
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/ioport.h>
#include <linux/of.h>
@@ -65,9 +66,6 @@ extern int of_irq_map_one(struct device_node *device, int index,
extern unsigned int irq_create_of_mapping(struct device_node *controller,
const u32 *intspec,
unsigned int intsize);
-#ifdef CONFIG_IRQ_DOMAIN
-extern void irq_dispose_mapping(unsigned int irq);
-#endif
extern int of_irq_to_resource(struct device_node *dev, int index,
struct resource *r);
extern int of_irq_count(struct device_node *dev);
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h
index 040ce2f6e8d..242fa3563e2 100644
--- a/include/linux/of_platform.h
+++ b/include/linux/of_platform.h
@@ -81,7 +81,7 @@ extern struct platform_device *of_device_alloc(struct device_node *np,
struct device *parent);
extern struct platform_device *of_find_device_by_node(struct device_node *np);
-#if !defined(CONFIG_SPARC) /* SPARC has its own device registration method */
+#ifdef CONFIG_OF_ADDRESS /* device reg helpers depend on OF_ADDRESS */
/* Platform devices and busses creation */
extern struct platform_device *of_platform_device_create(struct device_node *np,
const char *bus_id,
@@ -94,7 +94,15 @@ extern int of_platform_populate(struct device_node *root,
const struct of_device_id *matches,
const struct of_dev_auxdata *lookup,
struct device *parent);
-#endif /* !CONFIG_SPARC */
+#else
+static inline int of_platform_populate(struct device_node *root,
+ const struct of_device_id *matches,
+ const struct of_dev_auxdata *lookup,
+ struct device *parent)
+{
+ return -ENODEV;
+}
+#endif /* !CONFIG_OF_ADDRESS */
#endif /* CONFIG_OF_DEVICE */
diff --git a/arch/arm/mach-tegra/include/mach/system.h b/include/linux/platform_data/tegra_emc.h
index a312988bf6f..df67505e98f 100644
--- a/arch/arm/mach-tegra/include/mach/system.h
+++ b/include/linux/platform_data/tegra_emc.h
@@ -1,11 +1,9 @@
/*
- * arch/arm/mach-tegra/include/mach/system.h
- *
- * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2011 Google, Inc.
*
* Author:
- * Colin Cross <ccross@google.com>
- * Erik Gilling <konkers@google.com>
+ * Colin Cross <ccross@android.com>
+ * Olof Johansson <olof@lixom.net>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -18,11 +16,19 @@
*
*/
-#ifndef __MACH_TEGRA_SYSTEM_H
-#define __MACH_TEGRA_SYSTEM_H
+#ifndef __TEGRA_EMC_H_
+#define __TEGRA_EMC_H_
+
+#define TEGRA_EMC_NUM_REGS 46
+
+struct tegra_emc_table {
+ unsigned long rate;
+ u32 regs[TEGRA_EMC_NUM_REGS];
+};
-static inline void arch_idle(void)
-{
-}
+struct tegra_emc_pdata {
+ int num_tables;
+ struct tegra_emc_table *tables;
+};
#endif
diff --git a/include/linux/regset.h b/include/linux/regset.h
index 8abee655622..686f37327a4 100644
--- a/include/linux/regset.h
+++ b/include/linux/regset.h
@@ -335,8 +335,11 @@ static inline int copy_regset_to_user(struct task_struct *target,
{
const struct user_regset *regset = &view->regsets[setno];
+ if (!regset->get)
+ return -EOPNOTSUPP;
+
if (!access_ok(VERIFY_WRITE, data, size))
- return -EIO;
+ return -EFAULT;
return regset->get(target, regset, offset, size, NULL, data);
}
@@ -358,8 +361,11 @@ static inline int copy_regset_from_user(struct task_struct *target,
{
const struct user_regset *regset = &view->regsets[setno];
+ if (!regset->set)
+ return -EOPNOTSUPP;
+
if (!access_ok(VERIFY_READ, data, size))
- return -EIO;
+ return -EFAULT;
return regset->set(target, regset, offset, size, NULL, data);
}
diff --git a/include/linux/regulator/bq24022.h b/include/linux/regulator/bq24022.h
deleted file mode 100644
index a6d014005d4..00000000000
--- a/include/linux/regulator/bq24022.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Support for TI bq24022 (bqTINY-II) Dual Input (USB/AC Adpater)
- * 1-Cell Li-Ion Charger connected via GPIOs.
- *
- * Copyright (c) 2008 Philipp Zabel
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-
-struct regulator_init_data;
-
-/**
- * bq24022_mach_info - platform data for bq24022
- * @gpio_nce: GPIO line connected to the nCE pin, used to enable / disable charging
- * @gpio_iset2: GPIO line connected to the ISET2 pin, used to limit charging current to 100 mA / 500 mA
- */
-struct bq24022_mach_info {
- int gpio_nce;
- int gpio_iset2;
- struct regulator_init_data *init_data;
-};
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index 8e872ead88b..577592ea0ea 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -602,6 +602,9 @@ struct tcamsg {
#define TCA_ACT_TAB 1 /* attr type must be >=1 */
#define TCAA_MAX 1
+/* New extended info filters for IFLA_EXT_MASK */
+#define RTEXT_FILTER_VF (1 << 0)
+
/* End of information exported to user level */
#ifdef __KERNEL__
diff --git a/include/linux/signalfd.h b/include/linux/signalfd.h
index 3ff4961da9b..247399b2979 100644
--- a/include/linux/signalfd.h
+++ b/include/linux/signalfd.h
@@ -61,13 +61,16 @@ static inline void signalfd_notify(struct task_struct *tsk, int sig)
wake_up(&tsk->sighand->signalfd_wqh);
}
+extern void signalfd_cleanup(struct sighand_struct *sighand);
+
#else /* CONFIG_SIGNALFD */
static inline void signalfd_notify(struct task_struct *tsk, int sig) { }
+static inline void signalfd_cleanup(struct sighand_struct *sighand) { }
+
#endif /* CONFIG_SIGNALFD */
#endif /* __KERNEL__ */
#endif /* _LINUX_SIGNALFD_H */
-
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 50db9b04a55..ae86adee374 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1465,6 +1465,16 @@ static inline void skb_set_mac_header(struct sk_buff *skb, const int offset)
}
#endif /* NET_SKBUFF_DATA_USES_OFFSET */
+static inline void skb_mac_header_rebuild(struct sk_buff *skb)
+{
+ if (skb_mac_header_was_set(skb)) {
+ const unsigned char *old_mac = skb_mac_header(skb);
+
+ skb_set_mac_header(skb, -skb->mac_len);
+ memmove(skb_mac_header(skb), old_mac, skb->mac_len);
+ }
+}
+
static inline int skb_checksum_start_offset(const struct sk_buff *skb)
{
return skb->csum_start - skb_headroom(skb);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 515669fa3c1..8ec1153ff57 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -624,7 +624,7 @@ asmlinkage long sys_socketpair(int, int, int, int __user *);
asmlinkage long sys_socketcall(int call, unsigned long __user *args);
asmlinkage long sys_listen(int, int);
asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds,
- long timeout);
+ int timeout);
asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
fd_set __user *exp, struct timeval __user *tvp);
asmlinkage long sys_old_select(struct sel_arg_struct __user *arg);
diff --git a/include/linux/usb/ch11.h b/include/linux/usb/ch11.h
index 31fdb4c6ee3..0b83acd3360 100644
--- a/include/linux/usb/ch11.h
+++ b/include/linux/usb/ch11.h
@@ -61,12 +61,6 @@
#define USB_PORT_FEAT_TEST 21
#define USB_PORT_FEAT_INDICATOR 22
#define USB_PORT_FEAT_C_PORT_L1 23
-#define USB_PORT_FEAT_C_PORT_LINK_STATE 25
-#define USB_PORT_FEAT_C_PORT_CONFIG_ERROR 26
-#define USB_PORT_FEAT_PORT_REMOTE_WAKE_MASK 27
-#define USB_PORT_FEAT_BH_PORT_RESET 28
-#define USB_PORT_FEAT_C_BH_PORT_RESET 29
-#define USB_PORT_FEAT_FORCE_LINKPM_ACCEPT 30
/*
* Port feature selectors added by USB 3.0 spec.
@@ -75,8 +69,8 @@
#define USB_PORT_FEAT_LINK_STATE 5
#define USB_PORT_FEAT_U1_TIMEOUT 23
#define USB_PORT_FEAT_U2_TIMEOUT 24
-#define USB_PORT_FEAT_C_LINK_STATE 25
-#define USB_PORT_FEAT_C_CONFIG_ERR 26
+#define USB_PORT_FEAT_C_PORT_LINK_STATE 25
+#define USB_PORT_FEAT_C_PORT_CONFIG_ERROR 26
#define USB_PORT_FEAT_REMOTE_WAKE_MASK 27
#define USB_PORT_FEAT_BH_PORT_RESET 28
#define USB_PORT_FEAT_C_BH_PORT_RESET 29
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index abaad6ed9b8..4a82ca0bb0b 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -256,4 +256,6 @@ void l2cap_exit(void);
int sco_init(void);
void sco_exit(void);
+void bt_sock_reclassify_lock(struct sock *sk, int proto);
+
#endif /* __BLUETOOTH_H */
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index ea9231f4935..453893b3120 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -540,7 +540,7 @@ void hci_conn_put_device(struct hci_conn *conn);
static inline void hci_conn_hold(struct hci_conn *conn)
{
atomic_inc(&conn->refcnt);
- cancel_delayed_work_sync(&conn->disc_work);
+ cancel_delayed_work(&conn->disc_work);
}
static inline void hci_conn_put(struct hci_conn *conn)
@@ -559,9 +559,9 @@ static inline void hci_conn_put(struct hci_conn *conn)
} else {
timeo = msecs_to_jiffies(10);
}
- cancel_delayed_work_sync(&conn->disc_work);
+ cancel_delayed_work(&conn->disc_work);
queue_delayed_work(conn->hdev->workqueue,
- &conn->disc_work, jiffies + timeo);
+ &conn->disc_work, timeo);
}
}
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 68f58915069..b1664ed884e 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -611,7 +611,7 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
{
BT_DBG("chan %p state %d timeout %ld", chan, chan->state, timeout);
- if (!__cancel_delayed_work(work))
+ if (!cancel_delayed_work(work))
l2cap_chan_hold(chan);
schedule_delayed_work(work, timeout);
}
@@ -619,20 +619,20 @@ static inline void l2cap_set_timer(struct l2cap_chan *chan,
static inline void l2cap_clear_timer(struct l2cap_chan *chan,
struct delayed_work *work)
{
- if (__cancel_delayed_work(work))
+ if (cancel_delayed_work(work))
l2cap_chan_put(chan);
}
#define __set_chan_timer(c, t) l2cap_set_timer(c, &c->chan_timer, (t))
#define __clear_chan_timer(c) l2cap_clear_timer(c, &c->chan_timer)
#define __set_retrans_timer(c) l2cap_set_timer(c, &c->retrans_timer, \
- L2CAP_DEFAULT_RETRANS_TO);
+ msecs_to_jiffies(L2CAP_DEFAULT_RETRANS_TO));
#define __clear_retrans_timer(c) l2cap_clear_timer(c, &c->retrans_timer)
#define __set_monitor_timer(c) l2cap_set_timer(c, &c->monitor_timer, \
- L2CAP_DEFAULT_MONITOR_TO);
+ msecs_to_jiffies(L2CAP_DEFAULT_MONITOR_TO));
#define __clear_monitor_timer(c) l2cap_clear_timer(c, &c->monitor_timer)
#define __set_ack_timer(c) l2cap_set_timer(c, &chan->ack_timer, \
- L2CAP_DEFAULT_ACK_TO);
+ msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
#define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
@@ -834,7 +834,7 @@ int l2cap_add_scid(struct l2cap_chan *chan, __u16 scid);
struct l2cap_chan *l2cap_chan_create(struct sock *sk);
void l2cap_chan_close(struct l2cap_chan *chan, int reason);
void l2cap_chan_destroy(struct l2cap_chan *chan);
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
bdaddr_t *dst);
int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
u32 priority);
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 8a2b0ae7dbd..ab86036bbf0 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -209,7 +209,7 @@ extern struct nf_conntrack_tuple_hash *
__nf_conntrack_find(struct net *net, u16 zone,
const struct nf_conntrack_tuple *tuple);
-extern void nf_conntrack_hash_insert(struct nf_conn *ct);
+extern int nf_conntrack_hash_check_insert(struct nf_conn *ct);
extern void nf_ct_delete_from_lists(struct nf_conn *ct);
extern void nf_ct_insert_dying_list(struct nf_conn *ct);
diff --git a/include/net/rtnetlink.h b/include/net/rtnetlink.h
index 678f1ffaf84..37029390197 100644
--- a/include/net/rtnetlink.h
+++ b/include/net/rtnetlink.h
@@ -6,7 +6,7 @@
typedef int (*rtnl_doit_func)(struct sk_buff *, struct nlmsghdr *, void *);
typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *);
-typedef u16 (*rtnl_calcit_func)(struct sk_buff *);
+typedef u16 (*rtnl_calcit_func)(struct sk_buff *, struct nlmsghdr *);
extern int __rtnl_register(int protocol, int msgtype,
rtnl_doit_func, rtnl_dumpit_func,
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h
index 6ba596b07a7..e33ed1bfa11 100644
--- a/include/trace/events/sched.h
+++ b/include/trace/events/sched.h
@@ -370,56 +370,6 @@ TRACE_EVENT(sched_stat_runtime,
(unsigned long long)__entry->vruntime)
);
-#ifdef CREATE_TRACE_POINTS
-static inline u64 trace_get_sleeptime(struct task_struct *tsk)
-{
-#ifdef CONFIG_SCHEDSTATS
- u64 block, sleep;
-
- block = tsk->se.statistics.block_start;
- sleep = tsk->se.statistics.sleep_start;
- tsk->se.statistics.block_start = 0;
- tsk->se.statistics.sleep_start = 0;
-
- return block ? block : sleep ? sleep : 0;
-#else
- return 0;
-#endif
-}
-#endif
-
-/*
- * Tracepoint for accounting sleeptime (time the task is sleeping
- * or waiting for I/O).
- */
-TRACE_EVENT(sched_stat_sleeptime,
-
- TP_PROTO(struct task_struct *tsk, u64 now),
-
- TP_ARGS(tsk, now),
-
- TP_STRUCT__entry(
- __array( char, comm, TASK_COMM_LEN )
- __field( pid_t, pid )
- __field( u64, sleeptime )
- ),
-
- TP_fast_assign(
- memcpy(__entry->comm, tsk->comm, TASK_COMM_LEN);
- __entry->pid = tsk->pid;
- __entry->sleeptime = trace_get_sleeptime(tsk);
- __entry->sleeptime = __entry->sleeptime ?
- now - __entry->sleeptime : 0;
- )
- TP_perf_assign(
- __perf_count(__entry->sleeptime);
- ),
-
- TP_printk("comm=%s pid=%d sleeptime=%Lu [ns]",
- __entry->comm, __entry->pid,
- (unsigned long long)__entry->sleeptime)
-);
-
/*
* Tracepoint for showing priority inheritance modifying a tasks
* priority.
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c
index b7971d6f38b..ee706ce44aa 100644
--- a/kernel/events/hw_breakpoint.c
+++ b/kernel/events/hw_breakpoint.c
@@ -651,10 +651,10 @@ int __init init_hw_breakpoint(void)
err_alloc:
for_each_possible_cpu(err_cpu) {
- if (err_cpu == cpu)
- break;
for (i = 0; i < TYPE_MAX; i++)
kfree(per_cpu(nr_task_bp_pinned[i], cpu));
+ if (err_cpu == cpu)
+ break;
}
return -ENOMEM;
diff --git a/kernel/fork.c b/kernel/fork.c
index b77fd559c78..e2cd3e2a5ae 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -66,6 +66,7 @@
#include <linux/user-return-notifier.h>
#include <linux/oom.h>
#include <linux/khugepaged.h>
+#include <linux/signalfd.h>
#include <asm/pgtable.h>
#include <asm/pgalloc.h>
@@ -935,8 +936,10 @@ static int copy_sighand(unsigned long clone_flags, struct task_struct *tsk)
void __cleanup_sighand(struct sighand_struct *sighand)
{
- if (atomic_dec_and_test(&sighand->count))
+ if (atomic_dec_and_test(&sighand->count)) {
+ signalfd_cleanup(sighand);
kmem_cache_free(sighand_cachep, sighand);
+ }
}
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index 342d8f44e40..0119b9d467a 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -53,7 +53,7 @@ unsigned long probe_irq_on(void)
if (desc->irq_data.chip->irq_set_type)
desc->irq_data.chip->irq_set_type(&desc->irq_data,
IRQ_TYPE_PROBE);
- irq_startup(desc);
+ irq_startup(desc, false);
}
raw_spin_unlock_irq(&desc->lock);
}
@@ -70,7 +70,7 @@ 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))
+ if (irq_startup(desc, false))
desc->istate |= IRQS_PENDING;
}
raw_spin_unlock_irq(&desc->lock);
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index f7c543a801d..fb7db75ee0c 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -157,19 +157,22 @@ static void irq_state_set_masked(struct irq_desc *desc)
irqd_set(&desc->irq_data, IRQD_IRQ_MASKED);
}
-int irq_startup(struct irq_desc *desc)
+int irq_startup(struct irq_desc *desc, bool resend)
{
+ int ret = 0;
+
irq_state_clr_disabled(desc);
desc->depth = 0;
if (desc->irq_data.chip->irq_startup) {
- int ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
+ ret = desc->irq_data.chip->irq_startup(&desc->irq_data);
irq_state_clr_masked(desc);
- return ret;
+ } else {
+ irq_enable(desc);
}
-
- irq_enable(desc);
- return 0;
+ if (resend)
+ check_irq_resend(desc, desc->irq_data.irq);
+ return ret;
}
void irq_shutdown(struct irq_desc *desc)
@@ -330,6 +333,24 @@ out_unlock:
}
EXPORT_SYMBOL_GPL(handle_simple_irq);
+/*
+ * Called unconditionally from handle_level_irq() and only for oneshot
+ * interrupts from handle_fasteoi_irq()
+ */
+static void cond_unmask_irq(struct irq_desc *desc)
+{
+ /*
+ * We need to unmask in the following cases:
+ * - Standard level irq (IRQF_ONESHOT is not set)
+ * - Oneshot irq which did not wake the thread (caused by a
+ * spurious interrupt or a primary handler handling it
+ * completely).
+ */
+ if (!irqd_irq_disabled(&desc->irq_data) &&
+ irqd_irq_masked(&desc->irq_data) && !desc->threads_oneshot)
+ unmask_irq(desc);
+}
+
/**
* handle_level_irq - Level type irq handler
* @irq: the interrupt number
@@ -362,8 +383,8 @@ handle_level_irq(unsigned int irq, struct irq_desc *desc)
handle_irq_event(desc);
- if (!irqd_irq_disabled(&desc->irq_data) && !(desc->istate & IRQS_ONESHOT))
- unmask_irq(desc);
+ cond_unmask_irq(desc);
+
out_unlock:
raw_spin_unlock(&desc->lock);
}
@@ -417,6 +438,9 @@ handle_fasteoi_irq(unsigned int irq, struct irq_desc *desc)
preflow_handler(desc);
handle_irq_event(desc);
+ if (desc->istate & IRQS_ONESHOT)
+ cond_unmask_irq(desc);
+
out_eoi:
desc->irq_data.chip->irq_eoi(&desc->irq_data);
out_unlock:
@@ -625,7 +649,7 @@ __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
irq_settings_set_noprobe(desc);
irq_settings_set_norequest(desc);
irq_settings_set_nothread(desc);
- irq_startup(desc);
+ irq_startup(desc, true);
}
out:
irq_put_desc_busunlock(desc, flags);
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index b7952316016..40378ff877e 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -67,7 +67,7 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
extern void __disable_irq(struct irq_desc *desc, unsigned int irq, bool susp);
extern void __enable_irq(struct irq_desc *desc, unsigned int irq, bool resume);
-extern int irq_startup(struct irq_desc *desc);
+extern int irq_startup(struct irq_desc *desc, bool resend);
extern void irq_shutdown(struct irq_desc *desc);
extern void irq_enable(struct irq_desc *desc);
extern void irq_disable(struct irq_desc *desc);
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 1f9e26526b6..af48e59bc2f 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -1,189 +1,793 @@
+#include <linux/debugfs.h>
+#include <linux/hardirq.h>
+#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/irqdesc.h>
#include <linux/irqdomain.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_address.h>
+#include <linux/seq_file.h>
#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/fs.h>
+
+#define IRQ_DOMAIN_MAP_LEGACY 0 /* driver allocated fixed range of irqs.
+ * ie. legacy 8259, gets irqs 1..15 */
+#define IRQ_DOMAIN_MAP_NOMAP 1 /* no fast reverse mapping */
+#define IRQ_DOMAIN_MAP_LINEAR 2 /* linear map of interrupts */
+#define IRQ_DOMAIN_MAP_TREE 3 /* radix tree */
static LIST_HEAD(irq_domain_list);
static DEFINE_MUTEX(irq_domain_mutex);
+static DEFINE_MUTEX(revmap_trees_mutex);
+static unsigned int irq_virq_count = NR_IRQS;
+static struct irq_domain *irq_default_domain;
+
/**
- * irq_domain_add() - Register an irq_domain
- * @domain: ptr to initialized irq_domain structure
+ * irq_domain_alloc() - Allocate a new irq_domain data structure
+ * @of_node: optional device-tree node of the interrupt controller
+ * @revmap_type: type of reverse mapping to use
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
*
- * Registers an irq_domain structure. The irq_domain must at a minimum be
- * initialized with an ops structure pointer, and either a ->to_irq hook or
- * a valid irq_base value. Everything else is optional.
+ * Allocates and initialize and irq_domain structure. Caller is expected to
+ * register allocated irq_domain with irq_domain_register(). Returns pointer
+ * to IRQ domain, or NULL on failure.
*/
-void irq_domain_add(struct irq_domain *domain)
+static struct irq_domain *irq_domain_alloc(struct device_node *of_node,
+ unsigned int revmap_type,
+ const struct irq_domain_ops *ops,
+ void *host_data)
{
- struct irq_data *d;
- int hwirq, irq;
+ struct irq_domain *domain;
- /*
- * This assumes that the irq_domain owner has already allocated
- * the irq_descs. This block will be removed when support for dynamic
- * allocation of irq_descs is added to irq_domain.
- */
- irq_domain_for_each_irq(domain, hwirq, irq) {
- d = irq_get_irq_data(irq);
- if (!d) {
- WARN(1, "error: assigning domain to non existant irq_desc");
- return;
- }
- if (d->domain) {
- /* things are broken; just report, don't clean up */
- WARN(1, "error: irq_desc already assigned to a domain");
- return;
+ domain = kzalloc(sizeof(*domain), GFP_KERNEL);
+ if (WARN_ON(!domain))
+ return NULL;
+
+ /* Fill structure */
+ domain->revmap_type = revmap_type;
+ domain->ops = ops;
+ domain->host_data = host_data;
+ domain->of_node = of_node_get(of_node);
+
+ return domain;
+}
+
+static void irq_domain_add(struct irq_domain *domain)
+{
+ mutex_lock(&irq_domain_mutex);
+ list_add(&domain->link, &irq_domain_list);
+ mutex_unlock(&irq_domain_mutex);
+ pr_debug("irq: Allocated domain of type %d @0x%p\n",
+ domain->revmap_type, domain);
+}
+
+static unsigned int irq_domain_legacy_revmap(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+{
+ irq_hw_number_t first_hwirq = domain->revmap_data.legacy.first_hwirq;
+ int size = domain->revmap_data.legacy.size;
+
+ if (WARN_ON(hwirq < first_hwirq || hwirq >= first_hwirq + size))
+ return 0;
+ return hwirq - first_hwirq + domain->revmap_data.legacy.first_irq;
+}
+
+/**
+ * irq_domain_add_legacy() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @size: total number of irqs in legacy mapping
+ * @first_irq: first number of irq block assigned to the domain
+ * @first_hwirq: first hwirq number to use for the translation. Should normally
+ * be '0', but a positive integer can be used if the effective
+ * hwirqs numbering does not begin at zero.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ *
+ * Note: the map() callback will be called before this function returns
+ * for all legacy interrupts except 0 (which is always the invalid irq for
+ * a legacy controller).
+ */
+struct irq_domain *irq_domain_add_legacy(struct device_node *of_node,
+ unsigned int size,
+ unsigned int first_irq,
+ irq_hw_number_t first_hwirq,
+ const struct irq_domain_ops *ops,
+ void *host_data)
+{
+ struct irq_domain *domain;
+ unsigned int i;
+
+ domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LEGACY, ops, host_data);
+ if (!domain)
+ return NULL;
+
+ domain->revmap_data.legacy.first_irq = first_irq;
+ domain->revmap_data.legacy.first_hwirq = first_hwirq;
+ domain->revmap_data.legacy.size = size;
+
+ mutex_lock(&irq_domain_mutex);
+ /* Verify that all the irqs are available */
+ for (i = 0; i < size; i++) {
+ int irq = first_irq + i;
+ struct irq_data *irq_data = irq_get_irq_data(irq);
+
+ if (WARN_ON(!irq_data || irq_data->domain)) {
+ mutex_unlock(&irq_domain_mutex);
+ of_node_put(domain->of_node);
+ kfree(domain);
+ return NULL;
}
- d->domain = domain;
- d->hwirq = hwirq;
}
- mutex_lock(&irq_domain_mutex);
- list_add(&domain->list, &irq_domain_list);
+ /* Claim all of the irqs before registering a legacy domain */
+ for (i = 0; i < size; i++) {
+ struct irq_data *irq_data = irq_get_irq_data(first_irq + i);
+ irq_data->hwirq = first_hwirq + i;
+ irq_data->domain = domain;
+ }
mutex_unlock(&irq_domain_mutex);
+
+ for (i = 0; i < size; i++) {
+ int irq = first_irq + i;
+ int hwirq = first_hwirq + i;
+
+ /* IRQ0 gets ignored */
+ if (!irq)
+ continue;
+
+ /* Legacy flags are left to default at this point,
+ * one can then use irq_create_mapping() to
+ * explicitly change them
+ */
+ ops->map(domain, irq, hwirq);
+
+ /* Clear norequest flags */
+ irq_clear_status_flags(irq, IRQ_NOREQUEST);
+ }
+
+ irq_domain_add(domain);
+ return domain;
+}
+
+/**
+ * irq_domain_add_linear() - Allocate and register a legacy revmap irq_domain.
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ * @host_data: Controller private data pointer
+ */
+struct irq_domain *irq_domain_add_linear(struct device_node *of_node,
+ unsigned int size,
+ const struct irq_domain_ops *ops,
+ void *host_data)
+{
+ struct irq_domain *domain;
+ unsigned int *revmap;
+
+ revmap = kzalloc(sizeof(*revmap) * size, GFP_KERNEL);
+ if (WARN_ON(!revmap))
+ return NULL;
+
+ domain = irq_domain_alloc(of_node, IRQ_DOMAIN_MAP_LINEAR, ops, host_data);
+ if (!domain) {
+ kfree(revmap);
+ return NULL;
+ }
+ domain->revmap_data.linear.size = size;
+ domain->revmap_data.linear.revmap = revmap;
+ irq_domain_add(domain);
+ return domain;
+}
+
+struct irq_domain *irq_domain_add_nomap(struct device_node *of_node,
+ const struct irq_domain_ops *ops,
+ void *host_data)
+{
+ struct irq_domain *domain = irq_domain_alloc(of_node,
+ IRQ_DOMAIN_MAP_NOMAP, ops, host_data);
+ if (domain)
+ irq_domain_add(domain);
+ return domain;
+}
+
+/**
+ * irq_domain_add_tree()
+ * @of_node: pointer to interrupt controller's device tree node.
+ * @ops: map/unmap domain callbacks
+ *
+ * Note: The radix tree will be allocated later during boot automatically
+ * (the reverse mapping will use the slow path until that happens).
+ */
+struct irq_domain *irq_domain_add_tree(struct device_node *of_node,
+ const struct irq_domain_ops *ops,
+ void *host_data)
+{
+ struct irq_domain *domain = irq_domain_alloc(of_node,
+ IRQ_DOMAIN_MAP_TREE, ops, host_data);
+ if (domain) {
+ INIT_RADIX_TREE(&domain->revmap_data.tree, GFP_KERNEL);
+ irq_domain_add(domain);
+ }
+ return domain;
}
/**
- * irq_domain_del() - Unregister an irq_domain
- * @domain: ptr to registered irq_domain.
+ * irq_find_host() - Locates a domain for a given device node
+ * @node: device-tree node of the interrupt controller
*/
-void irq_domain_del(struct irq_domain *domain)
+struct irq_domain *irq_find_host(struct device_node *node)
{
- struct irq_data *d;
- int hwirq, irq;
+ struct irq_domain *h, *found = NULL;
+ int rc;
+ /* We might want to match the legacy controller last since
+ * it might potentially be set to match all interrupts in
+ * the absence of a device node. This isn't a problem so far
+ * yet though...
+ */
mutex_lock(&irq_domain_mutex);
- list_del(&domain->list);
+ list_for_each_entry(h, &irq_domain_list, link) {
+ if (h->ops->match)
+ rc = h->ops->match(h, node);
+ else
+ rc = (h->of_node != NULL) && (h->of_node == node);
+
+ if (rc) {
+ found = h;
+ break;
+ }
+ }
mutex_unlock(&irq_domain_mutex);
+ return found;
+}
+EXPORT_SYMBOL_GPL(irq_find_host);
+
+/**
+ * irq_set_default_host() - Set a "default" irq domain
+ * @domain: default domain pointer
+ *
+ * For convenience, it's possible to set a "default" domain that will be used
+ * whenever NULL is passed to irq_create_mapping(). It makes life easier for
+ * platforms that want to manipulate a few hard coded interrupt numbers that
+ * aren't properly represented in the device-tree.
+ */
+void irq_set_default_host(struct irq_domain *domain)
+{
+ pr_debug("irq: Default domain set to @0x%p\n", domain);
+
+ irq_default_domain = domain;
+}
+
+/**
+ * irq_set_virq_count() - Set the maximum number of linux irqs
+ * @count: number of linux irqs, capped with NR_IRQS
+ *
+ * This is mainly for use by platforms like iSeries who want to program
+ * the virtual irq number in the controller to avoid the reverse mapping
+ */
+void irq_set_virq_count(unsigned int count)
+{
+ pr_debug("irq: Trying to set virq count to %d\n", count);
- /* Clear the irq_domain assignments */
- irq_domain_for_each_irq(domain, hwirq, irq) {
- d = irq_get_irq_data(irq);
- d->domain = NULL;
+ BUG_ON(count < NUM_ISA_INTERRUPTS);
+ if (count < NR_IRQS)
+ irq_virq_count = count;
+}
+
+static int irq_setup_virq(struct irq_domain *domain, unsigned int virq,
+ irq_hw_number_t hwirq)
+{
+ struct irq_data *irq_data = irq_get_irq_data(virq);
+
+ irq_data->hwirq = hwirq;
+ irq_data->domain = domain;
+ if (domain->ops->map(domain, virq, hwirq)) {
+ pr_debug("irq: -> mapping failed, freeing\n");
+ irq_data->domain = NULL;
+ irq_data->hwirq = 0;
+ return -1;
}
+
+ irq_clear_status_flags(virq, IRQ_NOREQUEST);
+
+ return 0;
}
-#if defined(CONFIG_OF_IRQ)
/**
- * irq_create_of_mapping() - Map a linux irq number from a DT interrupt spec
+ * irq_create_direct_mapping() - Allocate an irq for direct mapping
+ * @domain: domain to allocate the irq for or NULL for default domain
*
- * Used by the device tree interrupt mapping code to translate a device tree
- * interrupt specifier to a valid linux irq number. Returns either a valid
- * linux IRQ number or 0.
+ * This routine is used for irq controllers which can choose the hardware
+ * interrupt numbers they generate. In such a case it's simplest to use
+ * the linux irq as the hardware interrupt number.
+ */
+unsigned int irq_create_direct_mapping(struct irq_domain *domain)
+{
+ unsigned int virq;
+
+ if (domain == NULL)
+ domain = irq_default_domain;
+
+ BUG_ON(domain == NULL);
+ WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_NOMAP);
+
+ virq = irq_alloc_desc_from(1, 0);
+ if (!virq) {
+ pr_debug("irq: create_direct virq allocation failed\n");
+ return 0;
+ }
+ if (virq >= irq_virq_count) {
+ pr_err("ERROR: no free irqs available below %i maximum\n",
+ irq_virq_count);
+ irq_free_desc(virq);
+ return 0;
+ }
+
+ pr_debug("irq: create_direct obtained virq %d\n", virq);
+
+ if (irq_setup_virq(domain, virq, virq)) {
+ irq_free_desc(virq);
+ return 0;
+ }
+
+ return virq;
+}
+
+/**
+ * irq_create_mapping() - Map a hardware interrupt into linux irq space
+ * @domain: domain owning this hardware interrupt or NULL for default domain
+ * @hwirq: hardware irq number in that domain space
*
- * When the caller no longer need the irq number returned by this function it
- * should arrange to call irq_dispose_mapping().
+ * Only one mapping per hardware interrupt is permitted. Returns a linux
+ * irq number.
+ * If the sense/trigger is to be specified, set_irq_type() should be called
+ * on the number returned from that call.
*/
+unsigned int irq_create_mapping(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+{
+ unsigned int virq, hint;
+
+ pr_debug("irq: irq_create_mapping(0x%p, 0x%lx)\n", domain, hwirq);
+
+ /* Look for default domain if nececssary */
+ if (domain == NULL)
+ domain = irq_default_domain;
+ if (domain == NULL) {
+ printk(KERN_WARNING "irq_create_mapping called for"
+ " NULL domain, hwirq=%lx\n", hwirq);
+ WARN_ON(1);
+ return 0;
+ }
+ pr_debug("irq: -> using domain @%p\n", domain);
+
+ /* Check if mapping already exists */
+ virq = irq_find_mapping(domain, hwirq);
+ if (virq) {
+ pr_debug("irq: -> existing mapping on virq %d\n", virq);
+ return virq;
+ }
+
+ /* Get a virtual interrupt number */
+ if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+ return irq_domain_legacy_revmap(domain, hwirq);
+
+ /* Allocate a virtual interrupt number */
+ hint = hwirq % irq_virq_count;
+ if (hint == 0)
+ hint++;
+ virq = irq_alloc_desc_from(hint, 0);
+ if (!virq)
+ virq = irq_alloc_desc_from(1, 0);
+ if (!virq) {
+ pr_debug("irq: -> virq allocation failed\n");
+ return 0;
+ }
+
+ if (irq_setup_virq(domain, virq, hwirq)) {
+ if (domain->revmap_type != IRQ_DOMAIN_MAP_LEGACY)
+ irq_free_desc(virq);
+ return 0;
+ }
+
+ pr_debug("irq: irq %lu on domain %s mapped to virtual irq %u\n",
+ hwirq, domain->of_node ? domain->of_node->full_name : "null", virq);
+
+ return virq;
+}
+EXPORT_SYMBOL_GPL(irq_create_mapping);
+
unsigned int irq_create_of_mapping(struct device_node *controller,
const u32 *intspec, unsigned int intsize)
{
struct irq_domain *domain;
- unsigned long hwirq;
- unsigned int irq, type;
- int rc = -EINVAL;
+ irq_hw_number_t hwirq;
+ unsigned int type = IRQ_TYPE_NONE;
+ unsigned int virq;
- /* Find a domain which can translate the irq spec */
- mutex_lock(&irq_domain_mutex);
- list_for_each_entry(domain, &irq_domain_list, list) {
- if (!domain->ops->dt_translate)
- continue;
- rc = domain->ops->dt_translate(domain, controller,
- intspec, intsize, &hwirq, &type);
- if (rc == 0)
- break;
+ domain = controller ? irq_find_host(controller) : irq_default_domain;
+ if (!domain) {
+#ifdef CONFIG_MIPS
+ /*
+ * Workaround to avoid breaking interrupt controller drivers
+ * that don't yet register an irq_domain. This is temporary
+ * code. ~~~gcl, Feb 24, 2012
+ *
+ * Scheduled for removal in Linux v3.6. That should be enough
+ * time.
+ */
+ if (intsize > 0)
+ return intspec[0];
+#endif
+ printk(KERN_WARNING "irq: no irq domain found for %s !\n",
+ controller->full_name);
+ return 0;
}
- mutex_unlock(&irq_domain_mutex);
- if (rc != 0)
- return 0;
+ /* If domain has no translation, then we assume interrupt line */
+ if (domain->ops->xlate == NULL)
+ hwirq = intspec[0];
+ else {
+ if (domain->ops->xlate(domain, controller, intspec, intsize,
+ &hwirq, &type))
+ return 0;
+ }
+
+ /* Create mapping */
+ virq = irq_create_mapping(domain, hwirq);
+ if (!virq)
+ return virq;
- irq = irq_domain_to_irq(domain, hwirq);
- if (type != IRQ_TYPE_NONE)
- irq_set_irq_type(irq, type);
- pr_debug("%s: mapped hwirq=%i to irq=%i, flags=%x\n",
- controller->full_name, (int)hwirq, irq, type);
- return irq;
+ /* Set type if specified and different than the current one */
+ if (type != IRQ_TYPE_NONE &&
+ 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);
/**
- * irq_dispose_mapping() - Discard a mapping created by irq_create_of_mapping()
- * @irq: linux irq number to be discarded
+ * irq_dispose_mapping() - Unmap an interrupt
+ * @virq: linux irq number of the interrupt to unmap
+ */
+void irq_dispose_mapping(unsigned int virq)
+{
+ struct irq_data *irq_data = irq_get_irq_data(virq);
+ struct irq_domain *domain;
+ irq_hw_number_t hwirq;
+
+ if (!virq || !irq_data)
+ return;
+
+ domain = irq_data->domain;
+ if (WARN_ON(domain == NULL))
+ return;
+
+ /* Never unmap legacy interrupts */
+ if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+ return;
+
+ irq_set_status_flags(virq, IRQ_NOREQUEST);
+
+ /* remove chip and handler */
+ irq_set_chip_and_handler(virq, NULL, NULL);
+
+ /* Make sure it's completed */
+ synchronize_irq(virq);
+
+ /* Tell the PIC about it */
+ if (domain->ops->unmap)
+ domain->ops->unmap(domain, virq);
+ smp_mb();
+
+ /* Clear reverse map */
+ hwirq = irq_data->hwirq;
+ switch(domain->revmap_type) {
+ case IRQ_DOMAIN_MAP_LINEAR:
+ if (hwirq < domain->revmap_data.linear.size)
+ domain->revmap_data.linear.revmap[hwirq] = 0;
+ break;
+ case IRQ_DOMAIN_MAP_TREE:
+ mutex_lock(&revmap_trees_mutex);
+ radix_tree_delete(&domain->revmap_data.tree, hwirq);
+ mutex_unlock(&revmap_trees_mutex);
+ break;
+ }
+
+ irq_free_desc(virq);
+}
+EXPORT_SYMBOL_GPL(irq_dispose_mapping);
+
+/**
+ * irq_find_mapping() - Find a linux irq from an hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
+ *
+ * This is a slow path, for use by generic code. It's expected that an
+ * irq controller implementation directly calls the appropriate low level
+ * mapping function.
+ */
+unsigned int irq_find_mapping(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+{
+ unsigned int i;
+ unsigned int hint = hwirq % irq_virq_count;
+
+ /* Look for default domain if nececssary */
+ if (domain == NULL)
+ domain = irq_default_domain;
+ if (domain == NULL)
+ return 0;
+
+ /* legacy -> bail early */
+ if (domain->revmap_type == IRQ_DOMAIN_MAP_LEGACY)
+ return irq_domain_legacy_revmap(domain, hwirq);
+
+ /* Slow path does a linear search of the map */
+ if (hint == 0)
+ hint = 1;
+ i = hint;
+ do {
+ struct irq_data *data = irq_get_irq_data(i);
+ if (data && (data->domain == domain) && (data->hwirq == hwirq))
+ return i;
+ i++;
+ if (i >= irq_virq_count)
+ i = 1;
+ } while(i != hint);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(irq_find_mapping);
+
+/**
+ * irq_radix_revmap_lookup() - Find a linux irq from a hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
*
- * Calling this function indicates the caller no longer needs a reference to
- * the linux irq number returned by a prior call to irq_create_of_mapping().
+ * This is a fast path, for use by irq controller code that uses radix tree
+ * revmaps
*/
-void irq_dispose_mapping(unsigned int irq)
+unsigned int irq_radix_revmap_lookup(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
{
+ struct irq_data *irq_data;
+
+ if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
+ return irq_find_mapping(domain, hwirq);
+
+ /*
+ * Freeing an irq can delete nodes along the path to
+ * do the lookup via call_rcu.
+ */
+ rcu_read_lock();
+ irq_data = radix_tree_lookup(&domain->revmap_data.tree, hwirq);
+ rcu_read_unlock();
+
/*
- * nothing yet; will be filled when support for dynamic allocation of
- * irq_descs is added to irq_domain
+ * If found in radix tree, then fine.
+ * Else fallback to linear lookup - this should not happen in practice
+ * as it means that we failed to insert the node in the radix tree.
*/
+ return irq_data ? irq_data->irq : irq_find_mapping(domain, hwirq);
}
-EXPORT_SYMBOL_GPL(irq_dispose_mapping);
-int irq_domain_simple_dt_translate(struct irq_domain *d,
- struct device_node *controller,
- const u32 *intspec, unsigned int intsize,
- unsigned long *out_hwirq, unsigned int *out_type)
+/**
+ * irq_radix_revmap_insert() - Insert a hw irq to linux irq number mapping.
+ * @domain: domain owning this hardware interrupt
+ * @virq: linux irq number
+ * @hwirq: hardware irq number in that domain space
+ *
+ * This is for use by irq controllers that use a radix tree reverse
+ * mapping for fast lookup.
+ */
+void irq_radix_revmap_insert(struct irq_domain *domain, unsigned int virq,
+ irq_hw_number_t hwirq)
{
- if (d->of_node != controller)
- return -EINVAL;
- if (intsize < 1)
- return -EINVAL;
- if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
- (intspec[0] >= d->hwirq_base + d->nr_irq)))
- return -EINVAL;
+ struct irq_data *irq_data = irq_get_irq_data(virq);
+
+ if (WARN_ON(domain->revmap_type != IRQ_DOMAIN_MAP_TREE))
+ return;
+
+ if (virq) {
+ mutex_lock(&revmap_trees_mutex);
+ radix_tree_insert(&domain->revmap_data.tree, hwirq, irq_data);
+ mutex_unlock(&revmap_trees_mutex);
+ }
+}
+
+/**
+ * irq_linear_revmap() - Find a linux irq from a hw irq number.
+ * @domain: domain owning this hardware interrupt
+ * @hwirq: hardware irq number in that domain space
+ *
+ * This is a fast path, for use by irq controller code that uses linear
+ * revmaps. It does fallback to the slow path if the revmap doesn't exist
+ * yet and will create the revmap entry with appropriate locking
+ */
+unsigned int irq_linear_revmap(struct irq_domain *domain,
+ irq_hw_number_t hwirq)
+{
+ unsigned int *revmap;
+
+ if (WARN_ON_ONCE(domain->revmap_type != IRQ_DOMAIN_MAP_LINEAR))
+ return irq_find_mapping(domain, hwirq);
+
+ /* Check revmap bounds */
+ if (unlikely(hwirq >= domain->revmap_data.linear.size))
+ return irq_find_mapping(domain, hwirq);
+
+ /* Check if revmap was allocated */
+ revmap = domain->revmap_data.linear.revmap;
+ if (unlikely(revmap == NULL))
+ return irq_find_mapping(domain, hwirq);
+
+ /* Fill up revmap with slow path if no mapping found */
+ if (unlikely(!revmap[hwirq]))
+ revmap[hwirq] = irq_find_mapping(domain, hwirq);
+
+ return revmap[hwirq];
+}
+
+#ifdef CONFIG_VIRQ_DEBUG
+static int virq_debug_show(struct seq_file *m, void *private)
+{
+ unsigned long flags;
+ struct irq_desc *desc;
+ const char *p;
+ static const char none[] = "none";
+ void *data;
+ int i;
+
+ seq_printf(m, "%-5s %-7s %-15s %-18s %s\n", "virq", "hwirq",
+ "chip name", "chip data", "domain name");
+
+ for (i = 1; i < nr_irqs; i++) {
+ desc = irq_to_desc(i);
+ if (!desc)
+ continue;
+
+ raw_spin_lock_irqsave(&desc->lock, flags);
+
+ if (desc->action && desc->action->handler) {
+ struct irq_chip *chip;
+
+ seq_printf(m, "%5d ", i);
+ seq_printf(m, "0x%05lx ", desc->irq_data.hwirq);
+
+ chip = irq_desc_get_chip(desc);
+ if (chip && chip->name)
+ p = chip->name;
+ else
+ p = none;
+ seq_printf(m, "%-15s ", p);
+
+ data = irq_desc_get_chip_data(desc);
+ seq_printf(m, "0x%16p ", data);
+
+ if (desc->irq_data.domain->of_node)
+ p = desc->irq_data.domain->of_node->full_name;
+ else
+ p = none;
+ seq_printf(m, "%s\n", p);
+ }
+
+ raw_spin_unlock_irqrestore(&desc->lock, flags);
+ }
+
+ return 0;
+}
+static int virq_debug_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, virq_debug_show, inode->i_private);
+}
+
+static const struct file_operations virq_debug_fops = {
+ .open = virq_debug_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init irq_debugfs_init(void)
+{
+ if (debugfs_create_file("virq_mapping", S_IRUGO, powerpc_debugfs_root,
+ NULL, &virq_debug_fops) == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+__initcall(irq_debugfs_init);
+#endif /* CONFIG_VIRQ_DEBUG */
+
+int irq_domain_simple_map(struct irq_domain *d, unsigned int irq,
+ irq_hw_number_t hwirq)
+{
+ return 0;
+}
+
+/**
+ * irq_domain_xlate_onecell() - Generic xlate for direct one cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with one cell
+ * bindings where the cell value maps directly to the hwirq number.
+ */
+int irq_domain_xlate_onecell(struct irq_domain *d, struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq, unsigned int *out_type)
+{
+ if (WARN_ON(intsize < 1))
+ return -EINVAL;
*out_hwirq = intspec[0];
*out_type = IRQ_TYPE_NONE;
- if (intsize > 1)
- *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
return 0;
}
+EXPORT_SYMBOL_GPL(irq_domain_xlate_onecell);
/**
- * irq_domain_create_simple() - Set up a 'simple' translation range
+ * irq_domain_xlate_twocell() - Generic xlate for direct two cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with two cell
+ * bindings where the cell values map directly to the hwirq number
+ * and linux irq flags.
*/
-void irq_domain_add_simple(struct device_node *controller, int irq_base)
+int irq_domain_xlate_twocell(struct irq_domain *d, struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq, unsigned int *out_type)
{
- struct irq_domain *domain;
-
- domain = kzalloc(sizeof(*domain), GFP_KERNEL);
- if (!domain) {
- WARN_ON(1);
- return;
- }
+ if (WARN_ON(intsize < 2))
+ return -EINVAL;
+ *out_hwirq = intspec[0];
+ *out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(irq_domain_xlate_twocell);
- domain->irq_base = irq_base;
- domain->of_node = of_node_get(controller);
- domain->ops = &irq_domain_simple_ops;
- irq_domain_add(domain);
+/**
+ * irq_domain_xlate_onetwocell() - Generic xlate for one or two cell bindings
+ *
+ * Device Tree IRQ specifier translation function which works with either one
+ * or two cell bindings where the cell values map directly to the hwirq number
+ * and linux irq flags.
+ *
+ * Note: don't use this function unless your interrupt controller explicitly
+ * supports both one and two cell bindings. For the majority of controllers
+ * the _onecell() or _twocell() variants above should be used.
+ */
+int irq_domain_xlate_onetwocell(struct irq_domain *d,
+ struct device_node *ctrlr,
+ const u32 *intspec, unsigned int intsize,
+ unsigned long *out_hwirq, unsigned int *out_type)
+{
+ if (WARN_ON(intsize < 1))
+ return -EINVAL;
+ *out_hwirq = intspec[0];
+ *out_type = (intsize > 1) ? intspec[1] : IRQ_TYPE_NONE;
+ return 0;
}
-EXPORT_SYMBOL_GPL(irq_domain_add_simple);
+EXPORT_SYMBOL_GPL(irq_domain_xlate_onetwocell);
+const struct irq_domain_ops irq_domain_simple_ops = {
+ .map = irq_domain_simple_map,
+ .xlate = irq_domain_xlate_onetwocell,
+};
+EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
+
+#ifdef CONFIG_OF_IRQ
void irq_domain_generate_simple(const struct of_device_id *match,
u64 phys_base, unsigned int irq_start)
{
struct device_node *node;
- pr_info("looking for phys_base=%llx, irq_start=%i\n",
+ pr_debug("looking for phys_base=%llx, irq_start=%i\n",
(unsigned long long) phys_base, (int) irq_start);
node = of_find_matching_node_by_address(NULL, match, phys_base);
if (node)
- irq_domain_add_simple(node, irq_start);
- else
- pr_info("no node found\n");
+ irq_domain_add_legacy(node, 32, irq_start, 0,
+ &irq_domain_simple_ops, NULL);
}
EXPORT_SYMBOL_GPL(irq_domain_generate_simple);
-#endif /* CONFIG_OF_IRQ */
-
-struct irq_domain_ops irq_domain_simple_ops = {
-#ifdef CONFIG_OF_IRQ
- .dt_translate = irq_domain_simple_dt_translate,
-#endif /* CONFIG_OF_IRQ */
-};
-EXPORT_SYMBOL_GPL(irq_domain_simple_ops);
+#endif
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a9a9dbe49fe..32313c08444 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1027,7 +1027,7 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
desc->istate |= IRQS_ONESHOT;
if (irq_settings_can_autoenable(desc))
- irq_startup(desc);
+ irq_startup(desc, true);
else
/* Undo nested disables: */
desc->depth = 1;
diff --git a/kernel/pid.c b/kernel/pid.c
index ce8e00deacc..9f08dfabaf1 100644
--- a/kernel/pid.c
+++ b/kernel/pid.c
@@ -543,12 +543,12 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns)
*/
void __init pidhash_init(void)
{
- int i, pidhash_size;
+ unsigned int i, pidhash_size;
pid_hash = alloc_large_system_hash("PID", sizeof(*pid_hash), 0, 18,
HASH_EARLY | HASH_SMALL,
&pidhash_shift, NULL, 4096);
- pidhash_size = 1 << pidhash_shift;
+ pidhash_size = 1U << pidhash_shift;
for (i = 0; i < pidhash_size; i++)
INIT_HLIST_HEAD(&pid_hash[i]);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 5255c9d2e05..33a0676ea74 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -1932,7 +1932,6 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
local_irq_enable();
#endif /* __ARCH_WANT_INTERRUPTS_ON_CTXSW */
finish_lock_switch(rq, prev);
- trace_sched_stat_sleeptime(current, rq->clock);
fire_sched_in_preempt_notifiers(current);
if (mm)
@@ -6729,7 +6728,7 @@ int __init sched_create_sysfs_power_savings_entries(struct device *dev)
static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,
void *hcpu)
{
- switch (action & ~CPU_TASKS_FROZEN) {
+ switch (action) {
case CPU_ONLINE:
case CPU_DOWN_FAILED:
cpuset_update_active_cpus();
@@ -6742,7 +6741,7 @@ static int cpuset_cpu_active(struct notifier_block *nfb, unsigned long action,
static int cpuset_cpu_inactive(struct notifier_block *nfb, unsigned long action,
void *hcpu)
{
- switch (action & ~CPU_TASKS_FROZEN) {
+ switch (action) {
case CPU_DOWN_PREPARE:
cpuset_update_active_cpus();
return NOTIFY_OK;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7c6414fc669..aca16b843b7 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1003,6 +1003,7 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
if (unlikely(delta > se->statistics.sleep_max))
se->statistics.sleep_max = delta;
+ se->statistics.sleep_start = 0;
se->statistics.sum_sleep_runtime += delta;
if (tsk) {
@@ -1019,6 +1020,7 @@ static void enqueue_sleeper(struct cfs_rq *cfs_rq, struct sched_entity *se)
if (unlikely(delta > se->statistics.block_max))
se->statistics.block_max = delta;
+ se->statistics.block_start = 0;
se->statistics.sum_sleep_runtime += delta;
if (tsk) {
diff --git a/mm/memblock.c b/mm/memblock.c
index 77b5f227e1d..99f28559950 100644
--- a/mm/memblock.c
+++ b/mm/memblock.c
@@ -99,9 +99,6 @@ phys_addr_t __init_memblock memblock_find_in_range_node(phys_addr_t start,
phys_addr_t this_start, this_end, cand;
u64 i;
- /* align @size to avoid excessive fragmentation on reserved array */
- size = round_up(size, align);
-
/* pump up @end */
if (end == MEMBLOCK_ALLOC_ACCESSIBLE)
end = memblock.current_limit;
@@ -731,6 +728,9 @@ static phys_addr_t __init memblock_alloc_base_nid(phys_addr_t size,
{
phys_addr_t found;
+ /* align @size to avoid excessive fragmentation on reserved array */
+ size = round_up(size, align);
+
found = memblock_find_in_range_node(0, max_addr, size, align, nid);
if (found && !memblock_reserve(found, size))
return found;
diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index 6728a7ae6f2..228d6461c12 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4414,6 +4414,9 @@ static void mem_cgroup_usage_unregister_event(struct cgroup *cgrp,
*/
BUG_ON(!thresholds);
+ if (!thresholds->primary)
+ goto unlock;
+
usage = mem_cgroup_usage(memcg, type == _MEMSWAP);
/* Check if a threshold crossed before removing */
@@ -4462,7 +4465,7 @@ swap_buffers:
/* To be sure that nobody uses thresholds */
synchronize_rcu();
-
+unlock:
mutex_unlock(&memcg->thresholds_lock);
}
diff --git a/mm/nommu.c b/mm/nommu.c
index b982290fd96..f59e170fceb 100644
--- a/mm/nommu.c
+++ b/mm/nommu.c
@@ -696,9 +696,11 @@ static void add_vma_to_mm(struct mm_struct *mm, struct vm_area_struct *vma)
if (vma->vm_file) {
mapping = vma->vm_file->f_mapping;
+ mutex_lock(&mapping->i_mmap_mutex);
flush_dcache_mmap_lock(mapping);
vma_prio_tree_insert(vma, &mapping->i_mmap);
flush_dcache_mmap_unlock(mapping);
+ mutex_unlock(&mapping->i_mmap_mutex);
}
/* add the VMA to the tree */
@@ -760,9 +762,11 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
if (vma->vm_file) {
mapping = vma->vm_file->f_mapping;
+ mutex_lock(&mapping->i_mmap_mutex);
flush_dcache_mmap_lock(mapping);
vma_prio_tree_remove(vma, &mapping->i_mmap);
flush_dcache_mmap_unlock(mapping);
+ mutex_unlock(&mapping->i_mmap_mutex);
}
/* remove from the MM's tree and list */
@@ -775,8 +779,6 @@ static void delete_vma_from_mm(struct vm_area_struct *vma)
if (vma->vm_next)
vma->vm_next->vm_prev = vma->vm_prev;
-
- vma->vm_mm = NULL;
}
/*
@@ -2052,6 +2054,7 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size,
high = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
down_write(&nommu_region_sem);
+ mutex_lock(&inode->i_mapping->i_mmap_mutex);
/* search for VMAs that fall within the dead zone */
vma_prio_tree_foreach(vma, &iter, &inode->i_mapping->i_mmap,
@@ -2059,6 +2062,7 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size,
/* found one - only interested if it's shared out of the page
* cache */
if (vma->vm_flags & VM_SHARED) {
+ mutex_unlock(&inode->i_mapping->i_mmap_mutex);
up_write(&nommu_region_sem);
return -ETXTBSY; /* not quite true, but near enough */
}
@@ -2086,6 +2090,7 @@ int nommu_shrink_inode_mappings(struct inode *inode, size_t size,
}
}
+ mutex_unlock(&inode->i_mapping->i_mmap_mutex);
up_write(&nommu_region_sem);
return 0;
}
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index d2186ecb36f..a13ded1938f 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -5236,6 +5236,7 @@ void *__init alloc_large_system_hash(const char *tablename,
max = ((unsigned long long)nr_all_pages << PAGE_SHIFT) >> 4;
do_div(max, bucketsize);
}
+ max = min(max, 0x80000000ULL);
if (numentries > max)
numentries = max;
diff --git a/net/atm/clip.c b/net/atm/clip.c
index c12c2582457..127fe70a1ba 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -46,8 +46,8 @@
static struct net_device *clip_devs;
static struct atm_vcc *atmarpd;
-static struct neigh_table clip_tbl;
static struct timer_list idle_timer;
+static const struct neigh_ops clip_neigh_ops;
static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
{
@@ -123,6 +123,8 @@ static int neigh_check_cb(struct neighbour *n)
struct atmarp_entry *entry = neighbour_priv(n);
struct clip_vcc *cv;
+ if (n->ops != &clip_neigh_ops)
+ return 0;
for (cv = entry->vccs; cv; cv = cv->next) {
unsigned long exp = cv->last_use + cv->idle_timeout;
@@ -154,10 +156,10 @@ static int neigh_check_cb(struct neighbour *n)
static void idle_timer_check(unsigned long dummy)
{
- write_lock(&clip_tbl.lock);
- __neigh_for_each_release(&clip_tbl, neigh_check_cb);
+ write_lock(&arp_tbl.lock);
+ __neigh_for_each_release(&arp_tbl, neigh_check_cb);
mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
- write_unlock(&clip_tbl.lock);
+ write_unlock(&arp_tbl.lock);
}
static int clip_arp_rcv(struct sk_buff *skb)
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index ef92864ac62..72eb187a5f6 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -71,19 +71,16 @@ static const char *const bt_slock_key_strings[BT_MAX_PROTO] = {
"slock-AF_BLUETOOTH-BTPROTO_AVDTP",
};
-static inline void bt_sock_reclassify_lock(struct socket *sock, int proto)
+void bt_sock_reclassify_lock(struct sock *sk, int proto)
{
- struct sock *sk = sock->sk;
-
- if (!sk)
- return;
-
+ BUG_ON(!sk);
BUG_ON(sock_owned_by_user(sk));
sock_lock_init_class_and_name(sk,
bt_slock_key_strings[proto], &bt_slock_key[proto],
bt_key_strings[proto], &bt_lock_key[proto]);
}
+EXPORT_SYMBOL(bt_sock_reclassify_lock);
int bt_sock_register(int proto, const struct net_proto_family *ops)
{
@@ -145,7 +142,8 @@ static int bt_sock_create(struct net *net, struct socket *sock, int proto,
if (bt_proto[proto] && try_module_get(bt_proto[proto]->owner)) {
err = bt_proto[proto]->create(net, sock, proto, kern);
- bt_sock_reclassify_lock(sock, proto);
+ if (!err)
+ bt_sock_reclassify_lock(sock->sk, proto);
module_put(bt_proto[proto]->owner);
}
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 3db432473ad..07bc69ed949 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -635,6 +635,10 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
+
+ /* encrypt must be pending if auth is also pending */
+ set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
+
cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
sizeof(cp), &cp);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9de93714213..5aeb6249119 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -640,7 +640,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
/* Reset device */
skb_queue_purge(&hdev->cmd_q);
atomic_set(&hdev->cmd_cnt, 1);
- if (!test_bit(HCI_RAW, &hdev->flags)) {
+ if (!test_bit(HCI_RAW, &hdev->flags) &&
+ test_bit(HCI_QUIRK_NO_RESET, &hdev->quirks)) {
set_bit(HCI_INIT, &hdev->flags);
__hci_request(hdev, hci_reset_req, 0,
msecs_to_jiffies(250));
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index faf0b11ac1d..32d338c30e6 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1018,10 +1018,10 @@ static void l2cap_conn_del(struct hci_conn *hcon, int err)
hci_chan_del(conn->hchan);
if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT)
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work_sync(&conn->info_timer);
if (test_and_clear_bit(HCI_CONN_LE_SMP_PEND, &hcon->pend)) {
- __cancel_delayed_work(&conn->security_timer);
+ cancel_delayed_work_sync(&conn->security_timer);
smp_chan_destroy(conn);
}
@@ -1120,7 +1120,7 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm, bdaddr
return c1;
}
-inline int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
+int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, bdaddr_t *dst)
{
struct sock *sk = chan->sk;
bdaddr_t *src = &bt_sk(sk)->src;
@@ -2574,7 +2574,7 @@ static inline int l2cap_command_rej(struct l2cap_conn *conn, struct l2cap_cmd_hd
if ((conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_SENT) &&
cmd->ident == conn->info_ident) {
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
conn->info_ident = 0;
@@ -2970,7 +2970,8 @@ static inline int l2cap_config_rsp(struct l2cap_conn *conn, struct l2cap_cmd_hdr
default:
sk->sk_err = ECONNRESET;
- __set_chan_timer(chan, L2CAP_DISC_REJ_TIMEOUT);
+ __set_chan_timer(chan,
+ msecs_to_jiffies(L2CAP_DISC_REJ_TIMEOUT));
l2cap_send_disconn_req(conn, chan, ECONNRESET);
goto done;
}
@@ -3120,7 +3121,7 @@ static inline int l2cap_information_rsp(struct l2cap_conn *conn, struct l2cap_cm
conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE)
return 0;
- __cancel_delayed_work(&conn->info_timer);
+ cancel_delayed_work(&conn->info_timer);
if (result != L2CAP_IR_SUCCESS) {
conn->info_state |= L2CAP_INFO_FEAT_MASK_REQ_DONE;
@@ -4478,7 +4479,8 @@ static inline void l2cap_check_encryption(struct l2cap_chan *chan, u8 encrypt)
if (encrypt == 0x00) {
if (chan->sec_level == BT_SECURITY_MEDIUM) {
__clear_chan_timer(chan);
- __set_chan_timer(chan, L2CAP_ENC_TIMEOUT);
+ __set_chan_timer(chan,
+ msecs_to_jiffies(L2CAP_ENC_TIMEOUT));
} else if (chan->sec_level == BT_SECURITY_HIGH)
l2cap_chan_close(chan, ECONNREFUSED);
} else {
@@ -4499,7 +4501,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
if (hcon->type == LE_LINK) {
smp_distribute_keys(conn, 0);
- __cancel_delayed_work(&conn->security_timer);
+ cancel_delayed_work(&conn->security_timer);
}
rcu_read_lock();
@@ -4546,7 +4548,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
L2CAP_CONN_REQ, sizeof(req), &req);
} else {
__clear_chan_timer(chan);
- __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+ __set_chan_timer(chan,
+ msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
}
} else if (chan->state == BT_CONNECT2) {
struct l2cap_conn_rsp rsp;
@@ -4566,7 +4569,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
}
} else {
l2cap_state_change(chan, BT_DISCONN);
- __set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
+ __set_chan_timer(chan,
+ msecs_to_jiffies(L2CAP_DISC_TIMEOUT));
res = L2CAP_CR_SEC_BLOCK;
stat = L2CAP_CS_NO_INFO;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c61d967012b..401d9428ae4 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -849,6 +849,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(void *data)
if (!sk)
return NULL;
+ bt_sock_reclassify_lock(sk, BTPROTO_L2CAP);
+
l2cap_sock_init(sk, parent);
return l2cap_pi(sk)->chan;
@@ -1002,7 +1004,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p
INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_destruct = l2cap_sock_destruct;
- sk->sk_sndtimeo = L2CAP_CONN_TIMEOUT;
+ sk->sk_sndtimeo = msecs_to_jiffies(L2CAP_CONN_TIMEOUT);
sock_reset_flag(sk, SOCK_ZAPPED);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 501649bf559..8a602388f1e 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1164,12 +1164,18 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci)
break;
case BT_DISCONN:
- /* When socket is closed and we are not RFCOMM
- * initiator rfcomm_process_rx already calls
- * rfcomm_session_put() */
- if (s->sock->sk->sk_state != BT_CLOSED)
- if (list_empty(&s->dlcs))
- rfcomm_session_put(s);
+ /* rfcomm_session_put is called later so don't do
+ * anything here otherwise we will mess up the session
+ * reference counter:
+ *
+ * (a) when we are the initiator dlc_unlink will drive
+ * the reference counter to 0 (there is no initial put
+ * after session_add)
+ *
+ * (b) when we are not the initiator rfcomm_rx_process
+ * will explicitly call put to balance the initial hold
+ * done after session add.
+ */
break;
}
}
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index f066678faee..22169c3f148 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -956,6 +956,8 @@ int rfcomm_connect_ind(struct rfcomm_session *s, u8 channel, struct rfcomm_dlc *
if (!sk)
goto done;
+ bt_sock_reclassify_lock(sk, BTPROTO_RFCOMM);
+
rfcomm_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, &src);
bacpy(&bt_sk(sk)->dst, &dst);
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index e287346e093..2a83914b027 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -826,6 +826,8 @@ next_elt:
write_unlock_bh(&tbl->lock);
cond_resched();
write_lock_bh(&tbl->lock);
+ nht = rcu_dereference_protected(tbl->nht,
+ lockdep_is_held(&tbl->lock));
}
/* Cycle through all hash buckets every base_reachable_time/2 ticks.
* ARP entry timeouts range from 1/2 base_reachable_time to 3/2
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 65aebd45002..606a6e8f367 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -60,7 +60,6 @@ struct rtnl_link {
};
static DEFINE_MUTEX(rtnl_mutex);
-static u16 min_ifinfo_dump_size;
void rtnl_lock(void)
{
@@ -724,10 +723,11 @@ static void copy_rtnl_link_stats64(void *v, const struct rtnl_link_stats64 *b)
}
/* All VF info */
-static inline int rtnl_vfinfo_size(const struct net_device *dev)
+static inline int rtnl_vfinfo_size(const struct net_device *dev,
+ u32 ext_filter_mask)
{
- if (dev->dev.parent && dev_is_pci(dev->dev.parent)) {
-
+ if (dev->dev.parent && dev_is_pci(dev->dev.parent) &&
+ (ext_filter_mask & RTEXT_FILTER_VF)) {
int num_vfs = dev_num_vf(dev->dev.parent);
size_t size = nla_total_size(sizeof(struct nlattr));
size += nla_total_size(num_vfs * sizeof(struct nlattr));
@@ -766,7 +766,8 @@ static size_t rtnl_port_size(const struct net_device *dev)
return port_self_size;
}
-static noinline size_t if_nlmsg_size(const struct net_device *dev)
+static noinline size_t if_nlmsg_size(const struct net_device *dev,
+ u32 ext_filter_mask)
{
return NLMSG_ALIGN(sizeof(struct ifinfomsg))
+ nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
@@ -784,8 +785,9 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev)
+ nla_total_size(4) /* IFLA_MASTER */
+ nla_total_size(1) /* IFLA_OPERSTATE */
+ nla_total_size(1) /* IFLA_LINKMODE */
- + nla_total_size(4) /* IFLA_NUM_VF */
- + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
+ + nla_total_size(ext_filter_mask
+ & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
+ + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
+ rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
+ rtnl_link_get_size(dev) /* IFLA_LINKINFO */
+ rtnl_link_get_af_size(dev); /* IFLA_AF_SPEC */
@@ -868,7 +870,7 @@ static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev)
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
int type, u32 pid, u32 seq, u32 change,
- unsigned int flags)
+ unsigned int flags, u32 ext_filter_mask)
{
struct ifinfomsg *ifm;
struct nlmsghdr *nlh;
@@ -941,10 +943,11 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
goto nla_put_failure;
copy_rtnl_link_stats64(nla_data(attr), stats);
- if (dev->dev.parent)
+ if (dev->dev.parent && (ext_filter_mask & RTEXT_FILTER_VF))
NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
- if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
+ if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent
+ && (ext_filter_mask & RTEXT_FILTER_VF)) {
int i;
struct nlattr *vfinfo, *vf;
@@ -1048,6 +1051,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
struct net_device *dev;
struct hlist_head *head;
struct hlist_node *node;
+ struct nlattr *tb[IFLA_MAX+1];
+ u32 ext_filter_mask = 0;
s_h = cb->args[0];
s_idx = cb->args[1];
@@ -1055,6 +1060,12 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
rcu_read_lock();
cb->seq = net->dev_base_seq;
+ nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX,
+ ifla_policy);
+
+ if (tb[IFLA_EXT_MASK])
+ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) {
idx = 0;
head = &net->dev_index_head[h];
@@ -1064,7 +1075,8 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq, 0,
- NLM_F_MULTI) <= 0)
+ NLM_F_MULTI,
+ ext_filter_mask) <= 0)
goto out;
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
@@ -1100,6 +1112,7 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_VF_PORTS] = { .type = NLA_NESTED },
[IFLA_PORT_SELF] = { .type = NLA_NESTED },
[IFLA_AF_SPEC] = { .type = NLA_NESTED },
+ [IFLA_EXT_MASK] = { .type = NLA_U32 },
};
EXPORT_SYMBOL(ifla_policy);
@@ -1509,8 +1522,6 @@ errout:
if (send_addr_notify)
call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
- min_ifinfo_dump_size = max_t(u16, if_nlmsg_size(dev),
- min_ifinfo_dump_size);
return err;
}
@@ -1842,6 +1853,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
struct net_device *dev = NULL;
struct sk_buff *nskb;
int err;
+ u32 ext_filter_mask = 0;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
if (err < 0)
@@ -1850,6 +1862,9 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
if (tb[IFLA_IFNAME])
nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
+ if (tb[IFLA_EXT_MASK])
+ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
ifm = nlmsg_data(nlh);
if (ifm->ifi_index > 0)
dev = __dev_get_by_index(net, ifm->ifi_index);
@@ -1861,12 +1876,12 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
if (dev == NULL)
return -ENODEV;
- nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
+ nskb = nlmsg_new(if_nlmsg_size(dev, ext_filter_mask), GFP_KERNEL);
if (nskb == NULL)
return -ENOBUFS;
err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
- nlh->nlmsg_seq, 0, 0);
+ nlh->nlmsg_seq, 0, 0, ext_filter_mask);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size */
WARN_ON(err == -EMSGSIZE);
@@ -1877,8 +1892,31 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
return err;
}
-static u16 rtnl_calcit(struct sk_buff *skb)
+static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh)
{
+ struct net *net = sock_net(skb->sk);
+ struct net_device *dev;
+ struct nlattr *tb[IFLA_MAX+1];
+ u32 ext_filter_mask = 0;
+ u16 min_ifinfo_dump_size = 0;
+
+ nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, ifla_policy);
+
+ if (tb[IFLA_EXT_MASK])
+ ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]);
+
+ if (!ext_filter_mask)
+ return NLMSG_GOODSIZE;
+ /*
+ * traverse the list of net devices and compute the minimum
+ * buffer size based upon the filter mask.
+ */
+ list_for_each_entry(dev, &net->dev_base_head, dev_list) {
+ min_ifinfo_dump_size = max_t(u16, min_ifinfo_dump_size,
+ if_nlmsg_size(dev,
+ ext_filter_mask));
+ }
+
return min_ifinfo_dump_size;
}
@@ -1913,13 +1951,11 @@ void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
int err = -ENOBUFS;
size_t if_info_size;
- skb = nlmsg_new((if_info_size = if_nlmsg_size(dev)), GFP_KERNEL);
+ skb = nlmsg_new((if_info_size = if_nlmsg_size(dev, 0)), GFP_KERNEL);
if (skb == NULL)
goto errout;
- min_ifinfo_dump_size = max_t(u16, if_info_size, min_ifinfo_dump_size);
-
- err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0);
+ err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0, 0);
if (err < 0) {
/* -EMSGSIZE implies BUG in if_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
@@ -1977,7 +2013,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EOPNOTSUPP;
calcit = rtnl_get_calcit(family, type);
if (calcit)
- min_dump_alloc = calcit(skb);
+ min_dump_alloc = calcit(skb, nlh);
__rtnl_unlock();
rtnl = net->rtnl;
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 6b3ca5ba445..38673d2860e 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -65,7 +65,7 @@
it is infeasible task. The most general solutions would be
to keep skb->encapsulation counter (sort of local ttl),
and silently drop packet when it expires. It is a good
- solution, but it supposes maintaing new variable in ALL
+ solution, but it supposes maintaining new variable in ALL
skb, even if no tunneling is used.
Current solution: xmit_recursion breaks dead loops. This is a percpu
@@ -91,14 +91,14 @@
One of them is to parse packet trying to detect inner encapsulation
made by our node. It is difficult or even impossible, especially,
- taking into account fragmentation. TO be short, tt is not solution at all.
+ taking into account fragmentation. TO be short, ttl is not solution at all.
Current solution: The solution was UNEXPECTEDLY SIMPLE.
We force DF flag on tunnels with preconfigured hop limit,
that is ALL. :-) Well, it does not remove the problem completely,
but exponential growth of network traffic is changed to linear
(branches, that exceed pmtu are pruned) and tunnel mtu
- fastly degrades to value <68, where looping stops.
+ rapidly degrades to value <68, where looping stops.
Yes, it is not good if there exists a router in the loop,
which does not force DF, even when encapsulating packets have DF set.
But it is not our problem! Nobody could accuse us, we made
@@ -457,8 +457,8 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
GRE tunnels with enabled checksum. Tell them "thank you".
Well, I wonder, rfc1812 was written by Cisco employee,
- what the hell these idiots break standrads established
- by themself???
+ what the hell these idiots break standards established
+ by themselves???
*/
const struct iphdr *iph = (const struct iphdr *)skb->data;
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index aea5a199c37..b072386cee2 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -630,6 +630,7 @@ static int ping_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
pr_debug("ping_recvmsg(sk=%p,sk->num=%u)\n", isk, isk->inet_num);
+ err = -EOPNOTSUPP;
if (flags & MSG_OOB)
goto out;
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 37755ccc0e9..22ef5f9fd2f 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3240,7 +3240,8 @@ void __init tcp_init(void)
{
struct sk_buff *skb = NULL;
unsigned long limit;
- int i, max_share, cnt;
+ int max_share, cnt;
+ unsigned int i;
unsigned long jiffy = jiffies;
BUILD_BUG_ON(sizeof(struct tcp_skb_cb) > sizeof(skb->cb));
@@ -3283,7 +3284,7 @@ void __init tcp_init(void)
&tcp_hashinfo.bhash_size,
NULL,
64 * 1024);
- tcp_hashinfo.bhash_size = 1 << tcp_hashinfo.bhash_size;
+ tcp_hashinfo.bhash_size = 1U << tcp_hashinfo.bhash_size;
for (i = 0; i < tcp_hashinfo.bhash_size; i++) {
spin_lock_init(&tcp_hashinfo.bhash[i].lock);
INIT_HLIST_HEAD(&tcp_hashinfo.bhash[i].chain);
diff --git a/net/ipv4/xfrm4_mode_beet.c b/net/ipv4/xfrm4_mode_beet.c
index 63418185f52..e3db3f91511 100644
--- a/net/ipv4/xfrm4_mode_beet.c
+++ b/net/ipv4/xfrm4_mode_beet.c
@@ -110,10 +110,7 @@ static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
skb_push(skb, sizeof(*iph));
skb_reset_network_header(skb);
-
- memmove(skb->data - skb->mac_len, skb_mac_header(skb),
- skb->mac_len);
- skb_set_mac_header(skb, -skb->mac_len);
+ skb_mac_header_rebuild(skb);
xfrm4_beet_make_header(skb);
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c
index 534972e114a..ed4bf11ef9f 100644
--- a/net/ipv4/xfrm4_mode_tunnel.c
+++ b/net/ipv4/xfrm4_mode_tunnel.c
@@ -66,7 +66,6 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
{
- const unsigned char *old_mac;
int err = -EINVAL;
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
@@ -84,10 +83,9 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
if (!(x->props.flags & XFRM_STATE_NOECN))
ipip_ecn_decapsulate(skb);
- old_mac = skb_mac_header(skb);
- skb_set_mac_header(skb, -skb->mac_len);
- memmove(skb_mac_header(skb), old_mac, skb->mac_len);
skb_reset_network_header(skb);
+ skb_mac_header_rebuild(skb);
+
err = 0;
out:
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index c7e95c8c579..5aa3981a392 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1926,8 +1926,10 @@ static int ip6mr_forward2(struct net *net, struct mr6_table *mrt,
};
dst = ip6_route_output(net, NULL, &fl6);
- if (!dst)
+ if (dst->error) {
+ dst_release(dst);
goto out_free;
+ }
skb_dst_drop(skb);
skb_dst_set(skb, dst);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index d8f02ef88e5..c964958ac47 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -1545,9 +1545,10 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
&saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
dst = ip6_route_output(net, NULL, &fl6);
- if (dst == NULL)
+ if (dst->error) {
+ dst_release(dst);
return;
-
+ }
dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst))
return;
diff --git a/net/ipv6/xfrm6_mode_beet.c b/net/ipv6/xfrm6_mode_beet.c
index a81ce945075..9949a356d62 100644
--- a/net/ipv6/xfrm6_mode_beet.c
+++ b/net/ipv6/xfrm6_mode_beet.c
@@ -80,7 +80,6 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
{
struct ipv6hdr *ip6h;
- const unsigned char *old_mac;
int size = sizeof(struct ipv6hdr);
int err;
@@ -90,10 +89,7 @@ static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
__skb_push(skb, size);
skb_reset_network_header(skb);
-
- old_mac = skb_mac_header(skb);
- skb_set_mac_header(skb, -skb->mac_len);
- memmove(skb_mac_header(skb), old_mac, skb->mac_len);
+ skb_mac_header_rebuild(skb);
xfrm6_beet_make_header(skb);
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c
index 261e6e6f487..9f2095b19ad 100644
--- a/net/ipv6/xfrm6_mode_tunnel.c
+++ b/net/ipv6/xfrm6_mode_tunnel.c
@@ -63,7 +63,6 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
{
int err = -EINVAL;
- const unsigned char *old_mac;
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
goto out;
@@ -80,10 +79,9 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
if (!(x->props.flags & XFRM_STATE_NOECN))
ipip6_ecn_decapsulate(skb);
- old_mac = skb_mac_header(skb);
- skb_set_mac_header(skb, -skb->mac_len);
- memmove(skb_mac_header(skb), old_mac, skb->mac_len);
skb_reset_network_header(skb);
+ skb_mac_header_rebuild(skb);
+
err = 0;
out:
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 2406b3e7393..d86217d56bd 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -63,14 +63,14 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
test_sta_flag(sta, WLAN_STA_##flg) ? #flg "\n" : ""
int res = scnprintf(buf, sizeof(buf),
- "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+ "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
TEST(PS_DRIVER), TEST(AUTHORIZED),
TEST(SHORT_PREAMBLE),
TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT),
TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
- TEST(TDLS_PEER_AUTH));
+ TEST(TDLS_PEER_AUTH), TEST(RATE_CONTROL));
#undef TEST
return simple_read_from_buffer(userbuf, count, ppos, buf, res);
}
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 5a5a7767d54..ad64f4d5271 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -336,7 +336,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
int i;
u32 mask;
- if (sta) {
+ if (sta && test_sta_flag(sta, WLAN_STA_RATE_CONTROL)) {
ista = &sta->sta;
priv_sta = sta->rate_ctrl_priv;
}
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index 168427b0ffd..80cfc006dd7 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -41,7 +41,7 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
struct ieee80211_sta *ista = &sta->sta;
void *priv_sta = sta->rate_ctrl_priv;
- if (!ref)
+ if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
return;
ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
@@ -62,6 +62,7 @@ static inline void rate_control_rate_init(struct sta_info *sta)
sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
ref->ops->rate_init(ref->priv, sband, ista, priv_sta);
+ set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
}
static inline void rate_control_rate_update(struct ieee80211_local *local,
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 6f77f12dc3f..bfed851d0d3 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -52,6 +52,7 @@
* @WLAN_STA_SP: Station is in a service period, so don't try to
* reply to other uAPSD trigger frames or PS-Poll.
* @WLAN_STA_4ADDR_EVENT: 4-addr event was already sent for this frame.
+ * @WLAN_STA_RATE_CONTROL: rate control was initialized for this station.
*/
enum ieee80211_sta_info_flags {
WLAN_STA_AUTH,
@@ -71,6 +72,7 @@ enum ieee80211_sta_info_flags {
WLAN_STA_UAPSD,
WLAN_STA_SP,
WLAN_STA_4ADDR_EVENT,
+ WLAN_STA_RATE_CONTROL,
};
enum ieee80211_sta_state {
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index 611c3359b94..2555816e778 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -232,6 +232,7 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
__be16 dport = 0; /* destination port to forward */
unsigned int flags;
struct ip_vs_conn_param param;
+ const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
union nf_inet_addr snet; /* source network of the client,
after masking */
@@ -267,7 +268,6 @@ ip_vs_sched_persist(struct ip_vs_service *svc,
{
int protocol = iph.protocol;
const union nf_inet_addr *vaddr = &iph.daddr;
- const union nf_inet_addr fwmark = { .ip = htonl(svc->fwmark) };
__be16 vport = 0;
if (dst_port == svc->port) {
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 76613f5a55c..ed86a3be678 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -404,19 +404,49 @@ static void __nf_conntrack_hash_insert(struct nf_conn *ct,
&net->ct.hash[repl_hash]);
}
-void nf_conntrack_hash_insert(struct nf_conn *ct)
+int
+nf_conntrack_hash_check_insert(struct nf_conn *ct)
{
struct net *net = nf_ct_net(ct);
unsigned int hash, repl_hash;
+ struct nf_conntrack_tuple_hash *h;
+ struct hlist_nulls_node *n;
u16 zone;
zone = nf_ct_zone(ct);
- hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
- repl_hash = hash_conntrack(net, zone, &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+ hash = hash_conntrack(net, zone,
+ &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
+ repl_hash = hash_conntrack(net, zone,
+ &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+
+ spin_lock_bh(&nf_conntrack_lock);
+ /* See if there's one in the list already, including reverse */
+ hlist_nulls_for_each_entry(h, n, &net->ct.hash[hash], hnnode)
+ if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+ &h->tuple) &&
+ zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
+ goto out;
+ hlist_nulls_for_each_entry(h, n, &net->ct.hash[repl_hash], hnnode)
+ if (nf_ct_tuple_equal(&ct->tuplehash[IP_CT_DIR_REPLY].tuple,
+ &h->tuple) &&
+ zone == nf_ct_zone(nf_ct_tuplehash_to_ctrack(h)))
+ goto out;
+
+ add_timer(&ct->timeout);
+ nf_conntrack_get(&ct->ct_general);
__nf_conntrack_hash_insert(ct, hash, repl_hash);
+ NF_CT_STAT_INC(net, insert);
+ spin_unlock_bh(&nf_conntrack_lock);
+
+ return 0;
+
+out:
+ NF_CT_STAT_INC(net, insert_failed);
+ spin_unlock_bh(&nf_conntrack_lock);
+ return -EEXIST;
}
-EXPORT_SYMBOL_GPL(nf_conntrack_hash_insert);
+EXPORT_SYMBOL_GPL(nf_conntrack_hash_check_insert);
/* Confirm a connection given skb; places it in hash table */
int
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 9307b033c0c..30c9d4ca021 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1367,15 +1367,12 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
nf_ct_protonum(ct));
if (helper == NULL) {
rcu_read_unlock();
- spin_unlock_bh(&nf_conntrack_lock);
#ifdef CONFIG_MODULES
if (request_module("nfct-helper-%s", helpname) < 0) {
- spin_lock_bh(&nf_conntrack_lock);
err = -EOPNOTSUPP;
goto err1;
}
- spin_lock_bh(&nf_conntrack_lock);
rcu_read_lock();
helper = __nf_conntrack_helper_find(helpname,
nf_ct_l3num(ct),
@@ -1468,8 +1465,10 @@ ctnetlink_create_conntrack(struct net *net, u16 zone,
if (tstamp)
tstamp->start = ktime_to_ns(ktime_get_real());
- add_timer(&ct->timeout);
- nf_conntrack_hash_insert(ct);
+ err = nf_conntrack_hash_check_insert(ct);
+ if (err < 0)
+ goto err2;
+
rcu_read_unlock();
return ct;
@@ -1490,6 +1489,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
struct nf_conntrack_tuple otuple, rtuple;
struct nf_conntrack_tuple_hash *h = NULL;
struct nfgenmsg *nfmsg = nlmsg_data(nlh);
+ struct nf_conn *ct;
u_int8_t u3 = nfmsg->nfgen_family;
u16 zone;
int err;
@@ -1510,27 +1510,22 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
return err;
}
- spin_lock_bh(&nf_conntrack_lock);
if (cda[CTA_TUPLE_ORIG])
- h = __nf_conntrack_find(net, zone, &otuple);
+ h = nf_conntrack_find_get(net, zone, &otuple);
else if (cda[CTA_TUPLE_REPLY])
- h = __nf_conntrack_find(net, zone, &rtuple);
+ h = nf_conntrack_find_get(net, zone, &rtuple);
if (h == NULL) {
err = -ENOENT;
if (nlh->nlmsg_flags & NLM_F_CREATE) {
- struct nf_conn *ct;
enum ip_conntrack_events events;
ct = ctnetlink_create_conntrack(net, zone, cda, &otuple,
&rtuple, u3);
- if (IS_ERR(ct)) {
- err = PTR_ERR(ct);
- goto out_unlock;
- }
+ if (IS_ERR(ct))
+ return PTR_ERR(ct);
+
err = 0;
- nf_conntrack_get(&ct->ct_general);
- spin_unlock_bh(&nf_conntrack_lock);
if (test_bit(IPS_EXPECTED_BIT, &ct->status))
events = IPCT_RELATED;
else
@@ -1545,23 +1540,19 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
ct, NETLINK_CB(skb).pid,
nlmsg_report(nlh));
nf_ct_put(ct);
- } else
- spin_unlock_bh(&nf_conntrack_lock);
+ }
return err;
}
/* implicit 'else' */
- /* We manipulate the conntrack inside the global conntrack table lock,
- * so there's no need to increase the refcount */
err = -EEXIST;
+ ct = nf_ct_tuplehash_to_ctrack(h);
if (!(nlh->nlmsg_flags & NLM_F_EXCL)) {
- struct nf_conn *ct = nf_ct_tuplehash_to_ctrack(h);
-
+ spin_lock_bh(&nf_conntrack_lock);
err = ctnetlink_change_conntrack(ct, cda);
+ spin_unlock_bh(&nf_conntrack_lock);
if (err == 0) {
- nf_conntrack_get(&ct->ct_general);
- spin_unlock_bh(&nf_conntrack_lock);
nf_conntrack_eventmask_report((1 << IPCT_REPLY) |
(1 << IPCT_ASSURED) |
(1 << IPCT_HELPER) |
@@ -1570,15 +1561,10 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
(1 << IPCT_MARK),
ct, NETLINK_CB(skb).pid,
nlmsg_report(nlh));
- nf_ct_put(ct);
- } else
- spin_unlock_bh(&nf_conntrack_lock);
-
- return err;
+ }
}
-out_unlock:
- spin_unlock_bh(&nf_conntrack_lock);
+ nf_ct_put(ct);
return err;
}
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index b3a7db678b8..ce60cf0f6c1 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -203,6 +203,27 @@ err:
return status;
}
+#ifdef CONFIG_BRIDGE_NETFILTER
+/* When called from bridge netfilter, skb->data must point to MAC header
+ * before calling skb_gso_segment(). Else, original MAC header is lost
+ * and segmented skbs will be sent to wrong destination.
+ */
+static void nf_bridge_adjust_skb_data(struct sk_buff *skb)
+{
+ if (skb->nf_bridge)
+ __skb_push(skb, skb->network_header - skb->mac_header);
+}
+
+static void nf_bridge_adjust_segmented_data(struct sk_buff *skb)
+{
+ if (skb->nf_bridge)
+ __skb_pull(skb, skb->network_header - skb->mac_header);
+}
+#else
+#define nf_bridge_adjust_skb_data(s) do {} while (0)
+#define nf_bridge_adjust_segmented_data(s) do {} while (0)
+#endif
+
int nf_queue(struct sk_buff *skb,
struct list_head *elem,
u_int8_t pf, unsigned int hook,
@@ -212,7 +233,7 @@ int nf_queue(struct sk_buff *skb,
unsigned int queuenum)
{
struct sk_buff *segs;
- int err;
+ int err = -EINVAL;
unsigned int queued;
if (!skb_is_gso(skb))
@@ -228,23 +249,25 @@ int nf_queue(struct sk_buff *skb,
break;
}
+ nf_bridge_adjust_skb_data(skb);
segs = skb_gso_segment(skb, 0);
/* Does not use PTR_ERR to limit the number of error codes that can be
* returned by nf_queue. For instance, callers rely on -ECANCELED to mean
* 'ignore this hook'.
*/
if (IS_ERR(segs))
- return -EINVAL;
-
+ goto out_err;
queued = 0;
err = 0;
do {
struct sk_buff *nskb = segs->next;
segs->next = NULL;
- if (err == 0)
+ if (err == 0) {
+ nf_bridge_adjust_segmented_data(segs);
err = __nf_queue(segs, elem, pf, hook, indev,
outdev, okfn, queuenum);
+ }
if (err == 0)
queued++;
else
@@ -252,11 +275,12 @@ int nf_queue(struct sk_buff *skb,
segs = nskb;
} while (segs);
- /* also free orig skb if only some segments were queued */
- if (unlikely(err && queued))
- err = 0;
- if (err == 0)
+ if (queued) {
kfree_skb(skb);
+ return 0;
+ }
+ out_err:
+ nf_bridge_adjust_segmented_data(skb);
return err;
}
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index 3aae66facf9..4d505790283 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -152,9 +152,10 @@ tee_tg_route6(struct sk_buff *skb, const struct xt_tee_tginfo *info)
fl6.flowlabel = ((iph->flow_lbl[0] & 0xF) << 16) |
(iph->flow_lbl[1] << 8) | iph->flow_lbl[2];
dst = ip6_route_output(net, NULL, &fl6);
- if (dst == NULL)
+ if (dst->error) {
+ dst_release(dst);
return false;
-
+ }
skb_dst_drop(skb);
skb_dst_set(skb, dst);
skb->dev = dst->dev;
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index e83d61ca78c..5da548fa7ae 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -501,9 +501,8 @@ tfifo_dequeue:
/* if more time remaining? */
if (cb->time_to_send <= psched_get_time()) {
- skb = qdisc_dequeue_tail(sch);
- if (unlikely(!skb))
- goto qdisc_dequeue;
+ __skb_unlink(skb, &sch->q);
+ sch->qstats.backlog -= qdisc_pkt_len(skb);
#ifdef CONFIG_NET_CLS_ACT
/*
@@ -539,7 +538,6 @@ deliver:
qdisc_watchdog_schedule(&q->watchdog, cb->time_to_send);
}
-qdisc_dequeue:
if (q->qdisc) {
skb = q->qdisc->ops->dequeue(q->qdisc);
if (skb)
diff --git a/scripts/coccicheck b/scripts/coccicheck
index 3c2776466d8..823e972149e 100755
--- a/scripts/coccicheck
+++ b/scripts/coccicheck
@@ -9,15 +9,10 @@ if [ "$C" = "1" -o "$C" = "2" ]; then
# FLAGS="-ignore_unknown_options -very_quiet"
# OPTIONS=$*
- if [ "$KBUILD_EXTMOD" = "" ] ; then
- # Workaround for Coccinelle < 0.2.3
- FLAGS="-I $srctree/include -very_quiet"
- shift $(( $# - 1 ))
- OPTIONS=$1
- else
- echo M= is not currently supported when C=1 or C=2
- exit 1
- fi
+# Workaround for Coccinelle < 0.2.3
+ FLAGS="-I $srctree/include -very_quiet"
+ shift $(( $# - 1 ))
+ OPTIONS=$1
else
ONLINE=0
FLAGS="-very_quiet"
diff --git a/scripts/depmod.sh b/scripts/depmod.sh
index a2723568594..2ae48170314 100755
--- a/scripts/depmod.sh
+++ b/scripts/depmod.sh
@@ -9,12 +9,6 @@ fi
DEPMOD=$1
KERNELRELEASE=$2
-if ! "$DEPMOD" -V 2>/dev/null | grep -q module-init-tools; then
- echo "Warning: you may need to install module-init-tools" >&2
- echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt" >&2
- sleep 1
-fi
-
if ! test -r System.map -a -x "$DEPMOD"; then
exit 0
fi
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index d0de2a2c3a2..b89efe6e4c8 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -46,11 +46,37 @@ struct devtable {
void *function;
};
+#define ___cat(a,b) a ## b
+#define __cat(a,b) ___cat(a,b)
+
+/* we need some special handling for this host tool running eventually on
+ * Darwin. The Mach-O section handling is a bit different than ELF section
+ * handling. The differnces in detail are:
+ * a) we have segments which have sections
+ * b) we need a API call to get the respective section symbols */
+#if defined(__MACH__)
+#include <mach-o/getsect.h>
+
+#define INIT_SECTION(name) do { \
+ unsigned long name ## _len; \
+ char *__cat(pstart_,name) = getsectdata("__TEXT", \
+ #name, &__cat(name,_len)); \
+ char *__cat(pstop_,name) = __cat(pstart_,name) + \
+ __cat(name, _len); \
+ __cat(__start_,name) = (void *)__cat(pstart_,name); \
+ __cat(__stop_,name) = (void *)__cat(pstop_,name); \
+ } while (0)
+#define SECTION(name) __attribute__((section("__TEXT, " #name)))
+
+struct devtable **__start___devtable, **__stop___devtable;
+#else
+#define INIT_SECTION(name) /* no-op for ELF */
+#define SECTION(name) __attribute__((section(#name)))
+
/* We construct a table of pointers in an ELF section (pointers generally
* go unpadded by gcc). ld creates boundary syms for us. */
extern struct devtable *__start___devtable[], *__stop___devtable[];
-#define ___cat(a,b) a ## b
-#define __cat(a,b) ___cat(a,b)
+#endif /* __MACH__ */
#if __GNUC__ == 3 && __GNUC_MINOR__ < 3
# define __used __attribute__((__unused__))
@@ -65,8 +91,8 @@ extern struct devtable *__start___devtable[], *__stop___devtable[];
(type *)NULL, \
(char *)NULL)), \
sizeof(type), (function) }; \
- static struct devtable *__attribute__((section("__devtable"))) \
- __used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
+ static struct devtable *SECTION(__devtable) __used \
+ __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
#define ADD(str, sep, cond, field) \
do { \
@@ -1080,6 +1106,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
do_pnp_card_entries(symval, sym->st_size, mod);
else {
struct devtable **p;
+ INIT_SECTION(__devtable);
for (p = __start___devtable; p < __stop___devtable; p++) {
if (sym_is(name, namelen, (*p)->device_id)) {
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 2bd594e6d1b..9adb667dd31 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -1494,6 +1494,13 @@ static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
return 0;
}
+#ifndef R_ARM_CALL
+#define R_ARM_CALL 28
+#endif
+#ifndef R_ARM_JUMP24
+#define R_ARM_JUMP24 29
+#endif
+
static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
{
unsigned int r_typ = ELF_R_TYPE(r->r_info);
@@ -1505,6 +1512,8 @@ static int addend_arm_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r)
(elf->symtab_start + ELF_R_SYM(r->r_info));
break;
case R_ARM_PC24:
+ case R_ARM_CALL:
+ case R_ARM_JUMP24:
/* From ARM ABI: ((S + A) | T) - P */
r->r_addend = (int)(long)(elf->hdr +
sechdr->sh_offset +
diff --git a/scripts/package/builddeb b/scripts/package/builddeb
index f6cbc3ddb68..3c6c0b14c80 100644
--- a/scripts/package/builddeb
+++ b/scripts/package/builddeb
@@ -238,14 +238,14 @@ EOF
fi
# Build header package
-(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$)
-(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> /tmp/files$$)
-(cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$)
+(cd $srctree; find . -name Makefile -o -name Kconfig\* -o -name \*.pl > "$objtree/debian/hdrsrcfiles")
+(cd $srctree; find arch/$SRCARCH/include include scripts -type f >> "$objtree/debian/hdrsrcfiles")
+(cd $objtree; find .config Module.symvers include scripts -type f >> "$objtree/debian/hdrobjfiles")
destdir=$kernel_headers_dir/usr/src/linux-headers-$version
mkdir -p "$destdir"
-(cd $srctree; tar -c -f - -T /tmp/files$$) | (cd $destdir; tar -xf -)
-(cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -)
-rm -f /tmp/files$$ /tmp/objfiles$$
+(cd $srctree; tar -c -f - -T "$objtree/debian/hdrsrcfiles") | (cd $destdir; tar -xf -)
+(cd $objtree; tar -c -f - -T "$objtree/debian/hdrobjfiles") | (cd $destdir; tar -xf -)
+rm -f "$objtree/debian/hdrsrcfiles" "$objtree/debian/hdrobjfiles"
arch=$(dpkg --print-architecture)
cat <<EOF >> debian/control
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index 95ffa6a9db6..496f14c1a73 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2684,10 +2684,9 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0)
goto out_err;
+ opl3->private_data = chip;
}
- opl3->private_data = chip;
-
sprintf(card->longname, "%s at 0x%lx, irq %i",
card->shortname, chip->ctrl_io, chip->irq);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index c2c65f63bf0..684307372d7 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1759,7 +1759,11 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
parm |= index << AC_AMP_SET_INDEX_SHIFT;
- parm |= val;
+ if ((val & HDA_AMP_MUTE) && !(info->amp_caps & AC_AMPCAP_MUTE) &&
+ (info->amp_caps & AC_AMPCAP_MIN_MUTE))
+ ; /* set the zero value as a fake mute */
+ else
+ parm |= val;
snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
info->vol[ch] = val;
}
@@ -2026,7 +2030,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
val1 += ofs;
val1 = ((int)val1) * ((int)val2);
- if (min_mute)
+ if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
val2 |= TLV_DB_SCALE_MUTE;
if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
return -EFAULT;
@@ -5114,7 +5118,7 @@ static int fill_audio_out_name(struct hda_codec *codec, hda_nid_t nid,
const char *pfx = "", *sfx = "";
/* handle as a speaker if it's a fixed line-out */
- if (!strcmp(name, "Line-Out") && attr == INPUT_PIN_ATTR_INT)
+ if (!strcmp(name, "Line Out") && attr == INPUT_PIN_ATTR_INT)
name = "Speaker";
/* check the location */
switch (attr) {
@@ -5173,7 +5177,7 @@ int snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid,
switch (get_defcfg_device(def_conf)) {
case AC_JACK_LINE_OUT:
- return fill_audio_out_name(codec, nid, cfg, "Line-Out",
+ return fill_audio_out_name(codec, nid, cfg, "Line Out",
label, maxlen, indexp);
case AC_JACK_SPEAKER:
return fill_audio_out_name(codec, nid, cfg, "Speaker",
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index e9f71dc0d46..f0f1943a4b2 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -298,6 +298,9 @@ enum {
#define AC_AMPCAP_MUTE (1<<31) /* mute capable */
#define AC_AMPCAP_MUTE_SHIFT 31
+/* driver-specific amp-caps: using bits 24-30 */
+#define AC_AMPCAP_MIN_MUTE (1 << 30) /* min-volume = mute */
+
/* Connection list */
#define AC_CLIST_LENGTH (0x7f<<0)
#define AC_CLIST_LONG (1<<7)
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index bc5a993d114..c83ccdba1e5 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -609,7 +609,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
"Front Speaker", "Surround Speaker", "Bass Speaker"
};
static const char * const line_outs[] = {
- "Front Line-Out", "Surround Line-Out", "Bass Line-Out"
+ "Front Line Out", "Surround Line Out", "Bass Line Out"
};
fix_volume_caps(codec, dac);
@@ -635,7 +635,7 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx,
if (num_ctls > 1)
name = line_outs[idx];
else
- name = "Line-Out";
+ name = "Line Out";
break;
}
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index a7a5733aa4d..d29d6d37790 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -3482,7 +3482,7 @@ static int cx_automute_mode_info(struct snd_kcontrol *kcontrol,
"Disabled", "Enabled"
};
static const char * const texts3[] = {
- "Disabled", "Speaker Only", "Line-Out+Speaker"
+ "Disabled", "Speaker Only", "Line Out+Speaker"
};
const char * const *texts;
@@ -4079,7 +4079,8 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
err = snd_hda_ctl_add(codec, nid, kctl);
if (err < 0)
return err;
- if (!(query_amp_caps(codec, nid, hda_dir) & AC_AMPCAP_MUTE))
+ if (!(query_amp_caps(codec, nid, hda_dir) &
+ (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)))
break;
}
return 0;
@@ -4379,6 +4380,22 @@ static const struct snd_pci_quirk cxt_fixups[] = {
{}
};
+/* add "fake" mute amp-caps to DACs on cx5051 so that mixer mute switches
+ * can be created (bko#42825)
+ */
+static void add_cx5051_fake_mutes(struct hda_codec *codec)
+{
+ static hda_nid_t out_nids[] = {
+ 0x10, 0x11, 0
+ };
+ hda_nid_t *p;
+
+ for (p = out_nids; *p; p++)
+ snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
+ AC_AMPCAP_MIN_MUTE |
+ query_amp_caps(codec, *p, HDA_OUTPUT));
+}
+
static int patch_conexant_auto(struct hda_codec *codec)
{
struct conexant_spec *spec;
@@ -4397,6 +4414,9 @@ static int patch_conexant_auto(struct hda_codec *codec)
case 0x14f15045:
spec->single_adc_amp = 1;
break;
+ case 0x14f15051:
+ add_cx5051_fake_mutes(codec);
+ break;
}
apply_pin_fixup(codec, cxt_fixups, cxt_pincfg_tbl);
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 1358987c49d..f286bb8fda1 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -80,6 +80,8 @@ enum {
ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */
};
+#define MAX_VOL_NIDS 0x40
+
struct alc_spec {
/* codec parameterization */
const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */
@@ -118,8 +120,8 @@ struct alc_spec {
const hda_nid_t *capsrc_nids;
hda_nid_t dig_in_nid; /* digital-in NID; optional */
hda_nid_t mixer_nid; /* analog-mixer NID */
- DECLARE_BITMAP(vol_ctls, 0x20 << 1);
- DECLARE_BITMAP(sw_ctls, 0x20 << 1);
+ DECLARE_BITMAP(vol_ctls, MAX_VOL_NIDS << 1);
+ DECLARE_BITMAP(sw_ctls, MAX_VOL_NIDS << 1);
/* capture setup for dynamic dual-adc switch */
hda_nid_t cur_adc;
@@ -800,7 +802,7 @@ static int alc_automute_mode_info(struct snd_kcontrol *kcontrol,
"Disabled", "Enabled"
};
static const char * const texts3[] = {
- "Disabled", "Speaker Only", "Line-Out+Speaker"
+ "Disabled", "Speaker Only", "Line Out+Speaker"
};
const char * const *texts;
@@ -1854,7 +1856,7 @@ static const char * const alc_slave_vols[] = {
"Headphone Playback Volume",
"Speaker Playback Volume",
"Mono Playback Volume",
- "Line-Out Playback Volume",
+ "Line Out Playback Volume",
"CLFE Playback Volume",
"Bass Speaker Playback Volume",
"PCM Playback Volume",
@@ -1871,7 +1873,7 @@ static const char * const alc_slave_sws[] = {
"Speaker Playback Switch",
"Mono Playback Switch",
"IEC958 Playback Switch",
- "Line-Out Playback Switch",
+ "Line Out Playback Switch",
"CLFE Playback Switch",
"Bass Speaker Playback Switch",
"PCM Playback Switch",
@@ -3149,7 +3151,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec)
static inline unsigned int get_ctl_pos(unsigned int data)
{
hda_nid_t nid = get_amp_nid_(data);
- unsigned int dir = get_amp_direction_(data);
+ unsigned int dir;
+ if (snd_BUG_ON(nid >= MAX_VOL_NIDS))
+ return 0;
+ dir = get_amp_direction_(data);
return (nid << 1) | dir;
}
@@ -3792,7 +3797,7 @@ static void alc_auto_init_input_src(struct hda_codec *codec)
else
nums = spec->num_adc_nids;
for (c = 0; c < nums; c++)
- alc_mux_select(codec, 0, spec->cur_mux[c], true);
+ alc_mux_select(codec, c, spec->cur_mux[c], true);
}
/* add mic boosts if needed */
@@ -4436,12 +4441,20 @@ static void alc889_fixup_dac_route(struct hda_codec *codec,
const struct alc_fixup *fix, int action)
{
if (action == ALC_FIXUP_ACT_PRE_PROBE) {
+ /* fake the connections during parsing the tree */
hda_nid_t conn1[2] = { 0x0c, 0x0d };
hda_nid_t conn2[2] = { 0x0e, 0x0f };
snd_hda_override_conn_list(codec, 0x14, 2, conn1);
snd_hda_override_conn_list(codec, 0x15, 2, conn1);
snd_hda_override_conn_list(codec, 0x18, 2, conn2);
snd_hda_override_conn_list(codec, 0x1a, 2, conn2);
+ } else if (action == ALC_FIXUP_ACT_PROBE) {
+ /* restore the connections */
+ hda_nid_t conn[5] = { 0x0c, 0x0d, 0x0e, 0x0f, 0x26 };
+ snd_hda_override_conn_list(codec, 0x14, 5, conn);
+ snd_hda_override_conn_list(codec, 0x15, 5, conn);
+ snd_hda_override_conn_list(codec, 0x18, 5, conn);
+ snd_hda_override_conn_list(codec, 0x1a, 5, conn);
}
}
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6345df131a0..9dbb5735d77 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4629,7 +4629,7 @@ static void stac92xx_hp_detect(struct hda_codec *codec)
unsigned int val = AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN;
if (no_hp_sensing(spec, i))
continue;
- if (presence)
+ if (1 /*presence*/)
stac92xx_set_pinctl(codec, cfg->hp_pins[i], val);
#if 0 /* FIXME */
/* Resetting the pinctl like below may lead to (a sort of) regressions
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index 5ef70b5d27e..278c0a0575f 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -146,13 +146,10 @@ static const struct snd_kcontrol_new ak4642_snd_controls[] = {
SOC_DOUBLE_R_TLV("Digital Playback Volume", L_DVC, R_DVC,
0, 0xFF, 1, out_tlv),
-
- SOC_SINGLE("Headphone Switch", PW_MGMT2, 6, 1, 0),
};
-static const struct snd_kcontrol_new ak4642_hpout_mixer_controls[] = {
- SOC_DAPM_SINGLE("DACH", MD_CTL4, 0, 1, 0),
-};
+static const struct snd_kcontrol_new ak4642_headphone_control =
+ SOC_DAPM_SINGLE("Switch", PW_MGMT2, 6, 1, 0);
static const struct snd_kcontrol_new ak4642_lout_mixer_controls[] = {
SOC_DAPM_SINGLE("DACL", SG_SL1, 4, 1, 0),
@@ -165,13 +162,12 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("HPOUTR"),
SND_SOC_DAPM_OUTPUT("LINEOUT"),
- SND_SOC_DAPM_MIXER("HPOUTL Mixer", PW_MGMT2, 5, 0,
- &ak4642_hpout_mixer_controls[0],
- ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+ SND_SOC_DAPM_PGA("HPL Out", PW_MGMT2, 5, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("HPR Out", PW_MGMT2, 4, 0, NULL, 0),
+ SND_SOC_DAPM_SWITCH("Headphone Enable", SND_SOC_NOPM, 0, 0,
+ &ak4642_headphone_control),
- SND_SOC_DAPM_MIXER("HPOUTR Mixer", PW_MGMT2, 4, 0,
- &ak4642_hpout_mixer_controls[0],
- ARRAY_SIZE(ak4642_hpout_mixer_controls)),
+ SND_SOC_DAPM_PGA("DACH", MD_CTL4, 0, 0, NULL, 0),
SND_SOC_DAPM_MIXER("LINEOUT Mixer", PW_MGMT1, 3, 0,
&ak4642_lout_mixer_controls[0],
@@ -184,12 +180,17 @@ static const struct snd_soc_dapm_widget ak4642_dapm_widgets[] = {
static const struct snd_soc_dapm_route ak4642_intercon[] = {
/* Outputs */
- {"HPOUTL", NULL, "HPOUTL Mixer"},
- {"HPOUTR", NULL, "HPOUTR Mixer"},
+ {"HPOUTL", NULL, "HPL Out"},
+ {"HPOUTR", NULL, "HPR Out"},
{"LINEOUT", NULL, "LINEOUT Mixer"},
- {"HPOUTL Mixer", "DACH", "DAC"},
- {"HPOUTR Mixer", "DACH", "DAC"},
+ {"HPL Out", NULL, "Headphone Enable"},
+ {"HPR Out", NULL, "Headphone Enable"},
+
+ {"Headphone Enable", "Switch", "DACH"},
+
+ {"DACH", NULL, "DAC"},
+
{"LINEOUT Mixer", "DACL", "DAC"},
};
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 29c4b02c479..0ac228b7dc0 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -2564,7 +2564,7 @@ static int dsp2_event(struct snd_soc_dapm_widget *w,
return 0;
}
-static const char *st_text[] = { "None", "Right", "Left" };
+static const char *st_text[] = { "None", "Left", "Right" };
static const struct soc_enum str_enum =
SOC_ENUM_SINGLE(WM8962_DAC_DSP_MIXING_1, 2, 3, st_text);
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c
index 01d1f749cf0..b6adbed6e50 100644
--- a/sound/soc/imx/imx-ssi.c
+++ b/sound/soc/imx/imx-ssi.c
@@ -112,7 +112,7 @@ static int imx_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
break;
case SND_SOC_DAIFMT_DSP_A:
/* data on rising edge of bclk, frame high 1clk before data */
- strcr |= SSI_STCR_TFSL | SSI_STCR_TEFS;
+ strcr |= SSI_STCR_TFSL | SSI_STCR_TXBIT0 | SSI_STCR_TEFS;
break;
}
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 1f55ded4047..1315663c1c0 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -3068,9 +3068,13 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
* standby.
*/
if (powerdown) {
- snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_PREPARE);
+ if (dapm->bias_level == SND_SOC_BIAS_ON)
+ snd_soc_dapm_set_bias_level(dapm,
+ SND_SOC_BIAS_PREPARE);
dapm_seq_run(dapm, &down_list, 0, false);
- snd_soc_dapm_set_bias_level(dapm, SND_SOC_BIAS_STANDBY);
+ if (dapm->bias_level == SND_SOC_BIAS_PREPARE)
+ snd_soc_dapm_set_bias_level(dapm,
+ SND_SOC_BIAS_STANDBY);
}
}
@@ -3083,7 +3087,9 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card)
list_for_each_entry(codec, &card->codec_dev_list, list) {
soc_dapm_shutdown_codec(&codec->dapm);
- snd_soc_dapm_set_bias_level(&codec->dapm, SND_SOC_BIAS_OFF);
+ if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY)
+ snd_soc_dapm_set_bias_level(&codec->dapm,
+ SND_SOC_BIAS_OFF);
}
}
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index 2cf87f5afed..fde9a7a29cb 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -311,8 +311,10 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
spin_lock(&dev->spinlock);
- if (dev->input_panic || dev->output_panic)
+ if (dev->input_panic || dev->output_panic) {
ptr = SNDRV_PCM_POS_XRUN;
+ goto unlock;
+ }
if (sub->stream == SNDRV_PCM_STREAM_PLAYBACK)
ptr = bytes_to_frames(sub->runtime,
@@ -321,6 +323,7 @@ snd_usb_caiaq_pcm_pointer(struct snd_pcm_substream *sub)
ptr = bytes_to_frames(sub->runtime,
dev->audio_in_buf_pos[index]);
+unlock:
spin_unlock(&dev->spinlock);
return ptr;
}
diff --git a/sound/usb/card.h b/sound/usb/card.h
index a39edcc32a9..da5fa1ac4ed 100644
--- a/sound/usb/card.h
+++ b/sound/usb/card.h
@@ -1,6 +1,7 @@
#ifndef __USBAUDIO_CARD_H
#define __USBAUDIO_CARD_H
+#define MAX_NR_RATES 1024
#define MAX_PACKS 20
#define MAX_PACKS_HS (MAX_PACKS * 8) /* in high speed mode */
#define MAX_URBS 8
diff --git a/sound/usb/format.c b/sound/usb/format.c
index e09aba19375..ddfef57c4c9 100644
--- a/sound/usb/format.c
+++ b/sound/usb/format.c
@@ -209,8 +209,6 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof
return 0;
}
-#define MAX_UAC2_NR_RATES 1024
-
/*
* Helper function to walk the array of sample rate triplets reported by
* the device. The problem is that we need to parse whole array first to
@@ -255,7 +253,7 @@ static int parse_uac2_sample_rate_range(struct audioformat *fp, int nr_triplets,
fp->rates |= snd_pcm_rate_to_rate_bit(rate);
nr_rates++;
- if (nr_rates >= MAX_UAC2_NR_RATES) {
+ if (nr_rates >= MAX_NR_RATES) {
snd_printk(KERN_ERR "invalid uac2 rates\n");
break;
}
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
index a3ddac0deff..27817266867 100644
--- a/sound/usb/quirks.c
+++ b/sound/usb/quirks.c
@@ -132,10 +132,14 @@ static int create_fixed_stream_quirk(struct snd_usb_audio *chip,
unsigned *rate_table = NULL;
fp = kmemdup(quirk->data, sizeof(*fp), GFP_KERNEL);
- if (! fp) {
+ if (!fp) {
snd_printk(KERN_ERR "cannot memdup\n");
return -ENOMEM;
}
+ if (fp->nr_rates > MAX_NR_RATES) {
+ kfree(fp);
+ return -EINVAL;
+ }
if (fp->nr_rates > 0) {
rate_table = kmemdup(fp->rate_table,
sizeof(int) * fp->nr_rates, GFP_KERNEL);
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c
index 2044324b755..2a6f33cd888 100644
--- a/tools/perf/util/event.c
+++ b/tools/perf/util/event.c
@@ -74,6 +74,7 @@ static pid_t perf_event__get_comm_tgid(pid_t pid, char *comm, size_t len)
if (size >= len)
size = len - 1;
memcpy(comm, name, size);
+ comm[size] = '\0';
} else if (memcmp(bf, "Tgid:", 5) == 0) {
char *tgids = bf + 5;
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 3f16e08a5c8..ea32a061f1c 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -349,6 +349,10 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
hlist_for_each_entry(sid, pos, head, node)
if (sid->id == id)
return sid->evsel;
+
+ if (!perf_evlist__sample_id_all(evlist))
+ return list_entry(evlist->entries.next, struct perf_evsel, node);
+
return NULL;
}
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 29cb6545981..e33554a562b 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1867,6 +1867,12 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
tev->point.symbol);
ret = -ENOENT;
goto error;
+ } else if (tev->point.offset > sym->end - sym->start) {
+ pr_warning("Offset specified is greater than size of %s\n",
+ tev->point.symbol);
+ ret = -ENOENT;
+ goto error;
+
}
return 1;
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 5d732621a46..74bd2e63c4b 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -672,7 +672,7 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
bool retprobe, struct probe_trace_point *tp)
{
- Dwarf_Addr eaddr;
+ Dwarf_Addr eaddr, highaddr;
const char *name;
/* Copy the name of probe point */
@@ -683,6 +683,16 @@ static int convert_to_trace_point(Dwarf_Die *sp_die, Dwarf_Addr paddr,
dwarf_diename(sp_die));
return -ENOENT;
}
+ if (dwarf_highpc(sp_die, &highaddr) != 0) {
+ pr_warning("Failed to get end address of %s\n",
+ dwarf_diename(sp_die));
+ return -ENOENT;
+ }
+ if (paddr > highaddr) {
+ pr_warning("Offset specified is greater than size of %s\n",
+ dwarf_diename(sp_die));
+ return -EINVAL;
+ }
tp->symbol = strdup(name);
if (tp->symbol == NULL)
return -ENOMEM;
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 62a134dc421..9507c4b251a 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -3244,9 +3244,11 @@ sub make_min_config {
$in_bisect = 1;
my $failed = 0;
- build "oldconfig";
- start_monitor_and_boot or $failed = 1;
- end_monitor;
+ build "oldconfig" or $failed = 1;
+ if (!$failed) {
+ start_monitor_and_boot or $failed = 1;
+ end_monitor;
+ }
$in_bisect = 0;