summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS5
-rw-r--r--Documentation/ABI/testing/sysfs-module16
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt-nv24.xml121
-rw-r--r--Documentation/DocBook/media/v4l/pixfmt.xml1
-rw-r--r--Documentation/devicetree/bindings/mfd/mc13xxx.txt78
-rw-r--r--Documentation/devicetree/bindings/mfd/twl-familly.txt47
-rw-r--r--Documentation/devicetree/bindings/resource-names.txt54
-rw-r--r--Documentation/dma-buf-sharing.txt4
-rw-r--r--Documentation/fb/api.txt306
-rw-r--r--Documentation/filesystems/nfs/00-INDEX2
-rw-r--r--Documentation/filesystems/nfs/fault_injection.txt69
-rw-r--r--Documentation/filesystems/squashfs.txt6
-rw-r--r--Documentation/kmemleak.txt3
-rw-r--r--Documentation/mmc/mmc-dev-attrs.txt10
-rw-r--r--Documentation/mmc/mmc-dev-parts.txt13
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/arm/include/asm/hwcap.h4
-rw-r--r--arch/arm/include/asm/swab.h7
-rw-r--r--arch/arm/include/asm/unistd.h4
-rw-r--r--arch/arm/mach-omap2/board-4430sdp.c23
-rw-r--r--arch/arm/mach-omap2/board-omap4panda.c25
-rw-r--r--arch/arm/mach-omap2/display.c39
-rw-r--r--arch/arm/mach-realview/realview_eb.c3
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c3
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c3
-rw-r--r--arch/arm/mach-realview/realview_pba8.c3
-rw-r--r--arch/arm/mach-realview/realview_pbx.c3
-rw-r--r--arch/arm/mach-sa1100/assabet.c12
-rw-r--r--arch/arm/mach-sa1100/cerf.c11
-rw-r--r--arch/arm/mach-sa1100/collie.c18
-rw-r--r--arch/arm/mach-sa1100/generic.c7
-rw-r--r--arch/arm/mach-sa1100/include/mach/gpio.h3
-rw-r--r--arch/arm/mach-sa1100/include/mach/mcp.h2
-rw-r--r--arch/arm/mach-sa1100/lart.c10
-rw-r--r--arch/arm/mach-sa1100/shannon.c11
-rw-r--r--arch/arm/mach-sa1100/simpad.c18
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c43
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c32
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c4
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c4
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c4
-rw-r--r--arch/arm/mach-ux500/board-mop500.c4
-rw-r--r--arch/arm/mach-ux500/board-u5500.c2
-rw-r--r--arch/arm/mach-ux500/include/mach/irqs-board-mop500.h2
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h1
-rw-r--r--arch/arm/plat-samsung/platformdata.c2
-rw-r--r--arch/frv/include/asm/param.h16
-rw-r--r--arch/ia64/hp/common/aml_nfw.c2
-rw-r--r--arch/ia64/include/asm/intrinsics.h21
-rw-r--r--arch/ia64/include/asm/unistd.h3
-rw-r--r--arch/ia64/kernel/entry.S1
-rw-r--r--arch/m32r/include/asm/param.h18
-rw-r--r--arch/mips/Kconfig84
-rw-r--r--arch/mips/Makefile1
-rw-r--r--arch/mips/alchemy/Kconfig60
-rw-r--r--arch/mips/alchemy/Makefile3
-rw-r--r--arch/mips/alchemy/Platform58
-rw-r--r--arch/mips/alchemy/board-gpr.c (renamed from arch/mips/alchemy/gpr/platform.c)81
-rw-r--r--arch/mips/alchemy/board-mtx1.c (renamed from arch/mips/alchemy/mtx-1/platform.c)93
-rw-r--r--arch/mips/alchemy/board-xxs1500.c154
-rw-r--r--arch/mips/alchemy/common/Makefile4
-rw-r--r--arch/mips/alchemy/common/dbdma.c49
-rw-r--r--arch/mips/alchemy/common/gpiolib.c42
-rw-r--r--arch/mips/alchemy/common/irq.c875
-rw-r--r--arch/mips/alchemy/common/platform.c31
-rw-r--r--arch/mips/alchemy/common/power.c3
-rw-r--r--arch/mips/alchemy/common/sleeper.S73
-rw-r--r--arch/mips/alchemy/common/time.c3
-rw-r--r--arch/mips/alchemy/common/vss.c84
-rw-r--r--arch/mips/alchemy/devboards/Makefile19
-rw-r--r--arch/mips/alchemy/devboards/bcsr.c11
-rw-r--r--arch/mips/alchemy/devboards/db1000.c565
-rw-r--r--arch/mips/alchemy/devboards/db1200.c (renamed from arch/mips/alchemy/devboards/db1200/platform.c)401
-rw-r--r--arch/mips/alchemy/devboards/db1200/Makefile1
-rw-r--r--arch/mips/alchemy/devboards/db1200/setup.c81
-rw-r--r--arch/mips/alchemy/devboards/db1300.c785
-rw-r--r--arch/mips/alchemy/devboards/db1550.c498
-rw-r--r--arch/mips/alchemy/devboards/db1x00/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/db1x00/board_setup.c229
-rw-r--r--arch/mips/alchemy/devboards/db1x00/platform.c316
-rw-r--r--arch/mips/alchemy/devboards/pb1000/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/pb1000/board_setup.c209
-rw-r--r--arch/mips/alchemy/devboards/pb1100.c (renamed from arch/mips/alchemy/devboards/pb1100/board_setup.c)92
-rw-r--r--arch/mips/alchemy/devboards/pb1100/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/pb1100/platform.c77
-rw-r--r--arch/mips/alchemy/devboards/pb1200/Makefile5
-rw-r--r--arch/mips/alchemy/devboards/pb1200/board_setup.c174
-rw-r--r--arch/mips/alchemy/devboards/pb1200/platform.c339
-rw-r--r--arch/mips/alchemy/devboards/pb1500.c (renamed from arch/mips/alchemy/devboards/pb1500/board_setup.c)113
-rw-r--r--arch/mips/alchemy/devboards/pb1500/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/pb1500/platform.c94
-rw-r--r--arch/mips/alchemy/devboards/pb1550.c (renamed from arch/mips/alchemy/devboards/pb1550/platform.c)112
-rw-r--r--arch/mips/alchemy/devboards/pb1550/Makefile8
-rw-r--r--arch/mips/alchemy/devboards/pb1550/board_setup.c80
-rw-r--r--arch/mips/alchemy/devboards/platform.c13
-rw-r--r--arch/mips/alchemy/devboards/prom.c11
-rw-r--r--arch/mips/alchemy/gpr/Makefile8
-rw-r--r--arch/mips/alchemy/gpr/board_setup.c75
-rw-r--r--arch/mips/alchemy/gpr/init.c63
-rw-r--r--arch/mips/alchemy/mtx-1/Makefile9
-rw-r--r--arch/mips/alchemy/mtx-1/board_setup.c94
-rw-r--r--arch/mips/alchemy/mtx-1/init.c66
-rw-r--r--arch/mips/alchemy/xxs1500/Makefile8
-rw-r--r--arch/mips/alchemy/xxs1500/board_setup.c93
-rw-r--r--arch/mips/alchemy/xxs1500/init.c63
-rw-r--r--arch/mips/alchemy/xxs1500/platform.c63
-rw-r--r--arch/mips/ar7/gpio.c2
-rw-r--r--arch/mips/ar7/platform.c39
-rw-r--r--arch/mips/ar7/prom.c4
-rw-r--r--arch/mips/ar7/setup.c2
-rw-r--r--arch/mips/ath79/Kconfig38
-rw-r--r--arch/mips/ath79/Makefile5
-rw-r--r--arch/mips/ath79/clock.c55
-rw-r--r--arch/mips/ath79/common.c5
-rw-r--r--arch/mips/ath79/dev-ar913x-wmac.c60
-rw-r--r--arch/mips/ath79/dev-common.c38
-rw-r--r--arch/mips/ath79/dev-usb.c197
-rw-r--r--arch/mips/ath79/dev-usb.h (renamed from arch/mips/ath79/dev-ar913x-wmac.h)10
-rw-r--r--arch/mips/ath79/dev-wmac.c109
-rw-r--r--arch/mips/ath79/dev-wmac.h17
-rw-r--r--arch/mips/ath79/early_printk.c76
-rw-r--r--arch/mips/ath79/gpio.c2
-rw-r--r--arch/mips/ath79/irq.c17
-rw-r--r--arch/mips/ath79/mach-ap121.c92
-rw-r--r--arch/mips/ath79/mach-ap81.c6
-rw-r--r--arch/mips/ath79/mach-pb44.c2
-rw-r--r--arch/mips/ath79/mach-ubnt-xm.c119
-rw-r--r--arch/mips/ath79/machtypes.h2
-rw-r--r--arch/mips/ath79/setup.c22
-rw-r--r--arch/mips/bcm47xx/setup.c4
-rw-r--r--arch/mips/bcm63xx/Kconfig4
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c46
-rw-r--r--arch/mips/bcm63xx/clk.c70
-rw-r--r--arch/mips/bcm63xx/cpu.c261
-rw-r--r--arch/mips/bcm63xx/dev-uart.c2
-rw-r--r--arch/mips/bcm63xx/gpio.c41
-rw-r--r--arch/mips/bcm63xx/irq.c403
-rw-r--r--arch/mips/bcm63xx/prom.c7
-rw-r--r--arch/mips/bcm63xx/setup.c32
-rw-r--r--arch/mips/boot/compressed/uart-alchemy.c5
-rw-r--r--arch/mips/cavium-octeon/Kconfig4
-rw-r--r--arch/mips/cavium-octeon/dma-octeon.c23
-rw-r--r--arch/mips/cavium-octeon/executive/Makefile7
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c (renamed from drivers/staging/octeon/cvmx-cmd-queue.c)8
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-fpa.c (renamed from drivers/staging/octeon/cvmx-fpa.c)0
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-board.c (renamed from drivers/staging/octeon/cvmx-helper-board.c)38
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c (renamed from drivers/staging/octeon/cvmx-helper-fpa.c)0
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-loop.c (renamed from drivers/staging/octeon/cvmx-helper-loop.c)6
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-npi.c (renamed from drivers/staging/octeon/cvmx-helper-npi.c)6
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c (renamed from drivers/staging/octeon/cvmx-helper-rgmii.c)17
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c (renamed from drivers/staging/octeon/cvmx-helper-sgmii.c)18
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-spi.c (renamed from drivers/staging/octeon/cvmx-helper-spi.c)20
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-util.c (renamed from drivers/staging/octeon/cvmx-helper-util.c)16
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c (renamed from drivers/staging/octeon/cvmx-helper-xaui.c)32
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper.c (renamed from drivers/staging/octeon/cvmx-helper.c)120
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c (renamed from drivers/staging/octeon/cvmx-interrupt-decodes.c)10
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c (renamed from drivers/staging/octeon/cvmx-interrupt-rsl.c)4
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-pko.c (renamed from drivers/staging/octeon/cvmx-pko.c)8
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-spi.c (renamed from drivers/staging/octeon/cvmx-spi.c)12
-rw-r--r--arch/mips/cavium-octeon/executive/octeon-model.c119
-rw-r--r--arch/mips/cavium-octeon/setup.c14
-rw-r--r--arch/mips/cavium-octeon/smp.c2
-rw-r--r--arch/mips/configs/db1000_defconfig369
-rw-r--r--arch/mips/configs/db1100_defconfig122
-rw-r--r--arch/mips/configs/db1300_defconfig391
-rw-r--r--arch/mips/configs/db1500_defconfig128
-rw-r--r--arch/mips/configs/db1550_defconfig288
-rw-r--r--arch/mips/configs/nlm_xlp_defconfig570
-rw-r--r--arch/mips/configs/nlm_xlr_defconfig16
-rw-r--r--arch/mips/configs/pb1200_defconfig170
-rw-r--r--arch/mips/dec/setup.c1
-rw-r--r--arch/mips/include/asm/Kbuild4
-rw-r--r--arch/mips/include/asm/bmips.h110
-rw-r--r--arch/mips/include/asm/bootinfo.h1
-rw-r--r--arch/mips/include/asm/branch.h5
-rw-r--r--arch/mips/include/asm/cpu.h6
-rw-r--r--arch/mips/include/asm/gio_device.h56
-rw-r--r--arch/mips/include/asm/hazards.h7
-rw-r--r--arch/mips/include/asm/hugetlb.h2
-rw-r--r--arch/mips/include/asm/kprobes.h5
-rw-r--r--arch/mips/include/asm/mach-ath79/ar71xx_regs.h81
-rw-r--r--arch/mips/include/asm/mach-ath79/ar933x_uart.h67
-rw-r--r--arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h18
-rw-r--r--arch/mips/include/asm/mach-ath79/ath79.h11
-rw-r--r--arch/mips/include/asm/mach-ath79/irq.h8
-rw-r--r--arch/mips/include/asm/mach-ath79/pci-ath724x.h21
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1000.h273
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1100_mmc.h2
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1200fb.h14
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1550nd.h16
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h31
-rw-r--r--arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h3
-rw-r--r--arch/mips/include/asm/mach-au1x00/gpio-au1300.h241
-rw-r--r--arch/mips/include/asm/mach-au1x00/gpio.h3
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h597
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h2
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h2
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h12
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h231
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/ioremap.h42
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/irq.h7
-rw-r--r--arch/mips/include/asm/mach-db1x00/bcsr.h36
-rw-r--r--arch/mips/include/asm/mach-db1x00/db1200.h11
-rw-r--r--arch/mips/include/asm/mach-db1x00/db1300.h40
-rw-r--r--arch/mips/include/asm/mach-db1x00/db1x00.h79
-rw-r--r--arch/mips/include/asm/mach-db1x00/irq.h23
-rw-r--r--arch/mips/include/asm/mach-generic/floppy.h2
-rw-r--r--arch/mips/include/asm/mach-jazz/floppy.h2
-rw-r--r--arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h23
-rw-r--r--arch/mips/include/asm/mach-pb1x00/mc146818rtc.h34
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1000.h87
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1200.h139
-rw-r--r--arch/mips/include/asm/mach-pb1x00/pb1550.h73
-rw-r--r--arch/mips/include/asm/mipsregs.h9
-rw-r--r--arch/mips/include/asm/module.h6
-rw-r--r--arch/mips/include/asm/netlogic/common.h76
-rw-r--r--arch/mips/include/asm/netlogic/haldefs.h163
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/bridge.h187
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h83
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/iomap.h153
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/pic.h411
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/sys.h129
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/uart.h191
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/xlp.h (renamed from arch/mips/netlogic/xlr/xlr_console.c)25
-rw-r--r--arch/mips/include/asm/netlogic/xlr/iomap.h22
-rw-r--r--arch/mips/include/asm/netlogic/xlr/msidef.h84
-rw-r--r--arch/mips/include/asm/netlogic/xlr/pic.h69
-rw-r--r--arch/mips/include/asm/netlogic/xlr/xlr.h13
-rw-r--r--arch/mips/include/asm/octeon/cvmx-address.h (renamed from drivers/staging/octeon/cvmx-address.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-asxx-defs.h (renamed from drivers/staging/octeon/cvmx-asxx-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-bootinfo.h82
-rw-r--r--arch/mips/include/asm/octeon/cvmx-cmd-queue.h (renamed from drivers/staging/octeon/cvmx-cmd-queue.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-config.h (renamed from drivers/staging/octeon/cvmx-config.h)1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-dbg-defs.h (renamed from drivers/staging/octeon/cvmx-dbg-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-dpi-defs.h643
-rw-r--r--arch/mips/include/asm/octeon/cvmx-fau.h (renamed from drivers/staging/octeon/cvmx-fau.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-fpa-defs.h (renamed from drivers/staging/octeon/cvmx-fpa-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-fpa.h (renamed from drivers/staging/octeon/cvmx-fpa.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-gmxx-defs.h (renamed from drivers/staging/octeon/cvmx-gmxx-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-board.h (renamed from drivers/staging/octeon/cvmx-helper-board.h)6
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-fpa.h (renamed from drivers/staging/octeon/cvmx-helper-fpa.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-loop.h (renamed from drivers/staging/octeon/cvmx-helper-loop.h)1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-npi.h (renamed from drivers/staging/octeon/cvmx-helper-npi.h)1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-rgmii.h (renamed from drivers/staging/octeon/cvmx-helper-rgmii.h)1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-sgmii.h (renamed from drivers/staging/octeon/cvmx-helper-sgmii.h)1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-spi.h (renamed from drivers/staging/octeon/cvmx-helper-spi.h)1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-util.h (renamed from drivers/staging/octeon/cvmx-helper-util.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-xaui.h (renamed from drivers/staging/octeon/cvmx-helper-xaui.h)1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper.h (renamed from drivers/staging/octeon/cvmx-helper.h)1
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ipd.h (renamed from drivers/staging/octeon/cvmx-ipd.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mdio.h (renamed from drivers/staging/octeon/cvmx-mdio.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mio-defs.h1033
-rw-r--r--arch/mips/include/asm/octeon/cvmx-npei-defs.h4
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pciercx-defs.h609
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pcsx-defs.h (renamed from drivers/staging/octeon/cvmx-pcsx-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h (renamed from drivers/staging/octeon/cvmx-pcsxx-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pemx-defs.h509
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pexp-defs.h19
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pip-defs.h (renamed from drivers/staging/octeon/cvmx-pip-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pip.h (renamed from drivers/staging/octeon/cvmx-pip.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pko-defs.h (renamed from drivers/staging/octeon/cvmx-pko-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pko.h (renamed from drivers/staging/octeon/cvmx-pko.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pow.h (renamed from drivers/staging/octeon/cvmx-pow.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-scratch.h (renamed from drivers/staging/octeon/cvmx-scratch.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-sli-defs.h2172
-rw-r--r--arch/mips/include/asm/octeon/cvmx-spi.h (renamed from drivers/staging/octeon/cvmx-spi.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-spxx-defs.h (renamed from drivers/staging/octeon/cvmx-spxx-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-sriox-defs.h1036
-rw-r--r--arch/mips/include/asm/octeon/cvmx-srxx-defs.h (renamed from drivers/staging/octeon/cvmx-srxx-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-stxx-defs.h (renamed from drivers/staging/octeon/cvmx-stxx-defs.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx-wqe.h (renamed from drivers/staging/octeon/cvmx-wqe.h)0
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h42
-rw-r--r--arch/mips/include/asm/octeon/octeon-feature.h114
-rw-r--r--arch/mips/include/asm/octeon/octeon-model.h215
-rw-r--r--arch/mips/include/asm/octeon/pci-octeon.h3
-rw-r--r--arch/mips/include/asm/page.h8
-rw-r--r--arch/mips/include/asm/pgtable-32.h18
-rw-r--r--arch/mips/include/asm/tlbmisc.h10
-rw-r--r--arch/mips/include/asm/traps.h13
-rw-r--r--arch/mips/include/asm/types.h10
-rw-r--r--arch/mips/jazz/irq.c3
-rw-r--r--arch/mips/jazz/setup.c1
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c2
-rw-r--r--arch/mips/kernel/Makefile2
-rw-r--r--arch/mips/kernel/bmips_vec.S255
-rw-r--r--arch/mips/kernel/branch.c128
-rw-r--r--arch/mips/kernel/cevt-bcm1480.c2
-rw-r--r--arch/mips/kernel/cevt-ds1287.c2
-rw-r--r--arch/mips/kernel/cevt-gt641xx.c2
-rw-r--r--arch/mips/kernel/cevt-r4k.c2
-rw-r--r--arch/mips/kernel/cevt-sb1250.c2
-rw-r--r--arch/mips/kernel/cevt-txx9.c2
-rw-r--r--arch/mips/kernel/cpu-probe.c28
-rw-r--r--arch/mips/kernel/i8253.c2
-rw-r--r--arch/mips/kernel/kprobes.c177
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c72
-rw-r--r--arch/mips/kernel/rtlx.c1
-rw-r--r--arch/mips/kernel/setup.c43
-rw-r--r--arch/mips/kernel/smp-bmips.c458
-rw-r--r--arch/mips/kernel/smtc.c6
-rw-r--r--arch/mips/kernel/traps.c16
-rw-r--r--arch/mips/lantiq/clk.c4
-rw-r--r--arch/mips/lantiq/irq.c13
-rw-r--r--arch/mips/lantiq/xway/dma.c6
-rw-r--r--arch/mips/lantiq/xway/ebu.c6
-rw-r--r--arch/mips/lantiq/xway/pmu.c8
-rw-r--r--arch/mips/lantiq/xway/reset.c6
-rw-r--r--arch/mips/lib/Makefile1
-rw-r--r--arch/mips/loongson/common/cs5536/cs5536_mfgpt.c2
-rw-r--r--arch/mips/math-emu/cp1emu.c2
-rw-r--r--arch/mips/mm/Makefile5
-rw-r--r--arch/mips/mm/c-octeon.c2
-rw-r--r--arch/mips/mm/c-r4k.c3
-rw-r--r--arch/mips/mm/gup.c315
-rw-r--r--arch/mips/mm/init.c9
-rw-r--r--arch/mips/mm/tlb-r3k.c1
-rw-r--r--arch/mips/mm/tlb-r4k.c68
-rw-r--r--arch/mips/mti-malta/malta-int.c4
-rw-r--r--arch/mips/netlogic/Kconfig3
-rw-r--r--arch/mips/netlogic/Makefile3
-rw-r--r--arch/mips/netlogic/Platform13
-rw-r--r--arch/mips/netlogic/common/Makefile3
-rw-r--r--arch/mips/netlogic/common/earlycons.c60
-rw-r--r--arch/mips/netlogic/common/irq.c238
-rw-r--r--arch/mips/netlogic/common/smp.c (renamed from arch/mips/netlogic/xlr/smp.c)152
-rw-r--r--arch/mips/netlogic/common/smpboot.S272
-rw-r--r--arch/mips/netlogic/common/time.c (renamed from arch/mips/netlogic/xlr/time.c)6
-rw-r--r--arch/mips/netlogic/xlp/Makefile2
-rw-r--r--arch/mips/netlogic/xlp/nlm_hal.c111
-rw-r--r--arch/mips/netlogic/xlp/platform.c108
-rw-r--r--arch/mips/netlogic/xlp/setup.c105
-rw-r--r--arch/mips/netlogic/xlp/wakeup.c102
-rw-r--r--arch/mips/netlogic/xlr/Makefile7
-rw-r--r--arch/mips/netlogic/xlr/irq.c300
-rw-r--r--arch/mips/netlogic/xlr/platform.c31
-rw-r--r--arch/mips/netlogic/xlr/setup.c31
-rw-r--r--arch/mips/netlogic/xlr/wakeup.c (renamed from arch/mips/netlogic/xlr/smpboot.S)80
-rw-r--r--arch/mips/pci/Makefile3
-rw-r--r--arch/mips/pci/msi-octeon.c2
-rw-r--r--arch/mips/pci/ops-pmcmsp.c2
-rw-r--r--arch/mips/pci/ops-tx3927.c2
-rw-r--r--arch/mips/pci/pci-alchemy.c138
-rw-r--r--arch/mips/pci/pci-ath724x.c174
-rw-r--r--arch/mips/pci/pci-bcm63xx.c4
-rw-r--r--arch/mips/pci/pci-octeon.c16
-rw-r--r--arch/mips/pci/pci-tx4927.c2
-rw-r--r--arch/mips/pci/pci-tx4938.c2
-rw-r--r--arch/mips/pci/pci-tx4939.c2
-rw-r--r--arch/mips/pci/pci-xlr.c128
-rw-r--r--arch/mips/pci/pci.c29
-rw-r--r--arch/mips/pci/pcie-octeon.c1349
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c2
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_setup.c2
-rw-r--r--arch/mips/pmc-sierra/msp71xx/msp_smp.c4
-rw-r--r--arch/mips/pnx8550/common/int.c4
-rw-r--r--arch/mips/pnx8550/common/time.c4
-rw-r--r--arch/mips/sgi-ip22/Makefile2
-rw-r--r--arch/mips/sgi-ip22/ip22-gio.c428
-rw-r--r--arch/mips/sgi-ip22/ip22-int.c10
-rw-r--r--arch/mips/sgi-ip22/ip22-mc.c10
-rw-r--r--arch/mips/sgi-ip22/ip22-setup.c21
-rw-r--r--arch/mips/sgi-ip27/ip27-irq.c6
-rw-r--r--arch/mips/sgi-ip27/ip27-timer.c2
-rw-r--r--arch/mips/sgi-ip32/ip32-irq.c2
-rw-r--r--arch/mips/sni/irq.c2
-rw-r--r--arch/mips/sni/time.c2
-rw-r--r--arch/mips/txx9/generic/pci.c2
-rw-r--r--arch/mn10300/include/asm/param.h18
-rw-r--r--arch/powerpc/kernel/idle.c12
-rw-r--r--arch/powerpc/platforms/pseries/hvCall.S3
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c14
-rw-r--r--arch/s390/include/asm/chpid.h2
-rw-r--r--arch/s390/include/asm/itcw.h2
-rw-r--r--arch/s390/include/asm/mman.h4
-rw-r--r--arch/sh/boards/mach-ap325rxa/setup.c2
-rw-r--r--arch/sh/boards/mach-ecovec24/setup.c2
-rw-r--r--arch/sh/boards/mach-kfr2r09/setup.c2
-rw-r--r--arch/sh/boards/mach-migor/setup.c4
-rw-r--r--arch/sh/boards/mach-se/7724/setup.c2
-rw-r--r--arch/sparc/include/asm/siginfo.h2
-rw-r--r--arch/tile/include/asm/signal.h4
-rw-r--r--arch/x86/kernel/apm_32.c16
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c2
-rw-r--r--arch/x86/kvm/mmu.c2
-rw-r--r--arch/x86/kvm/vmx.c18
-rw-r--r--arch/x86/kvm/x86.c4
-rw-r--r--arch/x86/mm/mmio-mod.c4
-rw-r--r--arch/x86/platform/geode/alix.c2
-rw-r--r--arch/x86/platform/iris/iris.c2
-rw-r--r--block/scsi_ioctl.c52
-rw-r--r--crypto/crypto_user.c2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/accessibility/braille/braille_console.c2
-rw-r--r--drivers/acpi/acpica/acglobal.h2
-rw-r--r--drivers/acpi/apei/ghes.c2
-rw-r--r--drivers/acpi/apei/hest.c2
-rw-r--r--drivers/acpi/dock.c2
-rw-r--r--drivers/acpi/pci_slot.c2
-rw-r--r--drivers/acpi/video.c6
-rw-r--r--drivers/ata/sata_nv.c6
-rw-r--r--drivers/ata/sata_sil24.c2
-rw-r--r--drivers/atm/he.c6
-rw-r--r--drivers/base/Kconfig2
-rw-r--r--drivers/block/cciss.c6
-rw-r--r--drivers/block/drbd/drbd_int.h4
-rw-r--r--drivers/block/drbd/drbd_main.c4
-rw-r--r--drivers/block/paride/bpck6.c5
-rw-r--r--drivers/block/paride/pcd.c2
-rw-r--r--drivers/block/paride/pd.c3
-rw-r--r--drivers/block/paride/pf.c4
-rw-r--r--drivers/block/paride/pg.c3
-rw-r--r--drivers/block/paride/pt.c4
-rw-r--r--drivers/block/ub.c3
-rw-r--r--drivers/block/virtio_blk.c4
-rw-r--r--drivers/block/xd.c2
-rw-r--r--drivers/bluetooth/btusb.c12
-rw-r--r--drivers/bluetooth/hci_bcsp.c4
-rw-r--r--drivers/bluetooth/hci_ldisc.c2
-rw-r--r--drivers/cdrom/cdrom.c15
-rw-r--r--drivers/char/agp/amd64-agp.c2
-rw-r--r--drivers/char/agp/sis-agp.c2
-rw-r--r--drivers/char/i8k.c8
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c2
-rw-r--r--drivers/char/lp.c2
-rw-r--r--drivers/char/nwflash.c2
-rw-r--r--drivers/char/pcmcia/synclink_cs.c2
-rw-r--r--drivers/char/random.c2
-rw-r--r--drivers/char/tpm/tpm_tis.c6
-rw-r--r--drivers/edac/r82600_edac.c2
-rw-r--r--drivers/firewire/sbp2.c2
-rw-r--r--drivers/gpio/Kconfig1
-rw-r--r--drivers/gpio/Makefile2
-rw-r--r--drivers/gpio/devres.c90
-rw-r--r--drivers/gpio/gpio-pl061.c200
-rw-r--r--drivers/gpio/gpio-sa1100.c6
-rw-r--r--drivers/gpio/gpio-stmpe.c25
-rw-r--r--drivers/gpio/gpio-tegra.c9
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_crt.c6
-rw-r--r--drivers/gpu/drm/gma500/cdv_intel_hdmi.c14
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_hdmi.c6
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_acpi.c79
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c1
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c3
-rw-r--r--drivers/gpu/drm/radeon/r100.c4
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c2
-rw-r--r--drivers/gpu/drm/radeon/rs600.c13
-rw-r--r--drivers/gpu/drm/ttm/ttm_page_alloc_dma.c5
-rw-r--r--drivers/hid/hid-prodikeys.c2
-rw-r--r--drivers/hwmon/abituguru.c2
-rw-r--r--drivers/hwmon/abituguru3.c4
-rw-r--r--drivers/hwmon/acpi_power_meter.c2
-rw-r--r--drivers/hwmon/adm1021.c2
-rw-r--r--drivers/hwmon/ads7828.c4
-rw-r--r--drivers/hwmon/dme1737.c4
-rw-r--r--drivers/hwmon/emc2103.c2
-rw-r--r--drivers/hwmon/it87.c4
-rw-r--r--drivers/hwmon/lm93.c4
-rw-r--r--drivers/hwmon/max1668.c2
-rw-r--r--drivers/hwmon/w83627hf.c2
-rw-r--r--drivers/hwmon/w83781d.c4
-rw-r--r--drivers/hwmon/w83791d.c4
-rw-r--r--drivers/hwmon/w83792d.c2
-rw-r--r--drivers/hwmon/w83793.c2
-rw-r--r--drivers/hwmon/w83795.c2
-rw-r--r--drivers/hwmon/w83l786ng.c2
-rw-r--r--drivers/i2c/busses/Kconfig4
-rw-r--r--drivers/i2c/busses/i2c-ali1535.c38
-rw-r--r--drivers/i2c/busses/i2c-ali1563.c2
-rw-r--r--drivers/i2c/busses/i2c-ali15x3.c2
-rw-r--r--drivers/i2c/busses/i2c-amd756.c2
-rw-r--r--drivers/i2c/busses/i2c-amd8111.c2
-rw-r--r--drivers/i2c/busses/i2c-at91.c17
-rw-r--r--drivers/i2c/busses/i2c-au1550.c13
-rw-r--r--drivers/i2c/busses/i2c-cpm.c13
-rw-r--r--drivers/i2c/busses/i2c-designware-pcidrv.c2
-rw-r--r--drivers/i2c/busses/i2c-eg20t.c2
-rw-r--r--drivers/i2c/busses/i2c-highlander.c15
-rw-r--r--drivers/i2c/busses/i2c-hydra.c2
-rw-r--r--drivers/i2c/busses/i2c-i801.c2
-rw-r--r--drivers/i2c/busses/i2c-ibm_iic.c17
-rw-r--r--drivers/i2c/busses/i2c-intel-mid.c2
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c16
-rw-r--r--drivers/i2c/busses/i2c-isch.c13
-rw-r--r--drivers/i2c/busses/i2c-ixp2000.c13
-rw-r--r--drivers/i2c/busses/i2c-mpc.c13
-rw-r--r--drivers/i2c/busses/i2c-mv64xxx.c15
-rw-r--r--drivers/i2c/busses/i2c-nforce2.c4
-rw-r--r--drivers/i2c/busses/i2c-ocores.c17
-rw-r--r--drivers/i2c/busses/i2c-octeon.c16
-rw-r--r--drivers/i2c/busses/i2c-pasemi.c2
-rw-r--r--drivers/i2c/busses/i2c-pca-platform.c14
-rw-r--r--drivers/i2c/busses/i2c-piix4.c2
-rw-r--r--drivers/i2c/busses/i2c-pmcmsp.c17
-rw-r--r--drivers/i2c/busses/i2c-powermac.c19
-rw-r--r--drivers/i2c/busses/i2c-pxa-pci.c2
-rw-r--r--drivers/i2c/busses/i2c-sh7760.c13
-rw-r--r--drivers/i2c/busses/i2c-simtec.c18
-rw-r--r--drivers/i2c/busses/i2c-sis5595.c6
-rw-r--r--drivers/i2c/busses/i2c-sis630.c12
-rw-r--r--drivers/i2c/busses/i2c-sis96x.c2
-rw-r--r--drivers/i2c/busses/i2c-via.c2
-rw-r--r--drivers/i2c/busses/i2c-viapro.c11
-rw-r--r--drivers/i2c/busses/i2c-xiic.c18
-rw-r--r--drivers/i2c/busses/scx200_acb.c2
-rw-r--r--drivers/i2c/i2c-dev.c13
-rw-r--r--drivers/i2c/muxes/gpio-i2cmux.c13
-rw-r--r--drivers/ide/ali14xx.c2
-rw-r--r--drivers/ide/cmd640.c2
-rw-r--r--drivers/ide/dtc2278.c2
-rw-r--r--drivers/ide/gayle.c2
-rw-r--r--drivers/ide/ht6560b.c2
-rw-r--r--drivers/ide/ide-4drives.c2
-rw-r--r--drivers/ide/ide-acpi.c6
-rw-r--r--drivers/ide/ide-floppy_ioctl.c3
-rw-r--r--drivers/ide/ide-pci-generic.c2
-rw-r--r--drivers/ide/qd65xx.c2
-rw-r--r--drivers/ide/umc8672.c2
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h4
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c10
-rw-r--r--drivers/infiniband/hw/nes/nes.c2
-rw-r--r--drivers/input/joystick/xpad.c6
-rw-r--r--drivers/input/misc/ab8500-ponkey.c2
-rw-r--r--drivers/input/misc/wistron_btns.c2
-rw-r--r--drivers/input/mouse/psmouse-base.c2
-rw-r--r--drivers/input/mouse/synaptics_i2c.c6
-rw-r--r--drivers/input/serio/hp_sdc.c2
-rw-r--r--drivers/input/touchscreen/eeti_ts.c4
-rw-r--r--drivers/input/touchscreen/htcpen.c4
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c2
-rw-r--r--drivers/input/touchscreen/usbtouchscreen.c4
-rw-r--r--drivers/isdn/hardware/avm/b1dma.c2
-rw-r--r--drivers/isdn/hardware/avm/c4.c2
-rw-r--r--drivers/isdn/sc/init.c2
-rw-r--r--drivers/leds/Kconfig7
-rw-r--r--drivers/leds/Makefile1
-rw-r--r--drivers/leds/leds-clevo-mail.c2
-rw-r--r--drivers/leds/leds-max8997.c372
-rw-r--r--drivers/leds/leds-ss4200.c2
-rw-r--r--drivers/macintosh/ams/ams-core.c2
-rw-r--r--drivers/macintosh/ams/ams-input.c4
-rw-r--r--drivers/macintosh/therm_adt746x.c2
-rw-r--r--drivers/md/dm-flakey.c11
-rw-r--r--drivers/md/dm-linear.c12
-rw-r--r--drivers/md/dm-mpath.c6
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.c2
-rw-r--r--drivers/media/dvb/dvb-usb/af9005.h2
-rw-r--r--drivers/media/radio/radio-gemtek.c10
-rw-r--r--drivers/media/radio/radio-miropcm20.c2
-rw-r--r--drivers/media/rc/lirc_dev.c2
-rw-r--r--drivers/media/rc/mceusb.c4
-rw-r--r--drivers/media/rc/streamzap.c4
-rw-r--r--drivers/media/rc/winbond-cir.c4
-rw-r--r--drivers/media/video/c-qcam.c2
-rw-r--r--drivers/media/video/cs5345.c2
-rw-r--r--drivers/media/video/cs53l32a.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx25821/cx25821-alsa.c2
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c2
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c4
-rw-r--r--drivers/media/video/gspca/m5602/m5602_core.c4
-rw-r--r--drivers/media/video/gspca/m5602/m5602_mt9m111.h2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov9650.h2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_po1030.h2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.h2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k83a.h2
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c4
-rw-r--r--drivers/media/video/hdpvr/hdpvr-core.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--drivers/media/video/ivtv/ivtvfb.c2
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.c6
-rw-r--r--drivers/media/video/msp3400-driver.c6
-rw-r--r--drivers/media/video/msp3400-driver.h6
-rw-r--r--drivers/media/video/omap/omap_vout.c39
-rw-r--r--drivers/media/video/omap/omap_vout_vrfb.c2
-rw-r--r--drivers/media/video/ov7670.c2
-rw-r--r--drivers/media/video/saa7115.c2
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c4
-rw-r--r--drivers/media/video/stk-webcam.c4
-rw-r--r--drivers/media/video/tm6000/tm6000-alsa.c2
-rw-r--r--drivers/media/video/tvp514x.c2
-rw-r--r--drivers/media/video/tvp7002.c2
-rw-r--r--drivers/media/video/upd64083.c2
-rw-r--r--drivers/media/video/via-camera.c4
-rw-r--r--drivers/media/video/zoran/zoran_device.c2
-rw-r--r--drivers/media/video/zoran/zr36060.c2
-rw-r--r--drivers/memstick/host/jmb38x_ms.c2
-rw-r--r--drivers/memstick/host/r592.c2
-rw-r--r--drivers/memstick/host/tifm_ms.c2
-rw-r--r--drivers/mfd/88pm860x-i2c.c241
-rw-r--r--drivers/mfd/Kconfig35
-rw-r--r--drivers/mfd/Makefile3
-rw-r--r--drivers/mfd/aat2870-core.c25
-rw-r--r--drivers/mfd/ab5500-core.c2
-rw-r--r--drivers/mfd/ab5500-debugfs.c2
-rw-r--r--drivers/mfd/ab8500-core.c2
-rw-r--r--drivers/mfd/ab8500-debugfs.c2
-rw-r--r--drivers/mfd/ab8500-gpadc.c4
-rw-r--r--drivers/mfd/ab8500-i2c.c2
-rw-r--r--drivers/mfd/ab8500-sysctrl.c4
-rw-r--r--drivers/mfd/cs5535-mfd.c8
-rw-r--r--drivers/mfd/dm355evm_msp.c3
-rw-r--r--drivers/mfd/intel_msic.c12
-rw-r--r--drivers/mfd/janz-cmodio.c2
-rw-r--r--drivers/mfd/jz4740-adc.c14
-rw-r--r--drivers/mfd/lpc_sch.c2
-rw-r--r--drivers/mfd/max8925-i2c.c27
-rw-r--r--drivers/mfd/max8997.c3
-rw-r--r--drivers/mfd/max8998.c6
-rw-r--r--drivers/mfd/mc13xxx-core.c111
-rw-r--r--drivers/mfd/mcp-core.c44
-rw-r--r--drivers/mfd/mcp-sa11x0.c182
-rw-r--r--drivers/mfd/omap-usb-host.c18
-rw-r--r--drivers/mfd/pcf50633-adc.c12
-rw-r--r--drivers/mfd/s5m-core.c176
-rw-r--r--drivers/mfd/s5m-irq.c487
-rw-r--r--drivers/mfd/sm501.c2
-rw-r--r--drivers/mfd/stmpe-i2c.c109
-rw-r--r--drivers/mfd/stmpe-spi.c150
-rw-r--r--drivers/mfd/stmpe.c277
-rw-r--r--drivers/mfd/stmpe.h53
-rw-r--r--drivers/mfd/t7l66xb.c16
-rw-r--r--drivers/mfd/tc6387xb.c14
-rw-r--r--drivers/mfd/ti-ssp.c12
-rw-r--r--drivers/mfd/timberdale.c2
-rw-r--r--drivers/mfd/tps65910-irq.c3
-rw-r--r--drivers/mfd/tps65910.c7
-rw-r--r--drivers/mfd/tps65912-spi.c1
-rw-r--r--drivers/mfd/twl-core.c51
-rw-r--r--drivers/mfd/twl4030-audio.c12
-rw-r--r--drivers/mfd/twl4030-irq.c3
-rw-r--r--drivers/mfd/twl4030-madc.c14
-rw-r--r--drivers/mfd/twl4030-power.c42
-rw-r--r--drivers/mfd/twl6040-core.c20
-rw-r--r--drivers/mfd/ucb1x00-core.c48
-rw-r--r--drivers/mfd/ucb1x00-ts.c2
-rw-r--r--drivers/mfd/vx855.c2
-rw-r--r--drivers/mfd/wm831x-core.c4
-rw-r--r--drivers/mfd/wm831x-i2c.c3
-rw-r--r--drivers/mfd/wm831x-irq.c8
-rw-r--r--drivers/mfd/wm831x-spi.c4
-rw-r--r--drivers/mfd/wm8350-core.c2
-rw-r--r--drivers/mfd/wm8350-i2c.c4
-rw-r--r--drivers/mfd/wm8400-core.c7
-rw-r--r--drivers/misc/Kconfig8
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/ab8500-pwm.c2
-rw-r--r--drivers/misc/iwmc3200top/main.c12
-rw-r--r--drivers/misc/lis3lv02d/lis3lv02d.c2
-rw-r--r--drivers/misc/max8997-muic.c505
-rw-r--r--drivers/mmc/Makefile3
-rw-r--r--drivers/mmc/card/block.c247
-rw-r--r--drivers/mmc/card/mmc_test.c1
-rw-r--r--drivers/mmc/card/queue.c5
-rw-r--r--drivers/mmc/core/Makefile2
-rw-r--r--drivers/mmc/core/bus.c5
-rw-r--r--drivers/mmc/core/cd-gpio.c74
-rw-r--r--drivers/mmc/core/core.c101
-rw-r--r--drivers/mmc/core/core.h5
-rw-r--r--drivers/mmc/core/debugfs.c5
-rw-r--r--drivers/mmc/core/host.c53
-rw-r--r--drivers/mmc/core/mmc.c203
-rw-r--r--drivers/mmc/core/sd.c21
-rw-r--r--drivers/mmc/core/sdio.c342
-rw-r--r--drivers/mmc/core/sdio_io.c8
-rw-r--r--drivers/mmc/core/sdio_ops.c14
-rw-r--r--drivers/mmc/host/Makefile1
-rw-r--r--drivers/mmc/host/at91_mci.c8
-rw-r--r--drivers/mmc/host/au1xmmc.c45
-rw-r--r--drivers/mmc/host/bfin_sdh.c12
-rw-r--r--drivers/mmc/host/cb710-mmc.c13
-rw-r--r--drivers/mmc/host/dw_mmc.c71
-rw-r--r--drivers/mmc/host/dw_mmc.h2
-rw-r--r--drivers/mmc/host/jz4740_mmc.c12
-rw-r--r--drivers/mmc/host/mmc_spi.c1
-rw-r--r--drivers/mmc/host/mmci.c1
-rw-r--r--drivers/mmc/host/msm_sdcc.c19
-rw-r--r--drivers/mmc/host/mxcmmc.c13
-rw-r--r--drivers/mmc/host/mxs-mmc.c13
-rw-r--r--drivers/mmc/host/omap_hsmmc.c43
-rw-r--r--drivers/mmc/host/pxamci.c13
-rw-r--r--drivers/mmc/host/s3cmci.c13
-rw-r--r--drivers/mmc/host/sdhci-cns3xxx.c12
-rw-r--r--drivers/mmc/host/sdhci-dove.c12
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c12
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h2
-rw-r--r--drivers/mmc/host/sdhci-of-esdhc.c12
-rw-r--r--drivers/mmc/host/sdhci-of-hlwd.c12
-rw-r--r--drivers/mmc/host/sdhci-pci-data.c5
-rw-r--r--drivers/mmc/host/sdhci-pci.c181
-rw-r--r--drivers/mmc/host/sdhci-pxav2.c12
-rw-r--r--drivers/mmc/host/sdhci-pxav3.c12
-rw-r--r--drivers/mmc/host/sdhci-s3c.c18
-rw-r--r--drivers/mmc/host/sdhci-spear.c51
-rw-r--r--drivers/mmc/host/sdhci-tegra.c12
-rw-r--r--drivers/mmc/host/sdhci.c150
-rw-r--r--drivers/mmc/host/sdhci.h1
-rw-r--r--drivers/mmc/host/sh_mmcif.c726
-rw-r--r--drivers/mmc/host/sh_mobile_sdhi.c13
-rw-r--r--drivers/mmc/host/tifm_sd.c20
-rw-r--r--drivers/mmc/host/tmio_mmc.c14
-rw-r--r--drivers/mmc/host/tmio_mmc.h4
-rw-r--r--drivers/mmc/host/tmio_mmc_pio.c30
-rw-r--r--drivers/mmc/host/vub300.c10
-rw-r--r--drivers/mtd/nand/au1550nd.c298
-rw-r--r--drivers/mtd/nand/pxa3xx_nand.c2
-rw-r--r--drivers/mtd/nand/r852.c2
-rw-r--r--drivers/net/irda/Kconfig6
-rw-r--r--drivers/net/irda/au1000_ircc.h125
-rw-r--r--drivers/net/irda/au1k_ir.c1229
-rw-r--r--drivers/of/address.c16
-rw-r--r--drivers/of/irq.c11
-rw-r--r--drivers/parport/parport_ip32.c2
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c2
-rw-r--r--drivers/pci/hotplug/acpiphp_core.c2
-rw-r--r--drivers/pci/hotplug/acpiphp_ibm.c2
-rw-r--r--drivers/pci/hotplug/cpcihp_zt5550.c4
-rw-r--r--drivers/pci/hotplug/cpqphp_core.c4
-rw-r--r--drivers/pci/hotplug/ibmphp_core.c2
-rw-r--r--drivers/pci/hotplug/pci_hotplug_core.c2
-rw-r--r--drivers/pci/hotplug/pciehp.h6
-rw-r--r--drivers/pci/hotplug/pciehp_core.c6
-rw-r--r--drivers/pci/hotplug/pcihp_skeleton.c2
-rw-r--r--drivers/pci/hotplug/rpaphp.h2
-rw-r--r--drivers/pci/hotplug/rpaphp_core.c2
-rw-r--r--drivers/pci/hotplug/shpchp.h4
-rw-r--r--drivers/pci/hotplug/shpchp_core.c4
-rw-r--r--drivers/pci/pci-sysfs.c2
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c2
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c4
-rw-r--r--drivers/pcmcia/Kconfig8
-rw-r--r--drivers/pcmcia/Makefile4
-rw-r--r--drivers/pcmcia/au1000_generic.c545
-rw-r--r--drivers/pcmcia/au1000_generic.h135
-rw-r--r--drivers/pcmcia/au1000_pb1x00.c294
-rw-r--r--drivers/pcmcia/db1xxx_ss.c26
-rw-r--r--drivers/pcmcia/yenta_socket.c6
-rw-r--r--drivers/platform/x86/compal-laptop.c2
-rw-r--r--drivers/platform/x86/intel_oaktrail.c2
-rw-r--r--drivers/platform/x86/msi-laptop.c2
-rw-r--r--drivers/platform/x86/samsung-laptop.c4
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c16
-rw-r--r--drivers/platform/x86/wmi.c4
-rw-r--r--drivers/power/ds2760_battery.c2
-rw-r--r--drivers/regulator/ab8500.c2
-rw-r--r--drivers/rtc/rtc-ab8500.c2
-rw-r--r--drivers/rtc/rtc-max8925.c26
-rw-r--r--drivers/s390/char/raw3270.c2
-rw-r--r--drivers/s390/char/vmwatchdog.c4
-rw-r--r--drivers/s390/cio/cmf.c2
-rw-r--r--drivers/scsi/aha1542.c2
-rw-r--r--drivers/scsi/dc395x.c2
-rw-r--r--drivers/scsi/nsp32.c4
-rw-r--r--drivers/scsi/pcmcia/nsp_cs.c2
-rw-r--r--drivers/scsi/scsi_netlink.c2
-rw-r--r--drivers/scsi/sd.c13
-rw-r--r--drivers/spi/Kconfig7
-rw-r--r--drivers/staging/comedi/comedi_fops.c2
-rw-r--r--drivers/staging/comedi/comedi_fops.h3
-rw-r--r--drivers/staging/media/go7007/snd-go7007.c2
-rw-r--r--drivers/staging/media/lirc/lirc_bt829.c2
-rw-r--r--drivers/staging/media/lirc/lirc_igorplugusb.c4
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c6
-rw-r--r--drivers/staging/media/lirc/lirc_serial.c10
-rw-r--r--drivers/staging/media/lirc/lirc_sir.c2
-rw-r--r--drivers/staging/media/lirc/lirc_zilog.c4
-rw-r--r--drivers/staging/octeon/Makefile5
-rw-r--r--drivers/staging/octeon/cvmx-packet.h65
-rw-r--r--drivers/staging/octeon/cvmx-smix-defs.h178
-rw-r--r--drivers/staging/octeon/ethernet-defines.h2
-rw-r--r--drivers/staging/octeon/ethernet-mdio.c4
-rw-r--r--drivers/staging/octeon/ethernet-mem.c2
-rw-r--r--drivers/staging/octeon/ethernet-rgmii.c4
-rw-r--r--drivers/staging/octeon/ethernet-rx.c16
-rw-r--r--drivers/staging/octeon/ethernet-rx.h2
-rw-r--r--drivers/staging/octeon/ethernet-sgmii.c4
-rw-r--r--drivers/staging/octeon/ethernet-spi.c6
-rw-r--r--drivers/staging/octeon/ethernet-tx.c12
-rw-r--r--drivers/staging/octeon/ethernet-xaui.c4
-rw-r--r--drivers/staging/octeon/ethernet.c16
-rw-r--r--drivers/staging/quatech_usb2/quatech_usb2.c2
-rw-r--r--drivers/staging/serqt_usb2/serqt_usb2.c2
-rw-r--r--drivers/staging/speakup/speakup.h2
-rw-r--r--drivers/staging/speakup/synth.c2
-rw-r--r--drivers/staging/vme/bridges/vme_tsi148.c2
-rw-r--r--drivers/tty/rocket.c2
-rw-r--r--drivers/tty/serial/Kconfig23
-rw-r--r--drivers/tty/serial/Makefile1
-rw-r--r--drivers/tty/serial/ar933x_uart.c688
-rw-r--r--drivers/tty/synclink.c2
-rw-r--r--drivers/tty/synclinkmp.c2
-rw-r--r--drivers/usb/atm/speedtch.c6
-rw-r--r--drivers/usb/atm/ueagle-atm.c2
-rw-r--r--drivers/usb/core/devio.c2
-rw-r--r--drivers/usb/core/hub.c8
-rw-r--r--drivers/usb/core/usb.c2
-rw-r--r--drivers/usb/gadget/amd5536udc.c8
-rw-r--r--drivers/usb/gadget/ether.c4
-rw-r--r--drivers/usb/gadget/file_storage.c10
-rw-r--r--drivers/usb/gadget/net2272.c2
-rw-r--r--drivers/usb/gadget/net2280.c6
-rw-r--r--drivers/usb/gadget/omap_udc.c2
-rw-r--r--drivers/usb/gadget/pch_udc.c2
-rw-r--r--drivers/usb/gadget/serial.c4
-rw-r--r--drivers/usb/gadget/zero.c2
-rw-r--r--drivers/usb/host/Kconfig2
-rw-r--r--drivers/usb/host/alchemy-common.c277
-rw-r--r--drivers/usb/host/ehci-ath79.c4
-rw-r--r--drivers/usb/host/ehci-hcd.c2
-rw-r--r--drivers/usb/host/ohci-au1xxx.c13
-rw-r--r--drivers/usb/host/ohci-hcd.c4
-rw-r--r--drivers/usb/host/oxu210hp-hcd.c2
-rw-r--r--drivers/usb/host/u132-hcd.c2
-rw-r--r--drivers/usb/host/uhci-hcd.c2
-rw-r--r--drivers/usb/misc/ftdi-elan.c2
-rw-r--r--drivers/usb/misc/iowarrior.c2
-rw-r--r--drivers/usb/musb/cppi_dma.c2
-rw-r--r--drivers/usb/musb/musb_core.c2
-rw-r--r--drivers/usb/otg/ab8500-usb.c2
-rw-r--r--drivers/usb/serial/aircable.c2
-rw-r--r--drivers/usb/serial/ark3116.c2
-rw-r--r--drivers/usb/serial/belkin_sa.c2
-rw-r--r--drivers/usb/serial/ch341.c2
-rw-r--r--drivers/usb/serial/cp210x.c2
-rw-r--r--drivers/usb/serial/cyberjack.c2
-rw-r--r--drivers/usb/serial/cypress_m8.c6
-rw-r--r--drivers/usb/serial/digi_acceleport.c2
-rw-r--r--drivers/usb/serial/empeg.c2
-rw-r--r--drivers/usb/serial/ftdi_sio.c2
-rw-r--r--drivers/usb/serial/funsoft.c2
-rw-r--r--drivers/usb/serial/garmin_gps.c2
-rw-r--r--drivers/usb/serial/io_edgeport.c2
-rw-r--r--drivers/usb/serial/io_ti.c4
-rw-r--r--drivers/usb/serial/ipaq.c2
-rw-r--r--drivers/usb/serial/ipw.c2
-rw-r--r--drivers/usb/serial/ir-usb.c2
-rw-r--r--drivers/usb/serial/iuu_phoenix.c6
-rw-r--r--drivers/usb/serial/keyspan.c2
-rw-r--r--drivers/usb/serial/keyspan_pda.c2
-rw-r--r--drivers/usb/serial/kl5kusb105.c2
-rw-r--r--drivers/usb/serial/mct_u232.c2
-rw-r--r--drivers/usb/serial/mos7720.c2
-rw-r--r--drivers/usb/serial/mos7840.c2
-rw-r--r--drivers/usb/serial/navman.c2
-rw-r--r--drivers/usb/serial/omninet.c2
-rw-r--r--drivers/usb/serial/opticon.c2
-rw-r--r--drivers/usb/serial/option.c2
-rw-r--r--drivers/usb/serial/oti6858.c2
-rw-r--r--drivers/usb/serial/pl2303.c2
-rw-r--r--drivers/usb/serial/qcserial.c2
-rw-r--r--drivers/usb/serial/safe_serial.c6
-rw-r--r--drivers/usb/serial/sierra.c4
-rw-r--r--drivers/usb/serial/spcp8x5.c2
-rw-r--r--drivers/usb/serial/ssu100.c2
-rw-r--r--drivers/usb/serial/symbolserial.c2
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c2
-rw-r--r--drivers/usb/serial/usb-serial.c2
-rw-r--r--drivers/usb/serial/usb_wwan.c2
-rw-r--r--drivers/usb/serial/visor.c2
-rw-r--r--drivers/usb/serial/whiteheat.c2
-rw-r--r--drivers/video/Kconfig9
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/amifb.c3732
-rw-r--r--drivers/video/atmel_lcdfb.c37
-rw-r--r--drivers/video/aty/atyfb_base.c4
-rw-r--r--drivers/video/aty/radeon_base.c18
-rw-r--r--drivers/video/au1100fb.c12
-rw-r--r--drivers/video/au1200fb.c273
-rw-r--r--drivers/video/cirrusfb.c270
-rw-r--r--drivers/video/console/newport_con.c63
-rw-r--r--drivers/video/controlfb.c2
-rw-r--r--drivers/video/display/Kconfig24
-rw-r--r--drivers/video/display/Makefile6
-rw-r--r--drivers/video/display/display-sysfs.c219
-rw-r--r--drivers/video/fbmem.c14
-rw-r--r--drivers/video/fsl-diu-fb.c587
-rw-r--r--drivers/video/grvga.c4
-rw-r--r--drivers/video/hgafb.c2
-rw-r--r--drivers/video/i810/i810_main.c16
-rw-r--r--drivers/video/intelfb/intelfbdrv.c18
-rw-r--r--drivers/video/logo/logo.c2
-rw-r--r--drivers/video/matrox/matroxfb_base.c1
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c1
-rw-r--r--drivers/video/mbx/mbxfb.c13
-rw-r--r--drivers/video/mxsfb.c13
-rw-r--r--drivers/video/neofb.c10
-rw-r--r--drivers/video/nuc900fb.c13
-rw-r--r--drivers/video/omap/lcd_ams_delta.c15
-rw-r--r--drivers/video/omap/lcd_h3.c16
-rw-r--r--drivers/video/omap/lcd_htcherald.c16
-rw-r--r--drivers/video/omap/lcd_inn1510.c16
-rw-r--r--drivers/video/omap/lcd_inn1610.c16
-rw-r--r--drivers/video/omap/lcd_mipid.c1
-rw-r--r--drivers/video/omap/lcd_osk.c16
-rw-r--r--drivers/video/omap/lcd_palmte.c16
-rw-r--r--drivers/video/omap/lcd_palmtt.c15
-rw-r--r--drivers/video/omap/lcd_palmz71.c15
-rw-r--r--drivers/video/omap/omapfb_main.c4
-rw-r--r--drivers/video/omap2/displays/Kconfig2
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c1
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c66
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c1
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c62
-rw-r--r--drivers/video/omap2/displays/panel-taal.c38
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c1
-rw-r--r--drivers/video/omap2/dss/Makefile3
-rw-r--r--drivers/video/omap2/dss/apply.c1324
-rw-r--r--drivers/video/omap2/dss/core.c4
-rw-r--r--drivers/video/omap2/dss/dispc.c407
-rw-r--r--drivers/video/omap2/dss/dispc.h11
-rw-r--r--drivers/video/omap2/dss/dispc_coefs.c326
-rw-r--r--drivers/video/omap2/dss/dpi.c7
-rw-r--r--drivers/video/omap2/dss/dsi.c616
-rw-r--r--drivers/video/omap2/dss/dss.h76
-rw-r--r--drivers/video/omap2/dss/dss_features.c11
-rw-r--r--drivers/video/omap2/dss/dss_features.h1
-rw-r--r--drivers/video/omap2/dss/hdmi.c59
-rw-r--r--drivers/video/omap2/dss/manager.c1221
-rw-r--r--drivers/video/omap2/dss/overlay.c435
-rw-r--r--drivers/video/omap2/dss/rfbi.c1
-rw-r--r--drivers/video/omap2/dss/sdi.c8
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h10
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c37
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h3
-rw-r--r--drivers/video/omap2/dss/venc.c28
-rw-r--r--drivers/video/omap2/omapfb/omapfb-ioctl.c42
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c22
-rw-r--r--drivers/video/omap2/omapfb/omapfb-sysfs.c4
-rw-r--r--drivers/video/omap2/omapfb/omapfb.h13
-rw-r--r--drivers/video/pm2fb.c8
-rw-r--r--drivers/video/pm3fb.c4
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c13
-rw-r--r--drivers/video/pnx4008/sdum.c13
-rw-r--r--drivers/video/pxa168fb.c12
-rw-r--r--drivers/video/pxa3xx-gcu.c15
-rw-r--r--drivers/video/riva/fbdev.c6
-rw-r--r--drivers/video/s3c-fb.c202
-rw-r--r--drivers/video/s3c2410fb.c29
-rw-r--r--drivers/video/s3fb.c30
-rw-r--r--drivers/video/sbuslib.c2
-rw-r--r--drivers/video/sh7760fb.c13
-rw-r--r--drivers/video/sh_mipi_dsi.c218
-rw-r--r--drivers/video/sh_mobile_lcdcfb.c375
-rw-r--r--drivers/video/sh_mobile_meram.c13
-rw-r--r--drivers/video/sm501fb.c13
-rw-r--r--drivers/video/smscufx.c4
-rw-r--r--drivers/video/sstfb.c6
-rw-r--r--drivers/video/tdfxfb.c2
-rw-r--r--drivers/video/udlfb.c6
-rw-r--r--drivers/video/uvesafb.c6
-rw-r--r--drivers/video/vfb.c2
-rw-r--r--drivers/video/vt8500lcdfb.c13
-rw-r--r--drivers/video/w100fb.c13
-rw-r--r--drivers/video/wm8505fb.c13
-rw-r--r--drivers/video/wmt_ge_rops.c13
-rw-r--r--drivers/video/xilinxfb.c20
-rw-r--r--drivers/watchdog/f71808e_wdt.c2
-rw-r--r--drivers/watchdog/mpc8xxx_wdt.c2
-rw-r--r--drivers/xen/xen-pciback/conf_space.c2
-rw-r--r--drivers/xen/xen-pciback/xenbus.c2
-rw-r--r--fs/aio.c11
-rw-r--r--fs/gfs2/glock.c2
-rw-r--r--fs/gfs2/glock.h7
-rw-r--r--fs/gfs2/incore.h60
-rw-r--r--fs/gfs2/inode.c4
-rw-r--r--fs/gfs2/lock_dlm.c993
-rw-r--r--fs/gfs2/main.c10
-rw-r--r--fs/gfs2/ops_fstype.c31
-rw-r--r--fs/gfs2/recovery.c11
-rw-r--r--fs/gfs2/rgrp.c2
-rw-r--r--fs/gfs2/sys.c33
-rw-r--r--fs/gfs2/sys.h2
-rw-r--r--fs/lockd/mon.c2
-rw-r--r--fs/nfs/client.c2
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfsd/Kconfig10
-rw-r--r--fs/nfsd/Makefile1
-rw-r--r--fs/nfsd/export.c12
-rw-r--r--fs/nfsd/fault_inject.c91
-rw-r--r--fs/nfsd/fault_inject.h28
-rw-r--r--fs/nfsd/nfs4idmap.c11
-rw-r--r--fs/nfsd/nfs4proc.c7
-rw-r--r--fs/nfsd/nfs4recover.c22
-rw-r--r--fs/nfsd/nfs4state.c328
-rw-r--r--fs/nfsd/nfs4xdr.c3
-rw-r--r--fs/nfsd/nfsctl.c10
-rw-r--r--fs/nfsd/nfsd.h20
-rw-r--r--fs/nfsd/state.h3
-rw-r--r--fs/nfsd/vfs.c17
-rw-r--r--fs/notify/mark.c8
-rw-r--r--fs/ntfs/super.c2
-rw-r--r--fs/proc/array.c2
-rw-r--r--fs/squashfs/cache.c30
-rw-r--r--fs/squashfs/inode.c4
-rw-r--r--fs/squashfs/squashfs_fs_sb.h1
-rw-r--r--fs/squashfs/super.c2
-rw-r--r--include/acpi/acpixf.h2
-rw-r--r--include/acpi/apei.h4
-rw-r--r--include/asm-generic/gpio.h4
-rw-r--r--include/asm-generic/param.h13
-rw-r--r--include/drm/drm_crtc.h2
-rw-r--r--include/linux/acct.h3
-rw-r--r--include/linux/amba/mmci.h2
-rw-r--r--include/linux/amba/pl061.h2
-rw-r--r--include/linux/blkdev.h3
-rw-r--r--include/linux/capability.h4
-rw-r--r--include/linux/console.h2
-rw-r--r--include/linux/cred.h6
-rw-r--r--include/linux/cuda.h5
-rw-r--r--include/linux/display.h61
-rw-r--r--include/linux/elf.h18
-rw-r--r--include/linux/fb.h14
-rw-r--r--include/linux/gfs2_ondisk.h2
-rw-r--r--include/linux/i2c/twl.h2
-rw-r--r--include/linux/init.h3
-rw-r--r--include/linux/isdn_divertif.h4
-rw-r--r--include/linux/kmemleak.h8
-rw-r--r--include/linux/lockd/lockd.h2
-rw-r--r--include/linux/mfd/88pm860x.h3
-rw-r--r--include/linux/mfd/abx500/ab5500.h (renamed from include/linux/mfd/ab5500/ab5500.h)0
-rw-r--r--include/linux/mfd/abx500/ab8500-gpadc.h (renamed from include/linux/mfd/ab8500/gpadc.h)0
-rw-r--r--include/linux/mfd/abx500/ab8500-gpio.h (renamed from include/linux/mfd/ab8500/gpio.h)0
-rw-r--r--include/linux/mfd/abx500/ab8500-sysctrl.h (renamed from include/linux/mfd/ab8500/sysctrl.h)0
-rw-r--r--include/linux/mfd/abx500/ab8500.h (renamed from include/linux/mfd/ab8500.h)0
-rw-r--r--include/linux/mfd/max8925.h2
-rw-r--r--include/linux/mfd/max8997.h83
-rw-r--r--include/linux/mfd/mc13xxx.h8
-rw-r--r--include/linux/mfd/mcp.h7
-rw-r--r--include/linux/mfd/s5m87xx/s5m-core.h373
-rw-r--r--include/linux/mfd/s5m87xx/s5m-pmic.h100
-rw-r--r--include/linux/mfd/s5m87xx/s5m-rtc.h84
-rw-r--r--include/linux/mfd/stmpe.h16
-rw-r--r--include/linux/mfd/ucb1x00.h5
-rw-r--r--include/linux/mmc/card.h23
-rw-r--r--include/linux/mmc/cd-gpio.h19
-rw-r--r--include/linux/mmc/core.h2
-rw-r--r--include/linux/mmc/dw_mmc.h1
-rw-r--r--include/linux/mmc/host.h27
-rw-r--r--include/linux/mmc/mmc.h72
-rw-r--r--include/linux/mmc/sdhci-pci-data.h18
-rw-r--r--include/linux/mmc/sdhci.h3
-rw-r--r--include/linux/mmc/sdio.h29
-rw-r--r--include/linux/mod_devicetable.h11
-rw-r--r--include/linux/module.h21
-rw-r--r--include/linux/moduleparam.h17
-rw-r--r--include/linux/mroute6.h4
-rw-r--r--include/linux/patchkey.h4
-rw-r--r--include/linux/pmu.h4
-rw-r--r--include/linux/ptrace.h5
-rw-r--r--include/linux/security.h60
-rw-r--r--include/linux/serial_core.h4
-rw-r--r--include/linux/sound.h4
-rw-r--r--include/linux/soundcard.h4
-rw-r--r--include/linux/sunrpc/svc_xprt.h3
-rw-r--r--include/linux/sunrpc/svcsock.h2
-rw-r--r--include/linux/videodev2.h2
-rw-r--r--include/linux/zorro_ids.h4
-rw-r--r--include/video/edid.h6
-rw-r--r--include/video/omapdss.h58
-rw-r--r--include/video/sh_mipi_dsi.h21
-rw-r--r--include/video/sh_mobile_lcdc.h4
-rw-r--r--init/main.c2
-rw-r--r--kernel/async.c2
-rw-r--r--kernel/audit.c4
-rw-r--r--kernel/capability.c80
-rw-r--r--kernel/debug/kdb/kdb_main.c2
-rw-r--r--kernel/irq/internals.h2
-rw-r--r--kernel/irq/spurious.c2
-rw-r--r--kernel/module.c205
-rw-r--r--kernel/params.c38
-rw-r--r--kernel/printk.c10
-rw-r--r--kernel/ptrace.c14
-rw-r--r--kernel/sched/core.c2
-rw-r--r--lib/Kconfig.debug2
-rw-r--r--mm/kmemleak.c158
-rw-r--r--mm/percpu.c12
-rw-r--r--net/core/rtnetlink.c2
-rw-r--r--net/decnet/netfilter/dn_rtmsg.c2
-rw-r--r--net/ipv4/netfilter/ip_queue.c2
-rw-r--r--net/ipv6/netfilter/ip6_queue.c2
-rw-r--r--net/netfilter/nfnetlink.c2
-rw-r--r--net/netlink/genetlink.c2
-rw-r--r--net/sunrpc/cache.c2
-rw-r--r--net/sunrpc/svc.c25
-rw-r--r--net/sunrpc/svc_xprt.c62
-rw-r--r--net/sunrpc/svcsock.c8
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_transport.c2
-rw-r--r--net/xfrm/xfrm_user.c2
-rw-r--r--scripts/kconfig/streamline_config.pl52
-rw-r--r--scripts/mod/file2alias.c222
-rw-r--r--security/apparmor/include/apparmor.h10
-rw-r--r--security/apparmor/lsm.c20
-rw-r--r--security/capability.c1
-rw-r--r--security/commoncap.c24
-rw-r--r--security/security.c35
-rw-r--r--security/selinux/hooks.c44
-rw-r--r--sound/pci/intel8x0.c4
-rw-r--r--sound/soc/au1x/Kconfig14
-rw-r--r--sound/soc/au1x/db1200.c73
-rwxr-xr-xtools/nfsd/inject_fault.sh49
-rw-r--r--virt/kvm/iommu.c2
1103 files changed, 38661 insertions, 17087 deletions
diff --git a/CREDITS b/CREDITS
index 44fce988eaac..370b4c7da39b 100644
--- a/CREDITS
+++ b/CREDITS
@@ -514,6 +514,11 @@ S: Bessemerstraat 21
S: Amsterdam
S: The Netherlands
+N: NeilBrown
+E: neil@brown.name
+P: 4096R/566281B9 1BC6 29EB D390 D870 7B5F 497A 39EC 9EDD 5662 81B9
+D: NFSD Maintainer 2000-2007
+
N: Zach Brown
E: zab@zabbo.net
D: maestro pci sound
diff --git a/Documentation/ABI/testing/sysfs-module b/Documentation/ABI/testing/sysfs-module
index 9489ea8e294c..47064c2b1f79 100644
--- a/Documentation/ABI/testing/sysfs-module
+++ b/Documentation/ABI/testing/sysfs-module
@@ -33,3 +33,19 @@ Description: Maximum time allowed for periodic transfers per microframe (μs)
Beware, non-standard modes are usually not thoroughly tested by
hardware designers, and the hardware can malfunction when this
setting differ from default 100.
+
+What: /sys/module/*/{coresize,initsize}
+Date: Jan 2012
+KernelVersion:»·3.3
+Contact: Kay Sievers <kay.sievers@vrfy.org>
+Description: Module size in bytes.
+
+What: /sys/module/*/taint
+Date: Jan 2012
+KernelVersion:»·3.3
+Contact: Kay Sievers <kay.sievers@vrfy.org>
+Description: Module taint flags:
+ P - proprietary module
+ O - out-of-tree module
+ F - force-loaded module
+ C - staging driver module
diff --git a/Documentation/DocBook/media/v4l/pixfmt-nv24.xml b/Documentation/DocBook/media/v4l/pixfmt-nv24.xml
new file mode 100644
index 000000000000..fb255f2ca9dd
--- /dev/null
+++ b/Documentation/DocBook/media/v4l/pixfmt-nv24.xml
@@ -0,0 +1,121 @@
+ <refentry>
+ <refmeta>
+ <refentrytitle>V4L2_PIX_FMT_NV24 ('NV24'), V4L2_PIX_FMT_NV42 ('NV42')</refentrytitle>
+ &manvol;
+ </refmeta>
+ <refnamediv>
+ <refname id="V4L2-PIX-FMT-NV24"><constant>V4L2_PIX_FMT_NV24</constant></refname>
+ <refname id="V4L2-PIX-FMT-NV42"><constant>V4L2_PIX_FMT_NV42</constant></refname>
+ <refpurpose>Formats with full horizontal and vertical
+chroma resolutions, also known as YUV 4:4:4. One luminance and one
+chrominance plane with alternating chroma samples as opposed to
+<constant>V4L2_PIX_FMT_YVU420</constant></refpurpose>
+ </refnamediv>
+ <refsect1>
+ <title>Description</title>
+
+ <para>These are two-plane versions of the YUV 4:4:4 format. The three
+ components are separated into two sub-images or planes. The Y plane is
+ first, with each Y sample stored in one byte per pixel. For
+ <constant>V4L2_PIX_FMT_NV24</constant>, a combined CbCr plane
+ immediately follows the Y plane in memory. The CbCr plane has the same
+ width and height, in pixels, as the Y plane (and the image). Each line
+ contains one CbCr pair per pixel, with each Cb and Cr sample stored in
+ one byte. <constant>V4L2_PIX_FMT_NV42</constant> is the same except that
+ the Cb and Cr samples are swapped, the CrCb plane starts with a Cr
+ sample.</para>
+
+ <para>If the Y plane has pad bytes after each row, then the CbCr plane
+ has twice as many pad bytes after its rows.</para>
+
+ <example>
+ <title><constant>V4L2_PIX_FMT_NV24</constant> 4 &times; 4
+pixel image</title>
+
+ <formalpara>
+ <title>Byte Order.</title>
+ <para>Each cell is one byte.
+ <informaltable frame="none">
+ <tgroup cols="9" align="center">
+ <colspec align="left" colwidth="2*" />
+ <tbody valign="top">
+ <row>
+ <entry>start&nbsp;+&nbsp;0:</entry>
+ <entry>Y'<subscript>00</subscript></entry>
+ <entry>Y'<subscript>01</subscript></entry>
+ <entry>Y'<subscript>02</subscript></entry>
+ <entry>Y'<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;4:</entry>
+ <entry>Y'<subscript>10</subscript></entry>
+ <entry>Y'<subscript>11</subscript></entry>
+ <entry>Y'<subscript>12</subscript></entry>
+ <entry>Y'<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;8:</entry>
+ <entry>Y'<subscript>20</subscript></entry>
+ <entry>Y'<subscript>21</subscript></entry>
+ <entry>Y'<subscript>22</subscript></entry>
+ <entry>Y'<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;12:</entry>
+ <entry>Y'<subscript>30</subscript></entry>
+ <entry>Y'<subscript>31</subscript></entry>
+ <entry>Y'<subscript>32</subscript></entry>
+ <entry>Y'<subscript>33</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;16:</entry>
+ <entry>Cb<subscript>00</subscript></entry>
+ <entry>Cr<subscript>00</subscript></entry>
+ <entry>Cb<subscript>01</subscript></entry>
+ <entry>Cr<subscript>01</subscript></entry>
+ <entry>Cb<subscript>02</subscript></entry>
+ <entry>Cr<subscript>02</subscript></entry>
+ <entry>Cb<subscript>03</subscript></entry>
+ <entry>Cr<subscript>03</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;24:</entry>
+ <entry>Cb<subscript>10</subscript></entry>
+ <entry>Cr<subscript>10</subscript></entry>
+ <entry>Cb<subscript>11</subscript></entry>
+ <entry>Cr<subscript>11</subscript></entry>
+ <entry>Cb<subscript>12</subscript></entry>
+ <entry>Cr<subscript>12</subscript></entry>
+ <entry>Cb<subscript>13</subscript></entry>
+ <entry>Cr<subscript>13</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;32:</entry>
+ <entry>Cb<subscript>20</subscript></entry>
+ <entry>Cr<subscript>20</subscript></entry>
+ <entry>Cb<subscript>21</subscript></entry>
+ <entry>Cr<subscript>21</subscript></entry>
+ <entry>Cb<subscript>22</subscript></entry>
+ <entry>Cr<subscript>22</subscript></entry>
+ <entry>Cb<subscript>23</subscript></entry>
+ <entry>Cr<subscript>23</subscript></entry>
+ </row>
+ <row>
+ <entry>start&nbsp;+&nbsp;40:</entry>
+ <entry>Cb<subscript>30</subscript></entry>
+ <entry>Cr<subscript>30</subscript></entry>
+ <entry>Cb<subscript>31</subscript></entry>
+ <entry>Cr<subscript>31</subscript></entry>
+ <entry>Cb<subscript>32</subscript></entry>
+ <entry>Cr<subscript>32</subscript></entry>
+ <entry>Cb<subscript>33</subscript></entry>
+ <entry>Cr<subscript>33</subscript></entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </informaltable>
+ </para>
+ </formalpara>
+ </example>
+ </refsect1>
+ </refentry>
diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml
index 2ff6b7776d7f..aef4615fb07b 100644
--- a/Documentation/DocBook/media/v4l/pixfmt.xml
+++ b/Documentation/DocBook/media/v4l/pixfmt.xml
@@ -714,6 +714,7 @@ information.</para>
&sub-nv12m;
&sub-nv12mt;
&sub-nv16;
+ &sub-nv24;
&sub-m420;
</section>
diff --git a/Documentation/devicetree/bindings/mfd/mc13xxx.txt b/Documentation/devicetree/bindings/mfd/mc13xxx.txt
new file mode 100644
index 000000000000..19f6af47a792
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/mc13xxx.txt
@@ -0,0 +1,78 @@
+* Freescale MC13783/MC13892 Power Management Integrated Circuit (PMIC)
+
+Required properties:
+- compatible : Should be "fsl,mc13783" or "fsl,mc13892"
+
+Optional properties:
+- fsl,mc13xxx-uses-adc : Indicate the ADC is being used
+- fsl,mc13xxx-uses-codec : Indicate the Audio Codec is being used
+- fsl,mc13xxx-uses-rtc : Indicate the RTC is being used
+- fsl,mc13xxx-uses-touch : Indicate the touchscreen controller is being used
+
+Sub-nodes:
+- regulators : Contain the regulator nodes. The MC13892 regulators are
+ bound using their names as listed below with their registers and bits
+ for enabling.
+
+ vcoincell : regulator VCOINCELL (register 13, bit 23)
+ sw1 : regulator SW1 (register 24, bit 0)
+ sw2 : regulator SW2 (register 25, bit 0)
+ sw3 : regulator SW3 (register 26, bit 0)
+ sw4 : regulator SW4 (register 27, bit 0)
+ swbst : regulator SWBST (register 29, bit 20)
+ vgen1 : regulator VGEN1 (register 32, bit 0)
+ viohi : regulator VIOHI (register 32, bit 3)
+ vdig : regulator VDIG (register 32, bit 9)
+ vgen2 : regulator VGEN2 (register 32, bit 12)
+ vpll : regulator VPLL (register 32, bit 15)
+ vusb2 : regulator VUSB2 (register 32, bit 18)
+ vgen3 : regulator VGEN3 (register 33, bit 0)
+ vcam : regulator VCAM (register 33, bit 6)
+ vvideo : regulator VVIDEO (register 33, bit 12)
+ vaudio : regulator VAUDIO (register 33, bit 15)
+ vsd : regulator VSD (register 33, bit 18)
+ gpo1 : regulator GPO1 (register 34, bit 6)
+ gpo2 : regulator GPO2 (register 34, bit 8)
+ gpo3 : regulator GPO3 (register 34, bit 10)
+ gpo4 : regulator GPO4 (register 34, bit 12)
+ pwgt1spi : regulator PWGT1SPI (register 34, bit 15)
+ pwgt2spi : regulator PWGT2SPI (register 34, bit 16)
+ vusb : regulator VUSB (register 50, bit 3)
+
+ The bindings details of individual regulator device can be found in:
+ Documentation/devicetree/bindings/regulator/regulator.txt
+
+Examples:
+
+ecspi@70010000 { /* ECSPI1 */
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio3 24 0>, /* GPIO4_24 */
+ <&gpio3 25 0>; /* GPIO4_25 */
+ status = "okay";
+
+ pmic: mc13892@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mc13892";
+ spi-max-frequency = <6000000>;
+ reg = <0>;
+ interrupt-parent = <&gpio0>;
+ interrupts = <8>;
+
+ regulators {
+ sw1_reg: mc13892__sw1 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw2_reg: mc13892__sw2 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+ };
+ };
+};
diff --git a/Documentation/devicetree/bindings/mfd/twl-familly.txt b/Documentation/devicetree/bindings/mfd/twl-familly.txt
new file mode 100644
index 000000000000..a66fcf946759
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/twl-familly.txt
@@ -0,0 +1,47 @@
+Texas Instruments TWL family
+
+The TWLs are Integrated Power Management Chips.
+Some version might contain much more analog function like
+USB transceiver or Audio amplifier.
+These chips are connected to an i2c bus.
+
+
+Required properties:
+- compatible : Must be "ti,twl4030";
+ For Integrated power-management/audio CODEC device used in OMAP3
+ based boards
+- compatible : Must be "ti,twl6030";
+ For Integrated power-management used in OMAP4 based boards
+- interrupts : This i2c device has an IRQ line connected to the main SoC
+- interrupt-controller : Since the twl support several interrupts internally,
+ it is considered as an interrupt controller cascaded to the SoC one.
+- #interrupt-cells = <1>;
+- interrupt-parent : The parent interrupt controller.
+
+Optional node:
+- Child nodes contain in the twl. The twl family is made of several variants
+ that support a different number of features.
+ The children nodes will thus depend of the capability of the variant.
+
+
+Example:
+/*
+ * Integrated Power Management Chip
+ * http://www.ti.com/lit/ds/symlink/twl6030.pdf
+ */
+twl@48 {
+ compatible = "ti,twl6030";
+ reg = <0x48>;
+ interrupts = <39>; /* IRQ_SYS_1N cascaded to gic */
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ interrupt-parent = <&gic>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ twl_rtc {
+ compatible = "ti,twl_rtc";
+ interrupts = <11>;
+ reg = <0>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/resource-names.txt b/Documentation/devicetree/bindings/resource-names.txt
new file mode 100644
index 000000000000..e280fef6f265
--- /dev/null
+++ b/Documentation/devicetree/bindings/resource-names.txt
@@ -0,0 +1,54 @@
+Some properties contain an ordered list of 1 or more datum which are
+normally accessed by index. However, some devices will have multiple
+values which are more naturally accessed by name. Device nodes can
+include a supplemental property for assigning names to each of the list
+items. The names property consists of a list of strings in the same
+order as the data in the resource property.
+
+The following supplemental names properties are defined.
+
+Resource Property Supplemental Names Property
+----------------- ---------------------------
+reg reg-names
+clocks clock-names
+interrupts interrupt-names
+
+Usage:
+
+The -names property must be used in conjunction with the normal resource
+property. If not it will be ignored.
+
+Examples:
+
+l4-abe {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <1>;
+ ranges = <0 0 0x48000000 0x00001000>, /* MPU path */
+ <1 0 0x49000000 0x00001000>; /* L3 path */
+ mcasp {
+ compatible = "ti,mcasp";
+ reg = <0 0x10 0x10>, <0 0x20 0x10>,
+ <1 0x10 0x10>, <1 0x20 0x10>;
+ reg-names = "mpu", "dat",
+ "dma", "dma_dat";
+ interrupts = <11>, <12>;
+ interrupt-names = "rx", "tx";
+ };
+
+ timer {
+ compatible = "ti,timer";
+ reg = <0 0x40 0x10>, <1 0x40 0x10>;
+ reg-names = "mpu", "dma";
+ };
+};
+
+
+usb {
+ compatible = "ti,usb-host";
+ reg = <0x4a064000 0x800>, <0x4a064800 0x200>,
+ <0x4a064c00 0x200>;
+ reg-names = "config", "ohci", "ehci";
+ interrupts = <14>, <15>;
+ interrupt-names = "ohci", "ehci";
+};
diff --git a/Documentation/dma-buf-sharing.txt b/Documentation/dma-buf-sharing.txt
index 510eab32f392..225f96d88f55 100644
--- a/Documentation/dma-buf-sharing.txt
+++ b/Documentation/dma-buf-sharing.txt
@@ -219,6 +219,10 @@ NOTES:
If the exporter chooses not to allow an attach() operation once a
map_dma_buf() API has been called, it simply returns an error.
+Miscellaneous notes:
+- Any exporters or users of the dma-buf buffer sharing framework must have
+ a 'select DMA_SHARED_BUFFER' in their respective Kconfigs.
+
References:
[1] struct dma_buf_ops in include/linux/dma-buf.h
[2] All interfaces mentioned above defined in include/linux/dma-buf.h
diff --git a/Documentation/fb/api.txt b/Documentation/fb/api.txt
new file mode 100644
index 000000000000..d4ff7de85700
--- /dev/null
+++ b/Documentation/fb/api.txt
@@ -0,0 +1,306 @@
+ The Frame Buffer Device API
+ ---------------------------
+
+Last revised: June 21, 2011
+
+
+0. Introduction
+---------------
+
+This document describes the frame buffer API used by applications to interact
+with frame buffer devices. In-kernel APIs between device drivers and the frame
+buffer core are not described.
+
+Due to a lack of documentation in the original frame buffer API, drivers
+behaviours differ in subtle (and not so subtle) ways. This document describes
+the recommended API implementation, but applications should be prepared to
+deal with different behaviours.
+
+
+1. Capabilities
+---------------
+
+Device and driver capabilities are reported in the fixed screen information
+capabilities field.
+
+struct fb_fix_screeninfo {
+ ...
+ __u16 capabilities; /* see FB_CAP_* */
+ ...
+};
+
+Application should use those capabilities to find out what features they can
+expect from the device and driver.
+
+- FB_CAP_FOURCC
+
+The driver supports the four character code (FOURCC) based format setting API.
+When supported, formats are configured using a FOURCC instead of manually
+specifying color components layout.
+
+
+2. Types and visuals
+--------------------
+
+Pixels are stored in memory in hardware-dependent formats. Applications need
+to be aware of the pixel storage format in order to write image data to the
+frame buffer memory in the format expected by the hardware.
+
+Formats are described by frame buffer types and visuals. Some visuals require
+additional information, which are stored in the variable screen information
+bits_per_pixel, grayscale, red, green, blue and transp fields.
+
+Visuals describe how color information is encoded and assembled to create
+macropixels. Types describe how macropixels are stored in memory. The following
+types and visuals are supported.
+
+- FB_TYPE_PACKED_PIXELS
+
+Macropixels are stored contiguously in a single plane. If the number of bits
+per macropixel is not a multiple of 8, whether macropixels are padded to the
+next multiple of 8 bits or packed together into bytes depends on the visual.
+
+Padding at end of lines may be present and is then reported through the fixed
+screen information line_length field.
+
+- FB_TYPE_PLANES
+
+Macropixels are split across multiple planes. The number of planes is equal to
+the number of bits per macropixel, with plane i'th storing i'th bit from all
+macropixels.
+
+Planes are located contiguously in memory.
+
+- FB_TYPE_INTERLEAVED_PLANES
+
+Macropixels are split across multiple planes. The number of planes is equal to
+the number of bits per macropixel, with plane i'th storing i'th bit from all
+macropixels.
+
+Planes are interleaved in memory. The interleave factor, defined as the
+distance in bytes between the beginning of two consecutive interleaved blocks
+belonging to different planes, is stored in the fixed screen information
+type_aux field.
+
+- FB_TYPE_FOURCC
+
+Macropixels are stored in memory as described by the format FOURCC identifier
+stored in the variable screen information grayscale field.
+
+- FB_VISUAL_MONO01
+
+Pixels are black or white and stored on a number of bits (typically one)
+specified by the variable screen information bpp field.
+
+Black pixels are represented by all bits set to 1 and white pixels by all bits
+set to 0. When the number of bits per pixel is smaller than 8, several pixels
+are packed together in a byte.
+
+FB_VISUAL_MONO01 is currently used with FB_TYPE_PACKED_PIXELS only.
+
+- FB_VISUAL_MONO10
+
+Pixels are black or white and stored on a number of bits (typically one)
+specified by the variable screen information bpp field.
+
+Black pixels are represented by all bits set to 0 and white pixels by all bits
+set to 1. When the number of bits per pixel is smaller than 8, several pixels
+are packed together in a byte.
+
+FB_VISUAL_MONO01 is currently used with FB_TYPE_PACKED_PIXELS only.
+
+- FB_VISUAL_TRUECOLOR
+
+Pixels are broken into red, green and blue components, and each component
+indexes a read-only lookup table for the corresponding value. Lookup tables
+are device-dependent, and provide linear or non-linear ramps.
+
+Each component is stored in a macropixel according to the variable screen
+information red, green, blue and transp fields.
+
+- FB_VISUAL_PSEUDOCOLOR and FB_VISUAL_STATIC_PSEUDOCOLOR
+
+Pixel values are encoded as indices into a colormap that stores red, green and
+blue components. The colormap is read-only for FB_VISUAL_STATIC_PSEUDOCOLOR
+and read-write for FB_VISUAL_PSEUDOCOLOR.
+
+Each pixel value is stored in the number of bits reported by the variable
+screen information bits_per_pixel field.
+
+- FB_VISUAL_DIRECTCOLOR
+
+Pixels are broken into red, green and blue components, and each component
+indexes a programmable lookup table for the corresponding value.
+
+Each component is stored in a macropixel according to the variable screen
+information red, green, blue and transp fields.
+
+- FB_VISUAL_FOURCC
+
+Pixels are encoded and interpreted as described by the format FOURCC
+identifier stored in the variable screen information grayscale field.
+
+
+3. Screen information
+---------------------
+
+Screen information are queried by applications using the FBIOGET_FSCREENINFO
+and FBIOGET_VSCREENINFO ioctls. Those ioctls take a pointer to a
+fb_fix_screeninfo and fb_var_screeninfo structure respectively.
+
+struct fb_fix_screeninfo stores device independent unchangeable information
+about the frame buffer device and the current format. Those information can't
+be directly modified by applications, but can be changed by the driver when an
+application modifies the format.
+
+struct fb_fix_screeninfo {
+ char id[16]; /* identification string eg "TT Builtin" */
+ unsigned long smem_start; /* Start of frame buffer mem */
+ /* (physical address) */
+ __u32 smem_len; /* Length of frame buffer mem */
+ __u32 type; /* see FB_TYPE_* */
+ __u32 type_aux; /* Interleave for interleaved Planes */
+ __u32 visual; /* see FB_VISUAL_* */
+ __u16 xpanstep; /* zero if no hardware panning */
+ __u16 ypanstep; /* zero if no hardware panning */
+ __u16 ywrapstep; /* zero if no hardware ywrap */
+ __u32 line_length; /* length of a line in bytes */
+ unsigned long mmio_start; /* Start of Memory Mapped I/O */
+ /* (physical address) */
+ __u32 mmio_len; /* Length of Memory Mapped I/O */
+ __u32 accel; /* Indicate to driver which */
+ /* specific chip/card we have */
+ __u16 capabilities; /* see FB_CAP_* */
+ __u16 reserved[2]; /* Reserved for future compatibility */
+};
+
+struct fb_var_screeninfo stores device independent changeable information
+about a frame buffer device, its current format and video mode, as well as
+other miscellaneous parameters.
+
+struct fb_var_screeninfo {
+ __u32 xres; /* visible resolution */
+ __u32 yres;
+ __u32 xres_virtual; /* virtual resolution */
+ __u32 yres_virtual;
+ __u32 xoffset; /* offset from virtual to visible */
+ __u32 yoffset; /* resolution */
+
+ __u32 bits_per_pixel; /* guess what */
+ __u32 grayscale; /* 0 = color, 1 = grayscale, */
+ /* >1 = FOURCC */
+ struct fb_bitfield red; /* bitfield in fb mem if true color, */
+ struct fb_bitfield green; /* else only length is significant */
+ struct fb_bitfield blue;
+ struct fb_bitfield transp; /* transparency */
+
+ __u32 nonstd; /* != 0 Non standard pixel format */
+
+ __u32 activate; /* see FB_ACTIVATE_* */
+
+ __u32 height; /* height of picture in mm */
+ __u32 width; /* width of picture in mm */
+
+ __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */
+
+ /* Timing: All values in pixclocks, except pixclock (of course) */
+ __u32 pixclock; /* pixel clock in ps (pico seconds) */
+ __u32 left_margin; /* time from sync to picture */
+ __u32 right_margin; /* time from picture to sync */
+ __u32 upper_margin; /* time from sync to picture */
+ __u32 lower_margin;
+ __u32 hsync_len; /* length of horizontal sync */
+ __u32 vsync_len; /* length of vertical sync */
+ __u32 sync; /* see FB_SYNC_* */
+ __u32 vmode; /* see FB_VMODE_* */
+ __u32 rotate; /* angle we rotate counter clockwise */
+ __u32 colorspace; /* colorspace for FOURCC-based modes */
+ __u32 reserved[4]; /* Reserved for future compatibility */
+};
+
+To modify variable information, applications call the FBIOPUT_VSCREENINFO
+ioctl with a pointer to a fb_var_screeninfo structure. If the call is
+successful, the driver will update the fixed screen information accordingly.
+
+Instead of filling the complete fb_var_screeninfo structure manually,
+applications should call the FBIOGET_VSCREENINFO ioctl and modify only the
+fields they care about.
+
+
+4. Format configuration
+-----------------------
+
+Frame buffer devices offer two ways to configure the frame buffer format: the
+legacy API and the FOURCC-based API.
+
+
+The legacy API has been the only frame buffer format configuration API for a
+long time and is thus widely used by application. It is the recommended API
+for applications when using RGB and grayscale formats, as well as legacy
+non-standard formats.
+
+To select a format, applications set the fb_var_screeninfo bits_per_pixel field
+to the desired frame buffer depth. Values up to 8 will usually map to
+monochrome, grayscale or pseudocolor visuals, although this is not required.
+
+- For grayscale formats, applications set the grayscale field to one. The red,
+ blue, green and transp fields must be set to 0 by applications and ignored by
+ drivers. Drivers must fill the red, blue and green offsets to 0 and lengths
+ to the bits_per_pixel value.
+
+- For pseudocolor formats, applications set the grayscale field to zero. The
+ red, blue, green and transp fields must be set to 0 by applications and
+ ignored by drivers. Drivers must fill the red, blue and green offsets to 0
+ and lengths to the bits_per_pixel value.
+
+- For truecolor and directcolor formats, applications set the grayscale field
+ to zero, and the red, blue, green and transp fields to describe the layout of
+ color components in memory.
+
+struct fb_bitfield {
+ __u32 offset; /* beginning of bitfield */
+ __u32 length; /* length of bitfield */
+ __u32 msb_right; /* != 0 : Most significant bit is */
+ /* right */
+};
+
+ Pixel values are bits_per_pixel wide and are split in non-overlapping red,
+ green, blue and alpha (transparency) components. Location and size of each
+ component in the pixel value are described by the fb_bitfield offset and
+ length fields. Offset are computed from the right.
+
+ Pixels are always stored in an integer number of bytes. If the number of
+ bits per pixel is not a multiple of 8, pixel values are padded to the next
+ multiple of 8 bits.
+
+Upon successful format configuration, drivers update the fb_fix_screeninfo
+type, visual and line_length fields depending on the selected format.
+
+
+The FOURCC-based API replaces format descriptions by four character codes
+(FOURCC). FOURCCs are abstract identifiers that uniquely define a format
+without explicitly describing it. This is the only API that supports YUV
+formats. Drivers are also encouraged to implement the FOURCC-based API for RGB
+and grayscale formats.
+
+Drivers that support the FOURCC-based API report this capability by setting
+the FB_CAP_FOURCC bit in the fb_fix_screeninfo capabilities field.
+
+FOURCC definitions are located in the linux/videodev2.h header. However, and
+despite starting with the V4L2_PIX_FMT_prefix, they are not restricted to V4L2
+and don't require usage of the V4L2 subsystem. FOURCC documentation is
+available in Documentation/DocBook/v4l/pixfmt.xml.
+
+To select a format, applications set the grayscale field to the desired FOURCC.
+For YUV formats, they should also select the appropriate colorspace by setting
+the colorspace field to one of the colorspaces listed in linux/videodev2.h and
+documented in Documentation/DocBook/v4l/colorspaces.xml.
+
+The red, green, blue and transp fields are not used with the FOURCC-based API.
+For forward compatibility reasons applications must zero those fields, and
+drivers must ignore them. Values other than 0 may get a meaning in future
+extensions.
+
+Upon successful format configuration, drivers update the fb_fix_screeninfo
+type, visual and line_length fields depending on the selected format. The type
+and visual fields are set to FB_TYPE_FOURCC and FB_VISUAL_FOURCC respectively.
diff --git a/Documentation/filesystems/nfs/00-INDEX b/Documentation/filesystems/nfs/00-INDEX
index a57e12411d2a..1716874a651e 100644
--- a/Documentation/filesystems/nfs/00-INDEX
+++ b/Documentation/filesystems/nfs/00-INDEX
@@ -2,6 +2,8 @@
- this file (nfs-related documentation).
Exporting
- explanation of how to make filesystems exportable.
+fault_injection.txt
+ - information for using fault injection on the server
knfsd-stats.txt
- statistics which the NFS server makes available to user space.
nfs.txt
diff --git a/Documentation/filesystems/nfs/fault_injection.txt b/Documentation/filesystems/nfs/fault_injection.txt
new file mode 100644
index 000000000000..426d166089a3
--- /dev/null
+++ b/Documentation/filesystems/nfs/fault_injection.txt
@@ -0,0 +1,69 @@
+
+Fault Injection
+===============
+Fault injection is a method for forcing errors that may not normally occur, or
+may be difficult to reproduce. Forcing these errors in a controlled environment
+can help the developer find and fix bugs before their code is shipped in a
+production system. Injecting an error on the Linux NFS server will allow us to
+observe how the client reacts and if it manages to recover its state correctly.
+
+NFSD_FAULT_INJECTION must be selected when configuring the kernel to use this
+feature.
+
+
+Using Fault Injection
+=====================
+On the client, mount the fault injection server through NFS v4.0+ and do some
+work over NFS (open files, take locks, ...).
+
+On the server, mount the debugfs filesystem to <debug_dir> and ls
+<debug_dir>/nfsd. This will show a list of files that will be used for
+injecting faults on the NFS server. As root, write a number n to the file
+corresponding to the action you want the server to take. The server will then
+process the first n items it finds. So if you want to forget 5 locks, echo '5'
+to <debug_dir>/nfsd/forget_locks. A value of 0 will tell the server to forget
+all corresponding items. A log message will be created containing the number
+of items forgotten (check dmesg).
+
+Go back to work on the client and check if the client recovered from the error
+correctly.
+
+
+Available Faults
+================
+forget_clients:
+ The NFS server keeps a list of clients that have placed a mount call. If
+ this list is cleared, the server will have no knowledge of who the client
+ is, forcing the client to reauthenticate with the server.
+
+forget_openowners:
+ The NFS server keeps a list of what files are currently opened and who
+ they were opened by. Clearing this list will force the client to reopen
+ its files.
+
+forget_locks:
+ The NFS server keeps a list of what files are currently locked in the VFS.
+ Clearing this list will force the client to reclaim its locks (files are
+ unlocked through the VFS as they are cleared from this list).
+
+forget_delegations:
+ A delegation is used to assure the client that a file, or part of a file,
+ has not changed since the delegation was awarded. Clearing this list will
+ force the client to reaquire its delegation before accessing the file
+ again.
+
+recall_delegations:
+ Delegations can be recalled by the server when another client attempts to
+ access a file. This test will notify the client that its delegation has
+ been revoked, forcing the client to reaquire the delegation before using
+ the file again.
+
+
+tools/nfs/inject_faults.sh script
+=================================
+This script has been created to ease the fault injection process. This script
+will detect the mounted debugfs directory and write to the files located there
+based on the arguments passed by the user. For example, running
+`inject_faults.sh forget_locks 1` as root will instruct the server to forget
+one lock. Running `inject_faults forget_locks` will instruct the server to
+forgetall locks.
diff --git a/Documentation/filesystems/squashfs.txt b/Documentation/filesystems/squashfs.txt
index 7db3ebda5a4c..403c090aca39 100644
--- a/Documentation/filesystems/squashfs.txt
+++ b/Documentation/filesystems/squashfs.txt
@@ -93,8 +93,8 @@ byte alignment:
Compressed data blocks are written to the filesystem as files are read from
the source directory, and checked for duplicates. Once all file data has been
-written the completed inode, directory, fragment, export and uid/gid lookup
-tables are written.
+written the completed inode, directory, fragment, export, uid/gid lookup and
+xattr tables are written.
3.1 Compression options
-----------------------
@@ -151,7 +151,7 @@ in each metadata block. Directories are sorted in alphabetical order,
and at lookup the index is scanned linearly looking for the first filename
alphabetically larger than the filename being looked up. At this point the
location of the metadata block the filename is in has been found.
-The general idea of the index is ensure only one metadata block needs to be
+The general idea of the index is to ensure only one metadata block needs to be
decompressed to do a lookup irrespective of the length of the directory.
This scheme has the advantage that it doesn't require extra memory overhead
and doesn't require much extra storage on disk.
diff --git a/Documentation/kmemleak.txt b/Documentation/kmemleak.txt
index 51063e681ca4..b6e39739a36d 100644
--- a/Documentation/kmemleak.txt
+++ b/Documentation/kmemleak.txt
@@ -127,7 +127,10 @@ See the include/linux/kmemleak.h header for the functions prototype.
kmemleak_init - initialize kmemleak
kmemleak_alloc - notify of a memory block allocation
+kmemleak_alloc_percpu - notify of a percpu memory block allocation
kmemleak_free - notify of a memory block freeing
+kmemleak_free_part - notify of a partial memory block freeing
+kmemleak_free_percpu - notify of a percpu memory block freeing
kmemleak_not_leak - mark an object as not a leak
kmemleak_ignore - do not scan or report an object as leak
kmemleak_scan_area - add scan areas inside a memory block
diff --git a/Documentation/mmc/mmc-dev-attrs.txt b/Documentation/mmc/mmc-dev-attrs.txt
index 8898a95b41e5..22ae8441489f 100644
--- a/Documentation/mmc/mmc-dev-attrs.txt
+++ b/Documentation/mmc/mmc-dev-attrs.txt
@@ -64,3 +64,13 @@ Note on Erase Size and Preferred Erase Size:
size specified by the card.
"preferred_erase_size" is in bytes.
+
+SD/MMC/SDIO Clock Gating Attribute
+==================================
+
+Read and write access is provided to following attribute.
+This attribute appears only if CONFIG_MMC_CLKGATE is enabled.
+
+ clkgate_delay Tune the clock gating delay with desired value in milliseconds.
+
+echo <desired delay> > /sys/class/mmc_host/mmcX/clkgate_delay
diff --git a/Documentation/mmc/mmc-dev-parts.txt b/Documentation/mmc/mmc-dev-parts.txt
index 2db28b8e662f..f08d078d43cf 100644
--- a/Documentation/mmc/mmc-dev-parts.txt
+++ b/Documentation/mmc/mmc-dev-parts.txt
@@ -25,3 +25,16 @@ echo 0 > /sys/block/mmcblkXbootY/force_ro
To re-enable read-only access:
echo 1 > /sys/block/mmcblkXbootY/force_ro
+
+The boot partitions can also be locked read only until the next power on,
+with:
+
+echo 1 > /sys/block/mmcblkXbootY/ro_lock_until_next_power_on
+
+This is a feature of the card and not of the kernel. If the card does
+not support boot partition locking, the file will not exist. If the
+feature has been disabled on the card, the file will be read-only.
+
+The boot partitions can also be locked permanently, but this feature is
+not accessible through sysfs in order to avoid accidental or malicious
+bricking.
diff --git a/MAINTAINERS b/MAINTAINERS
index 1094edf0da17..ebbee877330f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3193,6 +3193,7 @@ F: drivers/i2c/busses/i2c-stub.c
I2C SUBSYSTEM
M: "Jean Delvare (PC drivers, core)" <khali@linux-fr.org>
M: "Ben Dooks (embedded platforms)" <ben-linux@fluff.org>
+M: "Wolfram Sang (embedded platforms)" <w.sang@pengutronix.de>
L: linux-i2c@vger.kernel.org
W: http://i2c.wiki.kernel.org/
T: quilt kernel.org/pub/linux/kernel/people/jdelvare/linux-2.6/jdelvare-i2c/
@@ -3774,7 +3775,6 @@ S: Odd Fixes
KERNEL NFSD, SUNRPC, AND LOCKD SERVERS
M: "J. Bruce Fields" <bfields@fieldses.org>
-M: Neil Brown <neilb@suse.de>
L: linux-nfs@vger.kernel.org
W: http://nfs.sourceforge.net/
S: Supported
@@ -4683,6 +4683,8 @@ Q: http://patchwork.kernel.org/project/linux-omap/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap.git
S: Maintained
F: arch/arm/*omap*/
+F: drivers/i2c/busses/i2c-omap.c
+F: include/linux/i2c-omap.h
OMAP CLOCK FRAMEWORK SUPPORT
M: Paul Walmsley <paul@pwsan.com>
@@ -5667,6 +5669,12 @@ L: alsa-devel@alsa-project.org (moderated for non-subscribers)
S: Supported
F: sound/soc/samsung
+SAMSUNG FRAMEBUFFER DRIVER
+M: Jingoo Han <jg1.han@samsung.com>
+L: linux-fbdev@vger.kernel.org
+S: Maintained
+F: drivers/video/s3c-fb.c
+
SERIAL DRIVERS
M: Alan Cox <alan@linux.intel.com>
L: linux-serial@vger.kernel.org
@@ -5956,6 +5964,7 @@ L: davinci-linux-open-source@linux.davincidsp.com (subscribers-only)
Q: http://patchwork.kernel.org/project/linux-davinci/list/
S: Supported
F: arch/arm/mach-davinci
+F: drivers/i2c/busses/i2c-davinci.c
SIS 190 ETHERNET DRIVER
M: Francois Romieu <romieu@fr.zoreil.com>
diff --git a/arch/arm/include/asm/hwcap.h b/arch/arm/include/asm/hwcap.h
index c93a22a8b924..917626128a1d 100644
--- a/arch/arm/include/asm/hwcap.h
+++ b/arch/arm/include/asm/hwcap.h
@@ -25,7 +25,8 @@
#define HWCAP_IDIVT (1 << 18)
#define HWCAP_IDIV (HWCAP_IDIVA | HWCAP_IDIVT)
-#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+#if defined(__KERNEL__)
+#if !defined(__ASSEMBLY__)
/*
* This yields a mask that user programs can use to figure out what
* instruction set this cpu supports.
@@ -33,5 +34,6 @@
#define ELF_HWCAP (elf_hwcap)
extern unsigned int elf_hwcap;
#endif
+#endif
#endif
diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h
index 32ee164a2f6b..b859d82e30ca 100644
--- a/arch/arm/include/asm/swab.h
+++ b/arch/arm/include/asm/swab.h
@@ -22,7 +22,8 @@
# define __SWAB_64_THRU_32__
#endif
-#if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6
+#if defined(__KERNEL__)
+#if __LINUX_ARM_ARCH__ >= 6
static inline __attribute_const__ __u32 __arch_swahb32(__u32 x)
{
@@ -39,8 +40,10 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
}
#define __arch_swab32 __arch_swab32
-#else
+#endif
+#endif
+#if !defined(__KERNEL__) || __LINUX_ARM_ARCH__ < 6
static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
{
__u32 t;
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 4a1123783806..512cd1473454 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -427,7 +427,8 @@
/*
* The following syscalls are obsolete and no longer available for EABI.
*/
-#if defined(__ARM_EABI__) && !defined(__KERNEL__)
+#if !defined(__KERNEL__)
+#if defined(__ARM_EABI__)
#undef __NR_time
#undef __NR_umount
#undef __NR_stime
@@ -441,6 +442,7 @@
#undef __NR_syscall
#undef __NR_ipc
#endif
+#endif
#ifdef __KERNEL__
diff --git a/arch/arm/mach-omap2/board-4430sdp.c b/arch/arm/mach-omap2/board-4430sdp.c
index 2ceb75d21eb2..39fba9df17fb 100644
--- a/arch/arm/mach-omap2/board-4430sdp.c
+++ b/arch/arm/mach-omap2/board-4430sdp.c
@@ -602,20 +602,6 @@ static void __init omap_sfh7741prox_init(void)
__func__, OMAP4_SFH7741_ENABLE_GPIO, error);
}
-static void sdp4430_hdmi_mux_init(void)
-{
- /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
- omap_mux_init_signal("hdmi_hpd",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hdmi_cec",
- OMAP_PIN_INPUT_PULLUP);
- /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
- omap_mux_init_signal("hdmi_ddc_scl",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hdmi_ddc_sda",
- OMAP_PIN_INPUT_PULLUP);
-}
-
static struct gpio sdp4430_hdmi_gpios[] = {
{ HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
@@ -833,9 +819,16 @@ static void omap_4430sdp_display_init(void)
pr_err("%s: Could not get display_sel GPIO\n", __func__);
sdp4430_lcd_init();
- sdp4430_hdmi_mux_init();
sdp4430_picodlp_init();
omap_display_init(&sdp4430_dss_data);
+ /*
+ * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and
+ * later have external pull up on the HDMI I2C lines
+ */
+ if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2)
+ omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
+ else
+ omap_hdmi_init(0);
}
#ifdef CONFIG_OMAP_MUX
diff --git a/arch/arm/mach-omap2/board-omap4panda.c b/arch/arm/mach-omap2/board-omap4panda.c
index e96a2e7ad36f..30ad40db2cf3 100644
--- a/arch/arm/mach-omap2/board-omap4panda.c
+++ b/arch/arm/mach-omap2/board-omap4panda.c
@@ -412,21 +412,6 @@ int __init omap4_panda_dvi_init(void)
return r;
}
-
-static void omap4_panda_hdmi_mux_init(void)
-{
- /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
- omap_mux_init_signal("hdmi_hpd",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hdmi_cec",
- OMAP_PIN_INPUT_PULLUP);
- /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
- omap_mux_init_signal("hdmi_ddc_scl",
- OMAP_PIN_INPUT_PULLUP);
- omap_mux_init_signal("hdmi_ddc_sda",
- OMAP_PIN_INPUT_PULLUP);
-}
-
static struct gpio panda_hdmi_gpios[] = {
{ HDMI_GPIO_HPD, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_hpd" },
{ HDMI_GPIO_LS_OE, GPIOF_OUT_INIT_HIGH, "hdmi_gpio_ls_oe" },
@@ -478,8 +463,16 @@ void omap4_panda_display_init(void)
if (r)
pr_err("error initializing panda DVI\n");
- omap4_panda_hdmi_mux_init();
omap_display_init(&omap4_panda_dss_data);
+
+ /*
+ * OMAP4460SDP/Blaze and OMAP4430 ES2.3 SDP/Blaze boards and
+ * later have external pull up on the HDMI I2C lines
+ */
+ if (cpu_is_omap446x() || omap_rev() > OMAP4430_REV_ES2_2)
+ omap_hdmi_init(OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP);
+ else
+ omap_hdmi_init(0);
}
static void __init omap4_panda_init(void)
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index bc6cf863a563..3c446d1a1781 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -30,6 +30,7 @@
#include <plat/omap-pm.h>
#include "common.h"
+#include "mux.h"
#include "control.h"
#include "display.h"
@@ -97,6 +98,36 @@ static const struct omap_dss_hwmod_data omap4_dss_hwmod_data[] __initdata = {
{ "dss_hdmi", "omapdss_hdmi", -1 },
};
+static void omap4_hdmi_mux_pads(enum omap_hdmi_flags flags)
+{
+ u32 reg;
+ u16 control_i2c_1;
+
+ /* PAD0_HDMI_HPD_PAD1_HDMI_CEC */
+ omap_mux_init_signal("hdmi_hpd",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hdmi_cec",
+ OMAP_PIN_INPUT_PULLUP);
+ /* PAD0_HDMI_DDC_SCL_PAD1_HDMI_DDC_SDA */
+ omap_mux_init_signal("hdmi_ddc_scl",
+ OMAP_PIN_INPUT_PULLUP);
+ omap_mux_init_signal("hdmi_ddc_sda",
+ OMAP_PIN_INPUT_PULLUP);
+
+ /*
+ * CONTROL_I2C_1: HDMI_DDC_SDA_PULLUPRESX (bit 28) and
+ * HDMI_DDC_SCL_PULLUPRESX (bit 24) are set to disable
+ * internal pull up resistor.
+ */
+ if (flags & OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP) {
+ control_i2c_1 = OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_1;
+ reg = omap4_ctrl_pad_readl(control_i2c_1);
+ reg |= (OMAP4_HDMI_DDC_SDA_PULLUPRESX_MASK |
+ OMAP4_HDMI_DDC_SCL_PULLUPRESX_MASK);
+ omap4_ctrl_pad_writel(reg, control_i2c_1);
+ }
+}
+
static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
{
u32 enable_mask, enable_shift;
@@ -130,6 +161,14 @@ static int omap4_dsi_mux_pads(int dsi_id, unsigned lanes)
return 0;
}
+int omap_hdmi_init(enum omap_hdmi_flags flags)
+{
+ if (cpu_is_omap44xx())
+ omap4_hdmi_mux_pads(flags);
+
+ return 0;
+}
+
static int omap_dsi_enable_pads(int dsi_id, unsigned lane_mask)
{
if (cpu_is_omap44xx())
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 0069561464f9..e62962117763 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -117,17 +117,14 @@ static void __init realview_eb_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index 8fe395568a47..e4abe94fb11a 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -113,17 +113,14 @@ static void __init realview_pb1176_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 34a26011bb89..127a3fd42ab1 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -112,17 +112,14 @@ static void __init realview_pb11mp_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index d26a6def1d65..25b2e59296f8 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -102,17 +102,14 @@ static void __init realview_pba8_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index a250fb4124bf..ac715645b860 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -124,17 +124,14 @@ static void __init realview_pbx_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 6b93e200bcac..5bc6b3837b20 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -202,6 +202,7 @@ static struct irda_platform_data assabet_irda_data = {
static struct mcp_plat_data assabet_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
+ .codec = "ucb1x00",
};
static void __init assabet_init(void)
@@ -252,6 +253,17 @@ static void __init assabet_init(void)
sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
ARRAY_SIZE(assabet_flash_resources));
sa11x0_register_irda(&assabet_irda_data);
+
+ /*
+ * Setup the PPC unit correctly.
+ */
+ PPDR &= ~PPC_RXD4;
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PSDR |= PPC_RXD4;
+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
+ ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
sa11x0_register_mcp(&assabet_mcp_data);
}
diff --git a/arch/arm/mach-sa1100/cerf.c b/arch/arm/mach-sa1100/cerf.c
index 11bb6d0b9be3..d12d0f48b1dc 100644
--- a/arch/arm/mach-sa1100/cerf.c
+++ b/arch/arm/mach-sa1100/cerf.c
@@ -124,12 +124,23 @@ static void __init cerf_map_io(void)
static struct mcp_plat_data cerf_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
+ .codec = "ucb1x00",
};
static void __init cerf_init(void)
{
platform_add_devices(cerf_devices, ARRAY_SIZE(cerf_devices));
sa11x0_register_mtd(&cerf_flash_data, &cerf_flash_resource, 1);
+
+ /*
+ * Setup the PPC unit correctly.
+ */
+ PPDR &= ~PPC_RXD4;
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PSDR |= PPC_RXD4;
+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
sa11x0_register_mcp(&cerf_mcp_data);
}
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index b9060e236def..c483912d08af 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -27,6 +27,7 @@
#include <linux/timer.h>
#include <linux/gpio.h>
#include <linux/pda_power.h>
+#include <linux/mfd/ucb1x00.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -85,10 +86,15 @@ static struct scoop_pcmcia_config collie_pcmcia_config = {
.num_devs = 1,
};
+static struct ucb1x00_plat_data collie_ucb1x00_data = {
+ .gpio_base = COLLIE_TC35143_GPIO_BASE,
+};
+
static struct mcp_plat_data collie_mcp_data = {
.mccr0 = MCCR0_ADM | MCCR0_ExtClk,
.sclk_rate = 9216000,
- .gpio_base = COLLIE_TC35143_GPIO_BASE,
+ .codec = "ucb1x00",
+ .codec_pdata = &collie_ucb1x00_data,
};
/*
@@ -351,6 +357,16 @@ static void __init collie_init(void)
sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
ARRAY_SIZE(collie_flash_resources));
+
+ /*
+ * Setup the PPC unit correctly.
+ */
+ PPDR &= ~PPC_RXD4;
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PSDR |= PPC_RXD4;
+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
sa11x0_register_mcp(&collie_mcp_data);
sharpsl_save_param();
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index 480d2ea46b00..e3a28ca2a7b7 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -217,10 +217,15 @@ static struct platform_device sa11x0uart3_device = {
static struct resource sa11x0mcp_resources[] = {
[0] = {
.start = __PREG(Ser4MCCR0),
- .end = __PREG(Ser4MCCR0) + 0xffff,
+ .end = __PREG(Ser4MCCR0) + 0x1C - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
+ .start = __PREG(Ser4MCCR1),
+ .end = __PREG(Ser4MCCR1) + 0x4 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
.start = IRQ_Ser4MCP,
.end = IRQ_Ser4MCP,
.flags = IORESOURCE_IRQ,
diff --git a/arch/arm/mach-sa1100/include/mach/gpio.h b/arch/arm/mach-sa1100/include/mach/gpio.h
index 703631887c94..a38fc4f54241 100644
--- a/arch/arm/mach-sa1100/include/mach/gpio.h
+++ b/arch/arm/mach-sa1100/include/mach/gpio.h
@@ -51,7 +51,4 @@ static inline void gpio_set_value(unsigned gpio, int value)
#define gpio_cansleep __gpio_cansleep
-#define gpio_to_irq(gpio) ((gpio < 11) ? (IRQ_GPIO0 + gpio) : \
- (IRQ_GPIO11 - 11 + gpio))
-
#endif
diff --git a/arch/arm/mach-sa1100/include/mach/mcp.h b/arch/arm/mach-sa1100/include/mach/mcp.h
index ed1a331508a7..586cec898b35 100644
--- a/arch/arm/mach-sa1100/include/mach/mcp.h
+++ b/arch/arm/mach-sa1100/include/mach/mcp.h
@@ -17,6 +17,8 @@ struct mcp_plat_data {
u32 mccr1;
unsigned int sclk_rate;
int gpio_base;
+ const char *codec;
+ void *codec_pdata;
};
#endif
diff --git a/arch/arm/mach-sa1100/lart.c b/arch/arm/mach-sa1100/lart.c
index af4e2761f3db..d117ceab6215 100644
--- a/arch/arm/mach-sa1100/lart.c
+++ b/arch/arm/mach-sa1100/lart.c
@@ -24,10 +24,20 @@
static struct mcp_plat_data lart_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
+ .codec = "ucb1x00",
};
static void __init lart_init(void)
{
+ /*
+ * Setup the PPC unit correctly.
+ */
+ PPDR &= ~PPC_RXD4;
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PSDR |= PPC_RXD4;
+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
sa11x0_register_mcp(&lart_mcp_data);
}
diff --git a/arch/arm/mach-sa1100/shannon.c b/arch/arm/mach-sa1100/shannon.c
index 318b2b766a0b..748d34435b3f 100644
--- a/arch/arm/mach-sa1100/shannon.c
+++ b/arch/arm/mach-sa1100/shannon.c
@@ -55,11 +55,22 @@ static struct resource shannon_flash_resource = {
static struct mcp_plat_data shannon_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
+ .codec = "ucb1x00",
};
static void __init shannon_init(void)
{
sa11x0_register_mtd(&shannon_flash_data, &shannon_flash_resource, 1);
+
+ /*
+ * Setup the PPC unit correctly.
+ */
+ PPDR &= ~PPC_RXD4;
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PSDR |= PPC_RXD4;
+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
sa11x0_register_mcp(&shannon_mcp_data);
}
diff --git a/arch/arm/mach-sa1100/simpad.c b/arch/arm/mach-sa1100/simpad.c
index e17c04d6e324..458ececefa58 100644
--- a/arch/arm/mach-sa1100/simpad.c
+++ b/arch/arm/mach-sa1100/simpad.c
@@ -14,6 +14,7 @@
#include <linux/mtd/partitions.h>
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/mfd/ucb1x00.h>
#include <asm/irq.h>
#include <mach/hardware.h>
@@ -187,10 +188,15 @@ static struct resource simpad_flash_resources [] = {
}
};
+static struct ucb1x00_plat_data simpad_ucb1x00_data = {
+ .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
+};
+
static struct mcp_plat_data simpad_mcp_data = {
.mccr0 = MCCR0_ADM,
.sclk_rate = 11981000,
- .gpio_base = SIMPAD_UCB1X00_GPIO_BASE,
+ .codec = "ucb1300",
+ .codec_pdata = &simpad_ucb1x00_data,
};
@@ -378,6 +384,16 @@ static int __init simpad_init(void)
sa11x0_register_mtd(&simpad_flash_data, simpad_flash_resources,
ARRAY_SIZE(simpad_flash_resources));
+
+ /*
+ * Setup the PPC unit correctly.
+ */
+ PPDR &= ~PPC_RXD4;
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PSDR |= PPC_RXD4;
+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
sa11x0_register_mcp(&simpad_mcp_data);
ret = platform_add_devices(devices, ARRAY_SIZE(devices));
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index a4e6ca04e319..eff8a96c75ee 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -271,7 +271,7 @@ static struct sh_mobile_lcdc_info lcdc0_info = {
.flags = LCDC_FLAGS_DWPOL,
.lcd_size_cfg.width = 44,
.lcd_size_cfg.height = 79,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.lcd_cfg = lcdc0_modes,
.num_cfg = ARRAY_SIZE(lcdc0_modes),
.board_cfg = {
@@ -321,12 +321,46 @@ 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;
+ int ret;
+
+ pck = clk_get(&pdev->dev, "dsip_clk");
+ if (IS_ERR(pck)) {
+ ret = PTR_ERR(pck);
+ goto sh_mipi_set_dot_clock_pck_err;
+ }
+
+ if (enable) {
+ clk_set_rate(pck, clk_round_rate(pck, 24000000));
+ __raw_writel(0x2a809010, DSI0PHYCR);
+ clk_enable(pck);
+ } else {
+ clk_disable(pck);
+ }
+
+ ret = 0;
+
+ clk_put(pck);
+
+sh_mipi_set_dot_clock_pck_err:
+ return ret;
+}
+
static struct sh_mipi_dsi_info mipidsi0_info = {
.data_format = MIPI_RGB888,
.lcd_chan = &lcdc0_info.ch[0],
+ .lane = 2,
.vsynw_offset = 20,
.clksrc = 1,
- .flags = SH_MIPI_DSI_HSABM,
+ .flags = SH_MIPI_DSI_HSABM |
+ SH_MIPI_DSI_SYNC_PULSES_MODE |
+ SH_MIPI_DSI_HSbyteCLK,
+ .set_dot_clock = sh_mipi_set_dot_clock,
};
static struct platform_device mipidsi0_device = {
@@ -472,8 +506,6 @@ static void __init ag5evm_map_io(void)
shmobile_setup_console();
}
-#define DSI0PHYCR 0xe615006c
-
static void __init ag5evm_init(void)
{
sh73a0_pinmux_init();
@@ -554,9 +586,6 @@ static void __init ag5evm_init(void)
gpio_direction_output(GPIO_PORT235, 0);
lcd_backlight_reset();
- /* MIPI-DSI clock setup */
- __raw_writel(0x2a809010, DSI0PHYCR);
-
/* enable SDHI0 on CN15 [SD I/F] */
gpio_request(GPIO_FN_SDHICD0, NULL);
gpio_request(GPIO_FN_SDHIWP0, NULL);
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index d2e7b73aa9b6..aab0a349f759 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -491,7 +491,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.meram_dev = &meram_info,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.lcd_cfg = ap4evb_lcdc_modes,
.num_cfg = ARRAY_SIZE(ap4evb_lcdc_modes),
.meram_cfg = &lcd_meram_cfg,
@@ -564,6 +564,30 @@ static struct platform_device keysc_device = {
};
/* MIPI-DSI */
+#define PHYCTRL 0x0070
+static int sh_mipi_set_dot_clock(struct platform_device *pdev,
+ void __iomem *base,
+ int enable)
+{
+ struct clk *pck = clk_get(&pdev->dev, "dsip_clk");
+ void __iomem *phy = base + PHYCTRL;
+
+ if (IS_ERR(pck))
+ return PTR_ERR(pck);
+
+ if (enable) {
+ clk_set_rate(pck, clk_round_rate(pck, 24000000));
+ iowrite32(ioread32(phy) | (0xb << 8), phy);
+ clk_enable(pck);
+ } else {
+ clk_disable(pck);
+ }
+
+ clk_put(pck);
+
+ return 0;
+}
+
static struct resource mipidsi0_resources[] = {
[0] = {
.start = 0xffc60000,
@@ -580,7 +604,11 @@ static struct resource mipidsi0_resources[] = {
static struct sh_mipi_dsi_info mipidsi0_info = {
.data_format = MIPI_RGB888,
.lcd_chan = &lcdc_info.ch[0],
+ .lane = 2,
.vsynw_offset = 17,
+ .flags = SH_MIPI_DSI_SYNC_PULSES_MODE |
+ SH_MIPI_DSI_HSbyteCLK,
+ .set_dot_clock = sh_mipi_set_dot_clock,
};
static struct platform_device mipidsi0_device = {
@@ -798,7 +826,7 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = {
.meram_dev = &meram_info,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.interface_type = RGB24,
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index cbc5934ae03f..9b42fbd10f8e 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -388,7 +388,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.clock_source = LCDC_CLK_BUS,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.lcd_cfg = mackerel_lcdc_modes,
.num_cfg = ARRAY_SIZE(mackerel_lcdc_modes),
.interface_type = RGB24,
@@ -451,7 +451,7 @@ static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
.clock_source = LCDC_CLK_EXTERNAL,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.interface_type = RGB24,
.clock_divider = 1,
.flags = LCDC_FLAGS_DWPOL,
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index e349c22a0d71..293456d8dcfd 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -612,8 +612,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("hdmi_clk", &div6_reparent_clks[DIV6_HDMI]),
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
- CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
- CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+ 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]),
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* IIC2 */
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 34944d01bf1e..afbead6a6e17 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -427,8 +427,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("sdhi2_clk", &div6_clks[DIV6_SDHI2]),
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSIT]),
- CLKDEV_ICK_ID("dsi0p_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSI0P]),
- CLKDEV_ICK_ID("dsi1p_clk", "sh-mipi-dsi.1", &div6_clks[DIV6_DSI1P]),
+ 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]),
/* MSTP32 clocks */
CLKDEV_DEV_ID("i2c-sh_mobile.2", &mstp_clks[MSTP001]), /* I2C2 */
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index 9361a5290177..5c00712907d1 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -19,11 +19,11 @@
#include <linux/amba/pl022.h>
#include <linux/amba/serial.h>
#include <linux/spi/spi.h>
-#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <linux/regulator/ab8500.h>
#include <linux/mfd/tc3589x.h>
#include <linux/mfd/tps6105x.h>
-#include <linux/mfd/ab8500/gpio.h>
+#include <linux/mfd/abx500/ab8500-gpio.h>
#include <linux/leds-lp5521.h>
#include <linux/input.h>
#include <linux/smsc911x.h>
diff --git a/arch/arm/mach-ux500/board-u5500.c b/arch/arm/mach-ux500/board-u5500.c
index fe1569b67c91..9de9e9c4dbbb 100644
--- a/arch/arm/mach-ux500/board-u5500.c
+++ b/arch/arm/mach-ux500/board-u5500.c
@@ -10,7 +10,7 @@
#include <linux/amba/bus.h>
#include <linux/irq.h>
#include <linux/i2c.h>
-#include <linux/mfd/ab5500/ab5500.h>
+#include <linux/mfd/abx500/ab5500.h>
#include <asm/hardware/gic.h>
#include <asm/mach/arch.h>
diff --git a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
index 47969909836c..d2d4131435a6 100644
--- a/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
+++ b/arch/arm/mach-ux500/include/mach/irqs-board-mop500.h
@@ -9,7 +9,7 @@
#define __MACH_IRQS_BOARD_MOP500_H
/* Number of AB8500 irqs is taken from header file */
-#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500/ab8500.h>
#define MOP500_AB8500_IRQ_BASE IRQ_BOARD_START
#define MOP500_AB8500_IRQ_END (MOP500_AB8500_IRQ_BASE \
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 656dc00d30ed..f82f888b91a9 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -63,6 +63,7 @@ enum clk_types {
struct s3c_sdhci_platdata {
unsigned int max_width;
unsigned int host_caps;
+ unsigned int pm_caps;
enum cd_types cd_type;
enum clk_types clk_type;
diff --git a/arch/arm/plat-samsung/platformdata.c b/arch/arm/plat-samsung/platformdata.c
index ceb9fa3a80c0..0f707184eae0 100644
--- a/arch/arm/plat-samsung/platformdata.c
+++ b/arch/arm/plat-samsung/platformdata.c
@@ -53,6 +53,8 @@ void s3c_sdhci_set_platdata(struct s3c_sdhci_platdata *pd,
set->cfg_gpio = pd->cfg_gpio;
if (pd->host_caps)
set->host_caps |= pd->host_caps;
+ if (pd->pm_caps)
+ set->pm_caps |= pd->pm_caps;
if (pd->clk_type)
set->clk_type = pd->clk_type;
}
diff --git a/arch/frv/include/asm/param.h b/arch/frv/include/asm/param.h
index 6859dd503ed3..a52dca9a9566 100644
--- a/arch/frv/include/asm/param.h
+++ b/arch/frv/include/asm/param.h
@@ -1,22 +1,8 @@
#ifndef _ASM_PARAM_H
#define _ASM_PARAM_H
-#ifdef __KERNEL__
-#define HZ CONFIG_HZ /* Internal kernel timer frequency */
-#define USER_HZ 100 /* .. some user interfaces are in "ticks" */
-#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
#define EXEC_PAGESIZE 16384
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
+#include <asm-generic/param.h>
#endif /* _ASM_PARAM_H */
diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c
index 22078486d35d..6192f7188654 100644
--- a/arch/ia64/hp/common/aml_nfw.c
+++ b/arch/ia64/hp/common/aml_nfw.c
@@ -31,7 +31,7 @@ MODULE_AUTHOR("Bjorn Helgaas <bjorn.helgaas@hp.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ACPI opregion handler for native firmware calls");
-static int force_register;
+static bool force_register;
module_param_named(force, force_register, bool, 0);
MODULE_PARM_DESC(force, "Install opregion handler even without HPQ5001 device");
diff --git a/arch/ia64/include/asm/intrinsics.h b/arch/ia64/include/asm/intrinsics.h
index 111ed5222892..e4076b511829 100644
--- a/arch/ia64/include/asm/intrinsics.h
+++ b/arch/ia64/include/asm/intrinsics.h
@@ -201,16 +201,21 @@ extern long ia64_cmpxchg_called_with_bad_pointer (void);
#endif
#ifndef __ASSEMBLY__
-#if defined(CONFIG_PARAVIRT) && defined(__KERNEL__)
-#ifdef ASM_SUPPORTED
-# define IA64_INTRINSIC_API(name) paravirt_ ## name
-#else
-# define IA64_INTRINSIC_API(name) pv_cpu_ops.name
-#endif
-#define IA64_INTRINSIC_MACRO(name) paravirt_ ## name
-#else
+
#define IA64_INTRINSIC_API(name) ia64_native_ ## name
#define IA64_INTRINSIC_MACRO(name) ia64_native_ ## name
+
+#if defined(__KERNEL__)
+#if defined(CONFIG_PARAVIRT)
+# undef IA64_INTRINSIC_API
+# undef IA64_INTRINSIC_MACRO
+# ifdef ASM_SUPPORTED
+# define IA64_INTRINSIC_API(name) paravirt_ ## name
+# else
+# define IA64_INTRINSIC_API(name) pv_cpu_ops.name
+# endif
+#define IA64_INTRINSIC_MACRO(name) paravirt_ ## name
+#endif
#endif
/************************************************/
diff --git a/arch/ia64/include/asm/unistd.h b/arch/ia64/include/asm/unistd.h
index 7617248f0d11..7a3bd2524944 100644
--- a/arch/ia64/include/asm/unistd.h
+++ b/arch/ia64/include/asm/unistd.h
@@ -323,11 +323,12 @@
#define __NR_sendmmsg 1331
#define __NR_process_vm_readv 1332
#define __NR_process_vm_writev 1333
+#define __NR_accept4 1334
#ifdef __KERNEL__
-#define NR_syscalls 310 /* length of syscall table */
+#define NR_syscalls 311 /* length of syscall table */
/*
* The following defines stop scripts/checksyscalls.sh from complaining about
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index 5b31d46aff67..1ccbe12a4d84 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -1779,6 +1779,7 @@ sys_call_table:
data8 sys_sendmmsg
data8 sys_process_vm_readv
data8 sys_process_vm_writev
+ data8 sys_accept4
.org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls
#endif /* __IA64_ASM_PARAVIRTUALIZED_NATIVE */
diff --git a/arch/m32r/include/asm/param.h b/arch/m32r/include/asm/param.h
index 94c770196048..fa207bdf96e7 100644
--- a/arch/m32r/include/asm/param.h
+++ b/arch/m32r/include/asm/param.h
@@ -1,23 +1,7 @@
#ifndef _ASM_M32R_PARAM_H
#define _ASM_M32R_PARAM_H
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* .. some user interfaces are in "ticks" */
-# define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
-
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
+#include <asm-generic/param.h>
#endif /* _ASM_M32R_PARAM_H */
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 29d92187ff30..c4c1312473fb 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -719,7 +719,6 @@ config CAVIUM_OCTEON_SIMULATOR
select DMA_COHERENT
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
- select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_HOTPLUG_CPU
select SYS_HAS_CPU_CAVIUM_OCTEON
select HOLES_IN_ZONE
@@ -735,7 +734,6 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
select DMA_COHERENT
select SYS_SUPPORTS_64BIT_KERNEL
select SYS_SUPPORTS_BIG_ENDIAN
- select SYS_SUPPORTS_HIGHMEM
select SYS_SUPPORTS_HOTPLUG_CPU
select SYS_HAS_EARLY_PRINTK
select SYS_HAS_CPU_CAVIUM_OCTEON
@@ -764,7 +762,6 @@ config NLM_XLR_BOARD
depends on EXPERIMENTAL
select BOOT_ELF32
select NLM_COMMON
- select NLM_XLR
select SYS_HAS_CPU_XLR
select SYS_SUPPORTS_SMP
select HW_HAS_PCI
@@ -779,6 +776,7 @@ config NLM_XLR_BOARD
select CEVT_R4K
select CSRC_R4K
select IRQ_CPU
+ select ARCH_SUPPORTS_MSI
select ZONE_DMA if 64BIT
select SYNC_R4K
select SYS_HAS_EARLY_PRINTK
@@ -786,6 +784,33 @@ config NLM_XLR_BOARD
Support for systems based on Netlogic XLR and XLS processors.
Say Y here if you have a XLR or XLS based board.
+config NLM_XLP_BOARD
+ bool "Netlogic XLP based systems"
+ depends on EXPERIMENTAL
+ select BOOT_ELF32
+ select NLM_COMMON
+ select SYS_HAS_CPU_XLP
+ select SYS_SUPPORTS_SMP
+ select HW_HAS_PCI
+ select SWAP_IO_SPACE
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select 64BIT_PHYS_ADDR
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select DMA_COHERENT
+ select NR_CPUS_DEFAULT_32
+ select CEVT_R4K
+ select CSRC_R4K
+ select IRQ_CPU
+ select ZONE_DMA if 64BIT
+ select SYNC_R4K
+ select SYS_HAS_EARLY_PRINTK
+ help
+ This board is based on Netlogic XLP Processor.
+ Say Y here if you have a XLP based board.
+
endchoice
source "arch/mips/alchemy/Kconfig"
@@ -1416,51 +1441,36 @@ config CPU_CAVIUM_OCTEON
config CPU_BMIPS3300
bool "BMIPS3300"
depends on SYS_HAS_CPU_BMIPS3300
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
- select SYS_SUPPORTS_32BIT_KERNEL
- select WEAK_ORDERING
+ select CPU_BMIPS
help
Broadcom BMIPS3300 processors.
config CPU_BMIPS4350
bool "BMIPS4350"
depends on SYS_HAS_CPU_BMIPS4350
- select CPU_SUPPORTS_32BIT_KERNEL
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
+ select CPU_BMIPS
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
- select WEAK_ORDERING
help
Broadcom BMIPS4350 ("VIPER") processors.
config CPU_BMIPS4380
bool "BMIPS4380"
depends on SYS_HAS_CPU_BMIPS4380
- select CPU_SUPPORTS_32BIT_KERNEL
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
+ select CPU_BMIPS
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
- select WEAK_ORDERING
help
Broadcom BMIPS4380 processors.
config CPU_BMIPS5000
bool "BMIPS5000"
depends on SYS_HAS_CPU_BMIPS5000
- select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_BMIPS
select CPU_SUPPORTS_HIGHMEM
- select DMA_NONCOHERENT
- select IRQ_CPU
- select SWAP_IO_SPACE
+ select MIPS_CPU_SCACHE
select SYS_SUPPORTS_SMP
select SYS_SUPPORTS_HOTPLUG_CPU
- select WEAK_ORDERING
help
Broadcom BMIPS5000 processors.
@@ -1475,6 +1485,19 @@ config CPU_XLR
select CPU_SUPPORTS_HUGEPAGES
help
Netlogic Microsystems XLR/XLS processors.
+
+config CPU_XLP
+ bool "Netlogic XLP SoC"
+ depends on SYS_HAS_CPU_XLP
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+ select CPU_HAS_LLSC
+ select WEAK_ORDERING
+ select WEAK_REORDERING_BEYOND_LLSC
+ select CPU_HAS_PREFETCH
+ help
+ Netlogic Microsystems XLP processors.
endchoice
if CPU_LOONGSON2F
@@ -1521,6 +1544,15 @@ config CPU_LOONGSON2
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
+config CPU_BMIPS
+ bool
+ select CPU_MIPS32
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SWAP_IO_SPACE
+ select WEAK_ORDERING
+
config SYS_HAS_CPU_LOONGSON2E
bool
@@ -1608,6 +1640,9 @@ config SYS_HAS_CPU_BMIPS5000
config SYS_HAS_CPU_XLR
bool
+config SYS_HAS_CPU_XLP
+ bool
+
#
# CPU may reorder R->R, R->W, W->R, W->W
# Reordering beyond LL and SC is handled in WEAK_REORDERING_BEYOND_LLSC
@@ -1995,6 +2030,9 @@ config CPU_HAS_SMARTMIPS
config CPU_HAS_WB
bool
+config XKS01
+ bool
+
#
# Vectored interrupt mode is an R2 feature
#
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 0be318609fc6..4fedf5a51d96 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -157,6 +157,7 @@ ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
endif
cflags-$(CONFIG_CAVIUM_CN63XXP1) += -Wa,-mfix-cn63xxp1
+cflags-$(CONFIG_CPU_BMIPS) += -march=mips32 -Wa,-mips32 -Wa,--trap
cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
index 2a68be6a1b97..0faaab24376e 100644
--- a/arch/mips/alchemy/Kconfig
+++ b/arch/mips/alchemy/Kconfig
@@ -2,6 +2,10 @@
config ALCHEMY_GPIOINT_AU1000
bool
+# au1300-style GPIO/INT controller
+config ALCHEMY_GPIOINT_AU1300
+ bool
+
# select this in your board config if you don't want to use the gpio
# namespace as documented in the manuals. In this case however you need
# to create the necessary gpio_* functions in your board code/headers!
@@ -22,43 +26,29 @@ config MIPS_MTX1
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
-config MIPS_BOSPORUS
- bool "Alchemy Bosporus board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_NONCOHERENT
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
config MIPS_DB1000
- bool "Alchemy DB1000 board"
+ bool "Alchemy DB1000/DB1500/DB1100 boards"
select ALCHEMY_GPIOINT_AU1000
select DMA_NONCOHERENT
select HW_HAS_PCI
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
-config MIPS_DB1100
- bool "Alchemy DB1100 board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_NONCOHERENT
+ select MIPS_DISABLE_OBSOLETE_IDE
+ select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
config MIPS_DB1200
- bool "Alchemy DB1200 board"
+ bool "Alchemy DB1200/PB1200 board"
select ALCHEMY_GPIOINT_AU1000
select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
-config MIPS_DB1500
- bool "Alchemy DB1500 board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
+config MIPS_DB1300
+ bool "NetLogic DB1300 board"
+ select ALCHEMY_GPIOINT_AU1300
+ select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE
- select SYS_SUPPORTS_BIG_ENDIAN
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
@@ -66,27 +56,11 @@ config MIPS_DB1550
bool "Alchemy DB1550 board"
select ALCHEMY_GPIOINT_AU1000
select HW_HAS_PCI
- select DMA_NONCOHERENT
+ select DMA_COHERENT
select MIPS_DISABLE_OBSOLETE_IDE
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
-config MIPS_MIRAGE
- bool "Alchemy Mirage board"
- select DMA_NONCOHERENT
- select ALCHEMY_GPIOINT_AU1000
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
-config MIPS_PB1000
- bool "Alchemy PB1000 board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_NONCOHERENT
- select HW_HAS_PCI
- select SWAP_IO_SPACE
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
config MIPS_PB1100
bool "Alchemy PB1100 board"
select ALCHEMY_GPIOINT_AU1000
@@ -96,14 +70,6 @@ config MIPS_PB1100
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_HAS_EARLY_PRINTK
-config MIPS_PB1200
- bool "Alchemy PB1200 board"
- select ALCHEMY_GPIOINT_AU1000
- select DMA_NONCOHERENT
- select MIPS_DISABLE_OBSOLETE_IDE
- select SYS_SUPPORTS_LITTLE_ENDIAN
- select SYS_HAS_EARLY_PRINTK
-
config MIPS_PB1500
bool "Alchemy PB1500 board"
select ALCHEMY_GPIOINT_AU1000
diff --git a/arch/mips/alchemy/Makefile b/arch/mips/alchemy/Makefile
new file mode 100644
index 000000000000..aac3b179bbc0
--- /dev/null
+++ b/arch/mips/alchemy/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_MIPS_GPR) += board-gpr.o
+obj-$(CONFIG_MIPS_MTX1) += board-mtx1.o
+obj-$(CONFIG_MIPS_XXS1500) += board-xxs1500.o
diff --git a/arch/mips/alchemy/Platform b/arch/mips/alchemy/Platform
index 96e9e41f1b2a..7956274de15f 100644
--- a/arch/mips/alchemy/Platform
+++ b/arch/mips/alchemy/Platform
@@ -5,62 +5,31 @@ platform-$(CONFIG_MIPS_ALCHEMY) += alchemy/common/
#
-# AMD Alchemy Pb1000 eval board
-#
-platform-$(CONFIG_MIPS_PB1000) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1000) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1000) += 0xffffffff80100000
-
-#
# AMD Alchemy Pb1100 eval board
#
platform-$(CONFIG_MIPS_PB1100) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1100) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1100) += 0xffffffff80100000
#
# AMD Alchemy Pb1500 eval board
#
platform-$(CONFIG_MIPS_PB1500) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1500) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1500) += 0xffffffff80100000
#
# AMD Alchemy Pb1550 eval board
#
platform-$(CONFIG_MIPS_PB1550) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1550) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000
#
-# AMD Alchemy Pb1200 eval board
-#
-platform-$(CONFIG_MIPS_PB1200) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_PB1200) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
-load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000
-
-#
-# AMD Alchemy Db1000 eval board
+# AMD Alchemy Db1000/Db1500/Db1100 eval boards
#
platform-$(CONFIG_MIPS_DB1000) += alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000
#
-# AMD Alchemy Db1100 eval board
-#
-platform-$(CONFIG_MIPS_DB1100) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1100) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1100) += 0xffffffff80100000
-
-#
-# AMD Alchemy Db1500 eval board
-#
-platform-$(CONFIG_MIPS_DB1500) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_DB1500) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_DB1500) += 0xffffffff80100000
-
-#
# AMD Alchemy Db1550 eval board
#
platform-$(CONFIG_MIPS_DB1550) += alchemy/devboards/
@@ -68,42 +37,35 @@ cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
#
-# AMD Alchemy Db1200 eval board
+# AMD Alchemy Db1200/Pb1200 eval boards
#
platform-$(CONFIG_MIPS_DB1200) += alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1200) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
#
-# AMD Alchemy Bosporus eval board
-#
-platform-$(CONFIG_MIPS_BOSPORUS) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_BOSPORUS) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_BOSPORUS) += 0xffffffff80100000
-
-#
-# AMD Alchemy Mirage eval board
+# NetLogic DBAu1300 development platform
#
-platform-$(CONFIG_MIPS_MIRAGE) += alchemy/devboards/
-cflags-$(CONFIG_MIPS_MIRAGE) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
-load-$(CONFIG_MIPS_MIRAGE) += 0xffffffff80100000
+platform-$(CONFIG_MIPS_DB1300) += alchemy/devboards/
+cflags-$(CONFIG_MIPS_DB1300) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
+load-$(CONFIG_MIPS_DB1300) += 0xffffffff80100000
#
-# 4G-Systems eval board
+# 4G-Systems MTX-1 "MeshCube" wireless router
#
-platform-$(CONFIG_MIPS_MTX1) += alchemy/mtx-1/
+platform-$(CONFIG_MIPS_MTX1) += alchemy/
load-$(CONFIG_MIPS_MTX1) += 0xffffffff80100000
#
# MyCable eval board
#
-platform-$(CONFIG_MIPS_XXS1500) += alchemy/xxs1500/
+platform-$(CONFIG_MIPS_XXS1500) += alchemy/
load-$(CONFIG_MIPS_XXS1500) += 0xffffffff80100000
#
# Trapeze ITS GRP board
#
-platform-$(CONFIG_MIPS_GPR) += alchemy/gpr/
+platform-$(CONFIG_MIPS_GPR) += alchemy/
load-$(CONFIG_MIPS_GPR) += 0xffffffff80100000
# boards can specify their own <gpio.h> in one of their include dirs.
diff --git a/arch/mips/alchemy/gpr/platform.c b/arch/mips/alchemy/board-gpr.c
index 982ce85db60d..ba3259086b9d 100644
--- a/arch/mips/alchemy/gpr/platform.c
+++ b/arch/mips/alchemy/board-gpr.c
@@ -1,5 +1,5 @@
/*
- * GPR board platform device registration
+ * GPR board platform device registration (Au1550)
*
* Copyright (C) 2010 Wolfgang Grandegger <wg@denx.de>
*
@@ -18,16 +18,89 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/delay.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
-
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
#include <asm/mach-au1x00/au1000.h>
+#include <prom.h>
+
+const char *get_system_type(void)
+{
+ return "GPR";
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str)
+ memsize = 0x04000000;
+ else
+ strict_strtoul(memsize_str, 0, &memsize);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
+
+static void gpr_reset(char *c)
+{
+ /* switch System-LED to orange (red# and green# on) */
+ alchemy_gpio_direction_output(4, 0);
+ alchemy_gpio_direction_output(5, 0);
+
+ /* trigger watchdog to reset board in 200ms */
+ printk(KERN_EMERG "Triggering watchdog soft reset...\n");
+ raw_local_irq_disable();
+ alchemy_gpio_direction_output(1, 0);
+ udelay(1);
+ alchemy_gpio_set_value(1, 1);
+ while (1)
+ cpu_wait();
+}
+
+static void gpr_power_off(void)
+{
+ while (1)
+ cpu_wait();
+}
+
+void __init board_setup(void)
+{
+ printk(KERN_INFO "Trapeze ITS GPR board\n");
+
+ pm_power_off = gpr_power_off;
+ _machine_halt = gpr_power_off;
+ _machine_restart = gpr_reset;
+
+ /* Enable UART1/3 */
+ alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
+ alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
+
+ /* Take away Reset of UMTS-card */
+ alchemy_gpio_direction_output(215, 1);
+}
/*
* Watchdog
@@ -152,7 +225,7 @@ static struct i2c_gpio_platform_data gpr_i2c_data = {
.scl_is_open_drain = 1,
.udelay = 2, /* ~100 kHz */
.timeout = HZ,
- };
+};
static struct platform_device gpr_i2c_device = {
.name = "i2c-gpio",
@@ -184,7 +257,7 @@ static int gpr_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
else if ((slot == 0) && (pin == 2))
return AU1550_PCI_INTB;
- return -1;
+ return 0xff;
}
static struct alchemy_pci_platdata gpr_pci_pd = {
diff --git a/arch/mips/alchemy/mtx-1/platform.c b/arch/mips/alchemy/board-mtx1.c
index cc47b6868ca3..295f1a95f745 100644
--- a/arch/mips/alchemy/mtx-1/platform.c
+++ b/arch/mips/alchemy/board-mtx1.c
@@ -1,5 +1,5 @@
/*
- * MTX-1 platform devices registration
+ * MTX-1 platform devices registration (Au1500)
*
* Copyright (C) 2007-2009, Florian Fainelli <florian@openwrt.org>
*
@@ -19,6 +19,8 @@
*/
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/leds.h>
#include <linux/gpio.h>
@@ -27,8 +29,85 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <mtd/mtd-abi.h>
-
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_eth.h>
+#include <prom.h>
+
+const char *get_system_type(void)
+{
+ return "MTX-1";
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str)
+ memsize = 0x04000000;
+ else
+ strict_strtoul(memsize_str, 0, &memsize);
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
+
+static void mtx1_reset(char *c)
+{
+ /* Jump to the reset vector */
+ __asm__ __volatile__("jr\t%0" : : "r"(0xbfc00000));
+}
+
+static void mtx1_power_off(void)
+{
+ while (1)
+ asm volatile (
+ " .set mips32 \n"
+ " wait \n"
+ " .set mips0 \n");
+}
+
+void __init board_setup(void)
+{
+#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+ /* Enable USB power switch */
+ alchemy_gpio_direction_output(204, 0);
+#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+
+ /* Initialize sys_pinfunc */
+ au_writel(SYS_PF_NI2, SYS_PINFUNC);
+
+ /* Initialize GPIO */
+ au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR);
+ alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */
+ alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */
+ alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */
+ alchemy_gpio_direction_output(5, 0); /* Disable eth PHY TX_ER */
+
+ /* Enable LED and set it to green */
+ alchemy_gpio_direction_output(211, 1); /* green on */
+ alchemy_gpio_direction_output(212, 0); /* red off */
+
+ pm_power_off = mtx1_power_off;
+ _machine_halt = mtx1_power_off;
+ _machine_restart = mtx1_reset;
+
+ printk(KERN_INFO "4G Systems MTX-1 Board\n");
+}
+
+/******************************************************************************/
static struct gpio_keys_button mtx1_gpio_button[] = {
{
@@ -195,7 +274,6 @@ static struct platform_device mtx1_pci_host = {
.resource = alchemy_pci_host_res,
};
-
static struct __initdata platform_device * mtx1_devs[] = {
&mtx1_pci_host,
&mtx1_gpio_leds,
@@ -206,13 +284,19 @@ static struct __initdata platform_device * mtx1_devs[] = {
static struct au1000_eth_platform_data mtx1_au1000_eth0_pdata = {
.phy_search_highest_addr = 1,
- .phy1_search_mac0 = 1,
+ .phy1_search_mac0 = 1,
};
static int __init mtx1_register_devices(void)
{
int rc;
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_irq_type(AU1500_GPIO201_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO202_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO203_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
+
au1xxx_override_eth_cfg(0, &mtx1_au1000_eth0_pdata);
rc = gpio_request(mtx1_gpio_button[0].gpio,
@@ -226,5 +310,4 @@ static int __init mtx1_register_devices(void)
out:
return platform_add_devices(mtx1_devs, ARRAY_SIZE(mtx1_devs));
}
-
arch_initcall(mtx1_register_devices);
diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c
new file mode 100644
index 000000000000..bd5513650293
--- /dev/null
+++ b/arch/mips/alchemy/board-xxs1500.c
@@ -0,0 +1,154 @@
+/*
+ * BRIEF MODULE DESCRIPTION
+ * MyCable XXS1500 board support
+ *
+ * Copyright 2003, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <asm/bootinfo.h>
+#include <asm/reboot.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <prom.h>
+
+const char *get_system_type(void)
+{
+ return "XXS1500";
+}
+
+void __init prom_init(void)
+{
+ unsigned char *memsize_str;
+ unsigned long memsize;
+
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize_str = prom_getenv("memsize");
+ if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
+ memsize = 0x04000000;
+
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+}
+
+static void xxs1500_reset(char *c)
+{
+ /* Jump to the reset vector */
+ __asm__ __volatile__("jr\t%0" : : "r"(0xbfc00000));
+}
+
+static void xxs1500_power_off(void)
+{
+ while (1)
+ asm volatile (
+ " .set mips32 \n"
+ " wait \n"
+ " .set mips0 \n");
+}
+
+void __init board_setup(void)
+{
+ u32 pin_func;
+
+ pm_power_off = xxs1500_power_off;
+ _machine_halt = xxs1500_power_off;
+ _machine_restart = xxs1500_reset;
+
+ alchemy_gpio1_input_enable();
+ alchemy_gpio2_enable();
+
+ /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
+ pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
+ pin_func |= SYS_PF_UR3;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ /* Enable UART */
+ alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
+ /* Enable DTR (MCR bit 0) = USB power up */
+ __raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18));
+ wmb();
+}
+
+/******************************************************************************/
+
+static struct resource xxs1500_pcmcia_res[] = {
+ {
+ .name = "pcmcia-io",
+ .flags = IORESOURCE_MEM,
+ .start = AU1000_PCMCIA_IO_PHYS_ADDR,
+ .end = AU1000_PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1,
+ },
+ {
+ .name = "pcmcia-attr",
+ .flags = IORESOURCE_MEM,
+ .start = AU1000_PCMCIA_ATTR_PHYS_ADDR,
+ .end = AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ },
+ {
+ .name = "pcmcia-mem",
+ .flags = IORESOURCE_MEM,
+ .start = AU1000_PCMCIA_MEM_PHYS_ADDR,
+ .end = AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ },
+};
+
+static struct platform_device xxs1500_pcmcia_dev = {
+ .name = "xxs1500_pcmcia",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(xxs1500_pcmcia_res),
+ .resource = xxs1500_pcmcia_res,
+};
+
+static struct platform_device *xxs1500_devs[] __initdata = {
+ &xxs1500_pcmcia_dev,
+};
+
+static int __init xxs1500_dev_init(void)
+{
+ irq_set_irq_type(AU1500_GPIO204_INT, IRQ_TYPE_LEVEL_HIGH);
+ irq_set_irq_type(AU1500_GPIO201_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO202_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO203_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO205_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO207_INT, IRQ_TYPE_LEVEL_LOW);
+
+ irq_set_irq_type(AU1500_GPIO0_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO1_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO2_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO3_INT, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(AU1500_GPIO4_INT, IRQ_TYPE_LEVEL_LOW); /* CF irq */
+ irq_set_irq_type(AU1500_GPIO5_INT, IRQ_TYPE_LEVEL_LOW);
+
+ return platform_add_devices(xxs1500_devs,
+ ARRAY_SIZE(xxs1500_devs));
+}
+device_initcall(xxs1500_dev_init);
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
index 811ece7b22e3..407ebc00e661 100644
--- a/arch/mips/alchemy/common/Makefile
+++ b/arch/mips/alchemy/common/Makefile
@@ -6,9 +6,7 @@
#
obj-y += prom.o time.o clocks.o platform.o power.o setup.o \
- sleeper.o dma.o dbdma.o
-
-obj-$(CONFIG_ALCHEMY_GPIOINT_AU1000) += irq.o
+ sleeper.o dma.o dbdma.o vss.o irq.o
# optional gpiolib support
ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),)
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
index 0e63ee487d6d..cf02d7dc2df0 100644
--- a/arch/mips/alchemy/common/dbdma.c
+++ b/arch/mips/alchemy/common/dbdma.c
@@ -148,6 +148,50 @@ static dbdev_tab_t au1200_dbdev_tab[] __initdata = {
{ DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
};
+static dbdev_tab_t au1300_dbdev_tab[] __initdata = {
+ { AU1300_DSCR_CMD0_UART0_TX, DEV_FLAGS_OUT, 0, 8, 0x10100004, 0, 0 },
+ { AU1300_DSCR_CMD0_UART0_RX, DEV_FLAGS_IN, 0, 8, 0x10100000, 0, 0 },
+ { AU1300_DSCR_CMD0_UART1_TX, DEV_FLAGS_OUT, 0, 8, 0x10101004, 0, 0 },
+ { AU1300_DSCR_CMD0_UART1_RX, DEV_FLAGS_IN, 0, 8, 0x10101000, 0, 0 },
+ { AU1300_DSCR_CMD0_UART2_TX, DEV_FLAGS_OUT, 0, 8, 0x10102004, 0, 0 },
+ { AU1300_DSCR_CMD0_UART2_RX, DEV_FLAGS_IN, 0, 8, 0x10102000, 0, 0 },
+ { AU1300_DSCR_CMD0_UART3_TX, DEV_FLAGS_OUT, 0, 8, 0x10103004, 0, 0 },
+ { AU1300_DSCR_CMD0_UART3_RX, DEV_FLAGS_IN, 0, 8, 0x10103000, 0, 0 },
+
+ { AU1300_DSCR_CMD0_SDMS_TX0, DEV_FLAGS_OUT, 4, 8, 0x10600000, 0, 0 },
+ { AU1300_DSCR_CMD0_SDMS_RX0, DEV_FLAGS_IN, 4, 8, 0x10600004, 0, 0 },
+ { AU1300_DSCR_CMD0_SDMS_TX1, DEV_FLAGS_OUT, 8, 8, 0x10601000, 0, 0 },
+ { AU1300_DSCR_CMD0_SDMS_RX1, DEV_FLAGS_IN, 8, 8, 0x10601004, 0, 0 },
+
+ { AU1300_DSCR_CMD0_AES_RX, DEV_FLAGS_IN , 4, 32, 0x10300008, 0, 0 },
+ { AU1300_DSCR_CMD0_AES_TX, DEV_FLAGS_OUT, 4, 32, 0x10300004, 0, 0 },
+
+ { AU1300_DSCR_CMD0_PSC0_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0001c, 0, 0 },
+ { AU1300_DSCR_CMD0_PSC0_RX, DEV_FLAGS_IN, 0, 16, 0x10a0001c, 0, 0 },
+ { AU1300_DSCR_CMD0_PSC1_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0101c, 0, 0 },
+ { AU1300_DSCR_CMD0_PSC1_RX, DEV_FLAGS_IN, 0, 16, 0x10a0101c, 0, 0 },
+ { AU1300_DSCR_CMD0_PSC2_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0201c, 0, 0 },
+ { AU1300_DSCR_CMD0_PSC2_RX, DEV_FLAGS_IN, 0, 16, 0x10a0201c, 0, 0 },
+ { AU1300_DSCR_CMD0_PSC3_TX, DEV_FLAGS_OUT, 0, 16, 0x10a0301c, 0, 0 },
+ { AU1300_DSCR_CMD0_PSC3_RX, DEV_FLAGS_IN, 0, 16, 0x10a0301c, 0, 0 },
+
+ { AU1300_DSCR_CMD0_LCD, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ { AU1300_DSCR_CMD0_NAND_FLASH, DEV_FLAGS_IN, 0, 0, 0x00000000, 0, 0 },
+
+ { AU1300_DSCR_CMD0_SDMS_TX2, DEV_FLAGS_OUT, 4, 8, 0x10602000, 0, 0 },
+ { AU1300_DSCR_CMD0_SDMS_RX2, DEV_FLAGS_IN, 4, 8, 0x10602004, 0, 0 },
+
+ { AU1300_DSCR_CMD0_CIM_SYNC, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+
+ { AU1300_DSCR_CMD0_UDMA, DEV_FLAGS_ANYUSE, 0, 32, 0x14001810, 0, 0 },
+
+ { AU1300_DSCR_CMD0_DMA_REQ0, 0, 0, 0, 0x00000000, 0, 0 },
+ { AU1300_DSCR_CMD0_DMA_REQ1, 0, 0, 0, 0x00000000, 0, 0 },
+
+ { DSCR_CMD0_THROTTLE, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+ { DSCR_CMD0_ALWAYS, DEV_FLAGS_ANYUSE, 0, 0, 0x00000000, 0, 0 },
+};
+
/* 32 predefined plus 32 custom */
#define DBDEV_TAB_SIZE 64
@@ -1019,8 +1063,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable)
dbdma_gptr->ddma_inten = 0xffff;
au_sync();
- ret = request_irq(irq, dbdma_interrupt, IRQF_DISABLED, "dbdma",
- (void *)dbdma_gptr);
+ ret = request_irq(irq, dbdma_interrupt, 0, "dbdma", (void *)dbdma_gptr);
if (ret)
printk(KERN_ERR "Cannot grab DBDMA interrupt!\n");
else {
@@ -1038,6 +1081,8 @@ static int __init alchemy_dbdma_init(void)
return dbdma_setup(AU1550_DDMA_INT, au1550_dbdev_tab);
case ALCHEMY_CPU_AU1200:
return dbdma_setup(AU1200_DDMA_INT, au1200_dbdev_tab);
+ case ALCHEMY_CPU_AU1300:
+ return dbdma_setup(AU1300_DDMA_INT, au1300_dbdev_tab);
}
return 0;
}
diff --git a/arch/mips/alchemy/common/gpiolib.c b/arch/mips/alchemy/common/gpiolib.c
index 91fb4d9e30fd..f1b50f0c01db 100644
--- a/arch/mips/alchemy/common/gpiolib.c
+++ b/arch/mips/alchemy/common/gpiolib.c
@@ -27,6 +27,7 @@
* CONFIG_ALCHEMY_GPIO_INDIRECT=n, otherwise compilation will fail!
* au1000 SoC have only one GPIO block : GPIO1
* Au1100, Au15x0, Au12x0 have a second one : GPIO2
+ * Au1300 is totally different: 1 block with up to 128 GPIOs
*/
#include <linux/init.h>
@@ -35,6 +36,7 @@
#include <linux/types.h>
#include <linux/gpio.h>
#include <asm/mach-au1x00/gpio-au1000.h>
+#include <asm/mach-au1x00/gpio-au1300.h>
static int gpio2_get(struct gpio_chip *chip, unsigned offset)
{
@@ -115,6 +117,43 @@ struct gpio_chip alchemy_gpio_chip[] = {
},
};
+static int alchemy_gpic_get(struct gpio_chip *chip, unsigned int off)
+{
+ return au1300_gpio_get_value(off + AU1300_GPIO_BASE);
+}
+
+static void alchemy_gpic_set(struct gpio_chip *chip, unsigned int off, int v)
+{
+ au1300_gpio_set_value(off + AU1300_GPIO_BASE, v);
+}
+
+static int alchemy_gpic_dir_input(struct gpio_chip *chip, unsigned int off)
+{
+ return au1300_gpio_direction_input(off + AU1300_GPIO_BASE);
+}
+
+static int alchemy_gpic_dir_output(struct gpio_chip *chip, unsigned int off,
+ int v)
+{
+ return au1300_gpio_direction_output(off + AU1300_GPIO_BASE, v);
+}
+
+static int alchemy_gpic_gpio_to_irq(struct gpio_chip *chip, unsigned int off)
+{
+ return au1300_gpio_to_irq(off + AU1300_GPIO_BASE);
+}
+
+static struct gpio_chip au1300_gpiochip = {
+ .label = "alchemy-gpic",
+ .direction_input = alchemy_gpic_dir_input,
+ .direction_output = alchemy_gpic_dir_output,
+ .get = alchemy_gpic_get,
+ .set = alchemy_gpic_set,
+ .to_irq = alchemy_gpic_gpio_to_irq,
+ .base = AU1300_GPIO_BASE,
+ .ngpio = AU1300_GPIO_NUM,
+};
+
static int __init alchemy_gpiochip_init(void)
{
int ret = 0;
@@ -127,6 +166,9 @@ static int __init alchemy_gpiochip_init(void)
ret = gpiochip_add(&alchemy_gpio_chip[0]);
ret |= gpiochip_add(&alchemy_gpio_chip[1]);
break;
+ case ALCHEMY_CPU_AU1300:
+ ret = gpiochip_add(&au1300_gpiochip);
+ break;
}
return ret;
}
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index 8b60ba0675e2..94fbcd19eb9c 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -25,19 +25,15 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/bitops.h>
+#include <linux/export.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/syscore_ops.h>
#include <asm/irq_cpu.h>
-#include <asm/mipsregs.h>
#include <asm/mach-au1x00/au1000.h>
-#ifdef CONFIG_MIPS_PB1000
-#include <asm/mach-pb1x00/pb1000.h>
-#endif
+#include <asm/mach-au1x00/gpio-au1300.h>
/* Interrupt Controller register offsets */
#define IC_CFG0RD 0x40
@@ -69,7 +65,17 @@
#define IC_FALLINGCLR 0x7C
#define IC_TESTBIT 0x80
-static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
+/* per-processor fixed function irqs */
+struct alchemy_irqmap {
+ int irq; /* linux IRQ number */
+ int type; /* IRQ_TYPE_ */
+ int prio; /* irq priority, 0 highest, 3 lowest */
+ int internal; /* GPIC: internal source (no ext. pin)? */
+};
+
+static int au1x_ic_settype(struct irq_data *d, unsigned int type);
+static int au1300_gpic_settype(struct irq_data *d, unsigned int type);
+
/* NOTE on interrupt priorities: The original writers of this code said:
*
@@ -77,176 +83,207 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type);
* the USB devices-side packet complete interrupt (USB_DEV_REQ_INT)
* needs the highest priority.
*/
-
-/* per-processor fixed function irqs */
-struct au1xxx_irqmap {
- int im_irq;
- int im_type;
- int im_request; /* set 1 to get higher priority */
+struct alchemy_irqmap au1000_irqmap[] __initdata = {
+ { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
+ { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
+ { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { -1, },
};
-struct au1xxx_irqmap au1000_irqmap[] __initdata = {
- { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
- { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
- { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+struct alchemy_irqmap au1500_irqmap[] __initdata = {
+ { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
+ { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
+ { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ -1, },
};
-struct au1xxx_irqmap au1500_irqmap[] __initdata = {
- { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1500_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1500_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1500_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
- { AU1500_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
- { AU1500_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1500_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1500_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+struct alchemy_irqmap au1100_irqmap[] __initdata = {
+ { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
+ { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
+ { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
{ -1, },
};
-struct au1xxx_irqmap au1100_irqmap[] __initdata = {
- { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
- { AU1100_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
- { AU1100_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1100_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1100_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+struct alchemy_irqmap au1550_irqmap[] __initdata = {
+ { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
+ { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0, 0 },
+ { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 1, 0 },
+ { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ -1, },
};
-struct au1xxx_irqmap au1550_irqmap[] __initdata = {
- { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
- { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 1 },
- { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
- { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+struct alchemy_irqmap au1200_irqmap[] __initdata = {
+ { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 0 },
+ { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 1, 0 },
+ { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
+ { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0 },
{ -1, },
};
-struct au1xxx_irqmap au1200_irqmap[] __initdata = {
- { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
- { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
- { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
- { -1, },
+static struct alchemy_irqmap au1300_irqmap[] __initdata = {
+ /* multifunction: gpio pin or device */
+ { AU1300_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_SD1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_SD2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ { AU1300_NAND_INT, IRQ_TYPE_LEVEL_HIGH, 1, 0, },
+ /* au1300 internal */
+ { AU1300_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_MMU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_MPU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_GPU_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_UDMA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_TOY_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
+ { AU1300_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
+ { AU1300_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
+ { AU1300_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
+ { AU1300_RTC_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
+ { AU1300_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
+ { AU1300_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
+ { AU1300_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0, 1, },
+ { AU1300_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_SD0_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_USB_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_BSA_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_MPE_INT, IRQ_TYPE_EDGE_RISING, 1, 1, },
+ { AU1300_ITE_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_AES_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { AU1300_CIM_INT, IRQ_TYPE_LEVEL_HIGH, 1, 1, },
+ { -1, }, /* terminator */
};
+/******************************************************************************/
static void au1x_ic0_unmask(struct irq_data *d)
{
@@ -265,14 +302,6 @@ static void au1x_ic1_unmask(struct irq_data *d)
__raw_writel(1 << bit, base + IC_MASKSET);
__raw_writel(1 << bit, base + IC_WAKESET);
-
-/* very hacky. does the pb1000 cpld auto-disable this int?
- * nowhere in the current kernel sources is it disabled. --mlau
- */
-#if defined(CONFIG_MIPS_PB1000)
- if (d->irq == AU1000_GPIO15_INT)
- __raw_writel(0x4000, (void __iomem *)PB1000_MDR); /* enable int */
-#endif
wmb();
}
@@ -470,40 +499,219 @@ static int au1x_ic_settype(struct irq_data *d, unsigned int flow_type)
return ret;
}
-asmlinkage void plat_irq_dispatch(void)
+/******************************************************************************/
+
+/*
+ * au1300_gpic_chgcfg - change PIN configuration.
+ * @gpio: pin to change (0-based GPIO number from datasheet).
+ * @clr: clear all bits set in 'clr'.
+ * @set: set these bits.
+ *
+ * modifies a pins' configuration register, bits set in @clr will
+ * be cleared in the register, bits in @set will be set.
+ */
+static inline void au1300_gpic_chgcfg(unsigned int gpio,
+ unsigned long clr,
+ unsigned long set)
+{
+ void __iomem *r = AU1300_GPIC_ADDR;
+ unsigned long l;
+
+ r += gpio * 4; /* offset into pin config array */
+ l = __raw_readl(r + AU1300_GPIC_PINCFG);
+ l &= ~clr;
+ l |= set;
+ __raw_writel(l, r + AU1300_GPIC_PINCFG);
+ wmb();
+}
+
+/*
+ * au1300_pinfunc_to_gpio - assign a pin as GPIO input (GPIO ctrl).
+ * @pin: pin (0-based GPIO number from datasheet).
+ *
+ * Assigns a GPIO pin to the GPIO controller, so its level can either
+ * be read or set through the generic GPIO functions.
+ * If you need a GPOUT, use au1300_gpio_set_value(pin, 0/1).
+ * REVISIT: is this function really necessary?
+ */
+void au1300_pinfunc_to_gpio(enum au1300_multifunc_pins gpio)
+{
+ au1300_gpio_direction_input(gpio + AU1300_GPIO_BASE);
+}
+EXPORT_SYMBOL_GPL(au1300_pinfunc_to_gpio);
+
+/*
+ * au1300_pinfunc_to_dev - assign a pin to the device function.
+ * @pin: pin (0-based GPIO number from datasheet).
+ *
+ * Assigns a GPIO pin to its associated device function; the pin will be
+ * driven by the device and not through GPIO functions.
+ */
+void au1300_pinfunc_to_dev(enum au1300_multifunc_pins gpio)
+{
+ void __iomem *r = AU1300_GPIC_ADDR;
+ unsigned long bit;
+
+ r += GPIC_GPIO_BANKOFF(gpio);
+ bit = GPIC_GPIO_TO_BIT(gpio);
+ __raw_writel(bit, r + AU1300_GPIC_DEVSEL);
+ wmb();
+}
+EXPORT_SYMBOL_GPL(au1300_pinfunc_to_dev);
+
+/*
+ * au1300_set_irq_priority - set internal priority of IRQ.
+ * @irq: irq to set priority (linux irq number).
+ * @p: priority (0 = highest, 3 = lowest).
+ */
+void au1300_set_irq_priority(unsigned int irq, int p)
{
- unsigned int pending = read_c0_status() & read_c0_cause();
- unsigned long s, off;
-
- if (pending & CAUSEF_IP7) {
- off = MIPS_CPU_IRQ_BASE + 7;
- goto handle;
- } else if (pending & CAUSEF_IP2) {
- s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ0INT;
- off = AU1000_INTC0_INT_BASE;
- } else if (pending & CAUSEF_IP3) {
- s = KSEG1ADDR(AU1000_IC0_PHYS_ADDR) + IC_REQ1INT;
- off = AU1000_INTC0_INT_BASE;
- } else if (pending & CAUSEF_IP4) {
- s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ0INT;
- off = AU1000_INTC1_INT_BASE;
- } else if (pending & CAUSEF_IP5) {
- s = KSEG1ADDR(AU1000_IC1_PHYS_ADDR) + IC_REQ1INT;
- off = AU1000_INTC1_INT_BASE;
- } else
- goto spurious;
-
- s = __raw_readl((void __iomem *)s);
- if (unlikely(!s)) {
-spurious:
- spurious_interrupt();
- return;
+ irq -= ALCHEMY_GPIC_INT_BASE;
+ au1300_gpic_chgcfg(irq, GPIC_CFG_IL_MASK, GPIC_CFG_IL_SET(p));
+}
+EXPORT_SYMBOL_GPL(au1300_set_irq_priority);
+
+/*
+ * au1300_set_dbdma_gpio - assign a gpio to one of the DBDMA triggers.
+ * @dchan: dbdma trigger select (0, 1).
+ * @gpio: pin to assign as trigger.
+ *
+ * DBDMA controller has 2 external trigger sources; this function
+ * assigns a GPIO to the selected trigger.
+ */
+void au1300_set_dbdma_gpio(int dchan, unsigned int gpio)
+{
+ unsigned long r;
+
+ if ((dchan >= 0) && (dchan <= 1)) {
+ r = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL);
+ r &= ~(0xff << (8 * dchan));
+ r |= (gpio & 0x7f) << (8 * dchan);
+ __raw_writel(r, AU1300_GPIC_ADDR + AU1300_GPIC_DMASEL);
+ wmb();
}
- off += __ffs(s);
-handle:
- do_IRQ(off);
}
+static inline void gpic_pin_set_idlewake(unsigned int gpio, int allow)
+{
+ au1300_gpic_chgcfg(gpio, GPIC_CFG_IDLEWAKE,
+ allow ? GPIC_CFG_IDLEWAKE : 0);
+}
+
+static void au1300_gpic_mask(struct irq_data *d)
+{
+ void __iomem *r = AU1300_GPIC_ADDR;
+ unsigned long bit, irq = d->irq;
+
+ irq -= ALCHEMY_GPIC_INT_BASE;
+ r += GPIC_GPIO_BANKOFF(irq);
+ bit = GPIC_GPIO_TO_BIT(irq);
+ __raw_writel(bit, r + AU1300_GPIC_IDIS);
+ wmb();
+
+ gpic_pin_set_idlewake(irq, 0);
+}
+
+static void au1300_gpic_unmask(struct irq_data *d)
+{
+ void __iomem *r = AU1300_GPIC_ADDR;
+ unsigned long bit, irq = d->irq;
+
+ irq -= ALCHEMY_GPIC_INT_BASE;
+
+ gpic_pin_set_idlewake(irq, 1);
+
+ r += GPIC_GPIO_BANKOFF(irq);
+ bit = GPIC_GPIO_TO_BIT(irq);
+ __raw_writel(bit, r + AU1300_GPIC_IEN);
+ wmb();
+}
+
+static void au1300_gpic_maskack(struct irq_data *d)
+{
+ void __iomem *r = AU1300_GPIC_ADDR;
+ unsigned long bit, irq = d->irq;
+
+ irq -= ALCHEMY_GPIC_INT_BASE;
+ r += GPIC_GPIO_BANKOFF(irq);
+ bit = GPIC_GPIO_TO_BIT(irq);
+ __raw_writel(bit, r + AU1300_GPIC_IPEND); /* ack */
+ __raw_writel(bit, r + AU1300_GPIC_IDIS); /* mask */
+ wmb();
+
+ gpic_pin_set_idlewake(irq, 0);
+}
+
+static void au1300_gpic_ack(struct irq_data *d)
+{
+ void __iomem *r = AU1300_GPIC_ADDR;
+ unsigned long bit, irq = d->irq;
+
+ irq -= ALCHEMY_GPIC_INT_BASE;
+ r += GPIC_GPIO_BANKOFF(irq);
+ bit = GPIC_GPIO_TO_BIT(irq);
+ __raw_writel(bit, r + AU1300_GPIC_IPEND); /* ack */
+ wmb();
+}
+
+static struct irq_chip au1300_gpic = {
+ .name = "GPIOINT",
+ .irq_ack = au1300_gpic_ack,
+ .irq_mask = au1300_gpic_mask,
+ .irq_mask_ack = au1300_gpic_maskack,
+ .irq_unmask = au1300_gpic_unmask,
+ .irq_set_type = au1300_gpic_settype,
+};
+
+static int au1300_gpic_settype(struct irq_data *d, unsigned int type)
+{
+ unsigned long s;
+ unsigned char *name = NULL;
+ irq_flow_handler_t hdl = NULL;
+
+ switch (type) {
+ case IRQ_TYPE_LEVEL_HIGH:
+ s = GPIC_CFG_IC_LEVEL_HIGH;
+ name = "high";
+ hdl = handle_level_irq;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ s = GPIC_CFG_IC_LEVEL_LOW;
+ name = "low";
+ hdl = handle_level_irq;
+ break;
+ case IRQ_TYPE_EDGE_RISING:
+ s = GPIC_CFG_IC_EDGE_RISE;
+ name = "posedge";
+ hdl = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ s = GPIC_CFG_IC_EDGE_FALL;
+ name = "negedge";
+ hdl = handle_edge_irq;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ s = GPIC_CFG_IC_EDGE_BOTH;
+ name = "bothedge";
+ hdl = handle_edge_irq;
+ break;
+ case IRQ_TYPE_NONE:
+ s = GPIC_CFG_IC_OFF;
+ name = "disabled";
+ hdl = handle_level_irq;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ __irq_set_chip_handler_name_locked(d->irq, &au1300_gpic, hdl, name);
+
+ au1300_gpic_chgcfg(d->irq - ALCHEMY_GPIC_INT_BASE, GPIC_CFG_IC_MASK, s);
+
+ return 0;
+}
+
+/******************************************************************************/
static inline void ic_init(void __iomem *base)
{
@@ -521,13 +729,159 @@ static inline void ic_init(void __iomem *base)
wmb();
}
-static void __init au1000_init_irq(struct au1xxx_irqmap *map)
+static unsigned long alchemy_gpic_pmdata[ALCHEMY_GPIC_INT_NUM + 6];
+
+static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
+{
+ d[0] = __raw_readl(base + IC_CFG0RD);
+ d[1] = __raw_readl(base + IC_CFG1RD);
+ d[2] = __raw_readl(base + IC_CFG2RD);
+ d[3] = __raw_readl(base + IC_SRCRD);
+ d[4] = __raw_readl(base + IC_ASSIGNRD);
+ d[5] = __raw_readl(base + IC_WAKERD);
+ d[6] = __raw_readl(base + IC_MASKRD);
+ ic_init(base); /* shut it up too while at it */
+}
+
+static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
+{
+ ic_init(base);
+
+ __raw_writel(d[0], base + IC_CFG0SET);
+ __raw_writel(d[1], base + IC_CFG1SET);
+ __raw_writel(d[2], base + IC_CFG2SET);
+ __raw_writel(d[3], base + IC_SRCSET);
+ __raw_writel(d[4], base + IC_ASSIGNSET);
+ __raw_writel(d[5], base + IC_WAKESET);
+ wmb();
+
+ __raw_writel(d[6], base + IC_MASKSET);
+ wmb();
+}
+
+static int alchemy_ic_suspend(void)
+{
+ alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
+ alchemy_gpic_pmdata);
+ alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
+ &alchemy_gpic_pmdata[7]);
+ return 0;
+}
+
+static void alchemy_ic_resume(void)
+{
+ alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
+ &alchemy_gpic_pmdata[7]);
+ alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
+ alchemy_gpic_pmdata);
+}
+
+static int alchemy_gpic_suspend(void)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
+ int i;
+
+ /* save 4 interrupt mask status registers */
+ alchemy_gpic_pmdata[0] = __raw_readl(base + AU1300_GPIC_IEN + 0x0);
+ alchemy_gpic_pmdata[1] = __raw_readl(base + AU1300_GPIC_IEN + 0x4);
+ alchemy_gpic_pmdata[2] = __raw_readl(base + AU1300_GPIC_IEN + 0x8);
+ alchemy_gpic_pmdata[3] = __raw_readl(base + AU1300_GPIC_IEN + 0xc);
+
+ /* save misc register(s) */
+ alchemy_gpic_pmdata[4] = __raw_readl(base + AU1300_GPIC_DMASEL);
+
+ /* molto silenzioso */
+ __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0);
+ __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4);
+ __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8);
+ __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc);
+ wmb();
+
+ /* save pin/int-type configuration */
+ base += AU1300_GPIC_PINCFG;
+ for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++)
+ alchemy_gpic_pmdata[i + 5] = __raw_readl(base + (i << 2));
+
+ wmb();
+
+ return 0;
+}
+
+static void alchemy_gpic_resume(void)
+{
+ void __iomem *base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
+ int i;
+
+ /* disable all first */
+ __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x0);
+ __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x4);
+ __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0x8);
+ __raw_writel(~0UL, base + AU1300_GPIC_IDIS + 0xc);
+ wmb();
+
+ /* restore pin/int-type configurations */
+ base += AU1300_GPIC_PINCFG;
+ for (i = 0; i < ALCHEMY_GPIC_INT_NUM; i++)
+ __raw_writel(alchemy_gpic_pmdata[i + 5], base + (i << 2));
+ wmb();
+
+ /* restore misc register(s) */
+ base = (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR);
+ __raw_writel(alchemy_gpic_pmdata[4], base + AU1300_GPIC_DMASEL);
+ wmb();
+
+ /* finally restore masks */
+ __raw_writel(alchemy_gpic_pmdata[0], base + AU1300_GPIC_IEN + 0x0);
+ __raw_writel(alchemy_gpic_pmdata[1], base + AU1300_GPIC_IEN + 0x4);
+ __raw_writel(alchemy_gpic_pmdata[2], base + AU1300_GPIC_IEN + 0x8);
+ __raw_writel(alchemy_gpic_pmdata[3], base + AU1300_GPIC_IEN + 0xc);
+ wmb();
+}
+
+static struct syscore_ops alchemy_ic_pmops = {
+ .suspend = alchemy_ic_suspend,
+ .resume = alchemy_ic_resume,
+};
+
+static struct syscore_ops alchemy_gpic_pmops = {
+ .suspend = alchemy_gpic_suspend,
+ .resume = alchemy_gpic_resume,
+};
+
+/******************************************************************************/
+
+/* create chained handlers for the 4 IC requests to the MIPS IRQ ctrl */
+#define DISP(name, base, addr) \
+static void au1000_##name##_dispatch(unsigned int irq, struct irq_desc *d) \
+{ \
+ unsigned long r = __raw_readl((void __iomem *)KSEG1ADDR(addr)); \
+ if (likely(r)) \
+ generic_handle_irq(base + __ffs(r)); \
+ else \
+ spurious_interrupt(); \
+}
+
+DISP(ic0r0, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ0INT)
+DISP(ic0r1, AU1000_INTC0_INT_BASE, AU1000_IC0_PHYS_ADDR + IC_REQ1INT)
+DISP(ic1r0, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ0INT)
+DISP(ic1r1, AU1000_INTC1_INT_BASE, AU1000_IC1_PHYS_ADDR + IC_REQ1INT)
+
+static void alchemy_gpic_dispatch(unsigned int irq, struct irq_desc *d)
+{
+ int i = __raw_readl(AU1300_GPIC_ADDR + AU1300_GPIC_PRIENC);
+ generic_handle_irq(ALCHEMY_GPIC_INT_BASE + i);
+}
+
+/******************************************************************************/
+
+static void __init au1000_init_irq(struct alchemy_irqmap *map)
{
unsigned int bit, irq_nr;
void __iomem *base;
ic_init((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR));
ic_init((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR));
+ register_syscore_ops(&alchemy_ic_pmops);
mips_cpu_irq_init();
/* register all 64 possible IC0+IC1 irq sources as type "none".
@@ -544,8 +898,8 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
/*
* Initialize IC0, which is fixed per processor.
*/
- while (map->im_irq != -1) {
- irq_nr = map->im_irq;
+ while (map->irq != -1) {
+ irq_nr = map->irq;
if (irq_nr >= AU1000_INTC1_INT_BASE) {
bit = irq_nr - AU1000_INTC1_INT_BASE;
@@ -554,16 +908,61 @@ static void __init au1000_init_irq(struct au1xxx_irqmap *map)
bit = irq_nr - AU1000_INTC0_INT_BASE;
base = (void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR);
}
- if (map->im_request)
+ if (map->prio == 0)
__raw_writel(1 << bit, base + IC_ASSIGNSET);
- au1x_ic_settype(irq_get_irq_data(irq_nr), map->im_type);
+ au1x_ic_settype(irq_get_irq_data(irq_nr), map->type);
++map;
}
- set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, au1000_ic0r0_dispatch);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, au1000_ic0r1_dispatch);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, au1000_ic1r0_dispatch);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, au1000_ic1r1_dispatch);
+}
+
+static void __init alchemy_gpic_init_irq(const struct alchemy_irqmap *dints)
+{
+ int i;
+ void __iomem *bank_base;
+
+ register_syscore_ops(&alchemy_gpic_pmops);
+ mips_cpu_irq_init();
+
+ /* disable & ack all possible interrupt sources */
+ for (i = 0; i < 4; i++) {
+ bank_base = AU1300_GPIC_ADDR + (i * 4);
+ __raw_writel(~0UL, bank_base + AU1300_GPIC_IDIS);
+ wmb();
+ __raw_writel(~0UL, bank_base + AU1300_GPIC_IPEND);
+ wmb();
+ }
+
+ /* register an irq_chip for them, with 2nd highest priority */
+ for (i = ALCHEMY_GPIC_INT_BASE; i <= ALCHEMY_GPIC_INT_LAST; i++) {
+ au1300_set_irq_priority(i, 1);
+ au1300_gpic_settype(irq_get_irq_data(i), IRQ_TYPE_NONE);
+ }
+
+ /* setup known on-chip sources */
+ while ((i = dints->irq) != -1) {
+ au1300_gpic_settype(irq_get_irq_data(i), dints->type);
+ au1300_set_irq_priority(i, dints->prio);
+
+ if (dints->internal)
+ au1300_pinfunc_to_dev(i - ALCHEMY_GPIC_INT_BASE);
+
+ dints++;
+ }
+
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 2, alchemy_gpic_dispatch);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 3, alchemy_gpic_dispatch);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 4, alchemy_gpic_dispatch);
+ irq_set_chained_handler(MIPS_CPU_IRQ_BASE + 5, alchemy_gpic_dispatch);
}
+/******************************************************************************/
+
void __init arch_init_irq(void)
{
switch (alchemy_get_cputype()) {
@@ -582,65 +981,17 @@ void __init arch_init_irq(void)
case ALCHEMY_CPU_AU1200:
au1000_init_irq(au1200_irqmap);
break;
+ case ALCHEMY_CPU_AU1300:
+ alchemy_gpic_init_irq(au1300_irqmap);
+ break;
+ default:
+ pr_err("unknown Alchemy IRQ core\n");
+ break;
}
}
-
-static unsigned long alchemy_ic_pmdata[7 * 2];
-
-static inline void alchemy_ic_suspend_one(void __iomem *base, unsigned long *d)
-{
- d[0] = __raw_readl(base + IC_CFG0RD);
- d[1] = __raw_readl(base + IC_CFG1RD);
- d[2] = __raw_readl(base + IC_CFG2RD);
- d[3] = __raw_readl(base + IC_SRCRD);
- d[4] = __raw_readl(base + IC_ASSIGNRD);
- d[5] = __raw_readl(base + IC_WAKERD);
- d[6] = __raw_readl(base + IC_MASKRD);
- ic_init(base); /* shut it up too while at it */
-}
-
-static inline void alchemy_ic_resume_one(void __iomem *base, unsigned long *d)
-{
- ic_init(base);
-
- __raw_writel(d[0], base + IC_CFG0SET);
- __raw_writel(d[1], base + IC_CFG1SET);
- __raw_writel(d[2], base + IC_CFG2SET);
- __raw_writel(d[3], base + IC_SRCSET);
- __raw_writel(d[4], base + IC_ASSIGNSET);
- __raw_writel(d[5], base + IC_WAKESET);
- wmb();
-
- __raw_writel(d[6], base + IC_MASKSET);
- wmb();
-}
-
-static int alchemy_ic_suspend(void)
-{
- alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
- alchemy_ic_pmdata);
- alchemy_ic_suspend_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
- &alchemy_ic_pmdata[7]);
- return 0;
-}
-
-static void alchemy_ic_resume(void)
-{
- alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC1_PHYS_ADDR),
- &alchemy_ic_pmdata[7]);
- alchemy_ic_resume_one((void __iomem *)KSEG1ADDR(AU1000_IC0_PHYS_ADDR),
- alchemy_ic_pmdata);
-}
-
-static struct syscore_ops alchemy_ic_syscore_ops = {
- .suspend = alchemy_ic_suspend,
- .resume = alchemy_ic_resume,
-};
-
-static int __init alchemy_ic_pm_init(void)
+asmlinkage void plat_irq_dispatch(void)
{
- register_syscore_ops(&alchemy_ic_syscore_ops);
- return 0;
+ unsigned long r = (read_c0_status() & read_c0_cause()) >> 8;
+ do_IRQ(MIPS_CPU_IRQ_BASE + __ffs(r & 0xff));
}
-device_initcall(alchemy_ic_pm_init);
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index c8e5d72a5826..95cb9113b12c 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -82,6 +82,12 @@ static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = {
PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT),
PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT),
},
+ [ALCHEMY_CPU_AU1300] = {
+ PORT(AU1300_UART0_PHYS_ADDR, AU1300_UART0_INT),
+ PORT(AU1300_UART1_PHYS_ADDR, AU1300_UART1_INT),
+ PORT(AU1300_UART2_PHYS_ADDR, AU1300_UART2_INT),
+ PORT(AU1300_UART3_PHYS_ADDR, AU1300_UART3_INT),
+ },
};
static struct platform_device au1xx0_uart_device = {
@@ -122,10 +128,12 @@ static unsigned long alchemy_ohci_data[][2] __initdata = {
[ALCHEMY_CPU_AU1100] = { AU1000_USB_OHCI_PHYS_ADDR, AU1100_USB_HOST_INT },
[ALCHEMY_CPU_AU1550] = { AU1550_USB_OHCI_PHYS_ADDR, AU1550_USB_HOST_INT },
[ALCHEMY_CPU_AU1200] = { AU1200_USB_OHCI_PHYS_ADDR, AU1200_USB_INT },
+ [ALCHEMY_CPU_AU1300] = { AU1300_USB_OHCI0_PHYS_ADDR, AU1300_USB_INT },
};
static unsigned long alchemy_ehci_data[][2] __initdata = {
[ALCHEMY_CPU_AU1200] = { AU1200_USB_EHCI_PHYS_ADDR, AU1200_USB_INT },
+ [ALCHEMY_CPU_AU1300] = { AU1300_USB_EHCI_PHYS_ADDR, AU1300_USB_INT },
};
static int __init _new_usbres(struct resource **r, struct platform_device **d)
@@ -169,8 +177,8 @@ static void __init alchemy_setup_usb(int ctype)
printk(KERN_INFO "Alchemy USB: cannot add OHCI0\n");
- /* setup EHCI0: Au1200 */
- if (ctype == ALCHEMY_CPU_AU1200) {
+ /* setup EHCI0: Au1200/Au1300 */
+ if ((ctype == ALCHEMY_CPU_AU1200) || (ctype == ALCHEMY_CPU_AU1300)) {
if (_new_usbres(&res, &pdev))
return;
@@ -187,6 +195,25 @@ static void __init alchemy_setup_usb(int ctype)
if (platform_device_register(pdev))
printk(KERN_INFO "Alchemy USB: cannot add EHCI0\n");
}
+
+ /* Au1300: OHCI1 */
+ if (ctype == ALCHEMY_CPU_AU1300) {
+ if (_new_usbres(&res, &pdev))
+ return;
+
+ res[0].start = AU1300_USB_OHCI1_PHYS_ADDR;
+ res[0].end = res[0].start + 0x100 - 1;
+ res[0].flags = IORESOURCE_MEM;
+ res[1].start = AU1300_USB_INT;
+ res[1].end = res[1].start;
+ res[1].flags = IORESOURCE_IRQ;
+ pdev->name = "au1xxx-ohci";
+ pdev->id = 1;
+ pdev->dev.dma_mask = &alchemy_ohci_dmamask;
+
+ if (platform_device_register(pdev))
+ printk(KERN_INFO "Alchemy USB: cannot add OHCI1\n");
+ }
}
/* Macro to help defining the Ethernet MAC resources */
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index bdd6651e9a4f..0c7fce2a3c12 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -126,6 +126,9 @@ void au_sleep(void)
case ALCHEMY_CPU_AU1200:
alchemy_sleep_au1550();
break;
+ case ALCHEMY_CPU_AU1300:
+ alchemy_sleep_au1300();
+ break;
}
restore_core_regs();
diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S
index 77f3c743b716..c7bcc7e5c822 100644
--- a/arch/mips/alchemy/common/sleeper.S
+++ b/arch/mips/alchemy/common/sleeper.S
@@ -153,6 +153,79 @@ LEAF(alchemy_sleep_au1550)
END(alchemy_sleep_au1550)
+/* sleepcode for Au1300 memory controller type */
+LEAF(alchemy_sleep_au1300)
+
+ SETUP_SLEEP
+
+ /* cache following instructions, as memory gets put to sleep */
+ la t0, 2f
+ la t1, 4f
+ subu t2, t1, t0
+
+ .set mips3
+
+1: cache 0x14, 0(t0)
+ subu t2, t2, 32
+ bgez t2, 1b
+ addu t0, t0, 32
+
+ .set mips0
+
+2: lui a0, 0xb400 /* mem_xxx */
+
+ /* disable all ports in mem_sdportcfga */
+ sw zero, 0x868(a0) /* mem_sdportcfga */
+ sync
+
+ /* disable ODT */
+ li t0, 0x03010000
+ sw t0, 0x08d8(a0) /* mem_sdcmd0 */
+ sw t0, 0x08dc(a0) /* mem_sdcmd1 */
+ sync
+
+ /* precharge */
+ li t0, 0x23000400
+ sw t0, 0x08dc(a0) /* mem_sdcmd1 */
+ sw t0, 0x08d8(a0) /* mem_sdcmd0 */
+ sync
+
+ /* auto refresh */
+ sw zero, 0x08c8(a0) /* mem_sdautoref */
+ sync
+
+ /* block access to the DDR */
+ lw t0, 0x0848(a0) /* mem_sdconfigb */
+ li t1, (1 << 7 | 0x3F)
+ or t0, t0, t1
+ sw t0, 0x0848(a0) /* mem_sdconfigb */
+ sync
+
+ /* issue the Self Refresh command */
+ li t0, 0x10000000
+ sw t0, 0x08dc(a0) /* mem_sdcmd1 */
+ sw t0, 0x08d8(a0) /* mem_sdcmd0 */
+ sync
+
+ /* wait for sdram to enter self-refresh mode */
+ lui t0, 0x0300
+3: lw t1, 0x0850(a0) /* mem_sdstat */
+ and t2, t1, t0
+ bne t2, t0, 3b
+ nop
+
+ /* disable SDRAM clocks */
+ li t0, ~(3<<28)
+ lw t1, 0x0840(a0) /* mem_sdconfiga */
+ and t1, t1, t0 /* clear CE[1:0] */
+ sw t1, 0x0840(a0) /* mem_sdconfiga */
+ sync
+
+ DO_SLEEP
+4:
+
+END(alchemy_sleep_au1300)
+
/* This is where we return upon wakeup.
* Reload all of the registers and return.
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c
index d5da6adbf634..7da4d0081487 100644
--- a/arch/mips/alchemy/common/time.c
+++ b/arch/mips/alchemy/common/time.c
@@ -92,7 +92,7 @@ static struct clock_event_device au1x_rtcmatch2_clockdev = {
static struct irqaction au1x_rtcmatch2_irqaction = {
.handler = au1x_rtcmatch2_irq,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_TIMER,
.name = "timer",
.dev_id = &au1x_rtcmatch2_clockdev,
};
@@ -178,6 +178,7 @@ static int alchemy_m2inttab[] __initdata = {
AU1100_RTC_MATCH2_INT,
AU1550_RTC_MATCH2_INT,
AU1200_RTC_MATCH2_INT,
+ AU1300_RTC_MATCH2_INT,
};
void __init plat_time_init(void)
diff --git a/arch/mips/alchemy/common/vss.c b/arch/mips/alchemy/common/vss.c
new file mode 100644
index 000000000000..d23b1444d365
--- /dev/null
+++ b/arch/mips/alchemy/common/vss.c
@@ -0,0 +1,84 @@
+/*
+ * Au1300 media block power gating (VSS)
+ *
+ * This is a stop-gap solution until I have the clock framework integration
+ * ready. This stuff here really must be handled transparently when clocks
+ * for various media blocks are enabled/disabled.
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/mach-au1x00/au1000.h>
+
+#define VSS_GATE 0x00 /* gate wait timers */
+#define VSS_CLKRST 0x04 /* clock/block control */
+#define VSS_FTR 0x08 /* footers */
+
+#define VSS_ADDR(blk) (KSEG1ADDR(AU1300_VSS_PHYS_ADDR) + (blk * 0x0c))
+
+static DEFINE_SPINLOCK(au1300_vss_lock);
+
+/* enable a block as outlined in the databook */
+static inline void __enable_block(int block)
+{
+ void __iomem *base = (void __iomem *)VSS_ADDR(block);
+
+ __raw_writel(3, base + VSS_CLKRST); /* enable clock, assert reset */
+ wmb();
+
+ __raw_writel(0x01fffffe, base + VSS_GATE); /* maximum setup time */
+ wmb();
+
+ /* enable footers in sequence */
+ __raw_writel(0x01, base + VSS_FTR);
+ wmb();
+ __raw_writel(0x03, base + VSS_FTR);
+ wmb();
+ __raw_writel(0x07, base + VSS_FTR);
+ wmb();
+ __raw_writel(0x0f, base + VSS_FTR);
+ wmb();
+
+ __raw_writel(0x01ffffff, base + VSS_GATE); /* start FSM too */
+ wmb();
+
+ __raw_writel(2, base + VSS_CLKRST); /* deassert reset */
+ wmb();
+
+ __raw_writel(0x1f, base + VSS_FTR); /* enable isolation cells */
+ wmb();
+}
+
+/* disable a block as outlined in the databook */
+static inline void __disable_block(int block)
+{
+ void __iomem *base = (void __iomem *)VSS_ADDR(block);
+
+ __raw_writel(0x0f, base + VSS_FTR); /* disable isolation cells */
+ wmb();
+ __raw_writel(0, base + VSS_GATE); /* disable FSM */
+ wmb();
+ __raw_writel(3, base + VSS_CLKRST); /* assert reset */
+ wmb();
+ __raw_writel(1, base + VSS_CLKRST); /* disable clock */
+ wmb();
+ __raw_writel(0, base + VSS_FTR); /* disable all footers */
+ wmb();
+}
+
+void au1300_vss_block_control(int block, int enable)
+{
+ unsigned long flags;
+
+ if (alchemy_get_cputype() != ALCHEMY_CPU_AU1300)
+ return;
+
+ /* only one block at a time */
+ spin_lock_irqsave(&au1300_vss_lock, flags);
+ if (enable)
+ __enable_block(block);
+ else
+ __disable_block(block);
+ spin_unlock_irqrestore(&au1300_vss_lock, flags);
+}
+EXPORT_SYMBOL_GPL(au1300_vss_block_control);
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
index 826449c817c3..3c37fb303364 100644
--- a/arch/mips/alchemy/devboards/Makefile
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -4,15 +4,10 @@
obj-y += prom.o bcsr.o platform.o
obj-$(CONFIG_PM) += pm.o
-obj-$(CONFIG_MIPS_PB1000) += pb1000/
-obj-$(CONFIG_MIPS_PB1100) += pb1100/
-obj-$(CONFIG_MIPS_PB1200) += pb1200/
-obj-$(CONFIG_MIPS_PB1500) += pb1500/
-obj-$(CONFIG_MIPS_PB1550) += pb1550/
-obj-$(CONFIG_MIPS_DB1000) += db1x00/
-obj-$(CONFIG_MIPS_DB1100) += db1x00/
-obj-$(CONFIG_MIPS_DB1200) += db1200/
-obj-$(CONFIG_MIPS_DB1500) += db1x00/
-obj-$(CONFIG_MIPS_DB1550) += db1x00/
-obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/
-obj-$(CONFIG_MIPS_MIRAGE) += db1x00/
+obj-$(CONFIG_MIPS_PB1100) += pb1100.o
+obj-$(CONFIG_MIPS_PB1500) += pb1500.o
+obj-$(CONFIG_MIPS_PB1550) += pb1550.o
+obj-$(CONFIG_MIPS_DB1000) += db1000.o
+obj-$(CONFIG_MIPS_DB1200) += db1200.o
+obj-$(CONFIG_MIPS_DB1300) += db1300.o
+obj-$(CONFIG_MIPS_DB1550) += db1550.o
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
index 463d2c4d9441..1e83ce2e1147 100644
--- a/arch/mips/alchemy/devboards/bcsr.c
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -97,14 +97,9 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
enable_irq(irq);
}
-/* NOTE: both the enable and mask bits must be cleared, otherwise the
- * CPLD generates tons of spurious interrupts (at least on my DB1200).
- * -- mlau
- */
static void bcsr_irq_mask(struct irq_data *d)
{
unsigned short v = 1 << (d->irq - bcsr_csc_base);
- __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
wmb();
}
@@ -112,7 +107,6 @@ static void bcsr_irq_mask(struct irq_data *d)
static void bcsr_irq_maskack(struct irq_data *d)
{
unsigned short v = 1 << (d->irq - bcsr_csc_base);
- __raw_writew(v, bcsr_virt + BCSR_REG_INTCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKCLR);
__raw_writew(v, bcsr_virt + BCSR_REG_INTSTAT); /* ack */
wmb();
@@ -121,7 +115,6 @@ static void bcsr_irq_maskack(struct irq_data *d)
static void bcsr_irq_unmask(struct irq_data *d)
{
unsigned short v = 1 << (d->irq - bcsr_csc_base);
- __raw_writew(v, bcsr_virt + BCSR_REG_INTSET);
__raw_writew(v, bcsr_virt + BCSR_REG_MASKSET);
wmb();
}
@@ -137,9 +130,9 @@ void __init bcsr_init_irq(int csc_start, int csc_end, int hook_irq)
{
unsigned int irq;
- /* mask & disable & ack all */
- __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTCLR);
+ /* mask & enable & ack all */
__raw_writew(0xffff, bcsr_virt + BCSR_REG_MASKCLR);
+ __raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSET);
__raw_writew(0xffff, bcsr_virt + BCSR_REG_INTSTAT);
wmb();
diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c
new file mode 100644
index 000000000000..1b81dbf6b804
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1000.c
@@ -0,0 +1,565 @@
+/*
+ * DBAu1000/1500/1100 board support
+ *
+ * Copyright 2000, 2008 MontaVista Software Inc.
+ * Author: MontaVista Software, Inc. <source@mvista.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/leds.h>
+#include <linux/mmc/host.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/spi/ads7846.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1000_dma.h>
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/reboot.h>
+#include <prom.h>
+#include "platform.h"
+
+#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
+
+struct pci_dev;
+
+static const char *board_type_str(void)
+{
+ switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
+ case BCSR_WHOAMI_DB1000:
+ return "DB1000";
+ case BCSR_WHOAMI_DB1500:
+ return "DB1500";
+ case BCSR_WHOAMI_DB1100:
+ return "DB1100";
+ default:
+ return "(unknown)";
+ }
+}
+
+const char *get_system_type(void)
+{
+ return board_type_str();
+}
+
+void __init board_setup(void)
+{
+ /* initialize board register space */
+ bcsr_init(DB1000_BCSR_PHYS_ADDR,
+ DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);
+
+ printk(KERN_INFO "AMD Alchemy %s Board\n", board_type_str());
+}
+
+
+static int db1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
+{
+ if ((slot < 12) || (slot > 13) || pin == 0)
+ return -1;
+ if (slot == 12)
+ return (pin == 1) ? AU1500_PCI_INTA : 0xff;
+ if (slot == 13) {
+ switch (pin) {
+ case 1: return AU1500_PCI_INTA;
+ case 2: return AU1500_PCI_INTB;
+ case 3: return AU1500_PCI_INTC;
+ case 4: return AU1500_PCI_INTD;
+ }
+ }
+ return -1;
+}
+
+static struct resource alchemy_pci_host_res[] = {
+ [0] = {
+ .start = AU1500_PCI_PHYS_ADDR,
+ .end = AU1500_PCI_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct alchemy_pci_platdata db1500_pci_pd = {
+ .board_map_irq = db1500_map_pci_irq,
+};
+
+static struct platform_device db1500_pci_host_dev = {
+ .dev.platform_data = &db1500_pci_pd,
+ .name = "alchemy-pci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
+ .resource = alchemy_pci_host_res,
+};
+
+static int __init db1500_pci_init(void)
+{
+ if (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) == BCSR_WHOAMI_DB1500)
+ return platform_device_register(&db1500_pci_host_dev);
+ return 0;
+}
+/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
+arch_initcall(db1500_pci_init);
+
+
+static struct resource au1100_lcd_resources[] = {
+ [0] = {
+ .start = AU1100_LCD_PHYS_ADDR,
+ .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1100_LCD_INT,
+ .end = AU1100_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device au1100_lcd_device = {
+ .name = "au1100-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1100_lcd_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(au1100_lcd_resources),
+ .resource = au1100_lcd_resources,
+};
+
+static struct resource alchemy_ac97c_res[] = {
+ [0] = {
+ .start = AU1000_AC97_PHYS_ADDR,
+ .end = AU1000_AC97_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DMA_ID_AC97C_TX,
+ .end = DMA_ID_AC97C_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [2] = {
+ .start = DMA_ID_AC97C_RX,
+ .end = DMA_ID_AC97C_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device alchemy_ac97c_dev = {
+ .name = "alchemy-ac97c",
+ .id = -1,
+ .resource = alchemy_ac97c_res,
+ .num_resources = ARRAY_SIZE(alchemy_ac97c_res),
+};
+
+static struct platform_device alchemy_ac97c_dma_dev = {
+ .name = "alchemy-pcm-dma",
+ .id = 0,
+};
+
+static struct platform_device db1x00_codec_dev = {
+ .name = "ac97-codec",
+ .id = -1,
+};
+
+static struct platform_device db1x00_audio_dev = {
+ .name = "db1000-audio",
+};
+
+/******************************************************************************/
+
+static irqreturn_t db1100_mmc_cd(int irq, void *ptr)
+{
+ void (*mmc_cd)(struct mmc_host *, unsigned long);
+ /* link against CONFIG_MMC=m */
+ mmc_cd = symbol_get(mmc_detect_change);
+ mmc_cd(ptr, msecs_to_jiffies(500));
+ symbol_put(mmc_detect_change);
+
+ return IRQ_HANDLED;
+}
+
+static int db1100_mmc_cd_setup(void *mmc_host, int en)
+{
+ int ret = 0;
+
+ if (en) {
+ irq_set_irq_type(AU1100_GPIO19_INT, IRQ_TYPE_EDGE_BOTH);
+ ret = request_irq(AU1100_GPIO19_INT, db1100_mmc_cd, 0,
+ "sd0_cd", mmc_host);
+ } else
+ free_irq(AU1100_GPIO19_INT, mmc_host);
+ return ret;
+}
+
+static int db1100_mmc1_cd_setup(void *mmc_host, int en)
+{
+ int ret = 0;
+
+ if (en) {
+ irq_set_irq_type(AU1100_GPIO20_INT, IRQ_TYPE_EDGE_BOTH);
+ ret = request_irq(AU1100_GPIO20_INT, db1100_mmc_cd, 0,
+ "sd1_cd", mmc_host);
+ } else
+ free_irq(AU1100_GPIO20_INT, mmc_host);
+ return ret;
+}
+
+static int db1100_mmc_card_readonly(void *mmc_host)
+{
+ /* testing suggests that this bit is inverted */
+ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 0 : 1;
+}
+
+static int db1100_mmc_card_inserted(void *mmc_host)
+{
+ return !alchemy_gpio_get_value(19);
+}
+
+static void db1100_mmc_set_power(void *mmc_host, int state)
+{
+ if (state) {
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
+ msleep(400); /* stabilization time */
+ } else
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
+}
+
+static void db1100_mmcled_set(struct led_classdev *led, enum led_brightness b)
+{
+ if (b != LED_OFF)
+ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
+ else
+ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
+}
+
+static struct led_classdev db1100_mmc_led = {
+ .brightness_set = db1100_mmcled_set,
+};
+
+static int db1100_mmc1_card_readonly(void *mmc_host)
+{
+ return (bcsr_read(BCSR_BOARD) & BCSR_BOARD_SD1WP) ? 1 : 0;
+}
+
+static int db1100_mmc1_card_inserted(void *mmc_host)
+{
+ return !alchemy_gpio_get_value(20);
+}
+
+static void db1100_mmc1_set_power(void *mmc_host, int state)
+{
+ if (state) {
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
+ msleep(400); /* stabilization time */
+ } else
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
+}
+
+static void db1100_mmc1led_set(struct led_classdev *led, enum led_brightness b)
+{
+ if (b != LED_OFF)
+ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
+ else
+ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
+}
+
+static struct led_classdev db1100_mmc1_led = {
+ .brightness_set = db1100_mmc1led_set,
+};
+
+static struct au1xmmc_platform_data db1100_mmc_platdata[2] = {
+ [0] = {
+ .cd_setup = db1100_mmc_cd_setup,
+ .set_power = db1100_mmc_set_power,
+ .card_inserted = db1100_mmc_card_inserted,
+ .card_readonly = db1100_mmc_card_readonly,
+ .led = &db1100_mmc_led,
+ },
+ [1] = {
+ .cd_setup = db1100_mmc1_cd_setup,
+ .set_power = db1100_mmc1_set_power,
+ .card_inserted = db1100_mmc1_card_inserted,
+ .card_readonly = db1100_mmc1_card_readonly,
+ .led = &db1100_mmc1_led,
+ },
+};
+
+static struct resource au1100_mmc0_resources[] = {
+ [0] = {
+ .start = AU1100_SD0_PHYS_ADDR,
+ .end = AU1100_SD0_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1100_SD_INT,
+ .end = AU1100_SD_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DMA_ID_SD0_TX,
+ .end = DMA_ID_SD0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DMA_ID_SD0_RX,
+ .end = DMA_ID_SD0_RX,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device db1100_mmc0_dev = {
+ .name = "au1xxx-mmc",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1xxx_mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &db1100_mmc_platdata[0],
+ },
+ .num_resources = ARRAY_SIZE(au1100_mmc0_resources),
+ .resource = au1100_mmc0_resources,
+};
+
+static struct resource au1100_mmc1_res[] = {
+ [0] = {
+ .start = AU1100_SD1_PHYS_ADDR,
+ .end = AU1100_SD1_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1100_SD_INT,
+ .end = AU1100_SD_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = DMA_ID_SD1_TX,
+ .end = DMA_ID_SD1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = DMA_ID_SD1_RX,
+ .end = DMA_ID_SD1_RX,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+static struct platform_device db1100_mmc1_dev = {
+ .name = "au1xxx-mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &au1xxx_mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &db1100_mmc_platdata[1],
+ },
+ .num_resources = ARRAY_SIZE(au1100_mmc1_res),
+ .resource = au1100_mmc1_res,
+};
+
+/******************************************************************************/
+
+static void db1000_irda_set_phy_mode(int mode)
+{
+ unsigned short mask = BCSR_RESETS_IRDA_MODE_MASK | BCSR_RESETS_FIR_SEL;
+
+ switch (mode) {
+ case AU1000_IRDA_PHY_MODE_OFF:
+ bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_OFF);
+ break;
+ case AU1000_IRDA_PHY_MODE_SIR:
+ bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_FULL);
+ break;
+ case AU1000_IRDA_PHY_MODE_FIR:
+ bcsr_mod(BCSR_RESETS, mask, BCSR_RESETS_IRDA_MODE_FULL |
+ BCSR_RESETS_FIR_SEL);
+ break;
+ }
+}
+
+static struct au1k_irda_platform_data db1000_irda_platdata = {
+ .set_phy_mode = db1000_irda_set_phy_mode,
+};
+
+static struct resource au1000_irda_res[] = {
+ [0] = {
+ .start = AU1000_IRDA_PHYS_ADDR,
+ .end = AU1000_IRDA_PHYS_ADDR + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1000_IRDA_TX_INT,
+ .end = AU1000_IRDA_TX_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1000_IRDA_RX_INT,
+ .end = AU1000_IRDA_RX_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device db1000_irda_dev = {
+ .name = "au1000-irda",
+ .id = -1,
+ .dev = {
+ .platform_data = &db1000_irda_platdata,
+ },
+ .resource = au1000_irda_res,
+ .num_resources = ARRAY_SIZE(au1000_irda_res),
+};
+
+/******************************************************************************/
+
+static struct ads7846_platform_data db1100_touch_pd = {
+ .model = 7846,
+ .vref_mv = 3300,
+ .gpio_pendown = 21,
+};
+
+static struct spi_gpio_platform_data db1100_spictl_pd = {
+ .sck = 209,
+ .mosi = 208,
+ .miso = 207,
+ .num_chipselect = 1,
+};
+
+static struct spi_board_info db1100_spi_info[] __initdata = {
+ [0] = {
+ .modalias = "ads7846",
+ .max_speed_hz = 3250000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = 0,
+ .irq = AU1100_GPIO21_INT,
+ .platform_data = &db1100_touch_pd,
+ .controller_data = (void *)210, /* for spi_gpio: CS# GPIO210 */
+ },
+};
+
+static struct platform_device db1100_spi_dev = {
+ .name = "spi_gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &db1100_spictl_pd,
+ },
+};
+
+
+static struct platform_device *db1x00_devs[] = {
+ &db1x00_codec_dev,
+ &alchemy_ac97c_dma_dev,
+ &alchemy_ac97c_dev,
+ &db1x00_audio_dev,
+};
+
+static struct platform_device *db1000_devs[] = {
+ &db1000_irda_dev,
+};
+
+static struct platform_device *db1100_devs[] = {
+ &au1100_lcd_device,
+ &db1100_mmc0_dev,
+ &db1100_mmc1_dev,
+ &db1000_irda_dev,
+ &db1100_spi_dev,
+};
+
+static int __init db1000_dev_init(void)
+{
+ int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
+ int c0, c1, d0, d1, s0, s1;
+ unsigned long pfc;
+
+ if (board == BCSR_WHOAMI_DB1500) {
+ c0 = AU1500_GPIO2_INT;
+ c1 = AU1500_GPIO5_INT;
+ d0 = AU1500_GPIO0_INT;
+ d1 = AU1500_GPIO3_INT;
+ s0 = AU1500_GPIO1_INT;
+ s1 = AU1500_GPIO4_INT;
+ } else if (board == BCSR_WHOAMI_DB1100) {
+ c0 = AU1100_GPIO2_INT;
+ c1 = AU1100_GPIO5_INT;
+ d0 = AU1100_GPIO0_INT;
+ d1 = AU1100_GPIO3_INT;
+ s0 = AU1100_GPIO1_INT;
+ s1 = AU1100_GPIO4_INT;
+
+ gpio_direction_input(19); /* sd0 cd# */
+ gpio_direction_input(20); /* sd1 cd# */
+ gpio_direction_input(21); /* touch pendown# */
+ gpio_direction_input(207); /* SPI MISO */
+ gpio_direction_output(208, 0); /* SPI MOSI */
+ gpio_direction_output(209, 1); /* SPI SCK */
+ gpio_direction_output(210, 1); /* SPI CS# */
+
+ /* spi_gpio on SSI0 pins */
+ pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
+ pfc |= (1 << 0); /* SSI0 pins as GPIOs */
+ __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
+ wmb();
+
+ spi_register_board_info(db1100_spi_info,
+ ARRAY_SIZE(db1100_spi_info));
+
+ platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs));
+ } else if (board == BCSR_WHOAMI_DB1000) {
+ c0 = AU1000_GPIO2_INT;
+ c1 = AU1000_GPIO5_INT;
+ d0 = AU1000_GPIO0_INT;
+ d1 = AU1000_GPIO3_INT;
+ s0 = AU1000_GPIO1_INT;
+ s1 = AU1000_GPIO4_INT;
+ platform_add_devices(db1000_devs, ARRAY_SIZE(db1000_devs));
+ } else
+ return 0; /* unknown board, no further dev setup to do */
+
+ irq_set_irq_type(d0, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(d1, IRQ_TYPE_EDGE_BOTH);
+ irq_set_irq_type(c0, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(c1, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(s0, IRQ_TYPE_LEVEL_LOW);
+ irq_set_irq_type(s1, IRQ_TYPE_LEVEL_LOW);
+
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ c0, d0, /*s0*/0, 0, 0);
+
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
+ c1, d1, /*s1*/0, 0, 1);
+
+ platform_add_devices(db1x00_devs, ARRAY_SIZE(db1x00_devs));
+ db1x_register_norflash(32 << 20, 4 /* 32bit */, F_SWAPPED);
+ return 0;
+}
+device_initcall(db1000_dev_init);
diff --git a/arch/mips/alchemy/devboards/db1200/platform.c b/arch/mips/alchemy/devboards/db1200.c
index c61867c93c4a..a83302b96c01 100644
--- a/arch/mips/alchemy/devboards/db1200/platform.c
+++ b/arch/mips/alchemy/devboards/db1200.c
@@ -1,7 +1,7 @@
/*
- * DBAu1200 board platform device registration
+ * DBAu1200/PBAu1200 board platform device registration
*
- * Copyright (C) 2008-2009 Manuel Lauss
+ * Copyright (C) 2008-2011 Manuel Lauss
*
* 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
@@ -22,6 +22,7 @@
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/leds.h>
#include <linux/mmc/host.h>
@@ -33,18 +34,116 @@
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/smc91x.h>
-
+#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1100_mmc.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1200fb.h>
#include <asm/mach-au1x00/au1550_spi.h>
#include <asm/mach-db1x00/bcsr.h>
#include <asm/mach-db1x00/db1200.h>
-#include "../platform.h"
+#include "platform.h"
+
+static const char *board_type_str(void)
+{
+ switch (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
+ case BCSR_WHOAMI_PB1200_DDR1:
+ case BCSR_WHOAMI_PB1200_DDR2:
+ return "PB1200";
+ case BCSR_WHOAMI_DB1200:
+ return "DB1200";
+ default:
+ return "(unknown)";
+ }
+}
+
+const char *get_system_type(void)
+{
+ return board_type_str();
+}
+
+static int __init detect_board(void)
+{
+ int bid;
+
+ /* try the DB1200 first */
+ bcsr_init(DB1200_BCSR_PHYS_ADDR,
+ DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
+ if (BCSR_WHOAMI_DB1200 == BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI))) {
+ unsigned short t = bcsr_read(BCSR_HEXLEDS);
+ bcsr_write(BCSR_HEXLEDS, ~t);
+ if (bcsr_read(BCSR_HEXLEDS) != t) {
+ bcsr_write(BCSR_HEXLEDS, t);
+ return 0;
+ }
+ }
+
+ /* okay, try the PB1200 then */
+ bcsr_init(PB1200_BCSR_PHYS_ADDR,
+ PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
+ bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
+ if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
+ (bid == BCSR_WHOAMI_PB1200_DDR2)) {
+ unsigned short t = bcsr_read(BCSR_HEXLEDS);
+ bcsr_write(BCSR_HEXLEDS, ~t);
+ if (bcsr_read(BCSR_HEXLEDS) != t) {
+ bcsr_write(BCSR_HEXLEDS, t);
+ return 0;
+ }
+ }
+
+ return 1; /* it's neither */
+}
+
+void __init board_setup(void)
+{
+ unsigned long freq0, clksrc, div, pfc;
+ unsigned short whoami;
+
+ if (detect_board()) {
+ printk(KERN_ERR "NOT running on a DB1200/PB1200 board!\n");
+ return;
+ }
+
+ whoami = bcsr_read(BCSR_WHOAMI);
+ printk(KERN_INFO "Alchemy/AMD/RMI %s Board, CPLD Rev %d"
+ " Board-ID %d Daughtercard ID %d\n", board_type_str(),
+ (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
+
+ /* SMBus/SPI on PSC0, Audio on PSC1 */
+ pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
+ pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
+ pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
+ pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
+ __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
+ wmb();
+
+ /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
+ * CPU clock; all other clock generators off/unused.
+ */
+ div = (get_au1x00_speed() + 25000000) / 50000000;
+ if (div & 1)
+ div++;
+ div = ((div >> 1) - 1) & 0xff;
+
+ freq0 = div << SYS_FC_FRDIV0_BIT;
+ __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
+ wmb();
+ freq0 |= SYS_FC_FE0; /* enable F0 */
+ __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
+ wmb();
+
+ /* psc0_intclk comes 1:1 from F0 */
+ clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
+ __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
+ wmb();
+}
+
+/******************************************************************************/
static struct mtd_partition db1200_spiflash_parts[] = {
{
- .name = "DB1200 SPI flash",
+ .name = "spi_flash",
.offset = 0,
.size = MTDPART_SIZ_FULL,
},
@@ -78,18 +177,9 @@ static struct spi_board_info db1200_spi_devs[] __initdata = {
};
static struct i2c_board_info db1200_i2c_devs[] __initdata = {
- {
- /* AT24C04-10 I2C eeprom */
- I2C_BOARD_INFO("24c04", 0x52),
- },
- {
- /* Philips NE1619 temp/voltage sensor (adm1025 drv) */
- I2C_BOARD_INFO("ne1619", 0x2d),
- },
- {
- /* I2S audio codec WM8731 */
- I2C_BOARD_INFO("wm8731", 0x1b),
- },
+ { I2C_BOARD_INFO("24c04", 0x52), }, /* AT24C04-10 I2C eeprom */
+ { I2C_BOARD_INFO("ne1619", 0x2d), }, /* adm1025-compat hwmon */
+ { I2C_BOARD_INFO("wm8731", 0x1b), }, /* I2S audio codec WM8731 */
};
/**********************************************************************/
@@ -206,7 +296,7 @@ static struct platform_device db1200_eth_dev = {
static struct resource db1200_ide_res[] = {
[0] = {
.start = DB1200_IDE_PHYS_ADDR,
- .end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
+ .end = DB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1,
.flags = IORESOURCE_MEM,
},
[1] = {
@@ -221,13 +311,13 @@ static struct resource db1200_ide_res[] = {
},
};
-static u64 ide_dmamask = DMA_BIT_MASK(32);
+static u64 au1200_ide_dmamask = DMA_BIT_MASK(32);
static struct platform_device db1200_ide_dev = {
.name = "au1200-ide",
.id = 0,
.dev = {
- .dma_mask = &ide_dmamask,
+ .dma_mask = &au1200_ide_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
},
.num_resources = ARRAY_SIZE(db1200_ide_res),
@@ -236,13 +326,6 @@ static struct platform_device db1200_ide_dev = {
/**********************************************************************/
-static struct platform_device db1200_rtc_dev = {
- .name = "rtc-au1xxx",
- .id = -1,
-};
-
-/**********************************************************************/
-
/* SD carddetects: they're supposed to be edge-triggered, but ack
* doesn't seem to work (CPLD Rev 2). Instead, the screaming one
* is disabled and its counterpart enabled. The 500ms timeout is
@@ -276,12 +359,12 @@ static int db1200_mmc_cd_setup(void *mmc_host, int en)
if (en) {
ret = request_irq(DB1200_SD0_INSERT_INT, db1200_mmc_cd,
- IRQF_DISABLED, "sd_insert", mmc_host);
+ 0, "sd_insert", mmc_host);
if (ret)
goto out;
ret = request_irq(DB1200_SD0_EJECT_INT, db1200_mmc_cd,
- IRQF_DISABLED, "sd_eject", mmc_host);
+ 0, "sd_eject", mmc_host);
if (ret) {
free_irq(DB1200_SD0_INSERT_INT, mmc_host);
goto out;
@@ -333,12 +416,109 @@ static struct led_classdev db1200_mmc_led = {
.brightness_set = db1200_mmcled_set,
};
-static struct au1xmmc_platform_data db1200mmc_platdata = {
- .cd_setup = db1200_mmc_cd_setup,
- .set_power = db1200_mmc_set_power,
- .card_inserted = db1200_mmc_card_inserted,
- .card_readonly = db1200_mmc_card_readonly,
- .led = &db1200_mmc_led,
+/* -- */
+
+static irqreturn_t pb1200_mmc1_cd(int irq, void *ptr)
+{
+ void(*mmc_cd)(struct mmc_host *, unsigned long);
+
+ if (irq == PB1200_SD1_INSERT_INT) {
+ disable_irq_nosync(PB1200_SD1_INSERT_INT);
+ enable_irq(PB1200_SD1_EJECT_INT);
+ } else {
+ disable_irq_nosync(PB1200_SD1_EJECT_INT);
+ enable_irq(PB1200_SD1_INSERT_INT);
+ }
+
+ /* link against CONFIG_MMC=m */
+ mmc_cd = symbol_get(mmc_detect_change);
+ if (mmc_cd) {
+ mmc_cd(ptr, msecs_to_jiffies(500));
+ symbol_put(mmc_detect_change);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int pb1200_mmc1_cd_setup(void *mmc_host, int en)
+{
+ int ret;
+
+ if (en) {
+ ret = request_irq(PB1200_SD1_INSERT_INT, pb1200_mmc1_cd, 0,
+ "sd1_insert", mmc_host);
+ if (ret)
+ goto out;
+
+ ret = request_irq(PB1200_SD1_EJECT_INT, pb1200_mmc1_cd, 0,
+ "sd1_eject", mmc_host);
+ if (ret) {
+ free_irq(PB1200_SD1_INSERT_INT, mmc_host);
+ goto out;
+ }
+
+ if (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT)
+ enable_irq(PB1200_SD1_EJECT_INT);
+ else
+ enable_irq(PB1200_SD1_INSERT_INT);
+
+ } else {
+ free_irq(PB1200_SD1_INSERT_INT, mmc_host);
+ free_irq(PB1200_SD1_EJECT_INT, mmc_host);
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+static void pb1200_mmc1led_set(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ if (brightness != LED_OFF)
+ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
+ else
+ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
+}
+
+static struct led_classdev pb1200_mmc1_led = {
+ .brightness_set = pb1200_mmc1led_set,
+};
+
+static void pb1200_mmc1_set_power(void *mmc_host, int state)
+{
+ if (state) {
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
+ msleep(400); /* stabilization time */
+ } else
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
+}
+
+static int pb1200_mmc1_card_readonly(void *mmc_host)
+{
+ return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
+}
+
+static int pb1200_mmc1_card_inserted(void *mmc_host)
+{
+ return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
+}
+
+
+static struct au1xmmc_platform_data db1200_mmc_platdata[2] = {
+ [0] = {
+ .cd_setup = db1200_mmc_cd_setup,
+ .set_power = db1200_mmc_set_power,
+ .card_inserted = db1200_mmc_card_inserted,
+ .card_readonly = db1200_mmc_card_readonly,
+ .led = &db1200_mmc_led,
+ },
+ [1] = {
+ .cd_setup = pb1200_mmc1_cd_setup,
+ .set_power = pb1200_mmc1_set_power,
+ .card_inserted = pb1200_mmc1_card_inserted,
+ .card_readonly = pb1200_mmc1_card_readonly,
+ .led = &pb1200_mmc1_led,
+ },
};
static struct resource au1200_mmc0_resources[] = {
@@ -372,14 +552,76 @@ static struct platform_device db1200_mmc0_dev = {
.dev = {
.dma_mask = &au1xxx_mmc_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &db1200mmc_platdata,
+ .platform_data = &db1200_mmc_platdata[0],
},
.num_resources = ARRAY_SIZE(au1200_mmc0_resources),
.resource = au1200_mmc0_resources,
};
+static struct resource au1200_mmc1_res[] = {
+ [0] = {
+ .start = AU1100_SD1_PHYS_ADDR,
+ .end = AU1100_SD1_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1200_SD_INT,
+ .end = AU1200_SD_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1200_DSCR_CMD0_SDMS_TX1,
+ .end = AU1200_DSCR_CMD0_SDMS_TX1,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1200_DSCR_CMD0_SDMS_RX1,
+ .end = AU1200_DSCR_CMD0_SDMS_RX1,
+ .flags = IORESOURCE_DMA,
+ }
+};
+
+static struct platform_device pb1200_mmc1_dev = {
+ .name = "au1xxx-mmc",
+ .id = 1,
+ .dev = {
+ .dma_mask = &au1xxx_mmc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &db1200_mmc_platdata[1],
+ },
+ .num_resources = ARRAY_SIZE(au1200_mmc1_res),
+ .resource = au1200_mmc1_res,
+};
+
/**********************************************************************/
+static int db1200fb_panel_index(void)
+{
+ return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
+}
+
+static int db1200fb_panel_init(void)
+{
+ /* Apply power */
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+ BCSR_BOARD_LCDBL);
+ return 0;
+}
+
+static int db1200fb_panel_shutdown(void)
+{
+ /* Remove power */
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
+ BCSR_BOARD_LCDBL, 0);
+ return 0;
+}
+
+static struct au1200fb_platdata db1200fb_pd = {
+ .panel_index = db1200fb_panel_index,
+ .panel_init = db1200fb_panel_init,
+ .panel_shutdown = db1200fb_panel_shutdown,
+};
+
static struct resource au1200_lcd_res[] = {
[0] = {
.start = AU1200_LCD_PHYS_ADDR,
@@ -401,6 +643,7 @@ static struct platform_device au1200_lcd_dev = {
.dev = {
.dma_mask = &au1200_lcd_dmamask,
.coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &db1200fb_pd,
},
.num_resources = ARRAY_SIZE(au1200_lcd_res),
.resource = au1200_lcd_res,
@@ -519,7 +762,6 @@ static struct platform_device *db1200_devs[] __initdata = {
&db1200_mmc0_dev,
&au1200_lcd_dev,
&db1200_eth_dev,
- &db1200_rtc_dev,
&db1200_nand_dev,
&db1200_audiodma_dev,
&db1200_audio_dev,
@@ -527,11 +769,62 @@ static struct platform_device *db1200_devs[] __initdata = {
&db1200_sound_dev,
};
+static struct platform_device *pb1200_devs[] __initdata = {
+ &pb1200_mmc1_dev,
+};
+
+/* Some peripheral base addresses differ on the PB1200 */
+static int __init pb1200_res_fixup(void)
+{
+ /* CPLD Revs earlier than 4 cause problems */
+ if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "PB1200 must be at CPLD rev 4. Please have\n");
+ printk(KERN_ERR "the board updated to latest revisions.\n");
+ printk(KERN_ERR "This software will not work reliably\n");
+ printk(KERN_ERR "on anything older than CPLD rev 4.!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ printk(KERN_ERR "WARNING!!!\n");
+ return 1;
+ }
+
+ db1200_nand_res[0].start = PB1200_NAND_PHYS_ADDR;
+ db1200_nand_res[0].end = PB1200_NAND_PHYS_ADDR + 0xff;
+ db1200_ide_res[0].start = PB1200_IDE_PHYS_ADDR;
+ db1200_ide_res[0].end = PB1200_IDE_PHYS_ADDR + DB1200_IDE_PHYS_LEN - 1;
+ db1200_eth_res[0].start = PB1200_ETH_PHYS_ADDR;
+ db1200_eth_res[0].end = PB1200_ETH_PHYS_ADDR + 0xff;
+ return 0;
+}
+
static int __init db1200_dev_init(void)
{
unsigned long pfc;
unsigned short sw;
- int swapped;
+ int swapped, bid;
+
+ bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI));
+ if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
+ (bid == BCSR_WHOAMI_PB1200_DDR2)) {
+ if (pb1200_res_fixup())
+ return -ENODEV;
+ }
+
+ /* GPIO7 is low-level triggered CPLD cascade */
+ irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW);
+ bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
+
+ /* insert/eject pairs: one of both is always screaming. To avoid
+ * issues they must not be automatically enabled when initially
+ * requested.
+ */
+ irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN);
i2c_register_board_info(0, db1200_i2c_devs,
ARRAY_SIZE(db1200_i2c_devs));
@@ -540,6 +833,7 @@ static int __init db1200_dev_init(void)
/* SWITCHES: S6.8 I2C/SPI selector (OFF=I2C ON=SPI)
* S6.7 AC97/I2S selector (OFF=AC97 ON=I2S)
+ * or S12 on the PB1200.
*/
/* NOTE: GPIO215 controls OTG VBUS supply. In SPI mode however
@@ -554,7 +848,7 @@ static int __init db1200_dev_init(void)
gpio_request(215, "otg-vbus");
gpio_direction_output(215, 1);
- printk(KERN_INFO "DB1200 device configuration:\n");
+ printk(KERN_INFO "%s device configuration:\n", board_type_str());
sw = bcsr_read(BCSR_SWITCHES);
if (sw & BCSR_SWITCHES_DIP_8) {
@@ -595,7 +889,7 @@ static int __init db1200_dev_init(void)
/* Audio PSC clock is supplied externally. (FIXME: platdata!!) */
__raw_writel(PSC_SEL_CLK_SERCLK,
- (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
+ (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
wmb();
db1x_register_pcmcia_socket(
@@ -621,28 +915,13 @@ static int __init db1200_dev_init(void)
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
db1x_register_norflash(64 << 20, 2, swapped);
- return platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
-}
-device_initcall(db1200_dev_init);
-
-/* au1200fb calls these: STERBT EINEN TRAGISCHEN TOD!!! */
-int board_au1200fb_panel(void)
-{
- return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
-}
+ platform_add_devices(db1200_devs, ARRAY_SIZE(db1200_devs));
-int board_au1200fb_panel_init(void)
-{
- /* Apply power */
- bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
- BCSR_BOARD_LCDBL);
- return 0;
-}
+ /* PB1200 is a DB1200 with a 2nd MMC and Camera connector */
+ if ((bid == BCSR_WHOAMI_PB1200_DDR1) ||
+ (bid == BCSR_WHOAMI_PB1200_DDR2))
+ platform_add_devices(pb1200_devs, ARRAY_SIZE(pb1200_devs));
-int board_au1200fb_panel_shutdown(void)
-{
- /* Remove power */
- bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
- BCSR_BOARD_LCDBL, 0);
return 0;
}
+device_initcall(db1200_dev_init);
diff --git a/arch/mips/alchemy/devboards/db1200/Makefile b/arch/mips/alchemy/devboards/db1200/Makefile
deleted file mode 100644
index 17840a5e2738..000000000000
--- a/arch/mips/alchemy/devboards/db1200/Makefile
+++ /dev/null
@@ -1 +0,0 @@
-obj-y += setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/db1200/setup.c b/arch/mips/alchemy/devboards/db1200/setup.c
deleted file mode 100644
index 4a8980027ecf..000000000000
--- a/arch/mips/alchemy/devboards/db1200/setup.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Alchemy/AMD/RMI DB1200 board setup.
- *
- * Licensed under the terms outlined in the file COPYING in the root of
- * this source archive.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/bcsr.h>
-#include <asm/mach-db1x00/db1200.h>
-
-const char *get_system_type(void)
-{
- return "Alchemy Db1200";
-}
-
-void __init board_setup(void)
-{
- unsigned long freq0, clksrc, div, pfc;
- unsigned short whoami;
-
- bcsr_init(DB1200_BCSR_PHYS_ADDR,
- DB1200_BCSR_PHYS_ADDR + DB1200_BCSR_HEXLED_OFS);
-
- whoami = bcsr_read(BCSR_WHOAMI);
- printk(KERN_INFO "Alchemy/AMD/RMI DB1200 Board, CPLD Rev %d"
- " Board-ID %d Daughtercard ID %d\n",
- (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
-
- /* SMBus/SPI on PSC0, Audio on PSC1 */
- pfc = __raw_readl((void __iomem *)SYS_PINFUNC);
- pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
- pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3);
- pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */
- __raw_writel(pfc, (void __iomem *)SYS_PINFUNC);
- wmb();
-
- /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from
- * CPU clock; all other clock generators off/unused.
- */
- div = (get_au1x00_speed() + 25000000) / 50000000;
- if (div & 1)
- div++;
- div = ((div >> 1) - 1) & 0xff;
-
- freq0 = div << SYS_FC_FRDIV0_BIT;
- __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
- wmb();
- freq0 |= SYS_FC_FE0; /* enable F0 */
- __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0);
- wmb();
-
- /* psc0_intclk comes 1:1 from F0 */
- clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT;
- __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC);
- wmb();
-}
-
-static int __init db1200_arch_init(void)
-{
- /* GPIO7 is low-level triggered CPLD cascade */
- irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
- bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT);
-
- /* insert/eject pairs: one of both is always screaming. To avoid
- * issues they must not be automatically enabled when initially
- * requested.
- */
- irq_set_status_flags(DB1200_SD0_INSERT_INT, IRQ_NOAUTOEN);
- irq_set_status_flags(DB1200_SD0_EJECT_INT, IRQ_NOAUTOEN);
- irq_set_status_flags(DB1200_PC0_INSERT_INT, IRQ_NOAUTOEN);
- irq_set_status_flags(DB1200_PC0_EJECT_INT, IRQ_NOAUTOEN);
- irq_set_status_flags(DB1200_PC1_INSERT_INT, IRQ_NOAUTOEN);
- irq_set_status_flags(DB1200_PC1_EJECT_INT, IRQ_NOAUTOEN);
- return 0;
-}
-arch_initcall(db1200_arch_init);
diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c
new file mode 100644
index 000000000000..0893f2af0d01
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1300.c
@@ -0,0 +1,785 @@
+/*
+ * DBAu1300 init and platform device setup.
+ *
+ * (c) 2009 Manuel Lauss <manuel.lauss@googlemail.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/init.h>
+#include <linux/input.h> /* KEY_* codes */
+#include <linux/i2c.h>
+#include <linux/io.h>
+#include <linux/leds.h>
+#include <linux/ata_platform.h>
+#include <linux/mmc/host.h>
+#include <linux/module.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/smsc911x.h>
+
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1100_mmc.h>
+#include <asm/mach-au1x00/au1200fb.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+#include <asm/mach-db1x00/db1300.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <asm/mach-au1x00/prom.h>
+
+#include "platform.h"
+
+static struct i2c_board_info db1300_i2c_devs[] __initdata = {
+ { I2C_BOARD_INFO("wm8731", 0x1b), }, /* I2S audio codec */
+ { I2C_BOARD_INFO("ne1619", 0x2d), }, /* adm1025-compat hwmon */
+};
+
+/* multifunction pins to assign to GPIO controller */
+static int db1300_gpio_pins[] __initdata = {
+ AU1300_PIN_LCDPWM0, AU1300_PIN_PSC2SYNC1, AU1300_PIN_WAKE1,
+ AU1300_PIN_WAKE2, AU1300_PIN_WAKE3, AU1300_PIN_FG3AUX,
+ AU1300_PIN_EXTCLK1,
+ -1, /* terminator */
+};
+
+/* multifunction pins to assign to device functions */
+static int db1300_dev_pins[] __initdata = {
+ /* wake-from-str pins 0-3 */
+ AU1300_PIN_WAKE0,
+ /* external clock sources for PSC0 */
+ AU1300_PIN_EXTCLK0,
+ /* 8bit MMC interface on SD0: 6-9 */
+ AU1300_PIN_SD0DAT4, AU1300_PIN_SD0DAT5, AU1300_PIN_SD0DAT6,
+ AU1300_PIN_SD0DAT7,
+ /* UART1 pins: 11-18 */
+ AU1300_PIN_U1RI, AU1300_PIN_U1DCD, AU1300_PIN_U1DSR,
+ AU1300_PIN_U1CTS, AU1300_PIN_U1RTS, AU1300_PIN_U1DTR,
+ AU1300_PIN_U1RX, AU1300_PIN_U1TX,
+ /* UART0 pins: 19-24 */
+ AU1300_PIN_U0RI, AU1300_PIN_U0DCD, AU1300_PIN_U0DSR,
+ AU1300_PIN_U0CTS, AU1300_PIN_U0RTS, AU1300_PIN_U0DTR,
+ /* UART2: 25-26 */
+ AU1300_PIN_U2RX, AU1300_PIN_U2TX,
+ /* UART3: 27-28 */
+ AU1300_PIN_U3RX, AU1300_PIN_U3TX,
+ /* LCD controller PWMs, ext pixclock: 30-31 */
+ AU1300_PIN_LCDPWM1, AU1300_PIN_LCDCLKIN,
+ /* SD1 interface: 32-37 */
+ AU1300_PIN_SD1DAT0, AU1300_PIN_SD1DAT1, AU1300_PIN_SD1DAT2,
+ AU1300_PIN_SD1DAT3, AU1300_PIN_SD1CMD, AU1300_PIN_SD1CLK,
+ /* SD2 interface: 38-43 */
+ AU1300_PIN_SD2DAT0, AU1300_PIN_SD2DAT1, AU1300_PIN_SD2DAT2,
+ AU1300_PIN_SD2DAT3, AU1300_PIN_SD2CMD, AU1300_PIN_SD2CLK,
+ /* PSC0/1 clocks: 44-45 */
+ AU1300_PIN_PSC0CLK, AU1300_PIN_PSC1CLK,
+ /* PSCs: 46-49/50-53/54-57/58-61 */
+ AU1300_PIN_PSC0SYNC0, AU1300_PIN_PSC0SYNC1, AU1300_PIN_PSC0D0,
+ AU1300_PIN_PSC0D1,
+ AU1300_PIN_PSC1SYNC0, AU1300_PIN_PSC1SYNC1, AU1300_PIN_PSC1D0,
+ AU1300_PIN_PSC1D1,
+ AU1300_PIN_PSC2SYNC0, AU1300_PIN_PSC2D0,
+ AU1300_PIN_PSC2D1,
+ AU1300_PIN_PSC3SYNC0, AU1300_PIN_PSC3SYNC1, AU1300_PIN_PSC3D0,
+ AU1300_PIN_PSC3D1,
+ /* PCMCIA interface: 62-70 */
+ AU1300_PIN_PCE2, AU1300_PIN_PCE1, AU1300_PIN_PIOS16,
+ AU1300_PIN_PIOR, AU1300_PIN_PWE, AU1300_PIN_PWAIT,
+ AU1300_PIN_PREG, AU1300_PIN_POE, AU1300_PIN_PIOW,
+ /* camera interface H/V sync inputs: 71-72 */
+ AU1300_PIN_CIMLS, AU1300_PIN_CIMFS,
+ /* PSC2/3 clocks: 73-74 */
+ AU1300_PIN_PSC2CLK, AU1300_PIN_PSC3CLK,
+ -1, /* terminator */
+};
+
+static void __init db1300_gpio_config(void)
+{
+ int *i;
+
+ i = &db1300_dev_pins[0];
+ while (*i != -1)
+ au1300_pinfunc_to_dev(*i++);
+
+ i = &db1300_gpio_pins[0];
+ while (*i != -1)
+ au1300_gpio_direction_input(*i++);/* implies pin_to_gpio */
+
+ au1300_set_dbdma_gpio(1, AU1300_PIN_FG3AUX);
+}
+
+char *get_system_type(void)
+{
+ return "DB1300";
+}
+
+/**********************************************************************/
+
+static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
+
+ ioaddr &= 0xffffff00;
+
+ if (ctrl & NAND_CLE) {
+ ioaddr += MEM_STNAND_CMD;
+ } else if (ctrl & NAND_ALE) {
+ ioaddr += MEM_STNAND_ADDR;
+ } else {
+ /* assume we want to r/w real data by default */
+ ioaddr += MEM_STNAND_DATA;
+ }
+ this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
+ if (cmd != NAND_CMD_NONE) {
+ __raw_writeb(cmd, this->IO_ADDR_W);
+ wmb();
+ }
+}
+
+static int au1300_nand_device_ready(struct mtd_info *mtd)
+{
+ return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
+}
+
+static const char *db1300_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition db1300_nand_parts[] = {
+ {
+ .name = "NAND FS 0",
+ .offset = 0,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "NAND FS 1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+struct platform_nand_data db1300_nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(db1300_nand_parts),
+ .partitions = db1300_nand_parts,
+ .chip_delay = 20,
+ .part_probe_types = db1300_part_probes,
+ },
+ .ctrl = {
+ .dev_ready = au1300_nand_device_ready,
+ .cmd_ctrl = au1300_nand_cmd_ctrl,
+ },
+};
+
+static struct resource db1300_nand_res[] = {
+ [0] = {
+ .start = DB1300_NAND_PHYS_ADDR,
+ .end = DB1300_NAND_PHYS_ADDR + 0xff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device db1300_nand_dev = {
+ .name = "gen_nand",
+ .num_resources = ARRAY_SIZE(db1300_nand_res),
+ .resource = db1300_nand_res,
+ .id = -1,
+ .dev = {
+ .platform_data = &db1300_nand_platdata,
+ }
+};
+
+/**********************************************************************/
+
+static struct resource db1300_eth_res[] = {
+ [0] = {
+ .start = DB1300_ETH_PHYS_ADDR,
+ .end = DB1300_ETH_PHYS_END,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DB1300_ETH_INT,
+ .end = DB1300_ETH_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smsc911x_platform_config db1300_eth_config = {
+ .phy_interface = PHY_INTERFACE_MODE_MII,
+ .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+ .irq_type = SMSC911X_IRQ_TYPE_PUSH_PULL,
+ .flags = SMSC911X_USE_32BIT,
+};
+
+static struct platform_device db1300_eth_dev = {
+ .name = "smsc911x",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(db1300_eth_res),
+ .resource = db1300_eth_res,
+ .dev = {
+ .platform_data = &db1300_eth_config,
+ },
+};
+
+/**********************************************************************/
+
+static struct resource au1300_psc1_res[] = {
+ [0] = {
+ .start = AU1300_PSC1_PHYS_ADDR,
+ .end = AU1300_PSC1_PHYS_ADDR + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1300_PSC1_INT,
+ .end = AU1300_PSC1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1300_DSCR_CMD0_PSC1_TX,
+ .end = AU1300_DSCR_CMD0_PSC1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1300_DSCR_CMD0_PSC1_RX,
+ .end = AU1300_DSCR_CMD0_PSC1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1300_ac97_dev = {
+ .name = "au1xpsc_ac97",
+ .id = 1, /* PSC ID. match with AC97 codec ID! */
+ .num_resources = ARRAY_SIZE(au1300_psc1_res),
+ .resource = au1300_psc1_res,
+};
+
+/**********************************************************************/
+
+static struct resource au1300_psc2_res[] = {
+ [0] = {
+ .start = AU1300_PSC2_PHYS_ADDR,
+ .end = AU1300_PSC2_PHYS_ADDR + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1300_PSC2_INT,
+ .end = AU1300_PSC2_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1300_DSCR_CMD0_PSC2_TX,
+ .end = AU1300_DSCR_CMD0_PSC2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1300_DSCR_CMD0_PSC2_RX,
+ .end = AU1300_DSCR_CMD0_PSC2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1300_i2s_dev = {
+ .name = "au1xpsc_i2s",
+ .id = 2, /* PSC ID */
+ .num_resources = ARRAY_SIZE(au1300_psc2_res),
+ .resource = au1300_psc2_res,
+};
+
+/**********************************************************************/
+
+static struct resource au1300_psc3_res[] = {
+ [0] = {
+ .start = AU1300_PSC3_PHYS_ADDR,
+ .end = AU1300_PSC3_PHYS_ADDR + 0x0fff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1300_PSC3_INT,
+ .end = AU1300_PSC3_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1300_DSCR_CMD0_PSC3_TX,
+ .end = AU1300_DSCR_CMD0_PSC3_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1300_DSCR_CMD0_PSC3_RX,
+ .end = AU1300_DSCR_CMD0_PSC3_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1300_i2c_dev = {
+ .name = "au1xpsc_smbus",
+ .id = 0, /* bus number */
+ .num_resources = ARRAY_SIZE(au1300_psc3_res),
+ .resource = au1300_psc3_res,
+};
+
+/**********************************************************************/
+
+/* proper key assignments when facing the LCD panel. For key assignments
+ * according to the schematics swap up with down and left with right.
+ * I chose to use it to emulate the arrow keys of a keyboard.
+ */
+static struct gpio_keys_button db1300_5waysw_arrowkeys[] = {
+ {
+ .code = KEY_DOWN,
+ .gpio = AU1300_PIN_LCDPWM0,
+ .type = EV_KEY,
+ .debounce_interval = 1,
+ .active_low = 1,
+ .desc = "5waysw-down",
+ },
+ {
+ .code = KEY_UP,
+ .gpio = AU1300_PIN_PSC2SYNC1,
+ .type = EV_KEY,
+ .debounce_interval = 1,
+ .active_low = 1,
+ .desc = "5waysw-up",
+ },
+ {
+ .code = KEY_RIGHT,
+ .gpio = AU1300_PIN_WAKE3,
+ .type = EV_KEY,
+ .debounce_interval = 1,
+ .active_low = 1,
+ .desc = "5waysw-right",
+ },
+ {
+ .code = KEY_LEFT,
+ .gpio = AU1300_PIN_WAKE2,
+ .type = EV_KEY,
+ .debounce_interval = 1,
+ .active_low = 1,
+ .desc = "5waysw-left",
+ },
+ {
+ .code = KEY_ENTER,
+ .gpio = AU1300_PIN_WAKE1,
+ .type = EV_KEY,
+ .debounce_interval = 1,
+ .active_low = 1,
+ .desc = "5waysw-push",
+ },
+};
+
+static struct gpio_keys_platform_data db1300_5waysw_data = {
+ .buttons = db1300_5waysw_arrowkeys,
+ .nbuttons = ARRAY_SIZE(db1300_5waysw_arrowkeys),
+ .rep = 1,
+ .name = "db1300-5wayswitch",
+};
+
+static struct platform_device db1300_5waysw_dev = {
+ .name = "gpio-keys",
+ .dev = {
+ .platform_data = &db1300_5waysw_data,
+ },
+};
+
+/**********************************************************************/
+
+static struct pata_platform_info db1300_ide_info = {
+ .ioport_shift = DB1300_IDE_REG_SHIFT,
+};
+
+#define IDE_ALT_START (14 << DB1300_IDE_REG_SHIFT)
+static struct resource db1300_ide_res[] = {
+ [0] = {
+ .start = DB1300_IDE_PHYS_ADDR,
+ .end = DB1300_IDE_PHYS_ADDR + IDE_ALT_START - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = DB1300_IDE_PHYS_ADDR + IDE_ALT_START,
+ .end = DB1300_IDE_PHYS_ADDR + DB1300_IDE_PHYS_LEN - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = {
+ .start = DB1300_IDE_INT,
+ .end = DB1300_IDE_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device db1300_ide_dev = {
+ .dev = {
+ .platform_data = &db1300_ide_info,
+ },
+ .name = "pata_platform",
+ .resource = db1300_ide_res,
+ .num_resources = ARRAY_SIZE(db1300_ide_res),
+};
+
+/**********************************************************************/
+
+static irqreturn_t db1300_mmc_cd(int irq, void *ptr)
+{
+ void(*mmc_cd)(struct mmc_host *, unsigned long);
+
+ /* disable the one currently screaming. No other way to shut it up */
+ if (irq == DB1300_SD1_INSERT_INT) {
+ disable_irq_nosync(DB1300_SD1_INSERT_INT);
+ enable_irq(DB1300_SD1_EJECT_INT);
+ } else {
+ disable_irq_nosync(DB1300_SD1_EJECT_INT);
+ enable_irq(DB1300_SD1_INSERT_INT);
+ }
+
+ /* link against CONFIG_MMC=m. We can only be called once MMC core has
+ * initialized the controller, so symbol_get() should always succeed.
+ */
+ mmc_cd = symbol_get(mmc_detect_change);
+ mmc_cd(ptr, msecs_to_jiffies(500));
+ symbol_put(mmc_detect_change);
+
+ return IRQ_HANDLED;
+}
+
+static int db1300_mmc_card_readonly(void *mmc_host)
+{
+ /* it uses SD1 interface, but the DB1200's SD0 bit in the CPLD */
+ return bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP;
+}
+
+static int db1300_mmc_card_inserted(void *mmc_host)
+{
+ return bcsr_read(BCSR_SIGSTAT) & (1 << 12); /* insertion irq signal */
+}
+
+static int db1300_mmc_cd_setup(void *mmc_host, int en)
+{
+ int ret;
+
+ if (en) {
+ ret = request_irq(DB1300_SD1_INSERT_INT, db1300_mmc_cd, 0,
+ "sd_insert", mmc_host);
+ if (ret)
+ goto out;
+
+ ret = request_irq(DB1300_SD1_EJECT_INT, db1300_mmc_cd, 0,
+ "sd_eject", mmc_host);
+ if (ret) {
+ free_irq(DB1300_SD1_INSERT_INT, mmc_host);
+ goto out;
+ }
+
+ if (db1300_mmc_card_inserted(mmc_host))
+ enable_irq(DB1300_SD1_EJECT_INT);
+ else
+ enable_irq(DB1300_SD1_INSERT_INT);
+
+ } else {
+ free_irq(DB1300_SD1_INSERT_INT, mmc_host);
+ free_irq(DB1300_SD1_EJECT_INT, mmc_host);
+ }
+ ret = 0;
+out:
+ return ret;
+}
+
+static void db1300_mmcled_set(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ if (brightness != LED_OFF)
+ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
+ else
+ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
+}
+
+static struct led_classdev db1300_mmc_led = {
+ .brightness_set = db1300_mmcled_set,
+};
+
+struct au1xmmc_platform_data db1300_sd1_platdata = {
+ .cd_setup = db1300_mmc_cd_setup,
+ .card_inserted = db1300_mmc_card_inserted,
+ .card_readonly = db1300_mmc_card_readonly,
+ .led = &db1300_mmc_led,
+};
+
+static struct resource au1300_sd1_res[] = {
+ [0] = {
+ .start = AU1300_SD1_PHYS_ADDR,
+ .end = AU1300_SD1_PHYS_ADDR,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1300_SD1_INT,
+ .end = AU1300_SD1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1300_DSCR_CMD0_SDMS_TX1,
+ .end = AU1300_DSCR_CMD0_SDMS_TX1,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1300_DSCR_CMD0_SDMS_RX1,
+ .end = AU1300_DSCR_CMD0_SDMS_RX1,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1300_sd1_dev = {
+ .dev = {
+ .platform_data = &db1300_sd1_platdata,
+ },
+ .name = "au1xxx-mmc",
+ .id = 1,
+ .resource = au1300_sd1_res,
+ .num_resources = ARRAY_SIZE(au1300_sd1_res),
+};
+
+/**********************************************************************/
+
+static int db1300_movinand_inserted(void *mmc_host)
+{
+ return 0; /* disable for now, it doesn't work yet */
+}
+
+static int db1300_movinand_readonly(void *mmc_host)
+{
+ return 0;
+}
+
+static void db1300_movinand_led_set(struct led_classdev *led,
+ enum led_brightness brightness)
+{
+ if (brightness != LED_OFF)
+ bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED1, 0);
+ else
+ bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED1);
+}
+
+static struct led_classdev db1300_movinand_led = {
+ .brightness_set = db1300_movinand_led_set,
+};
+
+struct au1xmmc_platform_data db1300_sd0_platdata = {
+ .card_inserted = db1300_movinand_inserted,
+ .card_readonly = db1300_movinand_readonly,
+ .led = &db1300_movinand_led,
+ .mask_host_caps = MMC_CAP_NEEDS_POLL,
+};
+
+static struct resource au1300_sd0_res[] = {
+ [0] = {
+ .start = AU1100_SD0_PHYS_ADDR,
+ .end = AU1100_SD0_PHYS_ADDR,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1300_SD0_INT,
+ .end = AU1300_SD0_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1300_DSCR_CMD0_SDMS_TX0,
+ .end = AU1300_DSCR_CMD0_SDMS_TX0,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1300_DSCR_CMD0_SDMS_RX0,
+ .end = AU1300_DSCR_CMD0_SDMS_RX0,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1300_sd0_dev = {
+ .dev = {
+ .platform_data = &db1300_sd0_platdata,
+ },
+ .name = "au1xxx-mmc",
+ .id = 0,
+ .resource = au1300_sd0_res,
+ .num_resources = ARRAY_SIZE(au1300_sd0_res),
+};
+
+/**********************************************************************/
+
+static struct platform_device db1300_wm9715_dev = {
+ .name = "wm9712-codec",
+ .id = 1, /* ID of PSC for AC97 audio, see asoc glue! */
+};
+
+static struct platform_device db1300_ac97dma_dev = {
+ .name = "au1xpsc-pcm",
+ .id = 1, /* PSC ID */
+};
+
+static struct platform_device db1300_i2sdma_dev = {
+ .name = "au1xpsc-pcm",
+ .id = 2, /* PSC ID */
+};
+
+static struct platform_device db1300_sndac97_dev = {
+ .name = "db1300-ac97",
+};
+
+static struct platform_device db1300_sndi2s_dev = {
+ .name = "db1300-i2s",
+};
+
+/**********************************************************************/
+
+static int db1300fb_panel_index(void)
+{
+ return 9; /* DB1300_800x480 */
+}
+
+static int db1300fb_panel_init(void)
+{
+ /* Apply power (Vee/Vdd logic is inverted on Panel DB1300_800x480) */
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD,
+ BCSR_BOARD_LCDBL);
+ return 0;
+}
+
+static int db1300fb_panel_shutdown(void)
+{
+ /* Remove power (Vee/Vdd logic is inverted on Panel DB1300_800x480) */
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDBL,
+ BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD);
+ return 0;
+}
+
+static struct au1200fb_platdata db1300fb_pd = {
+ .panel_index = db1300fb_panel_index,
+ .panel_init = db1300fb_panel_init,
+ .panel_shutdown = db1300fb_panel_shutdown,
+};
+
+static struct resource au1300_lcd_res[] = {
+ [0] = {
+ .start = AU1200_LCD_PHYS_ADDR,
+ .end = AU1200_LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1300_LCD_INT,
+ .end = AU1300_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1300_lcd_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device db1300_lcd_dev = {
+ .name = "au1200-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1300_lcd_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &db1300fb_pd,
+ },
+ .num_resources = ARRAY_SIZE(au1300_lcd_res),
+ .resource = au1300_lcd_res,
+};
+
+/**********************************************************************/
+
+static struct platform_device *db1300_dev[] __initdata = {
+ &db1300_eth_dev,
+ &db1300_i2c_dev,
+ &db1300_5waysw_dev,
+ &db1300_nand_dev,
+ &db1300_ide_dev,
+ &db1300_sd0_dev,
+ &db1300_sd1_dev,
+ &db1300_lcd_dev,
+ &db1300_ac97_dev,
+ &db1300_i2s_dev,
+ &db1300_wm9715_dev,
+ &db1300_ac97dma_dev,
+ &db1300_i2sdma_dev,
+ &db1300_sndac97_dev,
+ &db1300_sndi2s_dev,
+};
+
+static int __init db1300_device_init(void)
+{
+ int swapped, cpldirq;
+
+ /* setup CPLD IRQ muxer */
+ cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1);
+ irq_set_irq_type(cpldirq, IRQ_TYPE_LEVEL_HIGH);
+ bcsr_init_irq(DB1300_FIRST_INT, DB1300_LAST_INT, cpldirq);
+
+ /* insert/eject IRQs: one always triggers so don't enable them
+ * when doing request_irq() on them. DB1200 has this bug too.
+ */
+ irq_set_status_flags(DB1300_SD1_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1300_SD1_EJECT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1300_CF_INSERT_INT, IRQ_NOAUTOEN);
+ irq_set_status_flags(DB1300_CF_EJECT_INT, IRQ_NOAUTOEN);
+
+ /*
+ * setup board
+ */
+ prom_get_ethernet_addr(&db1300_eth_config.mac[0]);
+
+ i2c_register_board_info(0, db1300_i2c_devs,
+ ARRAY_SIZE(db1300_i2c_devs));
+
+ /* Audio PSC clock is supplied by codecs (PSC1, 2) */
+ __raw_writel(PSC_SEL_CLK_SERCLK,
+ (void __iomem *)KSEG1ADDR(AU1300_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+ __raw_writel(PSC_SEL_CLK_SERCLK,
+ (void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+ /* I2C uses internal 48MHz EXTCLK1 */
+ __raw_writel(PSC_SEL_CLK_INTCLK,
+ (void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+
+ /* enable power to USB ports */
+ bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_USBHPWR | BCSR_RESETS_OTGPWR);
+
+ /* although it is socket #0, it uses the CPLD bits which previous boards
+ * have used for socket #1.
+ */
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x00400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x00400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x00010000 - 1,
+ DB1300_CF_INT, DB1300_CF_INSERT_INT, 0, DB1300_CF_EJECT_INT, 1);
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
+ db1x_register_norflash(64 << 20, 2, swapped);
+
+ return platform_add_devices(db1300_dev, ARRAY_SIZE(db1300_dev));
+}
+device_initcall(db1300_device_init);
+
+
+void __init board_setup(void)
+{
+ unsigned short whoami;
+
+ db1300_gpio_config();
+ bcsr_init(DB1300_BCSR_PHYS_ADDR,
+ DB1300_BCSR_PHYS_ADDR + DB1300_BCSR_HEXLED_OFS);
+
+ whoami = bcsr_read(BCSR_WHOAMI);
+ printk(KERN_INFO "NetLogic DBAu1300 Development Platform.\n\t"
+ "BoardID %d CPLD Rev %d DaughtercardID %d\n",
+ BCSR_WHOAMI_BOARD(whoami), BCSR_WHOAMI_CPLD(whoami),
+ BCSR_WHOAMI_DCID(whoami));
+
+ /* enable UARTs, YAMON only enables #2 */
+ alchemy_uart_enable(AU1300_UART0_PHYS_ADDR);
+ alchemy_uart_enable(AU1300_UART1_PHYS_ADDR);
+ alchemy_uart_enable(AU1300_UART3_PHYS_ADDR);
+}
diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c
new file mode 100644
index 000000000000..6815d0783cd8
--- /dev/null
+++ b/arch/mips/alchemy/devboards/db1550.c
@@ -0,0 +1,498 @@
+/*
+ * Alchemy Db1550 board support
+ *
+ * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com>
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/interrupt.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1xxx_eth.h>
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
+#include <asm/mach-au1x00/au1xxx_psc.h>
+#include <asm/mach-au1x00/au1550_spi.h>
+#include <asm/mach-db1x00/bcsr.h>
+#include <prom.h>
+#include "platform.h"
+
+
+const char *get_system_type(void)
+{
+ return "DB1550";
+}
+
+static void __init db1550_hw_setup(void)
+{
+ void __iomem *base;
+
+ alchemy_gpio_direction_output(203, 0); /* red led on */
+
+ /* complete SPI setup: link psc0_intclk to a 48MHz source,
+ * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line)
+ */
+ base = (void __iomem *)SYS_CLKSRC;
+ __raw_writel(__raw_readl(base) | 0x000001e0, base);
+ base = (void __iomem *)SYS_PINFUNC;
+ __raw_writel(__raw_readl(base) | 1, base);
+ wmb();
+
+ /* reset the AC97 codec now, the reset time in the psc-ac97 driver
+ * is apparently too short although it's ridiculous as it is.
+ */
+ base = (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR);
+ __raw_writel(PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE,
+ base + PSC_SEL_OFFSET);
+ __raw_writel(PSC_CTRL_DISABLE, base + PSC_CTRL_OFFSET);
+ wmb();
+ __raw_writel(PSC_AC97RST_RST, base + PSC_AC97RST_OFFSET);
+ wmb();
+
+ alchemy_gpio_direction_output(202, 0); /* green led on */
+}
+
+void __init board_setup(void)
+{
+ unsigned short whoami;
+
+ bcsr_init(DB1550_BCSR_PHYS_ADDR,
+ DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS);
+
+ whoami = bcsr_read(BCSR_WHOAMI);
+ printk(KERN_INFO "Alchemy/AMD DB1550 Board, CPLD Rev %d"
+ " Board-ID %d Daughtercard ID %d\n",
+ (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf);
+
+ db1550_hw_setup();
+}
+
+/*****************************************************************************/
+
+static struct mtd_partition db1550_spiflash_parts[] = {
+ {
+ .name = "spi_flash",
+ .offset = 0,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data db1550_spiflash_data = {
+ .name = "s25fl010",
+ .parts = db1550_spiflash_parts,
+ .nr_parts = ARRAY_SIZE(db1550_spiflash_parts),
+ .type = "m25p10",
+};
+
+static struct spi_board_info db1550_spi_devs[] __initdata = {
+ {
+ /* TI TMP121AIDBVR temp sensor */
+ .modalias = "tmp121",
+ .max_speed_hz = 2400000,
+ .bus_num = 0,
+ .chip_select = 0,
+ .mode = SPI_MODE_0,
+ },
+ {
+ /* Spansion S25FL001D0FMA SPI flash */
+ .modalias = "m25p80",
+ .max_speed_hz = 2400000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .mode = SPI_MODE_0,
+ .platform_data = &db1550_spiflash_data,
+ },
+};
+
+static struct i2c_board_info db1550_i2c_devs[] __initdata = {
+ { I2C_BOARD_INFO("24c04", 0x52),}, /* AT24C04-10 I2C eeprom */
+ { I2C_BOARD_INFO("ne1619", 0x2d),}, /* adm1025-compat hwmon */
+ { I2C_BOARD_INFO("wm8731", 0x1b),}, /* I2S audio codec WM8731 */
+};
+
+/**********************************************************************/
+
+static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ struct nand_chip *this = mtd->priv;
+ unsigned long ioaddr = (unsigned long)this->IO_ADDR_W;
+
+ ioaddr &= 0xffffff00;
+
+ if (ctrl & NAND_CLE) {
+ ioaddr += MEM_STNAND_CMD;
+ } else if (ctrl & NAND_ALE) {
+ ioaddr += MEM_STNAND_ADDR;
+ } else {
+ /* assume we want to r/w real data by default */
+ ioaddr += MEM_STNAND_DATA;
+ }
+ this->IO_ADDR_R = this->IO_ADDR_W = (void __iomem *)ioaddr;
+ if (cmd != NAND_CMD_NONE) {
+ __raw_writeb(cmd, this->IO_ADDR_W);
+ wmb();
+ }
+}
+
+static int au1550_nand_device_ready(struct mtd_info *mtd)
+{
+ return __raw_readl((void __iomem *)MEM_STSTAT) & 1;
+}
+
+static const char *db1550_part_probes[] = { "cmdlinepart", NULL };
+
+static struct mtd_partition db1550_nand_parts[] = {
+ {
+ .name = "NAND FS 0",
+ .offset = 0,
+ .size = 8 * 1024 * 1024,
+ },
+ {
+ .name = "NAND FS 1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL
+ },
+};
+
+struct platform_nand_data db1550_nand_platdata = {
+ .chip = {
+ .nr_chips = 1,
+ .chip_offset = 0,
+ .nr_partitions = ARRAY_SIZE(db1550_nand_parts),
+ .partitions = db1550_nand_parts,
+ .chip_delay = 20,
+ .part_probe_types = db1550_part_probes,
+ },
+ .ctrl = {
+ .dev_ready = au1550_nand_device_ready,
+ .cmd_ctrl = au1550_nand_cmd_ctrl,
+ },
+};
+
+static struct resource db1550_nand_res[] = {
+ [0] = {
+ .start = 0x20000000,
+ .end = 0x200000ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device db1550_nand_dev = {
+ .name = "gen_nand",
+ .num_resources = ARRAY_SIZE(db1550_nand_res),
+ .resource = db1550_nand_res,
+ .id = -1,
+ .dev = {
+ .platform_data = &db1550_nand_platdata,
+ }
+};
+
+/**********************************************************************/
+
+static struct resource au1550_psc0_res[] = {
+ [0] = {
+ .start = AU1550_PSC0_PHYS_ADDR,
+ .end = AU1550_PSC0_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1550_PSC0_INT,
+ .end = AU1550_PSC0_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1550_DSCR_CMD0_PSC0_TX,
+ .end = AU1550_DSCR_CMD0_PSC0_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1550_DSCR_CMD0_PSC0_RX,
+ .end = AU1550_DSCR_CMD0_PSC0_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static void db1550_spi_cs_en(struct au1550_spi_info *spi, int cs, int pol)
+{
+ if (cs)
+ bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SPISEL);
+ else
+ bcsr_mod(BCSR_BOARD, BCSR_BOARD_SPISEL, 0);
+}
+
+static struct au1550_spi_info db1550_spi_platdata = {
+ .mainclk_hz = 48000000, /* PSC0 clock: max. 2.4MHz SPI clk */
+ .num_chipselect = 2,
+ .activate_cs = db1550_spi_cs_en,
+};
+
+static u64 spi_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device db1550_spi_dev = {
+ .dev = {
+ .dma_mask = &spi_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &db1550_spi_platdata,
+ },
+ .name = "au1550-spi",
+ .id = 0, /* bus number */
+ .num_resources = ARRAY_SIZE(au1550_psc0_res),
+ .resource = au1550_psc0_res,
+};
+
+/**********************************************************************/
+
+static struct resource au1550_psc1_res[] = {
+ [0] = {
+ .start = AU1550_PSC1_PHYS_ADDR,
+ .end = AU1550_PSC1_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1550_PSC1_INT,
+ .end = AU1550_PSC1_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1550_DSCR_CMD0_PSC1_TX,
+ .end = AU1550_DSCR_CMD0_PSC1_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1550_DSCR_CMD0_PSC1_RX,
+ .end = AU1550_DSCR_CMD0_PSC1_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1550_ac97_dev = {
+ .name = "au1xpsc_ac97",
+ .id = 1, /* PSC ID */
+ .num_resources = ARRAY_SIZE(au1550_psc1_res),
+ .resource = au1550_psc1_res,
+};
+
+
+static struct resource au1550_psc2_res[] = {
+ [0] = {
+ .start = AU1550_PSC2_PHYS_ADDR,
+ .end = AU1550_PSC2_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1550_PSC2_INT,
+ .end = AU1550_PSC2_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1550_DSCR_CMD0_PSC2_TX,
+ .end = AU1550_DSCR_CMD0_PSC2_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1550_DSCR_CMD0_PSC2_RX,
+ .end = AU1550_DSCR_CMD0_PSC2_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1550_i2c_dev = {
+ .name = "au1xpsc_smbus",
+ .id = 0, /* bus number */
+ .num_resources = ARRAY_SIZE(au1550_psc2_res),
+ .resource = au1550_psc2_res,
+};
+
+/**********************************************************************/
+
+static struct resource au1550_psc3_res[] = {
+ [0] = {
+ .start = AU1550_PSC3_PHYS_ADDR,
+ .end = AU1550_PSC3_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1550_PSC3_INT,
+ .end = AU1550_PSC3_INT,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = AU1550_DSCR_CMD0_PSC3_TX,
+ .end = AU1550_DSCR_CMD0_PSC3_TX,
+ .flags = IORESOURCE_DMA,
+ },
+ [3] = {
+ .start = AU1550_DSCR_CMD0_PSC3_RX,
+ .end = AU1550_DSCR_CMD0_PSC3_RX,
+ .flags = IORESOURCE_DMA,
+ },
+};
+
+static struct platform_device db1550_i2s_dev = {
+ .name = "au1xpsc_i2s",
+ .id = 3, /* PSC ID */
+ .num_resources = ARRAY_SIZE(au1550_psc3_res),
+ .resource = au1550_psc3_res,
+};
+
+/**********************************************************************/
+
+static struct platform_device db1550_stac_dev = {
+ .name = "ac97-codec",
+ .id = 1, /* on PSC1 */
+};
+
+static struct platform_device db1550_ac97dma_dev = {
+ .name = "au1xpsc-pcm",
+ .id = 1, /* on PSC3 */
+};
+
+static struct platform_device db1550_i2sdma_dev = {
+ .name = "au1xpsc-pcm",
+ .id = 3, /* on PSC3 */
+};
+
+static struct platform_device db1550_sndac97_dev = {
+ .name = "db1550-ac97",
+};
+
+static struct platform_device db1550_sndi2s_dev = {
+ .name = "db1550-i2s",
+};
+
+/**********************************************************************/
+
+static int db1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
+{
+ if ((slot < 11) || (slot > 13) || pin == 0)
+ return -1;
+ if (slot == 11)
+ return (pin == 1) ? AU1550_PCI_INTC : 0xff;
+ if (slot == 12) {
+ switch (pin) {
+ case 1: return AU1550_PCI_INTB;
+ case 2: return AU1550_PCI_INTC;
+ case 3: return AU1550_PCI_INTD;
+ case 4: return AU1550_PCI_INTA;
+ }
+ }
+ if (slot == 13) {
+ switch (pin) {
+ case 1: return AU1550_PCI_INTA;
+ case 2: return AU1550_PCI_INTB;
+ case 3: return AU1550_PCI_INTC;
+ case 4: return AU1550_PCI_INTD;
+ }
+ }
+ return -1;
+}
+
+static struct resource alchemy_pci_host_res[] = {
+ [0] = {
+ .start = AU1500_PCI_PHYS_ADDR,
+ .end = AU1500_PCI_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct alchemy_pci_platdata db1550_pci_pd = {
+ .board_map_irq = db1550_map_pci_irq,
+};
+
+static struct platform_device db1550_pci_host_dev = {
+ .dev.platform_data = &db1550_pci_pd,
+ .name = "alchemy-pci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
+ .resource = alchemy_pci_host_res,
+};
+
+/**********************************************************************/
+
+static struct platform_device *db1550_devs[] __initdata = {
+ &db1550_nand_dev,
+ &db1550_i2c_dev,
+ &db1550_ac97_dev,
+ &db1550_spi_dev,
+ &db1550_i2s_dev,
+ &db1550_stac_dev,
+ &db1550_ac97dma_dev,
+ &db1550_i2sdma_dev,
+ &db1550_sndac97_dev,
+ &db1550_sndi2s_dev,
+};
+
+/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
+static int __init db1550_pci_init(void)
+{
+ return platform_device_register(&db1550_pci_host_dev);
+}
+arch_initcall(db1550_pci_init);
+
+static int __init db1550_dev_init(void)
+{
+ int swapped;
+
+ irq_set_irq_type(AU1550_GPIO0_INT, IRQ_TYPE_EDGE_BOTH); /* CD0# */
+ irq_set_irq_type(AU1550_GPIO1_INT, IRQ_TYPE_EDGE_BOTH); /* CD1# */
+ irq_set_irq_type(AU1550_GPIO3_INT, IRQ_TYPE_LEVEL_LOW); /* CARD0# */
+ irq_set_irq_type(AU1550_GPIO5_INT, IRQ_TYPE_LEVEL_LOW); /* CARD1# */
+ irq_set_irq_type(AU1550_GPIO21_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG0# */
+ irq_set_irq_type(AU1550_GPIO22_INT, IRQ_TYPE_LEVEL_LOW); /* STSCHG1# */
+
+ i2c_register_board_info(0, db1550_i2c_devs,
+ ARRAY_SIZE(db1550_i2c_devs));
+ spi_register_board_info(db1550_spi_devs,
+ ARRAY_SIZE(db1550_i2c_devs));
+
+ /* Audio PSC clock is supplied by codecs (PSC1, 3) FIXME: platdata!! */
+ __raw_writel(PSC_SEL_CLK_SERCLK,
+ (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+ __raw_writel(PSC_SEL_CLK_SERCLK,
+ (void __iomem *)KSEG1ADDR(AU1550_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+ /* SPI/I2C use internally supplied 50MHz source */
+ __raw_writel(PSC_SEL_CLK_INTCLK,
+ (void __iomem *)KSEG1ADDR(AU1550_PSC0_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+ __raw_writel(PSC_SEL_CLK_INTCLK,
+ (void __iomem *)KSEG1ADDR(AU1550_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET);
+ wmb();
+
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ AU1550_GPIO3_INT, AU1550_GPIO0_INT,
+ /*AU1550_GPIO21_INT*/0, 0, 0);
+
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
+ AU1550_GPIO5_INT, AU1550_GPIO1_INT,
+ /*AU1550_GPIO22_INT*/0, 0, 1);
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
+ db1x_register_norflash(128 << 20, 4, swapped);
+
+ return platform_add_devices(db1550_devs, ARRAY_SIZE(db1550_devs));
+}
+device_initcall(db1550_dev_init);
diff --git a/arch/mips/alchemy/devboards/db1x00/Makefile b/arch/mips/alchemy/devboards/db1x00/Makefile
deleted file mode 100644
index 613c0c0c8be9..000000000000
--- a/arch/mips/alchemy/devboards/db1x00/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2000, 2008 MontaVista Software Inc.
-# Author: MontaVista Software, Inc. <source@mvista.com>
-#
-# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
-#
-
-obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c
deleted file mode 100644
index 7cd36e631f6c..000000000000
--- a/arch/mips/alchemy/devboards/db1x00/board_setup.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * Alchemy Db1x00 board setup.
- *
- * Copyright 2000, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_eth.h>
-#include <asm/mach-db1x00/db1x00.h>
-#include <asm/mach-db1x00/bcsr.h>
-#include <asm/reboot.h>
-
-#include <prom.h>
-
-#ifdef CONFIG_MIPS_BOSPORUS
-char irq_tab_alchemy[][5] __initdata = {
- [11] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, 0xff, 0xff }, /* IDSEL 11 - miniPCI */
- [12] = { -1, AU1500_PCI_INTA, 0xff, 0xff, 0xff }, /* IDSEL 12 - SN1741 */
- [13] = { -1, AU1500_PCI_INTA, AU1500_PCI_INTB, AU1500_PCI_INTC, AU1500_PCI_INTD }, /* IDSEL 13 - PCI slot */
-};
-
-/*
- * Micrel/Kendin 5 port switch attached to MAC0,
- * MAC0 is associated with PHY address 5 (== WAN port)
- * MAC1 is not associated with any PHY, since it's connected directly
- * to the switch.
- * no interrupts are used
- */
-static struct au1000_eth_platform_data eth0_pdata = {
- .phy_static_config = 1,
- .phy_addr = 5,
-};
-
-static void bosporus_power_off(void)
-{
- while (1)
- asm volatile (".set mips3 ; wait ; .set mips0");
-}
-
-const char *get_system_type(void)
-{
- return "Alchemy Bosporus Gateway Reference";
-}
-#endif
-
-
-#ifdef CONFIG_MIPS_MIRAGE
-static void mirage_power_off(void)
-{
- alchemy_gpio_direction_output(210, 1);
-}
-
-const char *get_system_type(void)
-{
- return "Alchemy Mirage";
-}
-#endif
-
-
-#if defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
-static void mips_softreset(void)
-{
- asm volatile ("jr\t%0" : : "r"(0xbfc00000));
-}
-
-#else
-
-const char *get_system_type(void)
-{
- return "Alchemy Db1x00";
-}
-#endif
-
-
-void __init board_setup(void)
-{
- unsigned long bcsr1, bcsr2;
-
- bcsr1 = DB1000_BCSR_PHYS_ADDR;
- bcsr2 = DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS;
-
-#ifdef CONFIG_MIPS_DB1000
- printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
-#endif
-#ifdef CONFIG_MIPS_DB1500
- printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
-#endif
-#ifdef CONFIG_MIPS_DB1100
- printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
-#endif
-#ifdef CONFIG_MIPS_BOSPORUS
- au1xxx_override_eth_cfg(0, &eth0_pdata);
-
- printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
-#endif
-#ifdef CONFIG_MIPS_MIRAGE
- printk(KERN_INFO "AMD Alchemy Mirage Board\n");
-#endif
-#ifdef CONFIG_MIPS_DB1550
- printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
-
- bcsr1 = DB1550_BCSR_PHYS_ADDR;
- bcsr2 = DB1550_BCSR_PHYS_ADDR + DB1550_BCSR_HEXLED_OFS;
-#endif
-
- /* initialize board register space */
- bcsr_init(bcsr1, bcsr2);
-
-#if defined(CONFIG_IRDA) && defined(CONFIG_AU1000_FIR)
- {
- u32 pin_func;
-
- /* Set IRFIRSEL instead of GPIO15 */
- pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
- au_writel(pin_func, SYS_PINFUNC);
- /* Power off until the driver is in use */
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
- BCSR_RESETS_IRDA_MODE_OFF);
- }
-#endif
- bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
-
- /* Enable GPIO[31:0] inputs */
- alchemy_gpio1_input_enable();
-
-#ifdef CONFIG_MIPS_MIRAGE
- {
- u32 pin_func;
-
- /* GPIO[20] is output */
- alchemy_gpio_direction_output(20, 0);
-
- /* Set GPIO[210:208] instead of SSI_0 */
- pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;
-
- /* Set GPIO[215:211] for LEDs */
- pin_func |= 5 << 2;
-
- /* Set GPIO[214:213] for more LEDs */
- pin_func |= 5 << 12;
-
- /* Set GPIO[207:200] instead of PCMCIA/LCD */
- pin_func |= SYS_PF_LCD | SYS_PF_PC;
- au_writel(pin_func, SYS_PINFUNC);
-
- /*
- * Enable speaker amplifier. This should
- * be part of the audio driver.
- */
- alchemy_gpio_direction_output(209, 1);
-
- pm_power_off = mirage_power_off;
- _machine_halt = mirage_power_off;
- _machine_restart = (void(*)(char *))mips_softreset;
- }
-#endif
-
-#ifdef CONFIG_MIPS_BOSPORUS
- pm_power_off = bosporus_power_off;
- _machine_halt = bosporus_power_off;
- _machine_restart = (void(*)(char *))mips_softreset;
-#endif
- au_sync();
-}
-
-static int __init db1x00_init_irq(void)
-{
-#if defined(CONFIG_MIPS_MIRAGE)
- irq_set_irq_type(AU1500_GPIO7_INT, IRQF_TRIGGER_RISING); /* TS pendown */
-#elif defined(CONFIG_MIPS_DB1550)
- irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
- irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW); /* CD1# */
- irq_set_irq_type(AU1550_GPIO3_INT, IRQF_TRIGGER_LOW); /* CARD0# */
- irq_set_irq_type(AU1550_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
- irq_set_irq_type(AU1550_GPIO21_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- irq_set_irq_type(AU1550_GPIO22_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
-#elif defined(CONFIG_MIPS_DB1500)
- irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
- irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
- irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
- irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
- irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
-#elif defined(CONFIG_MIPS_DB1100)
- irq_set_irq_type(AU1100_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
- irq_set_irq_type(AU1100_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
- irq_set_irq_type(AU1100_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
- irq_set_irq_type(AU1100_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
- irq_set_irq_type(AU1100_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- irq_set_irq_type(AU1100_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
-#elif defined(CONFIG_MIPS_DB1000)
- irq_set_irq_type(AU1000_GPIO0_INT, IRQF_TRIGGER_LOW); /* CD0# */
- irq_set_irq_type(AU1000_GPIO3_INT, IRQF_TRIGGER_LOW); /* CD1# */
- irq_set_irq_type(AU1000_GPIO2_INT, IRQF_TRIGGER_LOW); /* CARD0# */
- irq_set_irq_type(AU1000_GPIO5_INT, IRQF_TRIGGER_LOW); /* CARD1# */
- irq_set_irq_type(AU1000_GPIO1_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
- irq_set_irq_type(AU1000_GPIO4_INT, IRQF_TRIGGER_LOW); /* STSCHG1# */
-#endif
- return 0;
-}
-arch_initcall(db1x00_init_irq);
diff --git a/arch/mips/alchemy/devboards/db1x00/platform.c b/arch/mips/alchemy/devboards/db1x00/platform.c
deleted file mode 100644
index 9e6b3d442acd..000000000000
--- a/arch/mips/alchemy/devboards/db1x00/platform.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/*
- * DBAu1xxx board platform device registration
- *
- * Copyright (C) 2009 Manuel Lauss
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1000_dma.h>
-#include <asm/mach-db1x00/bcsr.h>
-#include "../platform.h"
-
-struct pci_dev;
-
-/* DB1xxx PCMCIA interrupt sources:
- * CD0/1 GPIO0/3
- * STSCHG0/1 GPIO1/4
- * CARD0/1 GPIO2/5
- * Db1550: 0/1, 21/22, 3/5
- */
-
-#define DB1XXX_HAS_PCMCIA
-#define F_SWAPPED (bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT)
-
-#if defined(CONFIG_MIPS_DB1000)
-#define DB1XXX_PCMCIA_CD0 AU1000_GPIO0_INT
-#define DB1XXX_PCMCIA_STSCHG0 AU1000_GPIO1_INT
-#define DB1XXX_PCMCIA_CARD0 AU1000_GPIO2_INT
-#define DB1XXX_PCMCIA_CD1 AU1000_GPIO3_INT
-#define DB1XXX_PCMCIA_STSCHG1 AU1000_GPIO4_INT
-#define DB1XXX_PCMCIA_CARD1 AU1000_GPIO5_INT
-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#elif defined(CONFIG_MIPS_DB1100)
-#define DB1XXX_PCMCIA_CD0 AU1100_GPIO0_INT
-#define DB1XXX_PCMCIA_STSCHG0 AU1100_GPIO1_INT
-#define DB1XXX_PCMCIA_CARD0 AU1100_GPIO2_INT
-#define DB1XXX_PCMCIA_CD1 AU1100_GPIO3_INT
-#define DB1XXX_PCMCIA_STSCHG1 AU1100_GPIO4_INT
-#define DB1XXX_PCMCIA_CARD1 AU1100_GPIO5_INT
-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#elif defined(CONFIG_MIPS_DB1500)
-#define DB1XXX_PCMCIA_CD0 AU1500_GPIO0_INT
-#define DB1XXX_PCMCIA_STSCHG0 AU1500_GPIO1_INT
-#define DB1XXX_PCMCIA_CARD0 AU1500_GPIO2_INT
-#define DB1XXX_PCMCIA_CD1 AU1500_GPIO3_INT
-#define DB1XXX_PCMCIA_STSCHG1 AU1500_GPIO4_INT
-#define DB1XXX_PCMCIA_CARD1 AU1500_GPIO5_INT
-#define BOARD_FLASH_SIZE 0x02000000 /* 32MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#elif defined(CONFIG_MIPS_DB1550)
-#define DB1XXX_PCMCIA_CD0 AU1550_GPIO0_INT
-#define DB1XXX_PCMCIA_STSCHG0 AU1550_GPIO21_INT
-#define DB1XXX_PCMCIA_CARD0 AU1550_GPIO3_INT
-#define DB1XXX_PCMCIA_CD1 AU1550_GPIO1_INT
-#define DB1XXX_PCMCIA_STSCHG1 AU1550_GPIO22_INT
-#define DB1XXX_PCMCIA_CARD1 AU1550_GPIO5_INT
-#define BOARD_FLASH_SIZE 0x08000000 /* 128MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#else
-/* other board: no PCMCIA */
-#undef DB1XXX_HAS_PCMCIA
-#undef F_SWAPPED
-#define F_SWAPPED 0
-#if defined(CONFIG_MIPS_BOSPORUS)
-#define BOARD_FLASH_SIZE 0x01000000 /* 16MB */
-#define BOARD_FLASH_WIDTH 2 /* 16-bits */
-#elif defined(CONFIG_MIPS_MIRAGE)
-#define BOARD_FLASH_SIZE 0x04000000 /* 64MB */
-#define BOARD_FLASH_WIDTH 4 /* 32-bits */
-#endif
-#endif
-
-#ifdef CONFIG_PCI
-#ifdef CONFIG_MIPS_DB1500
-static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
-{
- if ((slot < 12) || (slot > 13) || pin == 0)
- return -1;
- if (slot == 12)
- return (pin == 1) ? AU1500_PCI_INTA : 0xff;
- if (slot == 13) {
- switch (pin) {
- case 1: return AU1500_PCI_INTA;
- case 2: return AU1500_PCI_INTB;
- case 3: return AU1500_PCI_INTC;
- case 4: return AU1500_PCI_INTD;
- }
- }
- return -1;
-}
-#endif
-
-#ifdef CONFIG_MIPS_DB1550
-static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
-{
- if ((slot < 11) || (slot > 13) || pin == 0)
- return -1;
- if (slot == 11)
- return (pin == 1) ? AU1550_PCI_INTC : 0xff;
- if (slot == 12) {
- switch (pin) {
- case 1: return AU1550_PCI_INTB;
- case 2: return AU1550_PCI_INTC;
- case 3: return AU1550_PCI_INTD;
- case 4: return AU1550_PCI_INTA;
- }
- }
- if (slot == 13) {
- switch (pin) {
- case 1: return AU1550_PCI_INTA;
- case 2: return AU1550_PCI_INTB;
- case 3: return AU1550_PCI_INTC;
- case 4: return AU1550_PCI_INTD;
- }
- }
- return -1;
-}
-#endif
-
-#ifdef CONFIG_MIPS_BOSPORUS
-static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
-{
- if ((slot < 11) || (slot > 13) || pin == 0)
- return -1;
- if (slot == 12)
- return (pin == 1) ? AU1500_PCI_INTA : 0xff;
- if (slot == 11) {
- switch (pin) {
- case 1: return AU1500_PCI_INTA;
- case 2: return AU1500_PCI_INTB;
- default: return 0xff;
- }
- }
- if (slot == 13) {
- switch (pin) {
- case 1: return AU1500_PCI_INTA;
- case 2: return AU1500_PCI_INTB;
- case 3: return AU1500_PCI_INTC;
- case 4: return AU1500_PCI_INTD;
- }
- }
- return -1;
-}
-#endif
-
-#ifdef CONFIG_MIPS_MIRAGE
-static int db1xxx_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
-{
- if ((slot < 11) || (slot > 13) || pin == 0)
- return -1;
- if (slot == 11)
- return (pin == 1) ? AU1500_PCI_INTD : 0xff;
- if (slot == 12)
- return (pin == 3) ? AU1500_PCI_INTC : 0xff;
- if (slot == 13) {
- switch (pin) {
- case 1: return AU1500_PCI_INTA;
- case 2: return AU1500_PCI_INTB;
- default: return 0xff;
- }
- }
- return -1;
-}
-#endif
-
-static struct resource alchemy_pci_host_res[] = {
- [0] = {
- .start = AU1500_PCI_PHYS_ADDR,
- .end = AU1500_PCI_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct alchemy_pci_platdata db1xxx_pci_pd = {
- .board_map_irq = db1xxx_map_pci_irq,
-};
-
-static struct platform_device db1xxx_pci_host_dev = {
- .dev.platform_data = &db1xxx_pci_pd,
- .name = "alchemy-pci",
- .id = 0,
- .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
- .resource = alchemy_pci_host_res,
-};
-
-static int __init db15x0_pci_init(void)
-{
- return platform_device_register(&db1xxx_pci_host_dev);
-}
-/* must be arch_initcall; MIPS PCI scans busses in a subsys_initcall */
-arch_initcall(db15x0_pci_init);
-#endif
-
-#ifdef CONFIG_MIPS_DB1100
-static struct resource au1100_lcd_resources[] = {
- [0] = {
- .start = AU1100_LCD_PHYS_ADDR,
- .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AU1100_LCD_INT,
- .end = AU1100_LCD_INT,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device au1100_lcd_device = {
- .name = "au1100-lcd",
- .id = 0,
- .dev = {
- .dma_mask = &au1100_lcd_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .num_resources = ARRAY_SIZE(au1100_lcd_resources),
- .resource = au1100_lcd_resources,
-};
-#endif
-
-static struct resource alchemy_ac97c_res[] = {
- [0] = {
- .start = AU1000_AC97_PHYS_ADDR,
- .end = AU1000_AC97_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = DMA_ID_AC97C_TX,
- .end = DMA_ID_AC97C_TX,
- .flags = IORESOURCE_DMA,
- },
- [2] = {
- .start = DMA_ID_AC97C_RX,
- .end = DMA_ID_AC97C_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static struct platform_device alchemy_ac97c_dev = {
- .name = "alchemy-ac97c",
- .id = -1,
- .resource = alchemy_ac97c_res,
- .num_resources = ARRAY_SIZE(alchemy_ac97c_res),
-};
-
-static struct platform_device alchemy_ac97c_dma_dev = {
- .name = "alchemy-pcm-dma",
- .id = 0,
-};
-
-static struct platform_device db1x00_codec_dev = {
- .name = "ac97-codec",
- .id = -1,
-};
-
-static struct platform_device db1x00_audio_dev = {
- .name = "db1000-audio",
-};
-
-static int __init db1xxx_dev_init(void)
-{
-#ifdef DB1XXX_HAS_PCMCIA
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
- DB1XXX_PCMCIA_CARD0, DB1XXX_PCMCIA_CD0,
- /*DB1XXX_PCMCIA_STSCHG0*/0, 0, 0);
-
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x004400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x004400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x004000000,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x004010000 - 1,
- DB1XXX_PCMCIA_CARD1, DB1XXX_PCMCIA_CD1,
- /*DB1XXX_PCMCIA_STSCHG1*/0, 0, 1);
-#endif
-#ifdef CONFIG_MIPS_DB1100
- platform_device_register(&au1100_lcd_device);
-#endif
- db1x_register_norflash(BOARD_FLASH_SIZE, BOARD_FLASH_WIDTH, F_SWAPPED);
-
- platform_device_register(&db1x00_codec_dev);
- platform_device_register(&alchemy_ac97c_dma_dev);
- platform_device_register(&alchemy_ac97c_dev);
- platform_device_register(&db1x00_audio_dev);
-
- return 0;
-}
-device_initcall(db1xxx_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1000/Makefile b/arch/mips/alchemy/devboards/pb1000/Makefile
deleted file mode 100644
index 97c6615ba2bb..000000000000
--- a/arch/mips/alchemy/devboards/pb1000/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2000, 2008 MontaVista Software Inc.
-# Author: MontaVista Software, Inc. <source@mvista.com>
-#
-# Makefile for the Alchemy Semiconductor Pb1000 board.
-#
-
-obj-y := board_setup.o
diff --git a/arch/mips/alchemy/devboards/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c
deleted file mode 100644
index e64fdcbf75d0..000000000000
--- a/arch/mips/alchemy/devboards/pb1000/board_setup.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright 2000, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-pb1x00/pb1000.h>
-#include <asm/reboot.h>
-#include <prom.h>
-
-#include "../platform.h"
-
-const char *get_system_type(void)
-{
- return "Alchemy Pb1000";
-}
-
-static void board_reset(char *c)
-{
- asm volatile ("jr %0" : : "r" (0xbfc00000));
-}
-
-static void board_power_off(void)
-{
- while (1)
- asm volatile (
- " .set mips32 \n"
- " wait \n"
- " .set mips0 \n");
-}
-
-void __init board_setup(void)
-{
- u32 pin_func, static_cfg0;
- u32 sys_freqctrl, sys_clksrc;
- u32 prid = read_c0_prid();
-
- sys_freqctrl = 0;
- sys_clksrc = 0;
-
- /* Set AUX clock to 12 MHz * 8 = 96 MHz */
- au_writel(8, SYS_AUXPLL);
- alchemy_gpio1_input_enable();
- udelay(100);
-
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
- /* Zero and disable FREQ2 */
- sys_freqctrl = au_readl(SYS_FREQCTRL0);
- sys_freqctrl &= ~0xFFF00000;
- au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
- /* Zero and disable USBH/USBD clocks */
- sys_clksrc = au_readl(SYS_CLKSRC);
- sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
- SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
- au_writel(sys_clksrc, SYS_CLKSRC);
-
- sys_freqctrl = au_readl(SYS_FREQCTRL0);
- sys_freqctrl &= ~0xFFF00000;
-
- sys_clksrc = au_readl(SYS_CLKSRC);
- sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
- SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
-
- switch (prid & 0x000000FF) {
- case 0x00: /* DA */
- case 0x01: /* HA */
- case 0x02: /* HB */
- /* CPU core freq to 48 MHz to slow it way down... */
- au_writel(4, SYS_CPUPLL);
-
- /*
- * Setup 48 MHz FREQ2 from CPUPLL for USB Host
- * FRDIV2 = 3 -> div by 8 of 384 MHz -> 48 MHz
- */
- sys_freqctrl |= (3 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2;
- au_writel(sys_freqctrl, SYS_FREQCTRL0);
-
- /* CPU core freq to 384 MHz */
- au_writel(0x20, SYS_CPUPLL);
-
- printk(KERN_INFO "Au1000: 48 MHz OHCI workaround enabled\n");
- break;
-
- default: /* HC and newer */
- /* FREQ2 = aux / 2 = 48 MHz */
- sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
- SYS_FC_FE2 | SYS_FC_FS2;
- au_writel(sys_freqctrl, SYS_FREQCTRL0);
- break;
- }
-
- /*
- * Route 48 MHz FREQ2 into USB Host and/or Device
- */
- sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
- au_writel(sys_clksrc, SYS_CLKSRC);
-
- /* Configure pins GPIO[14:9] as GPIO */
- pin_func = au_readl(SYS_PINFUNC) & ~(SYS_PF_UR3 | SYS_PF_USB);
-
- /* 2nd USB port is USB host */
- pin_func |= SYS_PF_USB;
-
- au_writel(pin_func, SYS_PINFUNC);
-
- alchemy_gpio_direction_input(11);
- alchemy_gpio_direction_input(13);
- alchemy_gpio_direction_output(4, 0);
- alchemy_gpio_direction_output(5, 0);
-#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
-
- /* Make GPIO 15 an input (for interrupt line) */
- pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_IRF;
- /* We don't need I2S, so make it available for GPIO[31:29] */
- pin_func |= SYS_PF_I2S;
- au_writel(pin_func, SYS_PINFUNC);
-
- alchemy_gpio_direction_input(15);
-
- static_cfg0 = au_readl(MEM_STCFG0) & ~0xc00;
- au_writel(static_cfg0, MEM_STCFG0);
-
- /* configure RCE2* for LCD */
- au_writel(0x00000004, MEM_STCFG2);
-
- /* MEM_STTIME2 */
- au_writel(0x09000000, MEM_STTIME2);
-
- /* Set 32-bit base address decoding for RCE2* */
- au_writel(0x10003ff0, MEM_STADDR2);
-
- /*
- * PCI CPLD setup
- * Expand CE0 to cover PCI
- */
- au_writel(0x11803e40, MEM_STADDR1);
-
- /* Burst visibility on */
- au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);
-
- au_writel(0x83, MEM_STCFG1); /* ewait enabled, flash timing */
- au_writel(0x33030a10, MEM_STTIME1); /* slower timing for FPGA */
-
- /* Setup the static bus controller */
- au_writel(0x00000002, MEM_STCFG3); /* type = PCMCIA */
- au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
- au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
-
- /*
- * Enable Au1000 BCLK switching - note: sed1356 must not use
- * its BCLK (Au1000 LCLK) for any timings
- */
- switch (prid & 0x000000FF) {
- case 0x00: /* DA */
- case 0x01: /* HA */
- case 0x02: /* HB */
- break;
- default: /* HC and newer */
- /*
- * Enable sys bus clock divider when IDLE state or no bus
- * activity.
- */
- au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
- break;
- }
-
- pm_power_off = board_power_off;
- _machine_halt = board_power_off;
- _machine_restart = board_reset;
-}
-
-static int __init pb1000_init_irq(void)
-{
- irq_set_irq_type(AU1000_GPIO15_INT, IRQF_TRIGGER_LOW);
- return 0;
-}
-arch_initcall(pb1000_init_irq);
-
-static int __init pb1000_device_init(void)
-{
- return db1x_register_norflash(8 * 1024 * 1024, 4, 0);
-}
-device_initcall(pb1000_device_init);
diff --git a/arch/mips/alchemy/devboards/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100.c
index d108fd573aaf..cff50d05ddd4 100644
--- a/arch/mips/alchemy/devboards/pb1100/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1100.c
@@ -1,42 +1,37 @@
/*
- * Copyright 2002, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
+ * Pb1100 board platform device registration
*
- * 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.
+ * Copyright (C) 2009 Manuel Lauss
*
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
+#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/init.h>
-#include <linux/delay.h>
#include <linux/interrupt.h>
-
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
-
#include <prom.h>
-
+#include "platform.h"
const char *get_system_type(void)
{
- return "Alchemy Pb1100";
+ return "PB1100";
}
void __init board_setup(void)
@@ -115,13 +110,58 @@ void __init board_setup(void)
}
}
-static int __init pb1100_init_irq(void)
+/******************************************************************************/
+
+static struct resource au1100_lcd_resources[] = {
+ [0] = {
+ .start = AU1100_LCD_PHYS_ADDR,
+ .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = AU1100_LCD_INT,
+ .end = AU1100_LCD_INT,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
+
+static struct platform_device au1100_lcd_device = {
+ .name = "au1100-lcd",
+ .id = 0,
+ .dev = {
+ .dma_mask = &au1100_lcd_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+ .num_resources = ARRAY_SIZE(au1100_lcd_resources),
+ .resource = au1100_lcd_resources,
+};
+
+static int __init pb1100_dev_init(void)
{
+ int swapped;
+
irq_set_irq_type(AU1100_GPIO9_INT, IRQF_TRIGGER_LOW); /* PCCD# */
irq_set_irq_type(AU1100_GPIO10_INT, IRQF_TRIGGER_LOW); /* PCSTSCHG# */
irq_set_irq_type(AU1100_GPIO11_INT, IRQF_TRIGGER_LOW); /* PCCard# */
irq_set_irq_type(AU1100_GPIO13_INT, IRQF_TRIGGER_LOW); /* DC_IRQ# */
+ /* PCMCIA. single socket, identical to Pb1500 */
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ AU1100_GPIO11_INT, AU1100_GPIO9_INT, /* card / insert */
+ /*AU1100_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
+ db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
+ platform_device_register(&au1100_lcd_device);
+
return 0;
}
-arch_initcall(pb1100_init_irq);
+device_initcall(pb1100_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1100/Makefile b/arch/mips/alchemy/devboards/pb1100/Makefile
deleted file mode 100644
index 7e3756c83fe5..000000000000
--- a/arch/mips/alchemy/devboards/pb1100/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2000, 2001, 2008 MontaVista Software Inc.
-# Author: MontaVista Software, Inc. <source@mvista.com>
-#
-# Makefile for the Alchemy Semiconductor Pb1100 board.
-#
-
-obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1100/platform.c b/arch/mips/alchemy/devboards/pb1100/platform.c
deleted file mode 100644
index 9c57c01a68c4..000000000000
--- a/arch/mips/alchemy/devboards/pb1100/platform.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Pb1100 board platform device registration
- *
- * Copyright (C) 2009 Manuel Lauss
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/init.h>
-#include <linux/dma-mapping.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/bcsr.h>
-
-#include "../platform.h"
-
-static struct resource au1100_lcd_resources[] = {
- [0] = {
- .start = AU1100_LCD_PHYS_ADDR,
- .end = AU1100_LCD_PHYS_ADDR + 0x800 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AU1100_LCD_INT,
- .end = AU1100_LCD_INT,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static u64 au1100_lcd_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device au1100_lcd_device = {
- .name = "au1100-lcd",
- .id = 0,
- .dev = {
- .dma_mask = &au1100_lcd_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .num_resources = ARRAY_SIZE(au1100_lcd_resources),
- .resource = au1100_lcd_resources,
-};
-
-static int __init pb1100_dev_init(void)
-{
- int swapped;
-
- /* PCMCIA. single socket, identical to Pb1500 */
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
- AU1100_GPIO11_INT, AU1100_GPIO9_INT, /* card / insert */
- /*AU1100_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
-
- swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
- db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
- platform_device_register(&au1100_lcd_device);
-
- return 0;
-}
-device_initcall(pb1100_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1200/Makefile b/arch/mips/alchemy/devboards/pb1200/Makefile
deleted file mode 100644
index 18c1bd53e4c0..000000000000
--- a/arch/mips/alchemy/devboards/pb1200/Makefile
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
-#
-
-obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c
deleted file mode 100644
index 6d06b07c2381..000000000000
--- a/arch/mips/alchemy/devboards/pb1200/board_setup.c
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * Alchemy Pb1200/Db1200 board setup.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/sched.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/bcsr.h>
-
-#ifdef CONFIG_MIPS_PB1200
-#include <asm/mach-pb1x00/pb1200.h>
-#endif
-
-#ifdef CONFIG_MIPS_DB1200
-#include <asm/mach-db1x00/db1200.h>
-#define PB1200_INT_BEGIN DB1200_INT_BEGIN
-#define PB1200_INT_END DB1200_INT_END
-#endif
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
- return "Alchemy Pb1200";
-}
-
-void __init board_setup(void)
-{
- printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
- bcsr_init(PB1200_BCSR_PHYS_ADDR,
- PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);
-
-#if 0
- {
- u32 pin_func;
-
- /*
- * Enable PSC1 SYNC for AC97. Normaly done in audio driver,
- * but it is board specific code, so put it here.
- */
- pin_func = au_readl(SYS_PINFUNC);
- au_sync();
- pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
- au_writel(pin_func, SYS_PINFUNC);
-
- au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
- au_sync();
- }
-#endif
-
-#if defined(CONFIG_I2C_AU1550)
- {
- u32 freq0, clksrc;
- u32 pin_func;
-
- /* Select SMBus in CPLD */
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
-
- pin_func = au_readl(SYS_PINFUNC);
- au_sync();
- pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
- /* Set GPIOs correctly */
- pin_func |= 2 << 17;
- au_writel(pin_func, SYS_PINFUNC);
- au_sync();
-
- /* The I2C driver depends on 50 MHz clock */
- freq0 = au_readl(SYS_FREQCTRL0);
- au_sync();
- freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
- freq0 |= 3 << SYS_FC_FRDIV1_BIT;
- /* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
- au_writel(freq0, SYS_FREQCTRL0);
- au_sync();
- freq0 |= SYS_FC_FE1;
- au_writel(freq0, SYS_FREQCTRL0);
- au_sync();
-
- clksrc = au_readl(SYS_CLKSRC);
- au_sync();
- clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
- /* Bit 22 is EXTCLK0 for PSC0 */
- clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
- au_writel(clksrc, SYS_CLKSRC);
- au_sync();
- }
-#endif
-
- /*
- * The Pb1200 development board uses external MUX for PSC0 to
- * support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
- */
-#ifdef CONFIG_I2C_AU1550
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
-#endif
- au_sync();
-}
-
-static int __init pb1200_init_irq(void)
-{
- /* We have a problem with CPLD rev 3. */
- if (BCSR_WHOAMI_CPLD(bcsr_read(BCSR_WHOAMI)) <= 3) {
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "Pb1200 must be at CPLD rev 4. Please have Pb1200\n");
- printk(KERN_ERR "updated to latest revision. This software will\n");
- printk(KERN_ERR "not work on anything less than CPLD rev 4.\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- printk(KERN_ERR "WARNING!!!\n");
- panic("Game over. Your score is 0.");
- }
-
- irq_set_irq_type(AU1200_GPIO7_INT, IRQF_TRIGGER_LOW);
- bcsr_init_irq(PB1200_INT_BEGIN, PB1200_INT_END, AU1200_GPIO7_INT);
-
- return 0;
-}
-arch_initcall(pb1200_init_irq);
-
-
-int board_au1200fb_panel(void)
-{
- return (bcsr_read(BCSR_SWITCHES) >> 8) & 0x0f;
-}
-
-int board_au1200fb_panel_init(void)
-{
- /* Apply power */
- bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
- BCSR_BOARD_LCDBL);
- /* printk(KERN_DEBUG "board_au1200fb_panel_init()\n"); */
- return 0;
-}
-
-int board_au1200fb_panel_shutdown(void)
-{
- /* Remove power */
- bcsr_mod(BCSR_BOARD, BCSR_BOARD_LCDVEE | BCSR_BOARD_LCDVDD |
- BCSR_BOARD_LCDBL, 0);
- /* printk(KERN_DEBUG "board_au1200fb_panel_shutdown()\n"); */
- return 0;
-}
diff --git a/arch/mips/alchemy/devboards/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c
deleted file mode 100644
index 54f7f7b0676e..000000000000
--- a/arch/mips/alchemy/devboards/pb1200/platform.c
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Pb1200/DBAu1200 board platform device registration
- *
- * Copyright (C) 2008 MontaVista Software Inc. <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/leds.h>
-#include <linux/platform_device.h>
-#include <linux/smc91x.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1100_mmc.h>
-#include <asm/mach-au1x00/au1xxx_dbdma.h>
-#include <asm/mach-db1x00/bcsr.h>
-#include <asm/mach-pb1x00/pb1200.h>
-
-#include "../platform.h"
-
-static int mmc_activity;
-
-static void pb1200mmc0_set_power(void *mmc_host, int state)
-{
- if (state)
- bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD0PWR);
- else
- bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD0PWR, 0);
-
- msleep(1);
-}
-
-static int pb1200mmc0_card_readonly(void *mmc_host)
-{
- return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD0WP) ? 1 : 0;
-}
-
-static int pb1200mmc0_card_inserted(void *mmc_host)
-{
- return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD0INSERT) ? 1 : 0;
-}
-
-static void pb1200_mmcled_set(struct led_classdev *led,
- enum led_brightness brightness)
-{
- if (brightness != LED_OFF) {
- if (++mmc_activity == 1)
- bcsr_mod(BCSR_LEDS, BCSR_LEDS_LED0, 0);
- } else {
- if (--mmc_activity == 0)
- bcsr_mod(BCSR_LEDS, 0, BCSR_LEDS_LED0);
- }
-}
-
-static struct led_classdev pb1200mmc_led = {
- .brightness_set = pb1200_mmcled_set,
-};
-
-static void pb1200mmc1_set_power(void *mmc_host, int state)
-{
- if (state)
- bcsr_mod(BCSR_BOARD, 0, BCSR_BOARD_SD1PWR);
- else
- bcsr_mod(BCSR_BOARD, BCSR_BOARD_SD1PWR, 0);
-
- msleep(1);
-}
-
-static int pb1200mmc1_card_readonly(void *mmc_host)
-{
- return (bcsr_read(BCSR_STATUS) & BCSR_STATUS_SD1WP) ? 1 : 0;
-}
-
-static int pb1200mmc1_card_inserted(void *mmc_host)
-{
- return (bcsr_read(BCSR_SIGSTAT) & BCSR_INT_SD1INSERT) ? 1 : 0;
-}
-
-static struct au1xmmc_platform_data pb1200mmc_platdata[2] = {
- [0] = {
- .set_power = pb1200mmc0_set_power,
- .card_inserted = pb1200mmc0_card_inserted,
- .card_readonly = pb1200mmc0_card_readonly,
- .cd_setup = NULL, /* use poll-timer in driver */
- .led = &pb1200mmc_led,
- },
- [1] = {
- .set_power = pb1200mmc1_set_power,
- .card_inserted = pb1200mmc1_card_inserted,
- .card_readonly = pb1200mmc1_card_readonly,
- .cd_setup = NULL, /* use poll-timer in driver */
- .led = &pb1200mmc_led,
- },
-};
-
-static u64 au1xxx_mmc_dmamask = DMA_BIT_MASK(32);
-
-static struct resource au1200_mmc0_res[] = {
- [0] = {
- .start = AU1100_SD0_PHYS_ADDR,
- .end = AU1100_SD0_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AU1200_SD_INT,
- .end = AU1200_SD_INT,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = AU1200_DSCR_CMD0_SDMS_TX0,
- .end = AU1200_DSCR_CMD0_SDMS_TX0,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = AU1200_DSCR_CMD0_SDMS_RX0,
- .end = AU1200_DSCR_CMD0_SDMS_RX0,
- .flags = IORESOURCE_DMA,
- }
-};
-
-static struct platform_device pb1200_mmc0_dev = {
- .name = "au1xxx-mmc",
- .id = 0,
- .dev = {
- .dma_mask = &au1xxx_mmc_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &pb1200mmc_platdata[0],
- },
- .num_resources = ARRAY_SIZE(au1200_mmc0_res),
- .resource = au1200_mmc0_res,
-};
-
-static struct resource au1200_mmc1_res[] = {
- [0] = {
- .start = AU1100_SD1_PHYS_ADDR,
- .end = AU1100_SD1_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AU1200_SD_INT,
- .end = AU1200_SD_INT,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = AU1200_DSCR_CMD0_SDMS_TX1,
- .end = AU1200_DSCR_CMD0_SDMS_TX1,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = AU1200_DSCR_CMD0_SDMS_RX1,
- .end = AU1200_DSCR_CMD0_SDMS_RX1,
- .flags = IORESOURCE_DMA,
- }
-};
-
-static struct platform_device pb1200_mmc1_dev = {
- .name = "au1xxx-mmc",
- .id = 1,
- .dev = {
- .dma_mask = &au1xxx_mmc_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- .platform_data = &pb1200mmc_platdata[1],
- },
- .num_resources = ARRAY_SIZE(au1200_mmc1_res),
- .resource = au1200_mmc1_res,
-};
-
-
-static struct resource ide_resources[] = {
- [0] = {
- .start = IDE_PHYS_ADDR,
- .end = IDE_PHYS_ADDR + IDE_PHYS_LEN - 1,
- .flags = IORESOURCE_MEM
- },
- [1] = {
- .start = IDE_INT,
- .end = IDE_INT,
- .flags = IORESOURCE_IRQ
- },
- [2] = {
- .start = AU1200_DSCR_CMD0_DMA_REQ1,
- .end = AU1200_DSCR_CMD0_DMA_REQ1,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static u64 ide_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device ide_device = {
- .name = "au1200-ide",
- .id = 0,
- .dev = {
- .dma_mask = &ide_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .num_resources = ARRAY_SIZE(ide_resources),
- .resource = ide_resources
-};
-
-static struct smc91x_platdata smc_data = {
- .flags = SMC91X_NOWAIT | SMC91X_USE_16BIT,
- .leda = RPC_LED_100_10,
- .ledb = RPC_LED_TX_RX,
-};
-
-static struct resource smc91c111_resources[] = {
- [0] = {
- .name = "smc91x-regs",
- .start = SMC91C111_PHYS_ADDR,
- .end = SMC91C111_PHYS_ADDR + 0xf,
- .flags = IORESOURCE_MEM
- },
- [1] = {
- .start = SMC91C111_INT,
- .end = SMC91C111_INT,
- .flags = IORESOURCE_IRQ
- },
-};
-
-static struct platform_device smc91c111_device = {
- .dev = {
- .platform_data = &smc_data,
- },
- .name = "smc91x",
- .id = -1,
- .num_resources = ARRAY_SIZE(smc91c111_resources),
- .resource = smc91c111_resources
-};
-
-static struct resource au1200_psc0_res[] = {
- [0] = {
- .start = AU1550_PSC0_PHYS_ADDR,
- .end = AU1550_PSC0_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AU1200_PSC0_INT,
- .end = AU1200_PSC0_INT,
- .flags = IORESOURCE_IRQ,
- },
- [2] = {
- .start = AU1200_DSCR_CMD0_PSC0_TX,
- .end = AU1200_DSCR_CMD0_PSC0_TX,
- .flags = IORESOURCE_DMA,
- },
- [3] = {
- .start = AU1200_DSCR_CMD0_PSC0_RX,
- .end = AU1200_DSCR_CMD0_PSC0_RX,
- .flags = IORESOURCE_DMA,
- },
-};
-
-static struct platform_device pb1200_i2c_dev = {
- .name = "au1xpsc_smbus",
- .id = 0, /* bus number */
- .num_resources = ARRAY_SIZE(au1200_psc0_res),
- .resource = au1200_psc0_res,
-};
-
-static struct resource au1200_lcd_res[] = {
- [0] = {
- .start = AU1200_LCD_PHYS_ADDR,
- .end = AU1200_LCD_PHYS_ADDR + 0x800 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = AU1200_LCD_INT,
- .end = AU1200_LCD_INT,
- .flags = IORESOURCE_IRQ,
- }
-};
-
-static u64 au1200_lcd_dmamask = DMA_BIT_MASK(32);
-
-static struct platform_device au1200_lcd_dev = {
- .name = "au1200-lcd",
- .id = 0,
- .dev = {
- .dma_mask = &au1200_lcd_dmamask,
- .coherent_dma_mask = DMA_BIT_MASK(32),
- },
- .num_resources = ARRAY_SIZE(au1200_lcd_res),
- .resource = au1200_lcd_res,
-};
-
-static struct platform_device *board_platform_devices[] __initdata = {
- &ide_device,
- &smc91c111_device,
- &pb1200_i2c_dev,
- &pb1200_mmc0_dev,
- &pb1200_mmc1_dev,
- &au1200_lcd_dev,
-};
-
-static int __init board_register_devices(void)
-{
- int swapped;
-
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
- PB1200_PC0_INT, PB1200_PC0_INSERT_INT,
- /*PB1200_PC0_STSCHG_INT*/0, PB1200_PC0_EJECT_INT, 0);
-
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008000000,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x008400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008000000,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x008400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x008000000,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
- PB1200_PC1_INT, PB1200_PC1_INSERT_INT,
- /*PB1200_PC1_STSCHG_INT*/0, PB1200_PC1_EJECT_INT, 1);
-
- swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1200_SWAPBOOT;
- db1x_register_norflash(128 * 1024 * 1024, 2, swapped);
-
- return platform_add_devices(board_platform_devices,
- ARRAY_SIZE(board_platform_devices));
-}
-device_initcall(board_register_devices);
diff --git a/arch/mips/alchemy/devboards/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500.c
index 37c1883b5ea9..e7b807b3ec51 100644
--- a/arch/mips/alchemy/devboards/pb1500/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1500.c
@@ -1,41 +1,37 @@
/*
- * Copyright 2000, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
+ * Pb1500 board support.
*
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
+ * Copyright (C) 2009 Manuel Lauss
*
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 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.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <linux/delay.h>
+#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/interrupt.h>
-
+#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
-
#include <prom.h>
+#include "platform.h"
const char *get_system_type(void)
{
- return "Alchemy Pb1500";
+ return "PB1500";
}
void __init board_setup(void)
@@ -123,17 +119,80 @@ void __init board_setup(void)
}
}
-static int __init pb1500_init_irq(void)
+/******************************************************************************/
+
+static int pb1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
- irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
- irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
- irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
+ if ((slot < 12) || (slot > 13) || pin == 0)
+ return -1;
+ if (slot == 12)
+ return (pin == 1) ? AU1500_PCI_INTA : 0xff;
+ if (slot == 13) {
+ switch (pin) {
+ case 1: return AU1500_PCI_INTA;
+ case 2: return AU1500_PCI_INTB;
+ case 3: return AU1500_PCI_INTC;
+ case 4: return AU1500_PCI_INTD;
+ }
+ }
+ return -1;
+}
+
+static struct resource alchemy_pci_host_res[] = {
+ [0] = {
+ .start = AU1500_PCI_PHYS_ADDR,
+ .end = AU1500_PCI_PHYS_ADDR + 0xfff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct alchemy_pci_platdata pb1500_pci_pd = {
+ .board_map_irq = pb1500_map_pci_irq,
+ .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
+ PCI_CONFIG_CH |
+#if defined(__MIPSEB__)
+ PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
+#else
+ 0,
+#endif
+};
+
+static struct platform_device pb1500_pci_host = {
+ .dev.platform_data = &pb1500_pci_pd,
+ .name = "alchemy-pci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
+ .resource = alchemy_pci_host_res,
+};
+
+static int __init pb1500_dev_init(void)
+{
+ int swapped;
+
+ irq_set_irq_type(AU1500_GPIO9_INT, IRQF_TRIGGER_LOW); /* CD0# */
+ irq_set_irq_type(AU1500_GPIO10_INT, IRQF_TRIGGER_LOW); /* CARD0 */
+ irq_set_irq_type(AU1500_GPIO11_INT, IRQF_TRIGGER_LOW); /* STSCHG0# */
irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
+ /* PCMCIA. single socket, identical to Pb1100 */
+ db1x_register_pcmcia_socket(
+ AU1000_PCMCIA_ATTR_PHYS_ADDR,
+ AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_MEM_PHYS_ADDR,
+ AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
+ AU1000_PCMCIA_IO_PHYS_ADDR,
+ AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
+ AU1500_GPIO11_INT, AU1500_GPIO9_INT, /* card / insert */
+ /*AU1500_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
+
+ swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
+ db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
+ platform_device_register(&pb1500_pci_host);
+
return 0;
}
-arch_initcall(pb1500_init_irq);
+arch_initcall(pb1500_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1500/Makefile b/arch/mips/alchemy/devboards/pb1500/Makefile
deleted file mode 100644
index e83b151b5b63..000000000000
--- a/arch/mips/alchemy/devboards/pb1500/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2000, 2001, 2008 MontaVista Software Inc.
-# Author: MontaVista Software, Inc. <source@mvista.com>
-#
-# Makefile for the Alchemy Semiconductor Pb1500 board.
-#
-
-obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1500/platform.c b/arch/mips/alchemy/devboards/pb1500/platform.c
deleted file mode 100644
index 1e52a01bac00..000000000000
--- a/arch/mips/alchemy/devboards/pb1500/platform.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Pb1500 board platform device registration
- *
- * Copyright (C) 2009 Manuel Lauss
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/dma-mapping.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-db1x00/bcsr.h>
-
-#include "../platform.h"
-
-static int pb1500_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
-{
- if ((slot < 12) || (slot > 13) || pin == 0)
- return -1;
- if (slot == 12)
- return (pin == 1) ? AU1500_PCI_INTA : 0xff;
- if (slot == 13) {
- switch (pin) {
- case 1: return AU1500_PCI_INTA;
- case 2: return AU1500_PCI_INTB;
- case 3: return AU1500_PCI_INTC;
- case 4: return AU1500_PCI_INTD;
- }
- }
- return -1;
-}
-
-static struct resource alchemy_pci_host_res[] = {
- [0] = {
- .start = AU1500_PCI_PHYS_ADDR,
- .end = AU1500_PCI_PHYS_ADDR + 0xfff,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct alchemy_pci_platdata pb1500_pci_pd = {
- .board_map_irq = pb1500_map_pci_irq,
- .pci_cfg_set = PCI_CONFIG_AEN | PCI_CONFIG_R2H | PCI_CONFIG_R1H |
- PCI_CONFIG_CH |
-#if defined(__MIPSEB__)
- PCI_CONFIG_SIC_HWA_DAT | PCI_CONFIG_SM,
-#else
- 0,
-#endif
-};
-
-static struct platform_device pb1500_pci_host = {
- .dev.platform_data = &pb1500_pci_pd,
- .name = "alchemy-pci",
- .id = 0,
- .num_resources = ARRAY_SIZE(alchemy_pci_host_res),
- .resource = alchemy_pci_host_res,
-};
-
-static int __init pb1500_dev_init(void)
-{
- int swapped;
-
- /* PCMCIA. single socket, identical to Pb1100 */
- db1x_register_pcmcia_socket(
- AU1000_PCMCIA_ATTR_PHYS_ADDR,
- AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_MEM_PHYS_ADDR,
- AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- AU1000_PCMCIA_IO_PHYS_ADDR,
- AU1000_PCMCIA_IO_PHYS_ADDR + 0x000010000 - 1,
- AU1500_GPIO11_INT, AU1500_GPIO9_INT, /* card / insert */
- /*AU1500_GPIO10_INT*/0, 0, 0); /* stschg / eject / id */
-
- swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_DB1000_SWAPBOOT;
- db1x_register_norflash(64 * 1024 * 1024, 4, swapped);
- platform_device_register(&pb1500_pci_host);
-
- return 0;
-}
-arch_initcall(pb1500_dev_init);
diff --git a/arch/mips/alchemy/devboards/pb1550/platform.c b/arch/mips/alchemy/devboards/pb1550.c
index a4604b8a349e..b37e7de8d920 100644
--- a/arch/mips/alchemy/devboards/pb1550/platform.c
+++ b/arch/mips/alchemy/devboards/pb1550.c
@@ -1,7 +1,7 @@
/*
- * Pb1550 board platform device registration
+ * Pb1550 board support.
*
- * Copyright (C) 2009 Manuel Lauss
+ * Copyright (C) 2009-2011 Manuel Lauss
*
* 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
@@ -20,13 +20,44 @@
#include <linux/dma-mapping.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/au1xxx_dbdma.h>
-#include <asm/mach-pb1x00/pb1550.h>
+#include <asm/mach-au1x00/au1550nd.h>
+#include <asm/mach-au1x00/gpio.h>
#include <asm/mach-db1x00/bcsr.h>
+#include "platform.h"
-#include "../platform.h"
+const char *get_system_type(void)
+{
+ return "PB1550";
+}
+
+void __init board_setup(void)
+{
+ u32 pin_func;
+
+ bcsr_init(PB1550_BCSR_PHYS_ADDR,
+ PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
+
+ alchemy_gpio2_enable();
+
+ /*
+ * Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
+ * but it is board specific code, so put it here.
+ */
+ pin_func = au_readl(SYS_PINFUNC);
+ au_sync();
+ pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
+ au_writel(pin_func, SYS_PINFUNC);
+
+ bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
+
+ printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
+}
+
+/******************************************************************************/
static int pb1550_map_pci_irq(const struct pci_dev *d, u8 slot, u8 pin)
{
@@ -101,10 +132,79 @@ static struct platform_device pb1550_i2c_dev = {
.resource = au1550_psc2_res,
};
+static struct mtd_partition pb1550_nand_parts[] = {
+ [0] = {
+ .name = "NAND FS 0",
+ .offset = 0,
+ .size = 8 * 1024 * 1024,
+ },
+ [1] = {
+ .name = "NAND FS 1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct au1550nd_platdata pb1550_nand_pd = {
+ .parts = pb1550_nand_parts,
+ .num_parts = ARRAY_SIZE(pb1550_nand_parts),
+ .devwidth = 0, /* x8 NAND default, needs fixing up */
+};
+
+static struct resource pb1550_nand_res[] = {
+ [0] = {
+ .start = 0x20000000,
+ .end = 0x20000fff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device pb1550_nand_dev = {
+ .name = "au1550-nand",
+ .id = -1,
+ .resource = pb1550_nand_res,
+ .num_resources = ARRAY_SIZE(pb1550_nand_res),
+ .dev = {
+ .platform_data = &pb1550_nand_pd,
+ },
+};
+
+static void __init pb1550_nand_setup(void)
+{
+ int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) |
+ ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
+
+ switch (boot_swapboot) {
+ case 0:
+ case 2:
+ case 8:
+ case 0xC:
+ case 0xD:
+ /* x16 NAND Flash */
+ pb1550_nand_pd.devwidth = 1;
+ /* fallthrough */
+ case 1:
+ case 9:
+ case 3:
+ case 0xE:
+ case 0xF:
+ /* x8 NAND, already set up */
+ platform_device_register(&pb1550_nand_dev);
+ }
+}
+
static int __init pb1550_dev_init(void)
{
int swapped;
+ irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
+ irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
+
+ /* enable both PCMCIA card irqs in the shared line */
+ alchemy_gpio2_enable_int(201);
+ alchemy_gpio2_enable_int(202);
+
/* Pb1550, like all others, also has statuschange irqs; however they're
* wired up on one of the Au1550's shared GPIO201_205 line, which also
* services the PCMCIA card interrupts. So we ignore statuschange and
@@ -130,6 +230,10 @@ static int __init pb1550_dev_init(void)
AU1000_PCMCIA_IO_PHYS_ADDR + 0x008010000 - 1,
AU1550_GPIO201_205_INT, AU1550_GPIO1_INT, 0, 0, 1);
+ /* NAND setup */
+ gpio_direction_input(206); /* GPIO206 high */
+ pb1550_nand_setup();
+
swapped = bcsr_read(BCSR_STATUS) & BCSR_STATUS_PB1550_SWAPBOOT;
db1x_register_norflash(128 * 1024 * 1024, 4, swapped);
platform_device_register(&pb1550_pci_host);
diff --git a/arch/mips/alchemy/devboards/pb1550/Makefile b/arch/mips/alchemy/devboards/pb1550/Makefile
deleted file mode 100644
index 9661b6ec5dd3..000000000000
--- a/arch/mips/alchemy/devboards/pb1550/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2000, 2008 MontaVista Software Inc.
-# Author: MontaVista Software, Inc. <source@mvista.com>
-#
-# Makefile for the Alchemy Semiconductor Pb1550 board.
-#
-
-obj-y := board_setup.o platform.o
diff --git a/arch/mips/alchemy/devboards/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c
deleted file mode 100644
index 0f62d1e3df24..000000000000
--- a/arch/mips/alchemy/devboards/pb1550/board_setup.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * Alchemy Pb1550 board setup.
- *
- * Copyright 2000, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-pb1x00/pb1550.h>
-#include <asm/mach-db1x00/bcsr.h>
-#include <asm/mach-au1x00/gpio.h>
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
- return "Alchemy Pb1550";
-}
-
-void __init board_setup(void)
-{
- u32 pin_func;
-
- bcsr_init(PB1550_BCSR_PHYS_ADDR,
- PB1550_BCSR_PHYS_ADDR + PB1550_BCSR_HEXLED_OFS);
-
- alchemy_gpio2_enable();
-
- /*
- * Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
- * but it is board specific code, so put it here.
- */
- pin_func = au_readl(SYS_PINFUNC);
- au_sync();
- pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
- au_writel(pin_func, SYS_PINFUNC);
-
- bcsr_write(BCSR_PCMCIA, 0); /* turn off PCMCIA power */
-
- printk(KERN_INFO "AMD Alchemy Pb1550 Board\n");
-}
-
-static int __init pb1550_init_irq(void)
-{
- irq_set_irq_type(AU1550_GPIO0_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1550_GPIO1_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1550_GPIO201_205_INT, IRQF_TRIGGER_HIGH);
-
- /* enable both PCMCIA card irqs in the shared line */
- alchemy_gpio2_enable_int(201);
- alchemy_gpio2_enable_int(202);
-
- return 0;
-}
-arch_initcall(pb1550_init_irq);
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c
index 49a4b3244d8e..621f70afb63a 100644
--- a/arch/mips/alchemy/devboards/platform.c
+++ b/arch/mips/alchemy/devboards/platform.c
@@ -13,6 +13,13 @@
#include <asm/reboot.h>
#include <asm/mach-db1x00/bcsr.h>
+
+static struct platform_device db1x00_rtc_dev = {
+ .name = "rtc-au1xxx",
+ .id = -1,
+};
+
+
static void db1x_power_off(void)
{
bcsr_write(BCSR_RESETS, 0);
@@ -25,7 +32,7 @@ static void db1x_reset(char *c)
bcsr_write(BCSR_SYSTEM, 0);
}
-static int __init db1x_poweroff_setup(void)
+static int __init db1x_late_setup(void)
{
if (!pm_power_off)
pm_power_off = db1x_power_off;
@@ -34,9 +41,11 @@ static int __init db1x_poweroff_setup(void)
if (!_machine_restart)
_machine_restart = db1x_reset;
+ platform_device_register(&db1x00_rtc_dev);
+
return 0;
}
-late_initcall(db1x_poweroff_setup);
+device_initcall(db1x_late_setup);
/* register a pcmcia socket */
int __init db1x_register_pcmcia_socket(phys_addr_t pcmcia_attr_start,
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c
index e5306b56da6d..93a22107cc41 100644
--- a/arch/mips/alchemy/devboards/prom.c
+++ b/arch/mips/alchemy/devboards/prom.c
@@ -33,10 +33,9 @@
#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_DB1000) || \
- defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || \
- defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_DB1500) || \
- defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
+#if defined(CONFIG_MIPS_DB1000) || \
+ defined(CONFIG_MIPS_PB1100) || \
+ defined(CONFIG_MIPS_PB1500)
#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000
#else /* Au1550/Au1200-based develboards */
@@ -62,5 +61,9 @@ void __init prom_init(void)
void prom_putchar(unsigned char c)
{
+#ifdef CONFIG_MIPS_DB1300
+ alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
+#else
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+#endif
}
diff --git a/arch/mips/alchemy/gpr/Makefile b/arch/mips/alchemy/gpr/Makefile
deleted file mode 100644
index cb73fe256dce..000000000000
--- a/arch/mips/alchemy/gpr/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2003 MontaVista Software Inc.
-# Author: MontaVista Software, Inc. <source@mvista.com>
-#
-# Makefile for Trapeze ITS GPR board.
-#
-
-obj-y += board_setup.o init.o platform.o
diff --git a/arch/mips/alchemy/gpr/board_setup.c b/arch/mips/alchemy/gpr/board_setup.c
deleted file mode 100644
index dea45c78fdcd..000000000000
--- a/arch/mips/alchemy/gpr/board_setup.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright 2010 Wolfgang Grandegger <wg@denx.de>
- *
- * Copyright 2000-2003, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-
-#include <asm/reboot.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#include <prom.h>
-
-static void gpr_reset(char *c)
-{
- /* switch System-LED to orange (red# and green# on) */
- alchemy_gpio_direction_output(4, 0);
- alchemy_gpio_direction_output(5, 0);
-
- /* trigger watchdog to reset board in 200ms */
- printk(KERN_EMERG "Triggering watchdog soft reset...\n");
- raw_local_irq_disable();
- alchemy_gpio_direction_output(1, 0);
- udelay(1);
- alchemy_gpio_set_value(1, 1);
- while (1)
- cpu_wait();
-}
-
-static void gpr_power_off(void)
-{
- while (1)
- cpu_wait();
-}
-
-void __init board_setup(void)
-{
- printk(KERN_INFO "Trapeze ITS GPR board\n");
-
- pm_power_off = gpr_power_off;
- _machine_halt = gpr_power_off;
- _machine_restart = gpr_reset;
-
- /* Enable UART1/3 */
- alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
- alchemy_uart_enable(AU1000_UART1_PHYS_ADDR);
-
- /* Take away Reset of UMTS-card */
- alchemy_gpio_direction_output(215, 1);
-}
diff --git a/arch/mips/alchemy/gpr/init.c b/arch/mips/alchemy/gpr/init.c
deleted file mode 100644
index 229aafae680c..000000000000
--- a/arch/mips/alchemy/gpr/init.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright 2010 Wolfgang Grandegger <wg@denx.de>
- *
- * Copyright 2003, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/bootinfo.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
- return "GPR";
-}
-
-void __init prom_init(void)
-{
- unsigned char *memsize_str;
- unsigned long memsize;
-
- prom_argc = fw_arg0;
- prom_argv = (char **)fw_arg1;
- prom_envp = (char **)fw_arg2;
-
- prom_init_cmdline();
-
- memsize_str = prom_getenv("memsize");
- if (!memsize_str)
- memsize = 0x04000000;
- else
- strict_strtoul(memsize_str, 0, &memsize);
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
-
-void prom_putchar(unsigned char c)
-{
- alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
-}
diff --git a/arch/mips/alchemy/mtx-1/Makefile b/arch/mips/alchemy/mtx-1/Makefile
deleted file mode 100644
index 81b540ceaf88..000000000000
--- a/arch/mips/alchemy/mtx-1/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# Copyright 2003 MontaVista Software Inc.
-# Author: MontaVista Software, Inc. <source@mvista.com>
-# Bruno Randolf <bruno.randolf@4g-systems.biz>
-#
-# Makefile for 4G Systems MTX-1 board.
-#
-
-obj-y += init.o board_setup.o platform.o
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c
deleted file mode 100644
index 851a5ab4c8f2..000000000000
--- a/arch/mips/alchemy/mtx-1/board_setup.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * 4G Systems MTX-1 board setup.
- *
- * Copyright 2003, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- * Bruno Randolf <bruno.randolf@4g-systems.biz>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pm.h>
-
-#include <asm/reboot.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#include <prom.h>
-
-static void mtx1_reset(char *c)
-{
- /* Jump to the reset vector */
- __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-static void mtx1_power_off(void)
-{
- while (1)
- asm volatile (
- " .set mips32 \n"
- " wait \n"
- " .set mips0 \n");
-}
-
-void __init board_setup(void)
-{
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
- /* Enable USB power switch */
- alchemy_gpio_direction_output(204, 0);
-#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
-
- /* Initialize sys_pinfunc */
- au_writel(SYS_PF_NI2, SYS_PINFUNC);
-
- /* Initialize GPIO */
- au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR);
- alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */
- alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */
- alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */
- alchemy_gpio_direction_output(5, 0); /* Disable eth PHY TX_ER */
-
- /* Enable LED and set it to green */
- alchemy_gpio_direction_output(211, 1); /* green on */
- alchemy_gpio_direction_output(212, 0); /* red off */
-
- pm_power_off = mtx1_power_off;
- _machine_halt = mtx1_power_off;
- _machine_restart = mtx1_reset;
-
- printk(KERN_INFO "4G Systems MTX-1 Board\n");
-}
-
-static int __init mtx1_init_irq(void)
-{
- irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
- irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
-
- return 0;
-}
-arch_initcall(mtx1_init_irq);
diff --git a/arch/mips/alchemy/mtx-1/init.c b/arch/mips/alchemy/mtx-1/init.c
deleted file mode 100644
index 2e81cc7f3422..000000000000
--- a/arch/mips/alchemy/mtx-1/init.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * 4G Systems MTX-1 board setup
- *
- * Copyright 2003, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- * Bruno Randolf <bruno.randolf@4g-systems.biz>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-
-#include <asm/bootinfo.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
- return "MTX-1";
-}
-
-void __init prom_init(void)
-{
- unsigned char *memsize_str;
- unsigned long memsize;
-
- prom_argc = fw_arg0;
- prom_argv = (char **)fw_arg1;
- prom_envp = (char **)fw_arg2;
-
- prom_init_cmdline();
-
- memsize_str = prom_getenv("memsize");
- if (!memsize_str)
- memsize = 0x04000000;
- else
- strict_strtoul(memsize_str, 0, &memsize);
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
-
-void prom_putchar(unsigned char c)
-{
- alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
-}
diff --git a/arch/mips/alchemy/xxs1500/Makefile b/arch/mips/alchemy/xxs1500/Makefile
deleted file mode 100644
index 91defcf4f335..000000000000
--- a/arch/mips/alchemy/xxs1500/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# Copyright 2003 MontaVista Software Inc.
-# Author: MontaVista Software, Inc. <source@mvista.com>
-#
-# Makefile for MyCable XXS1500 board.
-#
-
-obj-y += init.o board_setup.o platform.o
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c
deleted file mode 100644
index 3fa83f72e014..000000000000
--- a/arch/mips/alchemy/xxs1500/board_setup.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2000-2003, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/gpio.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/pm.h>
-
-#include <asm/reboot.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#include <prom.h>
-
-static void xxs1500_reset(char *c)
-{
- /* Jump to the reset vector */
- __asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
-}
-
-static void xxs1500_power_off(void)
-{
- while (1)
- asm volatile (
- " .set mips32 \n"
- " wait \n"
- " .set mips0 \n");
-}
-
-void __init board_setup(void)
-{
- u32 pin_func;
-
- pm_power_off = xxs1500_power_off;
- _machine_halt = xxs1500_power_off;
- _machine_restart = xxs1500_reset;
-
- alchemy_gpio1_input_enable();
- alchemy_gpio2_enable();
-
- /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
- pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
- pin_func |= SYS_PF_UR3;
- au_writel(pin_func, SYS_PINFUNC);
-
- /* Enable UART */
- alchemy_uart_enable(AU1000_UART3_PHYS_ADDR);
- /* Enable DTR (MCR bit 0) = USB power up */
- __raw_writel(1, (void __iomem *)KSEG1ADDR(AU1000_UART3_PHYS_ADDR + 0x18));
- wmb();
-}
-
-static int __init xxs1500_init_irq(void)
-{
- irq_set_irq_type(AU1500_GPIO204_INT, IRQF_TRIGGER_HIGH);
- irq_set_irq_type(AU1500_GPIO201_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO202_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO203_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO205_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO207_INT, IRQF_TRIGGER_LOW);
-
- irq_set_irq_type(AU1500_GPIO0_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO1_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO2_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO3_INT, IRQF_TRIGGER_LOW);
- irq_set_irq_type(AU1500_GPIO4_INT, IRQF_TRIGGER_LOW); /* CF irq */
- irq_set_irq_type(AU1500_GPIO5_INT, IRQF_TRIGGER_LOW);
-
- return 0;
-}
-arch_initcall(xxs1500_init_irq);
diff --git a/arch/mips/alchemy/xxs1500/init.c b/arch/mips/alchemy/xxs1500/init.c
deleted file mode 100644
index 0ee02cfa989d..000000000000
--- a/arch/mips/alchemy/xxs1500/init.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * XXS1500 board setup
- *
- * Copyright 2003, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#include <linux/init.h>
-#include <linux/kernel.h>
-
-#include <asm/bootinfo.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
- return "XXS1500";
-}
-
-void __init prom_init(void)
-{
- unsigned char *memsize_str;
- unsigned long memsize;
-
- prom_argc = fw_arg0;
- prom_argv = (char **)fw_arg1;
- prom_envp = (char **)fw_arg2;
-
- prom_init_cmdline();
-
- memsize_str = prom_getenv("memsize");
- if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize))
- memsize = 0x04000000;
-
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
-
-void prom_putchar(unsigned char c)
-{
- alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
-}
diff --git a/arch/mips/alchemy/xxs1500/platform.c b/arch/mips/alchemy/xxs1500/platform.c
deleted file mode 100644
index 06a3a459b8aa..000000000000
--- a/arch/mips/alchemy/xxs1500/platform.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * XXS1500 board platform device registration
- *
- * Copyright (C) 2009 Manuel Lauss
- *
- * 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 St, Fifth Floor, Boston, MA 02110-1301 USA
- */
-
-#include <linux/init.h>
-#include <linux/platform_device.h>
-
-#include <asm/mach-au1x00/au1000.h>
-
-static struct resource xxs1500_pcmcia_res[] = {
- {
- .name = "pcmcia-io",
- .flags = IORESOURCE_MEM,
- .start = AU1000_PCMCIA_IO_PHYS_ADDR,
- .end = AU1000_PCMCIA_IO_PHYS_ADDR + 0x000400000 - 1,
- },
- {
- .name = "pcmcia-attr",
- .flags = IORESOURCE_MEM,
- .start = AU1000_PCMCIA_ATTR_PHYS_ADDR,
- .end = AU1000_PCMCIA_ATTR_PHYS_ADDR + 0x000400000 - 1,
- },
- {
- .name = "pcmcia-mem",
- .flags = IORESOURCE_MEM,
- .start = AU1000_PCMCIA_MEM_PHYS_ADDR,
- .end = AU1000_PCMCIA_MEM_PHYS_ADDR + 0x000400000 - 1,
- },
-};
-
-static struct platform_device xxs1500_pcmcia_dev = {
- .name = "xxs1500_pcmcia",
- .id = -1,
- .num_resources = ARRAY_SIZE(xxs1500_pcmcia_res),
- .resource = xxs1500_pcmcia_res,
-};
-
-static struct platform_device *xxs1500_devs[] __initdata = {
- &xxs1500_pcmcia_dev,
-};
-
-static int __init xxs1500_dev_init(void)
-{
- return platform_add_devices(xxs1500_devs,
- ARRAY_SIZE(xxs1500_devs));
-}
-device_initcall(xxs1500_dev_init);
diff --git a/arch/mips/ar7/gpio.c b/arch/mips/ar7/gpio.c
index bb571bcdb8f2..d8dbd8f0c1d2 100644
--- a/arch/mips/ar7/gpio.c
+++ b/arch/mips/ar7/gpio.c
@@ -217,7 +217,7 @@ struct titan_gpio_cfg {
u32 func;
};
-static struct titan_gpio_cfg titan_gpio_table[] = {
+static const struct titan_gpio_cfg titan_gpio_table[] = {
/* reg, start bit, mux value */
{4, 24, 1},
{4, 26, 1},
diff --git a/arch/mips/ar7/platform.c b/arch/mips/ar7/platform.c
index 33ffecf6a6d6..1a24d317e7a3 100644
--- a/arch/mips/ar7/platform.c
+++ b/arch/mips/ar7/platform.c
@@ -462,6 +462,40 @@ static struct gpio_led fb_fon_leds[] = {
},
};
+static struct gpio_led gt701_leds[] = {
+ {
+ .name = "inet:green",
+ .gpio = 13,
+ .active_low = 1,
+ },
+ {
+ .name = "usb",
+ .gpio = 12,
+ .active_low = 1,
+ },
+ {
+ .name = "inet:red",
+ .gpio = 9,
+ .active_low = 1,
+ },
+ {
+ .name = "power:red",
+ .gpio = 7,
+ .active_low = 1,
+ },
+ {
+ .name = "power:green",
+ .gpio = 8,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "ethernet",
+ .gpio = 10,
+ .active_low = 1,
+ },
+};
+
static struct gpio_led_platform_data ar7_led_data;
static struct platform_device ar7_gpio_leds = {
@@ -503,6 +537,9 @@ static void __init detect_leds(void)
} else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
ar7_led_data.leds = titan_leds;
+ } else if (strstr(prid, "GT701")) {
+ ar7_led_data.num_leds = ARRAY_SIZE(gt701_leds);
+ ar7_led_data.leds = gt701_leds;
}
}
@@ -536,7 +573,7 @@ static int __init ar7_register_uarts(void)
bus_clk = clk_get(NULL, "bus");
if (IS_ERR(bus_clk))
- panic("unable to get bus clk\n");
+ panic("unable to get bus clk");
uart_port.type = PORT_AR7;
uart_port.uartclk = clk_get_rate(bus_clk) / 2;
diff --git a/arch/mips/ar7/prom.c b/arch/mips/ar7/prom.c
index 8088c6fdb83e..a23adc49d50f 100644
--- a/arch/mips/ar7/prom.c
+++ b/arch/mips/ar7/prom.c
@@ -69,7 +69,7 @@ struct psbl_rec {
u32 ffs_size;
};
-static __initdata char psp_env_version[] = "TIENV0.8";
+static const char psp_env_version[] __initconst = "TIENV0.8";
struct psp_env_chunk {
u8 num;
@@ -84,7 +84,7 @@ struct psp_var_map_entry {
char *value;
};
-static struct psp_var_map_entry psp_var_map[] = {
+static const struct psp_var_map_entry psp_var_map[] = {
{ 1, "cpufrequency" },
{ 2, "memsize" },
{ 3, "flashsize" },
diff --git a/arch/mips/ar7/setup.c b/arch/mips/ar7/setup.c
index f20b53e597c4..9a357fffcfbe 100644
--- a/arch/mips/ar7/setup.c
+++ b/arch/mips/ar7/setup.c
@@ -96,7 +96,7 @@ void __init plat_mem_setup(void)
io_base = (unsigned long)ioremap(AR7_REGS_BASE, 0x10000);
if (!io_base)
- panic("Can't remap IO base!\n");
+ panic("Can't remap IO base!");
set_io_port_base(io_base);
prom_meminit();
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 47707410582c..e0fae8f4442b 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -2,13 +2,26 @@ if ATH79
menu "Atheros AR71XX/AR724X/AR913X machine selection"
+config ATH79_MACH_AP121
+ bool "Atheros AP121 reference board"
+ select SOC_AR933X
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
+ select ATH79_DEV_USB
+ select ATH79_DEV_WMAC
+ help
+ Say 'Y' here if you want your kernel to support the
+ Atheros AP121 reference board.
+
config ATH79_MACH_AP81
bool "Atheros AP81 reference board"
select SOC_AR913X
- select ATH79_DEV_AR913X_WMAC
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
select ATH79_DEV_SPI
+ select ATH79_DEV_USB
+ select ATH79_DEV_WMAC
help
Say 'Y' here if you want your kernel to support the
Atheros AP81 reference board.
@@ -19,10 +32,21 @@ config ATH79_MACH_PB44
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
select ATH79_DEV_SPI
+ select ATH79_DEV_USB
help
Say 'Y' here if you want your kernel to support the
Atheros PB44 reference board.
+config ATH79_MACH_UBNT_XM
+ bool "Ubiquiti Networks XM (rev 1.0) board"
+ select SOC_AR724X
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
+ help
+ Say 'Y' here if you want your kernel to support the
+ Ubiquiti Networks XM (rev 1.0) board.
+
endmenu
config SOC_AR71XX
@@ -33,14 +57,15 @@ config SOC_AR71XX
config SOC_AR724X
select USB_ARCH_HAS_EHCI
select USB_ARCH_HAS_OHCI
+ select HW_HAS_PCI
def_bool n
config SOC_AR913X
select USB_ARCH_HAS_EHCI
def_bool n
-config ATH79_DEV_AR913X_WMAC
- depends on SOC_AR913X
+config SOC_AR933X
+ select USB_ARCH_HAS_EHCI
def_bool n
config ATH79_DEV_GPIO_BUTTONS
@@ -52,4 +77,11 @@ config ATH79_DEV_LEDS_GPIO
config ATH79_DEV_SPI
def_bool n
+config ATH79_DEV_USB
+ def_bool n
+
+config ATH79_DEV_WMAC
+ depends on (SOC_AR913X || SOC_AR933X)
+ def_bool n
+
endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index c33d4653007c..3b911e09dbec 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,13 +16,16 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
# Devices
#
obj-y += dev-common.o
-obj-$(CONFIG_ATH79_DEV_AR913X_WMAC) += dev-ar913x-wmac.o
obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o
+obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o
+obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o
#
# Machines
#
+obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
+obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c
index 680bde99a26c..54d0eb4db987 100644
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -110,6 +110,59 @@ static void __init ar913x_clocks_init(void)
ath79_uart_clk.rate = ath79_ahb_clk.rate;
}
+static void __init ar933x_clocks_init(void)
+{
+ u32 clock_ctrl;
+ u32 cpu_config;
+ u32 freq;
+ u32 t;
+
+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
+ if (t & AR933X_BOOTSTRAP_REF_CLK_40)
+ ath79_ref_clk.rate = (40 * 1000 * 1000);
+ else
+ ath79_ref_clk.rate = (25 * 1000 * 1000);
+
+ clock_ctrl = ath79_pll_rr(AR933X_PLL_CLOCK_CTRL_REG);
+ if (clock_ctrl & AR933X_PLL_CLOCK_CTRL_BYPASS) {
+ ath79_cpu_clk.rate = ath79_ref_clk.rate;
+ ath79_ahb_clk.rate = ath79_ref_clk.rate;
+ ath79_ddr_clk.rate = ath79_ref_clk.rate;
+ } else {
+ cpu_config = ath79_pll_rr(AR933X_PLL_CPU_CONFIG_REG);
+
+ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+ AR933X_PLL_CPU_CONFIG_REFDIV_MASK;
+ freq = ath79_ref_clk.rate / t;
+
+ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_NINT_SHIFT) &
+ AR933X_PLL_CPU_CONFIG_NINT_MASK;
+ freq *= t;
+
+ t = (cpu_config >> AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+ AR933X_PLL_CPU_CONFIG_OUTDIV_MASK;
+ if (t == 0)
+ t = 1;
+
+ freq >>= t;
+
+ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT) &
+ AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK) + 1;
+ ath79_cpu_clk.rate = freq / t;
+
+ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT) &
+ AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK) + 1;
+ ath79_ddr_clk.rate = freq / t;
+
+ t = ((clock_ctrl >> AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT) &
+ AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK) + 1;
+ ath79_ahb_clk.rate = freq / t;
+ }
+
+ ath79_wdt_clk.rate = ath79_ref_clk.rate;
+ ath79_uart_clk.rate = ath79_ref_clk.rate;
+}
+
void __init ath79_clocks_init(void)
{
if (soc_is_ar71xx())
@@ -118,6 +171,8 @@ void __init ath79_clocks_init(void)
ar724x_clocks_init();
else if (soc_is_ar913x())
ar913x_clocks_init();
+ else if (soc_is_ar933x())
+ ar933x_clocks_init();
else
BUG();
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
index 58f60e722a03..f0fda982b965 100644
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -30,6 +30,7 @@ u32 ath79_ddr_freq;
EXPORT_SYMBOL_GPL(ath79_ddr_freq);
enum ath79_soc_type ath79_soc;
+unsigned int ath79_soc_rev;
void __iomem *ath79_pll_base;
void __iomem *ath79_reset_base;
@@ -64,6 +65,8 @@ void ath79_device_reset_set(u32 mask)
reg = AR724X_RESET_REG_RESET_MODULE;
else if (soc_is_ar913x())
reg = AR913X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar933x())
+ reg = AR933X_RESET_REG_RESET_MODULE;
else
BUG();
@@ -86,6 +89,8 @@ void ath79_device_reset_clear(u32 mask)
reg = AR724X_RESET_REG_RESET_MODULE;
else if (soc_is_ar913x())
reg = AR913X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar933x())
+ reg = AR933X_RESET_REG_RESET_MODULE;
else
BUG();
diff --git a/arch/mips/ath79/dev-ar913x-wmac.c b/arch/mips/ath79/dev-ar913x-wmac.c
deleted file mode 100644
index 48f425a5ba28..000000000000
--- a/arch/mips/ath79/dev-ar913x-wmac.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Atheros AR913X SoC built-in WMAC device support
- *
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
- * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 as published
- * by the Free Software Foundation.
- */
-
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/platform_device.h>
-#include <linux/ath9k_platform.h>
-
-#include <asm/mach-ath79/ath79.h>
-#include <asm/mach-ath79/ar71xx_regs.h>
-#include "dev-ar913x-wmac.h"
-
-static struct ath9k_platform_data ar913x_wmac_data;
-
-static struct resource ar913x_wmac_resources[] = {
- {
- .start = AR913X_WMAC_BASE,
- .end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1,
- .flags = IORESOURCE_MEM,
- }, {
- .start = ATH79_CPU_IRQ_IP2,
- .end = ATH79_CPU_IRQ_IP2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device ar913x_wmac_device = {
- .name = "ath9k",
- .id = -1,
- .resource = ar913x_wmac_resources,
- .num_resources = ARRAY_SIZE(ar913x_wmac_resources),
- .dev = {
- .platform_data = &ar913x_wmac_data,
- },
-};
-
-void __init ath79_register_ar913x_wmac(u8 *cal_data)
-{
- if (cal_data)
- memcpy(ar913x_wmac_data.eeprom_data, cal_data,
- sizeof(ar913x_wmac_data.eeprom_data));
-
- /* reset the WMAC */
- ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
- mdelay(10);
-
- ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
- mdelay(10);
-
- platform_device_register(&ar913x_wmac_device);
-}
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
index 3b82e325bebf..f4956f809072 100644
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -20,6 +20,7 @@
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ar933x_uart_platform.h>
#include "common.h"
#include "dev-common.h"
@@ -54,6 +55,30 @@ static struct platform_device ath79_uart_device = {
},
};
+static struct resource ar933x_uart_resources[] = {
+ {
+ .start = AR933X_UART_BASE,
+ .end = AR933X_UART_BASE + AR71XX_UART_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = ATH79_MISC_IRQ_UART,
+ .end = ATH79_MISC_IRQ_UART,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct ar933x_uart_platform_data ar933x_uart_data;
+static struct platform_device ar933x_uart_device = {
+ .name = "ar933x-uart",
+ .id = -1,
+ .resource = ar933x_uart_resources,
+ .num_resources = ARRAY_SIZE(ar933x_uart_resources),
+ .dev = {
+ .platform_data = &ar933x_uart_data,
+ },
+};
+
void __init ath79_register_uart(void)
{
struct clk *clk;
@@ -62,8 +87,17 @@ void __init ath79_register_uart(void)
if (IS_ERR(clk))
panic("unable to get UART clock, err=%ld", PTR_ERR(clk));
- ath79_uart_data[0].uartclk = clk_get_rate(clk);
- platform_device_register(&ath79_uart_device);
+ if (soc_is_ar71xx() ||
+ soc_is_ar724x() ||
+ soc_is_ar913x()) {
+ ath79_uart_data[0].uartclk = clk_get_rate(clk);
+ platform_device_register(&ath79_uart_device);
+ } else if (soc_is_ar933x()) {
+ ar933x_uart_data.uartclk = clk_get_rate(clk);
+ platform_device_register(&ar933x_uart_device);
+ } else {
+ BUG();
+ }
}
static struct platform_device ath79_wdt_device = {
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
new file mode 100644
index 000000000000..002d6d2afe04
--- /dev/null
+++ b/arch/mips/ath79/dev-usb.c
@@ -0,0 +1,197 @@
+/*
+ * Atheros AR7XXX/AR9XXX USB Host Controller device
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * This program is free software; you can 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/delay.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-usb.h"
+
+static struct resource ath79_ohci_resources[] = {
+ [0] = {
+ /* .start and .end fields are filled dynamically */
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ATH79_MISC_IRQ_OHCI,
+ .end = ATH79_MISC_IRQ_OHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
+static struct platform_device ath79_ohci_device = {
+ .name = "ath79-ohci",
+ .id = -1,
+ .resource = ath79_ohci_resources,
+ .num_resources = ARRAY_SIZE(ath79_ohci_resources),
+ .dev = {
+ .dma_mask = &ath79_ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource ath79_ehci_resources[] = {
+ [0] = {
+ /* .start and .end fields are filled dynamically */
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ATH79_CPU_IRQ_USB,
+ .end = ATH79_CPU_IRQ_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
+static struct platform_device ath79_ehci_device = {
+ .name = "ath79-ehci",
+ .id = -1,
+ .resource = ath79_ehci_resources,
+ .num_resources = ARRAY_SIZE(ath79_ehci_resources),
+ .dev = {
+ .dma_mask = &ath79_ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \
+ AR71XX_RESET_USB_PHY | \
+ AR71XX_RESET_USB_OHCI_DLL)
+
+static void __init ath79_usb_setup(void)
+{
+ void __iomem *usb_ctrl_base;
+
+ ath79_device_reset_set(AR71XX_USB_RESET_MASK);
+ mdelay(1000);
+ ath79_device_reset_clear(AR71XX_USB_RESET_MASK);
+
+ usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE, AR71XX_USB_CTRL_SIZE);
+
+ /* Turning on the Buff and Desc swap bits */
+ __raw_writel(0xf0000, usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG);
+
+ /* WAR for HW bug. Here it adjusts the duration between two SOFS */
+ __raw_writel(0x20c00, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+ iounmap(usb_ctrl_base);
+
+ mdelay(900);
+
+ ath79_ohci_resources[0].start = AR71XX_OHCI_BASE;
+ ath79_ohci_resources[0].end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1;
+ platform_device_register(&ath79_ohci_device);
+
+ ath79_ehci_resources[0].start = AR71XX_EHCI_BASE;
+ ath79_ehci_resources[0].end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1;
+ ath79_ehci_device.name = "ar71xx-ehci";
+ platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar7240_usb_setup(void)
+{
+ void __iomem *usb_ctrl_base;
+
+ ath79_device_reset_clear(AR7240_RESET_OHCI_DLL);
+ ath79_device_reset_set(AR7240_RESET_USB_HOST);
+
+ mdelay(1000);
+
+ ath79_device_reset_set(AR7240_RESET_OHCI_DLL);
+ ath79_device_reset_clear(AR7240_RESET_USB_HOST);
+
+ usb_ctrl_base = ioremap(AR7240_USB_CTRL_BASE, AR7240_USB_CTRL_SIZE);
+
+ /* WAR for HW bug. Here it adjusts the duration between two SOFS */
+ __raw_writel(0x3, usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+ iounmap(usb_ctrl_base);
+
+ ath79_ohci_resources[0].start = AR7240_OHCI_BASE;
+ ath79_ohci_resources[0].end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1;
+ platform_device_register(&ath79_ohci_device);
+}
+
+static void __init ar724x_usb_setup(void)
+{
+ ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR724X_RESET_USB_HOST);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR724X_RESET_USB_PHY);
+ mdelay(10);
+
+ ath79_ehci_resources[0].start = AR724X_EHCI_BASE;
+ ath79_ehci_resources[0].end = AR724X_EHCI_BASE + AR724X_EHCI_SIZE - 1;
+ ath79_ehci_device.name = "ar724x-ehci";
+ platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar913x_usb_setup(void)
+{
+ ath79_device_reset_set(AR913X_RESET_USBSUS_OVERRIDE);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR913X_RESET_USB_HOST);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR913X_RESET_USB_PHY);
+ mdelay(10);
+
+ ath79_ehci_resources[0].start = AR913X_EHCI_BASE;
+ ath79_ehci_resources[0].end = AR913X_EHCI_BASE + AR913X_EHCI_SIZE - 1;
+ ath79_ehci_device.name = "ar913x-ehci";
+ platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar933x_usb_setup(void)
+{
+ ath79_device_reset_set(AR933X_RESET_USBSUS_OVERRIDE);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR933X_RESET_USB_HOST);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR933X_RESET_USB_PHY);
+ mdelay(10);
+
+ ath79_ehci_resources[0].start = AR933X_EHCI_BASE;
+ ath79_ehci_resources[0].end = AR933X_EHCI_BASE + AR933X_EHCI_SIZE - 1;
+ ath79_ehci_device.name = "ar933x-ehci";
+ platform_device_register(&ath79_ehci_device);
+}
+
+void __init ath79_register_usb(void)
+{
+ if (soc_is_ar71xx())
+ ath79_usb_setup();
+ else if (soc_is_ar7240())
+ ar7240_usb_setup();
+ else if (soc_is_ar7241() || soc_is_ar7242())
+ ar724x_usb_setup();
+ else if (soc_is_ar913x())
+ ar913x_usb_setup();
+ else if (soc_is_ar933x())
+ ar933x_usb_setup();
+ else
+ BUG();
+}
diff --git a/arch/mips/ath79/dev-ar913x-wmac.h b/arch/mips/ath79/dev-usb.h
index 579d562bbda8..4b86a69ca080 100644
--- a/arch/mips/ath79/dev-ar913x-wmac.h
+++ b/arch/mips/ath79/dev-usb.h
@@ -1,5 +1,5 @@
/*
- * Atheros AR913X SoC built-in WMAC device support
+ * Atheros AR71XX/AR724X/AR913X USB Host Controller support
*
* Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
@@ -9,9 +9,9 @@
* by the Free Software Foundation.
*/
-#ifndef _ATH79_DEV_AR913X_WMAC_H
-#define _ATH79_DEV_AR913X_WMAC_H
+#ifndef _ATH79_DEV_USB_H
+#define _ATH79_DEV_USB_H
-void ath79_register_ar913x_wmac(u8 *cal_data);
+void ath79_register_usb(void);
-#endif /* _ATH79_DEV_AR913X_WMAC_H */
+#endif /* _ATH79_DEV_USB_H */
diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c
new file mode 100644
index 000000000000..24f546985b69
--- /dev/null
+++ b/arch/mips/ath79/dev-wmac.c
@@ -0,0 +1,109 @@
+/*
+ * Atheros AR913X/AR933X SoC built-in WMAC device support
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-wmac.h"
+
+static struct ath9k_platform_data ath79_wmac_data;
+
+static struct resource ath79_wmac_resources[] = {
+ {
+ /* .start and .end fields are filled dynamically */
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = ATH79_CPU_IRQ_IP2,
+ .end = ATH79_CPU_IRQ_IP2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ath79_wmac_device = {
+ .name = "ath9k",
+ .id = -1,
+ .resource = ath79_wmac_resources,
+ .num_resources = ARRAY_SIZE(ath79_wmac_resources),
+ .dev = {
+ .platform_data = &ath79_wmac_data,
+ },
+};
+
+static void __init ar913x_wmac_setup(void)
+{
+ /* reset the WMAC */
+ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
+ ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
+}
+
+
+static int ar933x_wmac_reset(void)
+{
+ ath79_device_reset_clear(AR933X_RESET_WMAC);
+ ath79_device_reset_set(AR933X_RESET_WMAC);
+
+ return 0;
+}
+
+static int ar933x_r1_get_wmac_revision(void)
+{
+ return ath79_soc_rev;
+}
+
+static void __init ar933x_wmac_setup(void)
+{
+ u32 t;
+
+ ar933x_wmac_reset();
+
+ ath79_wmac_device.name = "ar933x_wmac";
+
+ ath79_wmac_resources[0].start = AR933X_WMAC_BASE;
+ ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
+
+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
+ if (t & AR933X_BOOTSTRAP_REF_CLK_40)
+ ath79_wmac_data.is_clk_25mhz = false;
+ else
+ ath79_wmac_data.is_clk_25mhz = true;
+
+ if (ath79_soc_rev == 1)
+ ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision;
+
+ ath79_wmac_data.external_reset = ar933x_wmac_reset;
+}
+
+void __init ath79_register_wmac(u8 *cal_data)
+{
+ if (soc_is_ar913x())
+ ar913x_wmac_setup();
+ if (soc_is_ar933x())
+ ar933x_wmac_setup();
+ else
+ BUG();
+
+ if (cal_data)
+ memcpy(ath79_wmac_data.eeprom_data, cal_data,
+ sizeof(ath79_wmac_data.eeprom_data));
+
+ platform_device_register(&ath79_wmac_device);
+}
diff --git a/arch/mips/ath79/dev-wmac.h b/arch/mips/ath79/dev-wmac.h
new file mode 100644
index 000000000000..c9cd8709f090
--- /dev/null
+++ b/arch/mips/ath79/dev-wmac.h
@@ -0,0 +1,17 @@
+/*
+ * Atheros AR913X/AR933X SoC built-in WMAC device support
+ *
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _ATH79_DEV_WMAC_H
+#define _ATH79_DEV_WMAC_H
+
+void ath79_register_wmac(u8 *cal_data);
+
+#endif /* _ATH79_DEV_WMAC_H */
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
index 7499b0e9df26..6a51ced7a293 100644
--- a/arch/mips/ath79/early_printk.c
+++ b/arch/mips/ath79/early_printk.c
@@ -1,7 +1,7 @@
/*
- * Atheros AR71XX/AR724X/AR913X SoC early printk support
+ * Atheros AR7XXX/AR9XXX SoC early printk support
*
- * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
* Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
*
* This program is free software; you can redistribute it and/or modify it
@@ -10,27 +10,85 @@
*/
#include <linux/io.h>
+#include <linux/errno.h>
#include <linux/serial_reg.h>
#include <asm/addrspace.h>
+#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ar933x_uart.h>
-static inline void prom_wait_thre(void __iomem *base)
+static void (*_prom_putchar) (unsigned char);
+
+static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
{
- u32 lsr;
+ u32 t;
do {
- lsr = __raw_readl(base + UART_LSR * 4);
- if (lsr & UART_LSR_THRE)
+ t = __raw_readl(reg);
+ if ((t & mask) == val)
break;
} while (1);
}
-void prom_putchar(unsigned char ch)
+static void prom_putchar_ar71xx(unsigned char ch)
{
void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
- prom_wait_thre(base);
+ prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
__raw_writel(ch, base + UART_TX * 4);
- prom_wait_thre(base);
+ prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
+}
+
+static void prom_putchar_ar933x(unsigned char ch)
+{
+ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR933X_UART_BASE));
+
+ prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
+ AR933X_UART_DATA_TX_CSR);
+ __raw_writel(AR933X_UART_DATA_TX_CSR | ch, base + AR933X_UART_DATA_REG);
+ prom_putchar_wait(base + AR933X_UART_DATA_REG, AR933X_UART_DATA_TX_CSR,
+ AR933X_UART_DATA_TX_CSR);
+}
+
+static void prom_putchar_dummy(unsigned char ch)
+{
+ /* nothing to do */
+}
+
+static void prom_putchar_init(void)
+{
+ void __iomem *base;
+ u32 id;
+
+ base = (void __iomem *)(KSEG1ADDR(AR71XX_RESET_BASE));
+ id = __raw_readl(base + AR71XX_RESET_REG_REV_ID);
+ id &= REV_ID_MAJOR_MASK;
+
+ switch (id) {
+ case REV_ID_MAJOR_AR71XX:
+ case REV_ID_MAJOR_AR7240:
+ case REV_ID_MAJOR_AR7241:
+ case REV_ID_MAJOR_AR7242:
+ case REV_ID_MAJOR_AR913X:
+ _prom_putchar = prom_putchar_ar71xx;
+ break;
+
+ case REV_ID_MAJOR_AR9330:
+ case REV_ID_MAJOR_AR9331:
+ _prom_putchar = prom_putchar_ar933x;
+ break;
+
+ default:
+ _prom_putchar = prom_putchar_dummy;
+ break;
+ }
+}
+
+void prom_putchar(unsigned char ch)
+{
+ if (!_prom_putchar)
+ prom_putchar_init();
+
+ _prom_putchar(ch);
}
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
index a0c426b82123..a2f8ca630ed6 100644
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -153,6 +153,8 @@ void __init ath79_gpio_init(void)
ath79_gpio_count = AR724X_GPIO_COUNT;
else if (soc_is_ar913x())
ath79_gpio_count = AR913X_GPIO_COUNT;
+ else if (soc_is_ar933x())
+ ath79_gpio_count = AR933X_GPIO_COUNT;
else
BUG();
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
index ac610d5fe3ba..1b073de44680 100644
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -46,6 +46,15 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
else if (pending & MISC_INT_TIMER)
generic_handle_irq(ATH79_MISC_IRQ_TIMER);
+ else if (pending & MISC_INT_TIMER2)
+ generic_handle_irq(ATH79_MISC_IRQ_TIMER2);
+
+ else if (pending & MISC_INT_TIMER3)
+ generic_handle_irq(ATH79_MISC_IRQ_TIMER3);
+
+ else if (pending & MISC_INT_TIMER4)
+ generic_handle_irq(ATH79_MISC_IRQ_TIMER4);
+
else if (pending & MISC_INT_OHCI)
generic_handle_irq(ATH79_MISC_IRQ_OHCI);
@@ -58,6 +67,9 @@ static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
else if (pending & MISC_INT_WDOG)
generic_handle_irq(ATH79_MISC_IRQ_WDOG);
+ else if (pending & MISC_INT_ETHSW)
+ generic_handle_irq(ATH79_MISC_IRQ_ETHSW);
+
else
spurious_interrupt();
}
@@ -117,7 +129,7 @@ static void __init ath79_misc_irq_init(void)
if (soc_is_ar71xx() || soc_is_ar913x())
ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
- else if (soc_is_ar724x())
+ else if (soc_is_ar724x() || soc_is_ar933x())
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
else
BUG();
@@ -174,6 +186,9 @@ void __init arch_init_irq(void)
} else if (soc_is_ar913x()) {
ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
+ } else if (soc_is_ar933x()) {
+ ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC;
+ ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB;
} else
BUG();
diff --git a/arch/mips/ath79/mach-ap121.c b/arch/mips/ath79/mach-ap121.c
new file mode 100644
index 000000000000..4c20200d7c72
--- /dev/null
+++ b/arch/mips/ath79/mach-ap121.c
@@ -0,0 +1,92 @@
+/*
+ * Atheros AP121 board support
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include "machtypes.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+#include "dev-usb.h"
+#include "dev-wmac.h"
+
+#define AP121_GPIO_LED_WLAN 0
+#define AP121_GPIO_LED_USB 1
+
+#define AP121_GPIO_BTN_JUMPSTART 11
+#define AP121_GPIO_BTN_RESET 12
+
+#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */
+#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL)
+
+#define AP121_CAL_DATA_ADDR 0x1fff1000
+
+static struct gpio_led ap121_leds_gpio[] __initdata = {
+ {
+ .name = "ap121:green:usb",
+ .gpio = AP121_GPIO_LED_USB,
+ .active_low = 0,
+ },
+ {
+ .name = "ap121:green:wlan",
+ .gpio = AP121_GPIO_LED_WLAN,
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_button ap121_gpio_keys[] __initdata = {
+ {
+ .desc = "jumpstart button",
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP121_GPIO_BTN_JUMPSTART,
+ .active_low = 1,
+ },
+ {
+ .desc = "reset button",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP121_GPIO_BTN_RESET,
+ .active_low = 1,
+ }
+};
+
+static struct spi_board_info ap121_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "mx25l1606e",
+ }
+};
+
+static struct ath79_spi_platform_data ap121_spi_data = {
+ .bus_num = 0,
+ .num_chipselect = 1,
+};
+
+static void __init ap121_setup(void)
+{
+ u8 *cal_data = (u8 *) KSEG1ADDR(AP121_CAL_DATA_ADDR);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio),
+ ap121_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ap121_gpio_keys),
+ ap121_gpio_keys);
+
+ ath79_register_spi(&ap121_spi_data, ap121_spi_info,
+ ARRAY_SIZE(ap121_spi_info));
+ ath79_register_usb();
+ ath79_register_wmac(cal_data);
+}
+
+MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board",
+ ap121_setup);
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
index eee4c121deb4..abe19836331c 100644
--- a/arch/mips/ath79/mach-ap81.c
+++ b/arch/mips/ath79/mach-ap81.c
@@ -10,10 +10,11 @@
*/
#include "machtypes.h"
-#include "dev-ar913x-wmac.h"
+#include "dev-wmac.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#include "dev-spi.h"
+#include "dev-usb.h"
#define AP81_GPIO_LED_STATUS 1
#define AP81_GPIO_LED_AOSS 3
@@ -91,7 +92,8 @@ static void __init ap81_setup(void)
ap81_gpio_keys);
ath79_register_spi(&ap81_spi_data, ap81_spi_info,
ARRAY_SIZE(ap81_spi_info));
- ath79_register_ar913x_wmac(cal_data);
+ ath79_register_wmac(cal_data);
+ ath79_register_usb();
}
MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index ec7b7a135d53..fe9701a32291 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -18,6 +18,7 @@
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#include "dev-spi.h"
+#include "dev-usb.h"
#define PB44_GPIO_I2C_SCL 0
#define PB44_GPIO_I2C_SDA 1
@@ -112,6 +113,7 @@ static void __init pb44_init(void)
pb44_gpio_keys);
ath79_register_spi(&pb44_spi_data, pb44_spi_info,
ARRAY_SIZE(pb44_spi_info));
+ ath79_register_usb();
}
MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c
new file mode 100644
index 000000000000..3c311a539347
--- /dev/null
+++ b/arch/mips/ath79/mach-ubnt-xm.c
@@ -0,0 +1,119 @@
+/*
+ * Ubiquiti Networks XM (rev 1.0) board support
+ *
+ * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
+ *
+ * Derived from: mach-pb44.c
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/pci.h>
+
+#ifdef CONFIG_PCI
+#include <linux/ath9k_platform.h>
+#include <asm/mach-ath79/pci-ath724x.h>
+#endif /* CONFIG_PCI */
+
+#include "machtypes.h"
+#include "dev-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+
+#define UBNT_XM_GPIO_LED_L1 0
+#define UBNT_XM_GPIO_LED_L2 1
+#define UBNT_XM_GPIO_LED_L3 11
+#define UBNT_XM_GPIO_LED_L4 7
+
+#define UBNT_XM_GPIO_BTN_RESET 12
+
+#define UBNT_XM_KEYS_POLL_INTERVAL 20
+#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL)
+
+#define UBNT_XM_PCI_IRQ 48
+#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000)
+
+static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
+ {
+ .name = "ubnt-xm:red:link1",
+ .gpio = UBNT_XM_GPIO_LED_L1,
+ .active_low = 0,
+ }, {
+ .name = "ubnt-xm:orange:link2",
+ .gpio = UBNT_XM_GPIO_LED_L2,
+ .active_low = 0,
+ }, {
+ .name = "ubnt-xm:green:link3",
+ .gpio = UBNT_XM_GPIO_LED_L3,
+ .active_low = 0,
+ }, {
+ .name = "ubnt-xm:green:link4",
+ .gpio = UBNT_XM_GPIO_LED_L4,
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_button ubnt_xm_gpio_keys[] __initdata = {
+ {
+ .desc = "reset",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = UBNT_XM_GPIO_BTN_RESET,
+ .active_low = 1,
+ }
+};
+
+static struct spi_board_info ubnt_xm_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "mx25l6405d",
+ }
+};
+
+static struct ath79_spi_platform_data ubnt_xm_spi_data = {
+ .bus_num = 0,
+ .num_chipselect = 1,
+};
+
+#ifdef CONFIG_PCI
+static struct ath9k_platform_data ubnt_xm_eeprom_data;
+
+static struct ath724x_pci_data ubnt_xm_pci_data[] = {
+ {
+ .irq = UBNT_XM_PCI_IRQ,
+ .pdata = &ubnt_xm_eeprom_data,
+ },
+};
+#endif /* CONFIG_PCI */
+
+static void __init ubnt_xm_init(void)
+{
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio),
+ ubnt_xm_leds_gpio);
+
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ubnt_xm_gpio_keys),
+ ubnt_xm_gpio_keys);
+
+ ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info,
+ ARRAY_SIZE(ubnt_xm_spi_info));
+
+#ifdef CONFIG_PCI
+ memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
+ sizeof(ubnt_xm_eeprom_data.eeprom_data));
+
+ ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data));
+#endif /* CONFIG_PCI */
+
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_XM,
+ "UBNT-XM",
+ "Ubiquiti Networks XM (rev 1.0) board",
+ ubnt_xm_init);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index 3940fe470b2d..9a1f3826626e 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -16,8 +16,10 @@
enum ath79_mach_type {
ATH79_MACH_GENERIC = 0,
+ ATH79_MACH_AP121, /* Atheros AP121 reference board */
ATH79_MACH_AP81, /* Atheros AP81 reference board */
ATH79_MACH_PB44, /* Atheros PB44 reference board */
+ ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */
};
#endif /* _ATH79_MACHTYPE_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 159b42f106b0..80a7d4023d7f 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -101,19 +101,31 @@ static void __init ath79_detect_sys_type(void)
case REV_ID_MAJOR_AR7240:
ath79_soc = ATH79_SOC_AR7240;
chip = "7240";
- rev = (id & AR724X_REV_ID_REVISION_MASK);
+ rev = id & AR724X_REV_ID_REVISION_MASK;
break;
case REV_ID_MAJOR_AR7241:
ath79_soc = ATH79_SOC_AR7241;
chip = "7241";
- rev = (id & AR724X_REV_ID_REVISION_MASK);
+ rev = id & AR724X_REV_ID_REVISION_MASK;
break;
case REV_ID_MAJOR_AR7242:
ath79_soc = ATH79_SOC_AR7242;
chip = "7242";
- rev = (id & AR724X_REV_ID_REVISION_MASK);
+ rev = id & AR724X_REV_ID_REVISION_MASK;
+ break;
+
+ case REV_ID_MAJOR_AR9330:
+ ath79_soc = ATH79_SOC_AR9330;
+ chip = "9330";
+ rev = id & AR933X_REV_ID_REVISION_MASK;
+ break;
+
+ case REV_ID_MAJOR_AR9331:
+ ath79_soc = ATH79_SOC_AR9331;
+ chip = "9331";
+ rev = id & AR933X_REV_ID_REVISION_MASK;
break;
case REV_ID_MAJOR_AR913X:
@@ -134,9 +146,11 @@ static void __init ath79_detect_sys_type(void)
break;
default:
- panic("ath79: unknown SoC, id:0x%08x\n", id);
+ panic("ath79: unknown SoC, id:0x%08x", id);
}
+ ath79_soc_rev = rev;
+
sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
pr_info("SoC: %s\n", ath79_sys_type);
}
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 1cfdda03546a..aab6b0c40a75 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -289,7 +289,7 @@ static void __init bcm47xx_register_ssb(void)
err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
bcm47xx_get_invariants);
if (err)
- panic("Failed to initialize SSB bus (err %d)\n", err);
+ panic("Failed to initialize SSB bus (err %d)", err);
mcore = &bcm47xx_bus.ssb.mipscore;
if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
@@ -314,7 +314,7 @@ static void __init bcm47xx_register_bcma(void)
err = bcma_host_soc_register(&bcm47xx_bus.bcma);
if (err)
- panic("Failed to initialize BCMA bus (err %d)\n", err);
+ panic("Failed to initialize BCMA bus (err %d)", err);
}
#endif
diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig
index fb177d6df066..6b1b9ad8d857 100644
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -20,6 +20,10 @@ config BCM63XX_CPU_6348
config BCM63XX_CPU_6358
bool "support 6358 CPU"
select HW_HAS_PCI
+
+config BCM63XX_CPU_6368
+ bool "support 6368 CPU"
+ select HW_HAS_PCI
endmenu
source "arch/mips/bcm63xx/boards/Kconfig"
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index c22385400fc9..2f1773f3fb7a 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -709,15 +709,9 @@ void __init board_prom_init(void)
char cfe_version[32];
u32 val;
- /* read base address of boot chip select (0)
- * 6345 does not have MPI but boots from standard
- * MIPS Flash address */
- if (BCMCPU_IS_6345())
- val = 0x1fc00000;
- else {
- val = bcm_mpi_readl(MPI_CSBASE_REG(0));
- val &= MPI_CSBASE_BASE_MASK;
- }
+ /* read base address of boot chip select (0) */
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
boot_addr = (u8 *)KSEG1ADDR(val);
/* dump cfe version */
@@ -797,18 +791,6 @@ void __init board_prom_init(void)
}
bcm_gpio_writel(val, GPIO_MODE_REG);
-
- /* Generate MAC address for WLAN and
- * register our SPROM */
-#ifdef CONFIG_SSB_PCIHOST
- if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
- memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
- memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
- if (ssb_arch_register_fallback_sprom(
- &bcm63xx_get_fallback_sprom) < 0)
- printk(KERN_ERR PFX "failed to register fallback SPROM\n");
- }
-#endif
}
/*
@@ -895,13 +877,23 @@ int __init board_register_devices(void)
if (board.has_dsp)
bcm63xx_dsp_register(&board.dsp);
- /* read base address of boot chip select (0) */
- if (BCMCPU_IS_6345())
- val = 0x1fc00000;
- else {
- val = bcm_mpi_readl(MPI_CSBASE_REG(0));
- val &= MPI_CSBASE_BASE_MASK;
+ /* Generate MAC address for WLAN and register our SPROM,
+ * do this after registering enet devices
+ */
+#ifdef CONFIG_SSB_PCIHOST
+ if (!board_get_mac_address(bcm63xx_sprom.il0mac)) {
+ memcpy(bcm63xx_sprom.et0mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+ memcpy(bcm63xx_sprom.et1mac, bcm63xx_sprom.il0mac, ETH_ALEN);
+ if (ssb_arch_register_fallback_sprom(
+ &bcm63xx_get_fallback_sprom) < 0)
+ pr_err(PFX "failed to register fallback SPROM\n");
}
+#endif
+
+ /* read base address of boot chip select (0) */
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+
mtd_resources[0].start = val;
mtd_resources[0].end = 0x1FFFFFFF;
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
index 2c68ee9ccee2..9d57c71b7b58 100644
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -10,6 +10,7 @@
#include <linux/mutex.h>
#include <linux/err.h>
#include <linux/clk.h>
+#include <linux/delay.h>
#include <bcm63xx_cpu.h>
#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>
@@ -113,6 +114,34 @@ static struct clk clk_ephy = {
};
/*
+ * Ethernet switch clock
+ */
+static void enetsw_set(struct clk *clk, int enable)
+{
+ if (!BCMCPU_IS_6368())
+ return;
+ bcm_hwclock_set(CKCTL_6368_ROBOSW_CLK_EN |
+ CKCTL_6368_SWPKT_USB_EN |
+ CKCTL_6368_SWPKT_SAR_EN, enable);
+ if (enable) {
+ u32 val;
+
+ /* reset switch core afer clock change */
+ val = bcm_perf_readl(PERF_SOFTRESET_6368_REG);
+ val &= ~SOFTRESET_6368_ENETSW_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
+ msleep(10);
+ val |= SOFTRESET_6368_ENETSW_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
+ msleep(10);
+ }
+}
+
+static struct clk clk_enetsw = {
+ .set = enetsw_set,
+};
+
+/*
* PCM clock
*/
static void pcm_set(struct clk *clk, int enable)
@@ -131,9 +160,10 @@ static struct clk clk_pcm = {
*/
static void usbh_set(struct clk *clk, int enable)
{
- if (!BCMCPU_IS_6348())
- return;
- bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
+ if (BCMCPU_IS_6348())
+ bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
+ else if (BCMCPU_IS_6368())
+ bcm_hwclock_set(CKCTL_6368_USBH_CLK_EN, enable);
}
static struct clk clk_usbh = {
@@ -162,6 +192,36 @@ static struct clk clk_spi = {
};
/*
+ * XTM clock
+ */
+static void xtm_set(struct clk *clk, int enable)
+{
+ if (!BCMCPU_IS_6368())
+ return;
+
+ bcm_hwclock_set(CKCTL_6368_SAR_CLK_EN |
+ CKCTL_6368_SWPKT_SAR_EN, enable);
+
+ if (enable) {
+ u32 val;
+
+ /* reset sar core afer clock change */
+ val = bcm_perf_readl(PERF_SOFTRESET_6368_REG);
+ val &= ~SOFTRESET_6368_SAR_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
+ mdelay(1);
+ val |= SOFTRESET_6368_SAR_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6368_REG);
+ mdelay(1);
+ }
+}
+
+
+static struct clk clk_xtm = {
+ .set = xtm_set,
+};
+
+/*
* Internal peripheral clock
*/
static struct clk clk_periph = {
@@ -204,12 +264,16 @@ struct clk *clk_get(struct device *dev, const char *id)
return &clk_enet0;
if (!strcmp(id, "enet1"))
return &clk_enet1;
+ if (!strcmp(id, "enetsw"))
+ return &clk_enetsw;
if (!strcmp(id, "ephy"))
return &clk_ephy;
if (!strcmp(id, "usbh"))
return &clk_usbh;
if (!strcmp(id, "spi"))
return &clk_spi;
+ if (!strcmp(id, "xtm"))
+ return &clk_xtm;
if (!strcmp(id, "periph"))
return &clk_periph;
if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 7c7e4d4486ce..8f0d6c7725ea 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -29,166 +29,47 @@ static u16 bcm63xx_cpu_rev;
static unsigned int bcm63xx_cpu_freq;
static unsigned int bcm63xx_memory_size;
-/*
- * 6338 register sets and irqs
- */
-static const unsigned long bcm96338_regs_base[] = {
- [RSET_DSL_LMEM] = BCM_6338_DSL_LMEM_BASE,
- [RSET_PERF] = BCM_6338_PERF_BASE,
- [RSET_TIMER] = BCM_6338_TIMER_BASE,
- [RSET_WDT] = BCM_6338_WDT_BASE,
- [RSET_UART0] = BCM_6338_UART0_BASE,
- [RSET_UART1] = BCM_6338_UART1_BASE,
- [RSET_GPIO] = BCM_6338_GPIO_BASE,
- [RSET_SPI] = BCM_6338_SPI_BASE,
- [RSET_OHCI0] = BCM_6338_OHCI0_BASE,
- [RSET_OHCI_PRIV] = BCM_6338_OHCI_PRIV_BASE,
- [RSET_USBH_PRIV] = BCM_6338_USBH_PRIV_BASE,
- [RSET_UDC0] = BCM_6338_UDC0_BASE,
- [RSET_MPI] = BCM_6338_MPI_BASE,
- [RSET_PCMCIA] = BCM_6338_PCMCIA_BASE,
- [RSET_SDRAM] = BCM_6338_SDRAM_BASE,
- [RSET_DSL] = BCM_6338_DSL_BASE,
- [RSET_ENET0] = BCM_6338_ENET0_BASE,
- [RSET_ENET1] = BCM_6338_ENET1_BASE,
- [RSET_ENETDMA] = BCM_6338_ENETDMA_BASE,
- [RSET_MEMC] = BCM_6338_MEMC_BASE,
- [RSET_DDR] = BCM_6338_DDR_BASE,
+static const unsigned long bcm6338_regs_base[] = {
+ __GEN_CPU_REGS_TABLE(6338)
};
-static const int bcm96338_irqs[] = {
- [IRQ_TIMER] = BCM_6338_TIMER_IRQ,
- [IRQ_UART0] = BCM_6338_UART0_IRQ,
- [IRQ_DSL] = BCM_6338_DSL_IRQ,
- [IRQ_ENET0] = BCM_6338_ENET0_IRQ,
- [IRQ_ENET_PHY] = BCM_6338_ENET_PHY_IRQ,
- [IRQ_ENET0_RXDMA] = BCM_6338_ENET0_RXDMA_IRQ,
- [IRQ_ENET0_TXDMA] = BCM_6338_ENET0_TXDMA_IRQ,
+static const int bcm6338_irqs[] = {
+ __GEN_CPU_IRQ_TABLE(6338)
};
-/*
- * 6345 register sets and irqs
- */
-static const unsigned long bcm96345_regs_base[] = {
- [RSET_DSL_LMEM] = BCM_6345_DSL_LMEM_BASE,
- [RSET_PERF] = BCM_6345_PERF_BASE,
- [RSET_TIMER] = BCM_6345_TIMER_BASE,
- [RSET_WDT] = BCM_6345_WDT_BASE,
- [RSET_UART0] = BCM_6345_UART0_BASE,
- [RSET_UART1] = BCM_6345_UART1_BASE,
- [RSET_GPIO] = BCM_6345_GPIO_BASE,
- [RSET_SPI] = BCM_6345_SPI_BASE,
- [RSET_UDC0] = BCM_6345_UDC0_BASE,
- [RSET_OHCI0] = BCM_6345_OHCI0_BASE,
- [RSET_OHCI_PRIV] = BCM_6345_OHCI_PRIV_BASE,
- [RSET_USBH_PRIV] = BCM_6345_USBH_PRIV_BASE,
- [RSET_MPI] = BCM_6345_MPI_BASE,
- [RSET_PCMCIA] = BCM_6345_PCMCIA_BASE,
- [RSET_DSL] = BCM_6345_DSL_BASE,
- [RSET_ENET0] = BCM_6345_ENET0_BASE,
- [RSET_ENET1] = BCM_6345_ENET1_BASE,
- [RSET_ENETDMA] = BCM_6345_ENETDMA_BASE,
- [RSET_EHCI0] = BCM_6345_EHCI0_BASE,
- [RSET_SDRAM] = BCM_6345_SDRAM_BASE,
- [RSET_MEMC] = BCM_6345_MEMC_BASE,
- [RSET_DDR] = BCM_6345_DDR_BASE,
+static const unsigned long bcm6345_regs_base[] = {
+ __GEN_CPU_REGS_TABLE(6345)
};
-static const int bcm96345_irqs[] = {
- [IRQ_TIMER] = BCM_6345_TIMER_IRQ,
- [IRQ_UART0] = BCM_6345_UART0_IRQ,
- [IRQ_DSL] = BCM_6345_DSL_IRQ,
- [IRQ_ENET0] = BCM_6345_ENET0_IRQ,
- [IRQ_ENET_PHY] = BCM_6345_ENET_PHY_IRQ,
- [IRQ_ENET0_RXDMA] = BCM_6345_ENET0_RXDMA_IRQ,
- [IRQ_ENET0_TXDMA] = BCM_6345_ENET0_TXDMA_IRQ,
+static const int bcm6345_irqs[] = {
+ __GEN_CPU_IRQ_TABLE(6345)
};
-/*
- * 6348 register sets and irqs
- */
-static const unsigned long bcm96348_regs_base[] = {
- [RSET_DSL_LMEM] = BCM_6348_DSL_LMEM_BASE,
- [RSET_PERF] = BCM_6348_PERF_BASE,
- [RSET_TIMER] = BCM_6348_TIMER_BASE,
- [RSET_WDT] = BCM_6348_WDT_BASE,
- [RSET_UART0] = BCM_6348_UART0_BASE,
- [RSET_UART1] = BCM_6348_UART1_BASE,
- [RSET_GPIO] = BCM_6348_GPIO_BASE,
- [RSET_SPI] = BCM_6348_SPI_BASE,
- [RSET_OHCI0] = BCM_6348_OHCI0_BASE,
- [RSET_OHCI_PRIV] = BCM_6348_OHCI_PRIV_BASE,
- [RSET_USBH_PRIV] = BCM_6348_USBH_PRIV_BASE,
- [RSET_MPI] = BCM_6348_MPI_BASE,
- [RSET_PCMCIA] = BCM_6348_PCMCIA_BASE,
- [RSET_SDRAM] = BCM_6348_SDRAM_BASE,
- [RSET_DSL] = BCM_6348_DSL_BASE,
- [RSET_ENET0] = BCM_6348_ENET0_BASE,
- [RSET_ENET1] = BCM_6348_ENET1_BASE,
- [RSET_ENETDMA] = BCM_6348_ENETDMA_BASE,
- [RSET_MEMC] = BCM_6348_MEMC_BASE,
- [RSET_DDR] = BCM_6348_DDR_BASE,
+static const unsigned long bcm6348_regs_base[] = {
+ __GEN_CPU_REGS_TABLE(6348)
};
-static const int bcm96348_irqs[] = {
- [IRQ_TIMER] = BCM_6348_TIMER_IRQ,
- [IRQ_UART0] = BCM_6348_UART0_IRQ,
- [IRQ_DSL] = BCM_6348_DSL_IRQ,
- [IRQ_ENET0] = BCM_6348_ENET0_IRQ,
- [IRQ_ENET1] = BCM_6348_ENET1_IRQ,
- [IRQ_ENET_PHY] = BCM_6348_ENET_PHY_IRQ,
- [IRQ_OHCI0] = BCM_6348_OHCI0_IRQ,
- [IRQ_PCMCIA] = BCM_6348_PCMCIA_IRQ,
- [IRQ_ENET0_RXDMA] = BCM_6348_ENET0_RXDMA_IRQ,
- [IRQ_ENET0_TXDMA] = BCM_6348_ENET0_TXDMA_IRQ,
- [IRQ_ENET1_RXDMA] = BCM_6348_ENET1_RXDMA_IRQ,
- [IRQ_ENET1_TXDMA] = BCM_6348_ENET1_TXDMA_IRQ,
- [IRQ_PCI] = BCM_6348_PCI_IRQ,
+static const int bcm6348_irqs[] = {
+ __GEN_CPU_IRQ_TABLE(6348)
+
};
-/*
- * 6358 register sets and irqs
- */
-static const unsigned long bcm96358_regs_base[] = {
- [RSET_DSL_LMEM] = BCM_6358_DSL_LMEM_BASE,
- [RSET_PERF] = BCM_6358_PERF_BASE,
- [RSET_TIMER] = BCM_6358_TIMER_BASE,
- [RSET_WDT] = BCM_6358_WDT_BASE,
- [RSET_UART0] = BCM_6358_UART0_BASE,
- [RSET_UART1] = BCM_6358_UART1_BASE,
- [RSET_GPIO] = BCM_6358_GPIO_BASE,
- [RSET_SPI] = BCM_6358_SPI_BASE,
- [RSET_OHCI0] = BCM_6358_OHCI0_BASE,
- [RSET_EHCI0] = BCM_6358_EHCI0_BASE,
- [RSET_OHCI_PRIV] = BCM_6358_OHCI_PRIV_BASE,
- [RSET_USBH_PRIV] = BCM_6358_USBH_PRIV_BASE,
- [RSET_MPI] = BCM_6358_MPI_BASE,
- [RSET_PCMCIA] = BCM_6358_PCMCIA_BASE,
- [RSET_SDRAM] = BCM_6358_SDRAM_BASE,
- [RSET_DSL] = BCM_6358_DSL_BASE,
- [RSET_ENET0] = BCM_6358_ENET0_BASE,
- [RSET_ENET1] = BCM_6358_ENET1_BASE,
- [RSET_ENETDMA] = BCM_6358_ENETDMA_BASE,
- [RSET_MEMC] = BCM_6358_MEMC_BASE,
- [RSET_DDR] = BCM_6358_DDR_BASE,
+static const unsigned long bcm6358_regs_base[] = {
+ __GEN_CPU_REGS_TABLE(6358)
+};
+
+static const int bcm6358_irqs[] = {
+ __GEN_CPU_IRQ_TABLE(6358)
+
};
-static const int bcm96358_irqs[] = {
- [IRQ_TIMER] = BCM_6358_TIMER_IRQ,
- [IRQ_UART0] = BCM_6358_UART0_IRQ,
- [IRQ_UART1] = BCM_6358_UART1_IRQ,
- [IRQ_DSL] = BCM_6358_DSL_IRQ,
- [IRQ_ENET0] = BCM_6358_ENET0_IRQ,
- [IRQ_ENET1] = BCM_6358_ENET1_IRQ,
- [IRQ_ENET_PHY] = BCM_6358_ENET_PHY_IRQ,
- [IRQ_OHCI0] = BCM_6358_OHCI0_IRQ,
- [IRQ_EHCI0] = BCM_6358_EHCI0_IRQ,
- [IRQ_PCMCIA] = BCM_6358_PCMCIA_IRQ,
- [IRQ_ENET0_RXDMA] = BCM_6358_ENET0_RXDMA_IRQ,
- [IRQ_ENET0_TXDMA] = BCM_6358_ENET0_TXDMA_IRQ,
- [IRQ_ENET1_RXDMA] = BCM_6358_ENET1_RXDMA_IRQ,
- [IRQ_ENET1_TXDMA] = BCM_6358_ENET1_TXDMA_IRQ,
- [IRQ_PCI] = BCM_6358_PCI_IRQ,
+static const unsigned long bcm6368_regs_base[] = {
+ __GEN_CPU_REGS_TABLE(6368)
+};
+
+static const int bcm6368_irqs[] = {
+ __GEN_CPU_IRQ_TABLE(6368)
+
};
u16 __bcm63xx_get_cpu_id(void)
@@ -217,20 +98,19 @@ unsigned int bcm63xx_get_memory_size(void)
static unsigned int detect_cpu_clock(void)
{
- unsigned int tmp, n1 = 0, n2 = 0, m1 = 0;
-
- /* BCM6338 has a fixed 240 Mhz frequency */
- if (BCMCPU_IS_6338())
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6338_CPU_ID:
+ /* BCM6338 has a fixed 240 Mhz frequency */
return 240000000;
- /* BCM6345 has a fixed 140Mhz frequency */
- if (BCMCPU_IS_6345())
+ case BCM6345_CPU_ID:
+ /* BCM6345 has a fixed 140Mhz frequency */
return 140000000;
- /*
- * frequency depends on PLL configuration:
- */
- if (BCMCPU_IS_6348()) {
+ case BCM6348_CPU_ID:
+ {
+ unsigned int tmp, n1, n2, m1;
+
/* 16MHz * (N1 + 1) * (N2 + 2) / (M1_CPU + 1) */
tmp = bcm_perf_readl(PERF_MIPSPLLCTL_REG);
n1 = (tmp & MIPSPLLCTL_N1_MASK) >> MIPSPLLCTL_N1_SHIFT;
@@ -239,17 +119,47 @@ static unsigned int detect_cpu_clock(void)
n1 += 1;
n2 += 2;
m1 += 1;
+ return (16 * 1000000 * n1 * n2) / m1;
}
- if (BCMCPU_IS_6358()) {
+ case BCM6358_CPU_ID:
+ {
+ unsigned int tmp, n1, n2, m1;
+
/* 16MHz * N1 * N2 / M1_CPU */
tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_REG);
n1 = (tmp & DMIPSPLLCFG_N1_MASK) >> DMIPSPLLCFG_N1_SHIFT;
n2 = (tmp & DMIPSPLLCFG_N2_MASK) >> DMIPSPLLCFG_N2_SHIFT;
m1 = (tmp & DMIPSPLLCFG_M1_MASK) >> DMIPSPLLCFG_M1_SHIFT;
+ return (16 * 1000000 * n1 * n2) / m1;
}
- return (16 * 1000000 * n1 * n2) / m1;
+ case BCM6368_CPU_ID:
+ {
+ unsigned int tmp, p1, p2, ndiv, m1;
+
+ /* (64MHz / P1) * P2 * NDIV / M1_CPU */
+ tmp = bcm_ddr_readl(DDR_DMIPSPLLCFG_6368_REG);
+
+ p1 = (tmp & DMIPSPLLCFG_6368_P1_MASK) >>
+ DMIPSPLLCFG_6368_P1_SHIFT;
+
+ p2 = (tmp & DMIPSPLLCFG_6368_P2_MASK) >>
+ DMIPSPLLCFG_6368_P2_SHIFT;
+
+ ndiv = (tmp & DMIPSPLLCFG_6368_NDIV_MASK) >>
+ DMIPSPLLCFG_6368_NDIV_SHIFT;
+
+ tmp = bcm_ddr_readl(DDR_DMIPSPLLDIV_6368_REG);
+ m1 = (tmp & DMIPSPLLDIV_6368_MDIV_MASK) >>
+ DMIPSPLLDIV_6368_MDIV_SHIFT;
+
+ return (((64 * 1000000) / p1) * p2 * ndiv) / m1;
+ }
+
+ default:
+ BUG();
+ }
}
/*
@@ -260,8 +170,10 @@ static unsigned int detect_memory_size(void)
unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
u32 val;
- if (BCMCPU_IS_6345())
- return (8 * 1024 * 1024);
+ if (BCMCPU_IS_6345()) {
+ val = bcm_sdram_readl(SDRAM_MBASE_REG);
+ return (val * 8 * 1024 * 1024);
+ }
if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
val = bcm_sdram_readl(SDRAM_CFG_REG);
@@ -271,7 +183,7 @@ static unsigned int detect_memory_size(void)
banks = (val & SDRAM_CFG_BANK_MASK) ? 2 : 1;
}
- if (BCMCPU_IS_6358()) {
+ if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
val = bcm_memc_readl(MEMC_CFG_REG);
rows = (val & MEMC_CFG_ROW_MASK) >> MEMC_CFG_ROW_SHIFT;
cols = (val & MEMC_CFG_COL_MASK) >> MEMC_CFG_COL_SHIFT;
@@ -301,24 +213,33 @@ void __init bcm63xx_cpu_init(void)
case CPU_BMIPS3300:
if ((read_c0_prid() & 0xff00) == PRID_IMP_BMIPS3300_ALT) {
expected_cpu_id = BCM6348_CPU_ID;
- bcm63xx_regs_base = bcm96348_regs_base;
- bcm63xx_irqs = bcm96348_irqs;
+ bcm63xx_regs_base = bcm6348_regs_base;
+ bcm63xx_irqs = bcm6348_irqs;
} else {
__cpu_name[cpu] = "Broadcom BCM6338";
expected_cpu_id = BCM6338_CPU_ID;
- bcm63xx_regs_base = bcm96338_regs_base;
- bcm63xx_irqs = bcm96338_irqs;
+ bcm63xx_regs_base = bcm6338_regs_base;
+ bcm63xx_irqs = bcm6338_irqs;
}
break;
case CPU_BMIPS32:
expected_cpu_id = BCM6345_CPU_ID;
- bcm63xx_regs_base = bcm96345_regs_base;
- bcm63xx_irqs = bcm96345_irqs;
+ bcm63xx_regs_base = bcm6345_regs_base;
+ bcm63xx_irqs = bcm6345_irqs;
break;
case CPU_BMIPS4350:
- expected_cpu_id = BCM6358_CPU_ID;
- bcm63xx_regs_base = bcm96358_regs_base;
- bcm63xx_irqs = bcm96358_irqs;
+ switch (read_c0_prid() & 0xf0) {
+ case 0x10:
+ expected_cpu_id = BCM6358_CPU_ID;
+ bcm63xx_regs_base = bcm6358_regs_base;
+ bcm63xx_irqs = bcm6358_irqs;
+ break;
+ case 0x30:
+ expected_cpu_id = BCM6368_CPU_ID;
+ bcm63xx_regs_base = bcm6368_regs_base;
+ bcm63xx_irqs = bcm6368_irqs;
+ break;
+ }
break;
}
diff --git a/arch/mips/bcm63xx/dev-uart.c b/arch/mips/bcm63xx/dev-uart.c
index c2963da0253e..d6e42c608325 100644
--- a/arch/mips/bcm63xx/dev-uart.c
+++ b/arch/mips/bcm63xx/dev-uart.c
@@ -54,7 +54,7 @@ int __init bcm63xx_uart_register(unsigned int id)
if (id >= ARRAY_SIZE(bcm63xx_uart_devices))
return -ENODEV;
- if (id == 1 && !BCMCPU_IS_6358())
+ if (id == 1 && (!BCMCPU_IS_6358() && !BCMCPU_IS_6368()))
return -ENODEV;
if (id == 0) {
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c
index f560fe7d38dd..a6c2135dbf38 100644
--- a/arch/mips/bcm63xx/gpio.c
+++ b/arch/mips/bcm63xx/gpio.c
@@ -4,7 +4,7 @@
* for more details.
*
* Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
- * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2008-2011 Florian Fainelli <florian@openwrt.org>
*/
#include <linux/kernel.h>
@@ -18,6 +18,34 @@
#include <bcm63xx_io.h>
#include <bcm63xx_regs.h>
+#ifndef BCMCPU_RUNTIME_DETECT
+#define gpio_out_low_reg GPIO_DATA_LO_REG
+#ifdef CONFIG_BCM63XX_CPU_6345
+#ifdef gpio_out_low_reg
+#undef gpio_out_low_reg
+#define gpio_out_low_reg GPIO_DATA_LO_REG_6345
+#endif /* gpio_out_low_reg */
+#endif /* CONFIG_BCM63XX_CPU_6345 */
+
+static inline void bcm63xx_gpio_out_low_reg_init(void)
+{
+}
+#else /* ! BCMCPU_RUNTIME_DETECT */
+static u32 gpio_out_low_reg;
+
+static void bcm63xx_gpio_out_low_reg_init(void)
+{
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6345_CPU_ID:
+ gpio_out_low_reg = GPIO_DATA_LO_REG_6345;
+ break;
+ default:
+ gpio_out_low_reg = GPIO_DATA_LO_REG;
+ break;
+ }
+}
+#endif /* ! BCMCPU_RUNTIME_DETECT */
+
static DEFINE_SPINLOCK(bcm63xx_gpio_lock);
static u32 gpio_out_low, gpio_out_high;
@@ -33,7 +61,7 @@ static void bcm63xx_gpio_set(struct gpio_chip *chip,
BUG();
if (gpio < 32) {
- reg = GPIO_DATA_LO_REG;
+ reg = gpio_out_low_reg;
mask = 1 << gpio;
v = &gpio_out_low;
} else {
@@ -60,7 +88,7 @@ static int bcm63xx_gpio_get(struct gpio_chip *chip, unsigned gpio)
BUG();
if (gpio < 32) {
- reg = GPIO_DATA_LO_REG;
+ reg = gpio_out_low_reg;
mask = 1 << gpio;
} else {
reg = GPIO_DATA_HI_REG;
@@ -125,8 +153,11 @@ static struct gpio_chip bcm63xx_gpio_chip = {
int __init bcm63xx_gpio_init(void)
{
- gpio_out_low = bcm_gpio_readl(GPIO_DATA_LO_REG);
- gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
+ bcm63xx_gpio_out_low_reg_init();
+
+ gpio_out_low = bcm_gpio_readl(gpio_out_low_reg);
+ if (!BCMCPU_IS_6345())
+ gpio_out_high = bcm_gpio_readl(GPIO_DATA_HI_REG);
bcm63xx_gpio_chip.ngpio = bcm63xx_gpio_count();
pr_info("registering %d GPIOs\n", bcm63xx_gpio_chip.ngpio);
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index 162e11b4ed75..9a216a451d92 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -19,19 +19,187 @@
#include <bcm63xx_io.h>
#include <bcm63xx_irq.h>
+static void __dispatch_internal(void) __maybe_unused;
+static void __dispatch_internal_64(void) __maybe_unused;
+static void __internal_irq_mask_32(unsigned int irq) __maybe_unused;
+static void __internal_irq_mask_64(unsigned int irq) __maybe_unused;
+static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused;
+static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
+
+#ifndef BCMCPU_RUNTIME_DETECT
+#ifdef CONFIG_BCM63XX_CPU_6338
+#define irq_stat_reg PERF_IRQSTAT_6338_REG
+#define irq_mask_reg PERF_IRQMASK_6338_REG
+#define irq_bits 32
+#define is_ext_irq_cascaded 0
+#define ext_irq_start 0
+#define ext_irq_end 0
+#define ext_irq_count 4
+#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6338
+#define ext_irq_cfg_reg2 0
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6345
+#define irq_stat_reg PERF_IRQSTAT_6345_REG
+#define irq_mask_reg PERF_IRQMASK_6345_REG
+#define irq_bits 32
+#define is_ext_irq_cascaded 0
+#define ext_irq_start 0
+#define ext_irq_end 0
+#define ext_irq_count 0
+#define ext_irq_cfg_reg1 0
+#define ext_irq_cfg_reg2 0
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+#define irq_stat_reg PERF_IRQSTAT_6348_REG
+#define irq_mask_reg PERF_IRQMASK_6348_REG
+#define irq_bits 32
+#define is_ext_irq_cascaded 0
+#define ext_irq_start 0
+#define ext_irq_end 0
+#define ext_irq_count 4
+#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6348
+#define ext_irq_cfg_reg2 0
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6358
+#define irq_stat_reg PERF_IRQSTAT_6358_REG
+#define irq_mask_reg PERF_IRQMASK_6358_REG
+#define irq_bits 32
+#define is_ext_irq_cascaded 1
+#define ext_irq_start (BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE)
+#define ext_irq_end (BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE)
+#define ext_irq_count 4
+#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358
+#define ext_irq_cfg_reg2 0
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6368
+#define irq_stat_reg PERF_IRQSTAT_6368_REG
+#define irq_mask_reg PERF_IRQMASK_6368_REG
+#define irq_bits 64
+#define is_ext_irq_cascaded 1
+#define ext_irq_start (BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE)
+#define ext_irq_end (BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE)
+#define ext_irq_count 6
+#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6368
+#define ext_irq_cfg_reg2 PERF_EXTIRQ_CFG_REG2_6368
+#endif
+
+#if irq_bits == 32
+#define dispatch_internal __dispatch_internal
+#define internal_irq_mask __internal_irq_mask_32
+#define internal_irq_unmask __internal_irq_unmask_32
+#else
+#define dispatch_internal __dispatch_internal_64
+#define internal_irq_mask __internal_irq_mask_64
+#define internal_irq_unmask __internal_irq_unmask_64
+#endif
+
+#define irq_stat_addr (bcm63xx_regset_address(RSET_PERF) + irq_stat_reg)
+#define irq_mask_addr (bcm63xx_regset_address(RSET_PERF) + irq_mask_reg)
+
+static inline void bcm63xx_init_irq(void)
+{
+}
+#else /* ! BCMCPU_RUNTIME_DETECT */
+
+static u32 irq_stat_addr, irq_mask_addr;
+static void (*dispatch_internal)(void);
+static int is_ext_irq_cascaded;
+static unsigned int ext_irq_count;
+static unsigned int ext_irq_start, ext_irq_end;
+static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2;
+static void (*internal_irq_mask)(unsigned int irq);
+static void (*internal_irq_unmask)(unsigned int irq);
+
+static void bcm63xx_init_irq(void)
+{
+ int irq_bits;
+
+ irq_stat_addr = bcm63xx_regset_address(RSET_PERF);
+ irq_mask_addr = bcm63xx_regset_address(RSET_PERF);
+
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6338_CPU_ID:
+ irq_stat_addr += PERF_IRQSTAT_6338_REG;
+ irq_mask_addr += PERF_IRQMASK_6338_REG;
+ irq_bits = 32;
+ break;
+ case BCM6345_CPU_ID:
+ irq_stat_addr += PERF_IRQSTAT_6345_REG;
+ irq_mask_addr += PERF_IRQMASK_6345_REG;
+ irq_bits = 32;
+ break;
+ case BCM6348_CPU_ID:
+ irq_stat_addr += PERF_IRQSTAT_6348_REG;
+ irq_mask_addr += PERF_IRQMASK_6348_REG;
+ irq_bits = 32;
+ ext_irq_count = 4;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
+ break;
+ case BCM6358_CPU_ID:
+ irq_stat_addr += PERF_IRQSTAT_6358_REG;
+ irq_mask_addr += PERF_IRQMASK_6358_REG;
+ irq_bits = 32;
+ ext_irq_count = 4;
+ is_ext_irq_cascaded = 1;
+ ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
+ ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
+ break;
+ case BCM6368_CPU_ID:
+ irq_stat_addr += PERF_IRQSTAT_6368_REG;
+ irq_mask_addr += PERF_IRQMASK_6368_REG;
+ irq_bits = 64;
+ ext_irq_count = 6;
+ is_ext_irq_cascaded = 1;
+ ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE;
+ ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368;
+ ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368;
+ break;
+ default:
+ BUG();
+ }
+
+ if (irq_bits == 32) {
+ dispatch_internal = __dispatch_internal;
+ internal_irq_mask = __internal_irq_mask_32;
+ internal_irq_unmask = __internal_irq_unmask_32;
+ } else {
+ dispatch_internal = __dispatch_internal_64;
+ internal_irq_mask = __internal_irq_mask_64;
+ internal_irq_unmask = __internal_irq_unmask_64;
+ }
+}
+#endif /* ! BCMCPU_RUNTIME_DETECT */
+
+static inline u32 get_ext_irq_perf_reg(int irq)
+{
+ if (irq < 4)
+ return ext_irq_cfg_reg1;
+ return ext_irq_cfg_reg2;
+}
+
+static inline void handle_internal(int intbit)
+{
+ if (is_ext_irq_cascaded &&
+ intbit >= ext_irq_start && intbit <= ext_irq_end)
+ do_IRQ(intbit - ext_irq_start + IRQ_EXTERNAL_BASE);
+ else
+ do_IRQ(intbit + IRQ_INTERNAL_BASE);
+}
+
/*
* dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
* prioritize any interrupt relatively to another. the static counter
* will resume the loop where it ended the last time we left this
* function.
*/
-static void bcm63xx_irq_dispatch_internal(void)
+static void __dispatch_internal(void)
{
u32 pending;
static int i;
- pending = bcm_perf_readl(PERF_IRQMASK_REG) &
- bcm_perf_readl(PERF_IRQSTAT_REG);
+ pending = bcm_readl(irq_stat_addr) & bcm_readl(irq_mask_addr);
if (!pending)
return ;
@@ -41,7 +209,28 @@ static void bcm63xx_irq_dispatch_internal(void)
i = (i + 1) & 0x1f;
if (pending & (1 << to_call)) {
- do_IRQ(to_call + IRQ_INTERNAL_BASE);
+ handle_internal(to_call);
+ break;
+ }
+ }
+}
+
+static void __dispatch_internal_64(void)
+{
+ u64 pending;
+ static int i;
+
+ pending = bcm_readq(irq_stat_addr) & bcm_readq(irq_mask_addr);
+
+ if (!pending)
+ return ;
+
+ while (1) {
+ int to_call = i;
+
+ i = (i + 1) & 0x3f;
+ if (pending & (1ull << to_call)) {
+ handle_internal(to_call);
break;
}
}
@@ -60,15 +249,17 @@ asmlinkage void plat_irq_dispatch(void)
if (cause & CAUSEF_IP7)
do_IRQ(7);
if (cause & CAUSEF_IP2)
- bcm63xx_irq_dispatch_internal();
- if (cause & CAUSEF_IP3)
- do_IRQ(IRQ_EXT_0);
- if (cause & CAUSEF_IP4)
- do_IRQ(IRQ_EXT_1);
- if (cause & CAUSEF_IP5)
- do_IRQ(IRQ_EXT_2);
- if (cause & CAUSEF_IP6)
- do_IRQ(IRQ_EXT_3);
+ dispatch_internal();
+ if (!is_ext_irq_cascaded) {
+ if (cause & CAUSEF_IP3)
+ do_IRQ(IRQ_EXT_0);
+ if (cause & CAUSEF_IP4)
+ do_IRQ(IRQ_EXT_1);
+ if (cause & CAUSEF_IP5)
+ do_IRQ(IRQ_EXT_2);
+ if (cause & CAUSEF_IP6)
+ do_IRQ(IRQ_EXT_3);
+ }
} while (1);
}
@@ -76,24 +267,50 @@ asmlinkage void plat_irq_dispatch(void)
* internal IRQs operations: only mask/unmask on PERF irq mask
* register.
*/
-static inline void bcm63xx_internal_irq_mask(struct irq_data *d)
+static void __internal_irq_mask_32(unsigned int irq)
{
- unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
u32 mask;
- mask = bcm_perf_readl(PERF_IRQMASK_REG);
+ mask = bcm_readl(irq_mask_addr);
mask &= ~(1 << irq);
- bcm_perf_writel(mask, PERF_IRQMASK_REG);
+ bcm_writel(mask, irq_mask_addr);
}
-static void bcm63xx_internal_irq_unmask(struct irq_data *d)
+static void __internal_irq_mask_64(unsigned int irq)
+{
+ u64 mask;
+
+ mask = bcm_readq(irq_mask_addr);
+ mask &= ~(1ull << irq);
+ bcm_writeq(mask, irq_mask_addr);
+}
+
+static void __internal_irq_unmask_32(unsigned int irq)
{
- unsigned int irq = d->irq - IRQ_INTERNAL_BASE;
u32 mask;
- mask = bcm_perf_readl(PERF_IRQMASK_REG);
+ mask = bcm_readl(irq_mask_addr);
mask |= (1 << irq);
- bcm_perf_writel(mask, PERF_IRQMASK_REG);
+ bcm_writel(mask, irq_mask_addr);
+}
+
+static void __internal_irq_unmask_64(unsigned int irq)
+{
+ u64 mask;
+
+ mask = bcm_readq(irq_mask_addr);
+ mask |= (1ull << irq);
+ bcm_writeq(mask, irq_mask_addr);
+}
+
+static void bcm63xx_internal_irq_mask(struct irq_data *d)
+{
+ internal_irq_mask(d->irq - IRQ_INTERNAL_BASE);
+}
+
+static void bcm63xx_internal_irq_unmask(struct irq_data *d)
+{
+ internal_irq_unmask(d->irq - IRQ_INTERNAL_BASE);
}
/*
@@ -102,94 +319,131 @@ static void bcm63xx_internal_irq_unmask(struct irq_data *d)
*/
static void bcm63xx_external_irq_mask(struct irq_data *d)
{
- unsigned int irq = d->irq - IRQ_EXT_BASE;
- u32 reg;
+ unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
+ u32 reg, regaddr;
- reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
- reg &= ~EXTIRQ_CFG_MASK(irq);
- bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+ regaddr = get_ext_irq_perf_reg(irq);
+ reg = bcm_perf_readl(regaddr);
+
+ if (BCMCPU_IS_6348())
+ reg &= ~EXTIRQ_CFG_MASK_6348(irq % 4);
+ else
+ reg &= ~EXTIRQ_CFG_MASK(irq % 4);
+
+ bcm_perf_writel(reg, regaddr);
+ if (is_ext_irq_cascaded)
+ internal_irq_mask(irq + ext_irq_start);
}
static void bcm63xx_external_irq_unmask(struct irq_data *d)
{
- unsigned int irq = d->irq - IRQ_EXT_BASE;
- u32 reg;
+ unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
+ u32 reg, regaddr;
- reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
- reg |= EXTIRQ_CFG_MASK(irq);
- bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+ regaddr = get_ext_irq_perf_reg(irq);
+ reg = bcm_perf_readl(regaddr);
+
+ if (BCMCPU_IS_6348())
+ reg |= EXTIRQ_CFG_MASK_6348(irq % 4);
+ else
+ reg |= EXTIRQ_CFG_MASK(irq % 4);
+
+ bcm_perf_writel(reg, regaddr);
+
+ if (is_ext_irq_cascaded)
+ internal_irq_unmask(irq + ext_irq_start);
}
static void bcm63xx_external_irq_clear(struct irq_data *d)
{
- unsigned int irq = d->irq - IRQ_EXT_BASE;
- u32 reg;
+ unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
+ u32 reg, regaddr;
- reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
- reg |= EXTIRQ_CFG_CLEAR(irq);
- bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
-}
+ regaddr = get_ext_irq_perf_reg(irq);
+ reg = bcm_perf_readl(regaddr);
-static unsigned int bcm63xx_external_irq_startup(struct irq_data *d)
-{
- set_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
- irq_enable_hazard();
- bcm63xx_external_irq_unmask(d);
- return 0;
-}
+ if (BCMCPU_IS_6348())
+ reg |= EXTIRQ_CFG_CLEAR_6348(irq % 4);
+ else
+ reg |= EXTIRQ_CFG_CLEAR(irq % 4);
-static void bcm63xx_external_irq_shutdown(struct irq_data *d)
-{
- bcm63xx_external_irq_mask(d);
- clear_c0_status(0x100 << (d->irq - IRQ_MIPS_BASE));
- irq_disable_hazard();
+ bcm_perf_writel(reg, regaddr);
}
static int bcm63xx_external_irq_set_type(struct irq_data *d,
unsigned int flow_type)
{
- unsigned int irq = d->irq - IRQ_EXT_BASE;
- u32 reg;
+ unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
+ u32 reg, regaddr;
+ int levelsense, sense, bothedge;
flow_type &= IRQ_TYPE_SENSE_MASK;
if (flow_type == IRQ_TYPE_NONE)
flow_type = IRQ_TYPE_LEVEL_LOW;
- reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
+ levelsense = sense = bothedge = 0;
switch (flow_type) {
case IRQ_TYPE_EDGE_BOTH:
- reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
- reg |= EXTIRQ_CFG_BOTHEDGE(irq);
+ bothedge = 1;
break;
case IRQ_TYPE_EDGE_RISING:
- reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
- reg |= EXTIRQ_CFG_SENSE(irq);
- reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+ sense = 1;
break;
case IRQ_TYPE_EDGE_FALLING:
- reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
- reg &= ~EXTIRQ_CFG_SENSE(irq);
- reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
break;
case IRQ_TYPE_LEVEL_HIGH:
- reg |= EXTIRQ_CFG_LEVELSENSE(irq);
- reg |= EXTIRQ_CFG_SENSE(irq);
+ levelsense = 1;
+ sense = 1;
break;
case IRQ_TYPE_LEVEL_LOW:
- reg |= EXTIRQ_CFG_LEVELSENSE(irq);
- reg &= ~EXTIRQ_CFG_SENSE(irq);
+ levelsense = 1;
break;
default:
printk(KERN_ERR "bogus flow type combination given !\n");
return -EINVAL;
}
- bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+
+ regaddr = get_ext_irq_perf_reg(irq);
+ reg = bcm_perf_readl(regaddr);
+ irq %= 4;
+
+ if (BCMCPU_IS_6348()) {
+ if (levelsense)
+ reg |= EXTIRQ_CFG_LEVELSENSE_6348(irq);
+ else
+ reg &= ~EXTIRQ_CFG_LEVELSENSE_6348(irq);
+ if (sense)
+ reg |= EXTIRQ_CFG_SENSE_6348(irq);
+ else
+ reg &= ~EXTIRQ_CFG_SENSE_6348(irq);
+ if (bothedge)
+ reg |= EXTIRQ_CFG_BOTHEDGE_6348(irq);
+ else
+ reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
+ }
+
+ if (BCMCPU_IS_6338() || BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+ if (levelsense)
+ reg |= EXTIRQ_CFG_LEVELSENSE(irq);
+ else
+ reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
+ if (sense)
+ reg |= EXTIRQ_CFG_SENSE(irq);
+ else
+ reg &= ~EXTIRQ_CFG_SENSE(irq);
+ if (bothedge)
+ reg |= EXTIRQ_CFG_BOTHEDGE(irq);
+ else
+ reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
+ }
+
+ bcm_perf_writel(reg, regaddr);
irqd_set_trigger_type(d, flow_type);
if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
@@ -208,9 +462,6 @@ static struct irq_chip bcm63xx_internal_irq_chip = {
static struct irq_chip bcm63xx_external_irq_chip = {
.name = "bcm63xx_epic",
- .irq_startup = bcm63xx_external_irq_startup,
- .irq_shutdown = bcm63xx_external_irq_shutdown,
-
.irq_ack = bcm63xx_external_irq_clear,
.irq_mask = bcm63xx_external_irq_mask,
@@ -225,18 +476,30 @@ static struct irqaction cpu_ip2_cascade_action = {
.flags = IRQF_NO_THREAD,
};
+static struct irqaction cpu_ext_cascade_action = {
+ .handler = no_action,
+ .name = "cascade_extirq",
+ .flags = IRQF_NO_THREAD,
+};
+
void __init arch_init_irq(void)
{
int i;
+ bcm63xx_init_irq();
mips_cpu_irq_init();
for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip,
handle_level_irq);
- for (i = IRQ_EXT_BASE; i < IRQ_EXT_BASE + 4; ++i)
+ for (i = IRQ_EXTERNAL_BASE; i < IRQ_EXTERNAL_BASE + ext_irq_count; ++i)
irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip,
handle_edge_irq);
- setup_irq(IRQ_MIPS_BASE + 2, &cpu_ip2_cascade_action);
+ if (!is_ext_irq_cascaded) {
+ for (i = 3; i < 3 + ext_irq_count; ++i)
+ setup_irq(MIPS_CPU_IRQ_BASE + i, &cpu_ext_cascade_action);
+ }
+
+ setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action);
}
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
index be252efa0757..99d7f405cbeb 100644
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -32,9 +32,12 @@ void __init prom_init(void)
mask = CKCTL_6345_ALL_SAFE_EN;
else if (BCMCPU_IS_6348())
mask = CKCTL_6348_ALL_SAFE_EN;
- else
- /* BCMCPU_IS_6358() */
+ else if (BCMCPU_IS_6358())
mask = CKCTL_6358_ALL_SAFE_EN;
+ else if (BCMCPU_IS_6368())
+ mask = CKCTL_6368_ALL_SAFE_EN;
+ else
+ mask = 0;
reg = bcm_perf_readl(PERF_CKCTL_REG);
reg &= ~mask;
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index d0056598fbfc..d209f85d87bb 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -63,13 +63,33 @@ static void bcm6348_a1_reboot(void)
void bcm63xx_machine_reboot(void)
{
- u32 reg;
+ u32 reg, perf_regs[2] = { 0, 0 };
+ unsigned int i;
/* mask and clear all external irq */
- reg = bcm_perf_readl(PERF_EXTIRQ_CFG_REG);
- reg &= ~EXTIRQ_CFG_MASK_ALL;
- reg |= EXTIRQ_CFG_CLEAR_ALL;
- bcm_perf_writel(reg, PERF_EXTIRQ_CFG_REG);
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6338_CPU_ID:
+ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
+ break;
+ case BCM6348_CPU_ID:
+ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6348;
+ break;
+ case BCM6358_CPU_ID:
+ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6358;
+ break;
+ }
+
+ for (i = 0; i < 2; i++) {
+ reg = bcm_perf_readl(perf_regs[i]);
+ if (BCMCPU_IS_6348()) {
+ reg &= ~EXTIRQ_CFG_MASK_ALL_6348;
+ reg |= EXTIRQ_CFG_CLEAR_ALL_6348;
+ } else {
+ reg &= ~EXTIRQ_CFG_MASK_ALL;
+ reg |= EXTIRQ_CFG_CLEAR_ALL;
+ }
+ bcm_perf_writel(reg, perf_regs[i]);
+ }
if (BCMCPU_IS_6348() && (bcm63xx_get_cpu_rev() == 0xa1))
bcm6348_a1_reboot();
@@ -124,4 +144,4 @@ int __init bcm63xx_register_devices(void)
return board_register_devices();
}
-arch_initcall(bcm63xx_register_devices);
+device_initcall(bcm63xx_register_devices);
diff --git a/arch/mips/boot/compressed/uart-alchemy.c b/arch/mips/boot/compressed/uart-alchemy.c
index eb063e6dead9..3112df8f90db 100644
--- a/arch/mips/boot/compressed/uart-alchemy.c
+++ b/arch/mips/boot/compressed/uart-alchemy.c
@@ -2,6 +2,9 @@
void putc(char c)
{
- /* all current (Jan. 2010) in-kernel boards */
+#ifdef CONFIG_MIPS_DB1300
+ alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
+#else
alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+#endif
}
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
index cad555ebeca3..f9e275a50d98 100644
--- a/arch/mips/cavium-octeon/Kconfig
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -86,10 +86,6 @@ config ARCH_SPARSEMEM_ENABLE
def_bool y
select SPARSEMEM_STATIC
-config CAVIUM_OCTEON_HELPER
- def_bool y
- depends on OCTEON_ETHERNET || PCI
-
config IOMMU_HELPER
bool
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index ea4febaa4bb1..b6bb92c16a47 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -61,6 +61,16 @@ static phys_addr_t octeon_gen1_dma_to_phys(struct device *dev, dma_addr_t daddr)
return daddr;
}
+static dma_addr_t octeon_gen2_phys_to_dma(struct device *dev, phys_addr_t paddr)
+{
+ return octeon_hole_phys_to_dma(paddr);
+}
+
+static phys_addr_t octeon_gen2_dma_to_phys(struct device *dev, dma_addr_t daddr)
+{
+ return octeon_hole_dma_to_phys(daddr);
+}
+
static dma_addr_t octeon_big_phys_to_dma(struct device *dev, phys_addr_t paddr)
{
if (paddr >= 0x410000000ull && paddr < 0x420000000ull)
@@ -262,11 +272,11 @@ void __init plat_swiotlb_setup(void)
for (i = 0 ; i < boot_mem_map.nr_map; i++) {
struct boot_mem_map_entry *e = &boot_mem_map.map[i];
- if (e->type != BOOT_MEM_RAM)
+ if (e->type != BOOT_MEM_RAM && e->type != BOOT_MEM_INIT_RAM)
continue;
/* These addresses map low for PCI. */
- if (e->addr > 0x410000000ull)
+ if (e->addr > 0x410000000ull && !OCTEON_IS_MODEL(OCTEON_CN6XXX))
continue;
addr_size += e->size;
@@ -296,6 +306,11 @@ void __init plat_swiotlb_setup(void)
swiotlbsize = 64 * (1<<20);
}
#endif
+#ifdef CONFIG_USB_OCTEON_OHCI
+ /* OCTEON II ohci is only 32-bit. */
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX) && max_addr >= 0x100000000ul)
+ swiotlbsize = 64 * (1<<20);
+#endif
swiotlb_nslabs = swiotlbsize >> IO_TLB_SHIFT;
swiotlb_nslabs = ALIGN(swiotlb_nslabs, IO_TLB_SEGSIZE);
swiotlbsize = swiotlb_nslabs << IO_TLB_SHIFT;
@@ -330,6 +345,10 @@ struct dma_map_ops *octeon_pci_dma_map_ops;
void __init octeon_pci_dma_init(void)
{
switch (octeon_dma_bar_type) {
+ case OCTEON_DMA_BAR_TYPE_PCIE2:
+ _octeon_pci_dma_map_ops.phys_to_dma = octeon_gen2_phys_to_dma;
+ _octeon_pci_dma_map_ops.dma_to_phys = octeon_gen2_dma_to_phys;
+ break;
case OCTEON_DMA_BAR_TYPE_PCIE:
_octeon_pci_dma_map_ops.phys_to_dma = octeon_gen1_phys_to_dma;
_octeon_pci_dma_map_ops.dma_to_phys = octeon_gen1_dma_to_phys;
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile
index 7f41c5be2190..b6d6e841a984 100644
--- a/arch/mips/cavium-octeon/executive/Makefile
+++ b/arch/mips/cavium-octeon/executive/Makefile
@@ -10,5 +10,10 @@
#
obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o
+obj-y += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \
+ cvmx-helper-board.o cvmx-helper.o cvmx-helper-xaui.o \
+ cvmx-helper-rgmii.o cvmx-helper-sgmii.o cvmx-helper-npi.o \
+ cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \
+ cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o
-obj-$(CONFIG_CAVIUM_OCTEON_HELPER) += cvmx-helper-errata.o cvmx-helper-jtag.o
+obj-y += cvmx-helper-errata.o cvmx-helper-jtag.o
diff --git a/drivers/staging/octeon/cvmx-cmd-queue.c b/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c
index e9809d375162..132bccc66a93 100644
--- a/drivers/staging/octeon/cvmx-cmd-queue.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-cmd-queue.c
@@ -34,13 +34,13 @@
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
-#include "cvmx-fpa.h"
-#include "cvmx-cmd-queue.h"
+#include <asm/octeon/cvmx-config.h>
+#include <asm/octeon/cvmx-fpa.h>
+#include <asm/octeon/cvmx-cmd-queue.h>
#include <asm/octeon/cvmx-npei-defs.h>
#include <asm/octeon/cvmx-pexp-defs.h>
-#include "cvmx-pko-defs.h"
+#include <asm/octeon/cvmx-pko-defs.h>
/**
* This application uses this pointer to access the global queue
diff --git a/drivers/staging/octeon/cvmx-fpa.c b/arch/mips/cavium-octeon/executive/cvmx-fpa.c
index ad44b8bd8057..ad44b8bd8057 100644
--- a/drivers/staging/octeon/cvmx-fpa.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-fpa.c
diff --git a/drivers/staging/octeon/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
index 57d35dc63ddb..fd2015331a20 100644
--- a/drivers/staging/octeon/cvmx-helper-board.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c
@@ -34,16 +34,16 @@
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-bootinfo.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-mdio.h"
+#include <asm/octeon/cvmx-mdio.h>
-#include "cvmx-helper.h"
-#include "cvmx-helper-util.h"
-#include "cvmx-helper-board.h"
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-util.h>
+#include <asm/octeon/cvmx-helper-board.h>
-#include "cvmx-gmxx-defs.h"
-#include "cvmx-asxx-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
+#include <asm/octeon/cvmx-asxx-defs.h>
/**
* cvmx_override_board_link_get(int ipd_port) is a function
@@ -117,6 +117,10 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
case CVMX_BOARD_TYPE_EBH5200:
case CVMX_BOARD_TYPE_EBH5201:
case CVMX_BOARD_TYPE_EBT5200:
+ /* Board has 2 management ports */
+ if ((ipd_port >= CVMX_HELPER_BOARD_MGMT_IPD_PORT) &&
+ (ipd_port < (CVMX_HELPER_BOARD_MGMT_IPD_PORT + 2)))
+ return ipd_port - CVMX_HELPER_BOARD_MGMT_IPD_PORT;
/*
* Board has 4 SGMII ports. The PHYs start right after the MII
* ports MII0 = 0, MII1 = 1, SGMII = 2-5.
@@ -128,6 +132,9 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
case CVMX_BOARD_TYPE_EBH5600:
case CVMX_BOARD_TYPE_EBH5601:
case CVMX_BOARD_TYPE_EBH5610:
+ /* Board has 1 management port */
+ if (ipd_port == CVMX_HELPER_BOARD_MGMT_IPD_PORT)
+ return 0;
/*
* Board has 8 SGMII ports. 4 connect out, two connect
* to a switch, and 2 loop to each other
@@ -147,6 +154,19 @@ int cvmx_helper_board_get_mii_address(int ipd_port)
return ipd_port - 16 + 1;
else
return -1;
+ case CVMX_BOARD_TYPE_NIC_XLE_10G:
+ case CVMX_BOARD_TYPE_NIC10E:
+ return -1;
+ case CVMX_BOARD_TYPE_NIC4E:
+ if (ipd_port >= 0 && ipd_port <= 3)
+ return (ipd_port + 0x1f) & 0x1f;
+ else
+ return -1;
+ case CVMX_BOARD_TYPE_NIC2E:
+ if (ipd_port >= 0 && ipd_port <= 1)
+ return ipd_port + 1;
+ else
+ return -1;
case CVMX_BOARD_TYPE_BBGW_REF:
/*
* No PHYs are connected to Octeon, everything is
@@ -493,7 +513,6 @@ int cvmx_helper_board_link_set_phy(int phy_addr,
cvmx_mdio_phy_reg_control_t reg_control;
cvmx_mdio_phy_reg_status_t reg_status;
cvmx_mdio_phy_reg_autoneg_adver_t reg_autoneg_adver;
- cvmx_mdio_phy_reg_extended_status_t reg_extended_status;
cvmx_mdio_phy_reg_control_1000_t reg_control_1000;
reg_status.u16 =
@@ -508,9 +527,6 @@ int cvmx_helper_board_link_set_phy(int phy_addr,
reg_autoneg_adver.s.advert_100base_tx_full = 0;
reg_autoneg_adver.s.advert_100base_tx_half = 0;
if (reg_status.s.capable_extended_status) {
- reg_extended_status.u16 =
- cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
- CVMX_MDIO_PHY_REG_EXTENDED_STATUS);
reg_control_1000.u16 =
cvmx_mdio_read(phy_addr >> 8, phy_addr & 0xff,
CVMX_MDIO_PHY_REG_CONTROL_1000);
diff --git a/drivers/staging/octeon/cvmx-helper-fpa.c b/arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c
index c239e5f4ab9a..c239e5f4ab9a 100644
--- a/drivers/staging/octeon/cvmx-helper-fpa.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c
diff --git a/drivers/staging/octeon/cvmx-helper-loop.c b/arch/mips/cavium-octeon/executive/cvmx-helper-loop.c
index 55a571a69529..bfbd46115e71 100644
--- a/drivers/staging/octeon/cvmx-helper-loop.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-loop.c
@@ -31,10 +31,10 @@
*/
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-helper.h"
-#include "cvmx-pip-defs.h"
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-pip-defs.h>
/**
* Probe a LOOP interface and determine the number of ports
diff --git a/drivers/staging/octeon/cvmx-helper-npi.c b/arch/mips/cavium-octeon/executive/cvmx-helper-npi.c
index 7388a1e72b38..cc94cfa545b4 100644
--- a/drivers/staging/octeon/cvmx-helper-npi.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-npi.c
@@ -31,11 +31,11 @@
*/
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-helper.h>
-#include "cvmx-pip-defs.h"
+#include <asm/octeon/cvmx-pip-defs.h>
/**
* Probe a NPI interface and determine the number of ports
diff --git a/drivers/staging/octeon/cvmx-helper-rgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c
index aa2d5d7fee2b..82b21843421c 100644
--- a/drivers/staging/octeon/cvmx-helper-rgmii.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-rgmii.c
@@ -31,18 +31,18 @@
*/
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-mdio.h"
-#include "cvmx-pko.h"
-#include "cvmx-helper.h"
-#include "cvmx-helper-board.h"
+#include <asm/octeon/cvmx-mdio.h>
+#include <asm/octeon/cvmx-pko.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-board.h>
#include <asm/octeon/cvmx-npi-defs.h>
-#include "cvmx-gmxx-defs.h"
-#include "cvmx-asxx-defs.h"
-#include "cvmx-dbg-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
+#include <asm/octeon/cvmx-asxx-defs.h>
+#include <asm/octeon/cvmx-dbg-defs.h>
void __cvmx_interrupt_gmxx_enable(int interface);
void __cvmx_interrupt_asxx_enable(int block);
@@ -326,6 +326,7 @@ int __cvmx_helper_rgmii_link_set(int ipd_port,
cvmx_read_csr(CVMX_ASXX_RX_PRT_EN(interface)) &
~(1 << index));
+ memset(pko_mem_queue_qos_save, 0, sizeof(pko_mem_queue_qos_save));
/* Disable all queues so that TX should become idle */
for (i = 0; i < cvmx_pko_get_num_queues(ipd_port); i++) {
int queue = cvmx_pko_get_base_queue(ipd_port) + i;
diff --git a/drivers/staging/octeon/cvmx-helper-sgmii.c b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c
index 6214e3b6d975..0c0bf5d30e70 100644
--- a/drivers/staging/octeon/cvmx-helper-sgmii.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-sgmii.c
@@ -32,14 +32,14 @@
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-mdio.h"
-#include "cvmx-helper.h"
-#include "cvmx-helper-board.h"
+#include <asm/octeon/cvmx-mdio.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-board.h>
-#include "cvmx-gmxx-defs.h"
-#include "cvmx-pcsx-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
+#include <asm/octeon/cvmx-pcsx-defs.h>
void __cvmx_interrupt_gmxx_enable(int interface);
void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
@@ -326,6 +326,10 @@ static int __cvmx_helper_sgmii_hardware_init(int interface, int num_ports)
return 0;
}
+int __cvmx_helper_sgmii_enumerate(int interface)
+{
+ return 4;
+}
/**
* Probe a SGMII interface and determine the number of ports
* connected to it. The SGMII interface should still be down after
@@ -347,7 +351,7 @@ int __cvmx_helper_sgmii_probe(int interface)
mode.u64 = cvmx_read_csr(CVMX_GMXX_INF_MODE(interface));
mode.s.en = 1;
cvmx_write_csr(CVMX_GMXX_INF_MODE(interface), mode.u64);
- return 4;
+ return __cvmx_helper_sgmii_enumerate(interface);
}
/**
diff --git a/drivers/staging/octeon/cvmx-helper-spi.c b/arch/mips/cavium-octeon/executive/cvmx-helper-spi.c
index 8ba6c832471e..2830e4bdf7f3 100644
--- a/drivers/staging/octeon/cvmx-helper-spi.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-spi.c
@@ -35,12 +35,12 @@ void __cvmx_interrupt_stxx_int_msk_enable(int index);
*/
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
-#include "cvmx-spi.h"
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-config.h>
+#include <asm/octeon/cvmx-spi.h>
+#include <asm/octeon/cvmx-helper.h>
-#include "cvmx-pip-defs.h"
-#include "cvmx-pko-defs.h"
+#include <asm/octeon/cvmx-pip-defs.h>
+#include <asm/octeon/cvmx-pko-defs.h>
/*
* CVMX_HELPER_SPI_TIMEOUT is used to determine how long the SPI
@@ -51,6 +51,16 @@ void __cvmx_interrupt_stxx_int_msk_enable(int index);
#define CVMX_HELPER_SPI_TIMEOUT 10
#endif
+int __cvmx_helper_spi_enumerate(int interface)
+{
+ if ((cvmx_sysinfo_get()->board_type != CVMX_BOARD_TYPE_SIM) &&
+ cvmx_spi4000_is_present(interface)) {
+ return 10;
+ } else {
+ return 16;
+ }
+}
+
/**
* Probe a SPI interface and determine the number of ports
* connected to it. The SPI interface should still be down after
diff --git a/drivers/staging/octeon/cvmx-helper-util.c b/arch/mips/cavium-octeon/executive/cvmx-helper-util.c
index 131182bf5abb..116dea17acf5 100644
--- a/drivers/staging/octeon/cvmx-helper-util.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-util.c
@@ -32,16 +32,16 @@
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-fpa.h"
-#include "cvmx-pip.h"
-#include "cvmx-pko.h"
-#include "cvmx-ipd.h"
-#include "cvmx-spi.h"
+#include <asm/octeon/cvmx-fpa.h>
+#include <asm/octeon/cvmx-pip.h>
+#include <asm/octeon/cvmx-pko.h>
+#include <asm/octeon/cvmx-ipd.h>
+#include <asm/octeon/cvmx-spi.h>
-#include "cvmx-helper.h"
-#include "cvmx-helper-util.h"
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-util.h>
#include <asm/octeon/cvmx-ipd-defs.h>
diff --git a/drivers/staging/octeon/cvmx-helper-xaui.c b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c
index a11e6769e234..1723248e987d 100644
--- a/drivers/staging/octeon/cvmx-helper-xaui.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper-xaui.c
@@ -33,17 +33,30 @@
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-helper.h>
-#include "cvmx-pko-defs.h"
-#include "cvmx-gmxx-defs.h"
-#include "cvmx-pcsxx-defs.h"
+#include <asm/octeon/cvmx-pko-defs.h>
+#include <asm/octeon/cvmx-gmxx-defs.h>
+#include <asm/octeon/cvmx-pcsxx-defs.h>
void __cvmx_interrupt_gmxx_enable(int interface);
void __cvmx_interrupt_pcsx_intx_en_reg_enable(int index, int block);
void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
+
+int __cvmx_helper_xaui_enumerate(int interface)
+{
+ union cvmx_gmxx_hg2_control gmx_hg2_control;
+
+ /* If HiGig2 is enabled return 16 ports, otherwise return 1 port */
+ gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface));
+ if (gmx_hg2_control.s.hg2tx_en)
+ return 16;
+ else
+ return 1;
+}
+
/**
* Probe a XAUI interface and determine the number of ports
* connected to it. The XAUI interface should still be down
@@ -56,7 +69,6 @@ void __cvmx_interrupt_pcsxx_int_en_reg_enable(int index);
int __cvmx_helper_xaui_probe(int interface)
{
int i;
- union cvmx_gmxx_hg2_control gmx_hg2_control;
union cvmx_gmxx_inf_mode mode;
/*
@@ -90,13 +102,7 @@ int __cvmx_helper_xaui_probe(int interface)
pko_mem_port_ptrs.s.pid = interface * 16 + i;
cvmx_write_csr(CVMX_PKO_MEM_PORT_PTRS, pko_mem_port_ptrs.u64);
}
-
- /* If HiGig2 is enabled return 16 ports, otherwise return 1 port */
- gmx_hg2_control.u64 = cvmx_read_csr(CVMX_GMXX_HG2_CONTROL(interface));
- if (gmx_hg2_control.s.hg2tx_en)
- return 16;
- else
- return 1;
+ return __cvmx_helper_xaui_enumerate(interface);
}
/**
diff --git a/drivers/staging/octeon/cvmx-helper.c b/arch/mips/cavium-octeon/executive/cvmx-helper.c
index e9c5c836ceff..fa4963856353 100644
--- a/drivers/staging/octeon/cvmx-helper.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-helper.c
@@ -32,19 +32,19 @@
*/
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-fpa.h"
-#include "cvmx-pip.h"
-#include "cvmx-pko.h"
-#include "cvmx-ipd.h"
-#include "cvmx-spi.h"
-#include "cvmx-helper.h"
-#include "cvmx-helper-board.h"
+#include <asm/octeon/cvmx-fpa.h>
+#include <asm/octeon/cvmx-pip.h>
+#include <asm/octeon/cvmx-pko.h>
+#include <asm/octeon/cvmx-ipd.h>
+#include <asm/octeon/cvmx-spi.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-board.h>
-#include "cvmx-pip-defs.h"
-#include "cvmx-smix-defs.h"
-#include "cvmx-asxx-defs.h"
+#include <asm/octeon/cvmx-pip-defs.h>
+#include <asm/octeon/cvmx-smix-defs.h>
+#include <asm/octeon/cvmx-asxx-defs.h>
/**
* cvmx_override_pko_queue_priority(int ipd_port, uint64_t
@@ -234,21 +234,16 @@ static int __cvmx_helper_port_setup_ipd(int ipd_port)
}
/**
- * This function probes an interface to determine the actual
- * number of hardware ports connected to it. It doesn't setup the
- * ports or enable them. The main goal here is to set the global
- * interface_port_count[interface] correctly. Hardware setup of the
- * ports will be performed later.
+ * This function sets the interface_port_count[interface] correctly,
+ * without modifying any hardware configuration. Hardware setup of
+ * the ports will be performed later.
*
* @interface: Interface to probe
*
* Returns Zero on success, negative on failure
*/
-int cvmx_helper_interface_probe(int interface)
+int cvmx_helper_interface_enumerate(int interface)
{
- /* At this stage in the game we don't want packets to be moving yet.
- The following probe calls should perform hardware setup
- needed to determine port counts. Receive must still be disabled */
switch (cvmx_helper_interface_get_mode(interface)) {
/* These types don't support ports to IPD/PKO */
case CVMX_HELPER_INTERFACE_MODE_DISABLED:
@@ -258,7 +253,7 @@ int cvmx_helper_interface_probe(int interface)
/* XAUI is a single high speed port */
case CVMX_HELPER_INTERFACE_MODE_XAUI:
interface_port_count[interface] =
- __cvmx_helper_xaui_probe(interface);
+ __cvmx_helper_xaui_enumerate(interface);
break;
/*
* RGMII/GMII/MII are all treated about the same. Most
@@ -267,7 +262,7 @@ int cvmx_helper_interface_probe(int interface)
case CVMX_HELPER_INTERFACE_MODE_RGMII:
case CVMX_HELPER_INTERFACE_MODE_GMII:
interface_port_count[interface] =
- __cvmx_helper_rgmii_probe(interface);
+ __cvmx_helper_rgmii_enumerate(interface);
break;
/*
* SPI4 can have 1-16 ports depending on the device at
@@ -275,7 +270,7 @@ int cvmx_helper_interface_probe(int interface)
*/
case CVMX_HELPER_INTERFACE_MODE_SPI:
interface_port_count[interface] =
- __cvmx_helper_spi_probe(interface);
+ __cvmx_helper_spi_enumerate(interface);
break;
/*
* SGMII can have 1-4 ports depending on how many are
@@ -284,12 +279,12 @@ int cvmx_helper_interface_probe(int interface)
case CVMX_HELPER_INTERFACE_MODE_SGMII:
case CVMX_HELPER_INTERFACE_MODE_PICMG:
interface_port_count[interface] =
- __cvmx_helper_sgmii_probe(interface);
+ __cvmx_helper_sgmii_enumerate(interface);
break;
/* PCI target Network Packet Interface */
case CVMX_HELPER_INTERFACE_MODE_NPI:
interface_port_count[interface] =
- __cvmx_helper_npi_probe(interface);
+ __cvmx_helper_npi_enumerate(interface);
break;
/*
* Special loopback only ports. These are not the same
@@ -297,7 +292,7 @@ int cvmx_helper_interface_probe(int interface)
*/
case CVMX_HELPER_INTERFACE_MODE_LOOP:
interface_port_count[interface] =
- __cvmx_helper_loop_probe(interface);
+ __cvmx_helper_loop_enumerate(interface);
break;
}
@@ -313,6 +308,74 @@ int cvmx_helper_interface_probe(int interface)
}
/**
+ * This function probes an interface to determine the actual
+ * number of hardware ports connected to it. It doesn't setup the
+ * ports or enable them. The main goal here is to set the global
+ * interface_port_count[interface] correctly. Hardware setup of the
+ * ports will be performed later.
+ *
+ * @interface: Interface to probe
+ *
+ * Returns Zero on success, negative on failure
+ */
+int cvmx_helper_interface_probe(int interface)
+{
+ cvmx_helper_interface_enumerate(interface);
+ /* At this stage in the game we don't want packets to be moving yet.
+ The following probe calls should perform hardware setup
+ needed to determine port counts. Receive must still be disabled */
+ switch (cvmx_helper_interface_get_mode(interface)) {
+ /* These types don't support ports to IPD/PKO */
+ case CVMX_HELPER_INTERFACE_MODE_DISABLED:
+ case CVMX_HELPER_INTERFACE_MODE_PCIE:
+ break;
+ /* XAUI is a single high speed port */
+ case CVMX_HELPER_INTERFACE_MODE_XAUI:
+ __cvmx_helper_xaui_probe(interface);
+ break;
+ /*
+ * RGMII/GMII/MII are all treated about the same. Most
+ * functions refer to these ports as RGMII.
+ */
+ case CVMX_HELPER_INTERFACE_MODE_RGMII:
+ case CVMX_HELPER_INTERFACE_MODE_GMII:
+ __cvmx_helper_rgmii_probe(interface);
+ break;
+ /*
+ * SPI4 can have 1-16 ports depending on the device at
+ * the other end.
+ */
+ case CVMX_HELPER_INTERFACE_MODE_SPI:
+ __cvmx_helper_spi_probe(interface);
+ break;
+ /*
+ * SGMII can have 1-4 ports depending on how many are
+ * hooked up.
+ */
+ case CVMX_HELPER_INTERFACE_MODE_SGMII:
+ case CVMX_HELPER_INTERFACE_MODE_PICMG:
+ __cvmx_helper_sgmii_probe(interface);
+ break;
+ /* PCI target Network Packet Interface */
+ case CVMX_HELPER_INTERFACE_MODE_NPI:
+ __cvmx_helper_npi_probe(interface);
+ break;
+ /*
+ * Special loopback only ports. These are not the same
+ * as other ports in loopback mode.
+ */
+ case CVMX_HELPER_INTERFACE_MODE_LOOP:
+ __cvmx_helper_loop_probe(interface);
+ break;
+ }
+
+ /* Make sure all global variables propagate to other cores */
+ CVMX_SYNCWS;
+
+ return 0;
+}
+
+/**
* Setup the IPD/PIP for the ports on an interface. Packet
* classification and tagging are set for every port on the
* interface. The number of ports on the interface must already
@@ -548,7 +611,6 @@ int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
union cvmx_gmxx_prtx_cfg gmx_cfg;
int retry_cnt;
int retry_loop_cnt;
- int mtu;
int i;
cvmx_helper_link_info_t link_info;
@@ -662,10 +724,6 @@ int __cvmx_helper_errata_fix_ipd_ptr_alignment(void)
cvmx_write_csr(CVMX_ASXX_RX_PRT_EN(INTERFACE(FIX_IPD_OUTPORT)),
1 << INDEX(FIX_IPD_OUTPORT));
- mtu =
- cvmx_read_csr(CVMX_GMXX_RXX_JABBER
- (INDEX(FIX_IPD_OUTPORT),
- INTERFACE(FIX_IPD_OUTPORT)));
cvmx_write_csr(CVMX_GMXX_RXX_JABBER
(INDEX(FIX_IPD_OUTPORT),
INTERFACE(FIX_IPD_OUTPORT)), 65392 - 14 - 4);
diff --git a/drivers/staging/octeon/cvmx-interrupt-decodes.c b/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c
index a3337e382ee9..e59d1b79f24c 100644
--- a/drivers/staging/octeon/cvmx-interrupt-decodes.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-interrupt-decodes.c
@@ -34,11 +34,11 @@
#include <asm/octeon/octeon.h>
-#include "cvmx-gmxx-defs.h"
-#include "cvmx-pcsx-defs.h"
-#include "cvmx-pcsxx-defs.h"
-#include "cvmx-spxx-defs.h"
-#include "cvmx-stxx-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
+#include <asm/octeon/cvmx-pcsx-defs.h>
+#include <asm/octeon/cvmx-pcsxx-defs.h>
+#include <asm/octeon/cvmx-spxx-defs.h>
+#include <asm/octeon/cvmx-stxx-defs.h>
#ifndef PRINT_ERROR
#define PRINT_ERROR(format, ...)
diff --git a/drivers/staging/octeon/cvmx-interrupt-rsl.c b/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c
index df50048cfbc0..bea7538ea4e9 100644
--- a/drivers/staging/octeon/cvmx-interrupt-rsl.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-interrupt-rsl.c
@@ -32,8 +32,8 @@
#include <asm/octeon/octeon.h>
-#include "cvmx-asxx-defs.h"
-#include "cvmx-gmxx-defs.h"
+#include <asm/octeon/cvmx-asxx-defs.h>
+#include <asm/octeon/cvmx-gmxx-defs.h>
#ifndef PRINT_ERROR
#define PRINT_ERROR(format, ...)
diff --git a/drivers/staging/octeon/cvmx-pko.c b/arch/mips/cavium-octeon/executive/cvmx-pko.c
index 50a2c9bd5a55..f557084b1092 100644
--- a/drivers/staging/octeon/cvmx-pko.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-pko.c
@@ -31,9 +31,9 @@
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
-#include "cvmx-pko.h"
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-config.h>
+#include <asm/octeon/cvmx-pko.h>
+#include <asm/octeon/cvmx-helper.h>
/**
* Internal state of packet output
@@ -54,7 +54,7 @@ void cvmx_pko_initialize_global(void)
/*
* Set the size of the PKO command buffers to an odd number of
* 64bit words. This allows the normal two word send to stay
- * aligned and never span a command word buffer.
+ * aligned and never span a comamnd word buffer.
*/
config.u64 = 0;
config.s.pool = CVMX_FPA_OUTPUT_BUFFER_POOL;
diff --git a/drivers/staging/octeon/cvmx-spi.c b/arch/mips/cavium-octeon/executive/cvmx-spi.c
index 82794d920cec..74afb1710cd9 100644
--- a/drivers/staging/octeon/cvmx-spi.c
+++ b/arch/mips/cavium-octeon/executive/cvmx-spi.c
@@ -31,14 +31,14 @@
*/
#include <asm/octeon/octeon.h>
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
-#include "cvmx-pko.h"
-#include "cvmx-spi.h"
+#include <asm/octeon/cvmx-pko.h>
+#include <asm/octeon/cvmx-spi.h>
-#include "cvmx-spxx-defs.h"
-#include "cvmx-stxx-defs.h"
-#include "cvmx-srxx-defs.h"
+#include <asm/octeon/cvmx-spxx-defs.h>
+#include <asm/octeon/cvmx-stxx-defs.h>
+#include <asm/octeon/cvmx-srxx-defs.h>
#define INVOKE_CB(function_p, args...) \
do { \
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c
index c8d35684504e..f4c1b36fdf65 100644
--- a/arch/mips/cavium-octeon/executive/octeon-model.c
+++ b/arch/mips/cavium-octeon/executive/octeon-model.c
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
@@ -25,10 +25,6 @@
* Contact Cavium Networks for more information
***********************license end**************************************/
-/*
- * File defining functions for working with different Octeon
- * models.
- */
#include <asm/octeon/octeon.h>
/**
@@ -69,11 +65,12 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
char fuse_model[10];
uint32_t fuse_data = 0;
- fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
+ fus3.u64 = 0;
+ if (!OCTEON_IS_MODEL(OCTEON_CN6XXX))
+ fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
-
- num_cores = cvmx_octeon_num_cores();
+ num_cores = cvmx_pop(cvmx_read_csr(CVMX_CIU_FUSE));
/* Make sure the non existent devices look disabled */
switch ((chip_id >> 8) & 0xff) {
@@ -108,7 +105,7 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
* Assume pass number is encoded using <5:3><2:0>. Exceptions
* will be fixed later.
*/
- sprintf(pass, "%u.%u", ((chip_id >> 3) & 7) + 1, chip_id & 7);
+ sprintf(pass, "%d.%d", (int)((chip_id >> 3) & 7) + 1, (int)chip_id & 7);
/*
* Use the number of cores to determine the last 2 digits of
@@ -116,6 +113,12 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
* later.
*/
switch (num_cores) {
+ case 32:
+ core_model = "80";
+ break;
+ case 24:
+ core_model = "70";
+ break;
case 16:
core_model = "60";
break;
@@ -246,8 +249,8 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
break;
case 3: /* CN58XX */
family = "58";
- /* Special case. 4 core, no crypto */
- if ((num_cores == 4) && fus_dat2.cn38xx.nocrypto)
+ /* Special case. 4 core, half cache (CP with half cache) */
+ if ((num_cores == 4) && fus3.cn58xx.crip_1024k && !strncmp(suffix, "CP", 2))
core_model = "29";
/* Pass 1 uses different encodings for pass numbers */
@@ -285,6 +288,9 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
suffix = "NSP";
if (fus_dat3.s.nozip)
suffix = "SCP";
+
+ if (fus_dat3.s.bar2_en)
+ suffix = "NSPB2";
}
if (fus3.cn56xx.crip_1024k)
family = "54";
@@ -301,6 +307,60 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
else
family = "52";
break;
+ case 0x93: /* CN61XX */
+ family = "61";
+ if (fus_dat2.cn61xx.nocrypto && fus_dat2.cn61xx.dorm_crypto)
+ suffix = "AP";
+ if (fus_dat2.cn61xx.nocrypto)
+ suffix = "CP";
+ else if (fus_dat2.cn61xx.dorm_crypto)
+ suffix = "DAP";
+ else if (fus_dat3.cn61xx.nozip)
+ suffix = "SCP";
+ break;
+ case 0x90: /* CN63XX */
+ family = "63";
+ if (fus_dat3.s.l2c_crip == 2)
+ family = "62";
+ if (num_cores == 6) /* Other core counts match generic */
+ core_model = "35";
+ if (fus_dat2.cn63xx.nocrypto)
+ suffix = "CP";
+ else if (fus_dat2.cn63xx.dorm_crypto)
+ suffix = "DAP";
+ else if (fus_dat3.cn63xx.nozip)
+ suffix = "SCP";
+ else
+ suffix = "AAP";
+ break;
+ case 0x92: /* CN66XX */
+ family = "66";
+ if (num_cores == 6) /* Other core counts match generic */
+ core_model = "35";
+ if (fus_dat2.cn66xx.nocrypto && fus_dat2.cn66xx.dorm_crypto)
+ suffix = "AP";
+ if (fus_dat2.cn66xx.nocrypto)
+ suffix = "CP";
+ else if (fus_dat2.cn66xx.dorm_crypto)
+ suffix = "DAP";
+ else if (fus_dat3.cn66xx.nozip)
+ suffix = "SCP";
+ else
+ suffix = "AAP";
+ break;
+ case 0x91: /* CN68XX */
+ family = "68";
+ if (fus_dat2.cn68xx.nocrypto && fus_dat3.cn68xx.nozip)
+ suffix = "CP";
+ else if (fus_dat2.cn68xx.dorm_crypto)
+ suffix = "DAP";
+ else if (fus_dat3.cn68xx.nozip)
+ suffix = "SCP";
+ else if (fus_dat2.cn68xx.nocrypto)
+ suffix = "SP";
+ else
+ suffix = "AAP";
+ break;
default:
family = "XX";
core_model = "XX";
@@ -310,49 +370,40 @@ const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
}
clock_mhz = octeon_get_clock_rate() / 1000000;
-
if (family[0] != '3') {
+ int fuse_base = 384 / 8;
+ if (family[0] == '6')
+ fuse_base = 832 / 8;
+
/* Check for model in fuses, overrides normal decode */
/* This is _not_ valid for Octeon CN3XXX models */
- fuse_data |= cvmx_fuse_read_byte(51);
+ fuse_data |= cvmx_fuse_read_byte(fuse_base + 3);
fuse_data = fuse_data << 8;
- fuse_data |= cvmx_fuse_read_byte(50);
+ fuse_data |= cvmx_fuse_read_byte(fuse_base + 2);
fuse_data = fuse_data << 8;
- fuse_data |= cvmx_fuse_read_byte(49);
+ fuse_data |= cvmx_fuse_read_byte(fuse_base + 1);
fuse_data = fuse_data << 8;
- fuse_data |= cvmx_fuse_read_byte(48);
+ fuse_data |= cvmx_fuse_read_byte(fuse_base);
if (fuse_data & 0x7ffff) {
int model = fuse_data & 0x3fff;
int suffix = (fuse_data >> 14) & 0x1f;
if (suffix && model) {
- /*
- * Have both number and suffix in
- * fuses, so both
- */
- sprintf(fuse_model, "%d%c",
- model, 'A' + suffix - 1);
+ /* Have both number and suffix in fuses, so both */
+ sprintf(fuse_model, "%d%c", model, 'A' + suffix - 1);
core_model = "";
family = fuse_model;
} else if (suffix && !model) {
- /*
- * Only have suffix, so add suffix to
- * 'normal' model number.
- */
- sprintf(fuse_model, "%s%c", core_model,
- 'A' + suffix - 1);
+ /* Only have suffix, so add suffix to 'normal' model number */
+ sprintf(fuse_model, "%s%c", core_model, 'A' + suffix - 1);
core_model = fuse_model;
} else {
- /*
- * Don't have suffix, so just use
- * model from fuses.
- */
+ /* Don't have suffix, so just use model from fuses */
sprintf(fuse_model, "%d", model);
core_model = "";
family = fuse_model;
}
}
}
- sprintf(buffer, "CN%s%sp%s-%d-%s",
- family, core_model, pass, clock_mhz, suffix);
+ sprintf(buffer, "CN%s%sp%s-%d-%s", family, core_model, pass, clock_mhz, suffix);
return buffer;
}
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 2d9028f1474c..260b27367347 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -642,14 +642,6 @@ void __init plat_mem_setup(void)
total = 0;
- /* First add the init memory we will be returning. */
- memory = __pa_symbol(&__init_begin) & PAGE_MASK;
- mem_alloc_size = (__pa_symbol(&__init_end) & PAGE_MASK) - memory;
- if (mem_alloc_size > 0) {
- add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
- total += mem_alloc_size;
- }
-
/*
* The Mips memory init uses the first memory location for
* some memory vectors. When SPARSEMEM is in use, it doesn't
@@ -767,11 +759,11 @@ void prom_free_prom_memory(void)
: "=r" (insn) : : "$31", "memory");
if ((insn >> 26) != 0x33)
- panic("No PREF instruction at Core-14449 probe point.\n");
+ panic("No PREF instruction at Core-14449 probe point.");
if (((insn >> 16) & 0x1f) != 28)
panic("Core-14449 WAR not in place (%04x).\n"
- "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).\n", insn);
+ "Please build kernel with proper options (CONFIG_CAVIUM_CN63XXP1).", insn);
}
#ifdef CONFIG_CAVIUM_DECODE_RSL
cvmx_interrupt_rsl_enable();
@@ -779,7 +771,7 @@ void prom_free_prom_memory(void)
/* Add an interrupt handler for general failures. */
if (request_irq(OCTEON_IRQ_RML, octeon_rlm_interrupt, IRQF_SHARED,
"RML/RSL", octeon_rlm_interrupt)) {
- panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
+ panic("Unable to request_irq(OCTEON_IRQ_RML)");
}
#endif
}
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
index efcfff4d4627..b1535fe409d4 100644
--- a/arch/mips/cavium-octeon/smp.c
+++ b/arch/mips/cavium-octeon/smp.c
@@ -210,7 +210,7 @@ void octeon_prepare_cpus(unsigned int max_cpus)
if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt,
IRQF_PERCPU | IRQF_NO_THREAD, "SMP-IPI",
mailbox_interrupt)) {
- panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
+ panic("Cannot request_irq(OCTEON_IRQ_MBOX0)");
}
}
diff --git a/arch/mips/configs/db1000_defconfig b/arch/mips/configs/db1000_defconfig
index 4044c9e0fb73..17a36c125172 100644
--- a/arch/mips/configs/db1000_defconfig
+++ b/arch/mips/configs/db1000_defconfig
@@ -1,118 +1,359 @@
+CONFIG_MIPS=y
CONFIG_MIPS_ALCHEMY=y
+CONFIG_MIPS_DB1000=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
+CONFIG_HZ=100
+CONFIG_PREEMPT_NONE=y
CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-db1000"
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION="-db1x00"
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_KERNEL_LZMA=y
+CONFIG_DEFAULT_HOSTNAME="db1x00"
+CONFIG_SWAP=y
CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_FHANDLE=y
+CONFIG_AUDIT=y
CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+CONFIG_SYSCTL=y
CONFIG_EXPERT=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_PCI_QUIRKS=y
CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
+CONFIG_SLABINFO=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_FREEZER=y
+CONFIG_PCI=y
+CONFIG_PCI_DOMAINS=y
CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_PM=y
+CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=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_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_NET_IPIP=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_LRO=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_STP=y
+CONFIG_GARP=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_LLC=y
+CONFIG_LLC2=y
+CONFIG_DNS_RESOLVER=y
+CONFIG_BT=y
+CONFIG_BT_L2CAP=y
+CONFIG_BT_SCO=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIBTUSB=y
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+CONFIG_MTD_CFI_GEOMETRY=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+CONFIG_MTD_CFI_I4=y
+CONFIG_MTD_CFI_I8=y
+CONFIG_MTD_CFI_INTELEXT=y
CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_PHYSMAP=y
-# CONFIG_MISC_DEVICES is not set
+CONFIG_SCSI_MOD=y
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_SCSI_PROC_FS=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_ATA=y
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_ATA_SFF=y
+CONFIG_ATA_BMDMA=y
+CONFIG_PATA_HPT37X=y
+CONFIG_PATA_PCMCIA=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_FIREWIRE=y
+CONFIG_FIREWIRE_OHCI=y
+CONFIG_FIREWIRE_OHCI_DEBUG=y
+CONFIG_FIREWIRE_NET=y
CONFIG_NETDEVICES=y
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_STE10XP=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+CONFIG_PHYLIB=y
+CONFIG_NET_ETHERNET=y
CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=y
+CONFIG_PCMCIA_PCNET=y
+CONFIG_PPP=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPPOE=y
+CONFIG_INPUT=y
CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_DEVKMEM=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_TTY_PRINTK=y
+CONFIG_DEVPORT=y
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_FB=y
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+CONFIG_FB_AU1100=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
+CONFIG_FONTS=y
+CONFIG_FONT_8x16=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_SEQUENCER=y
+CONFIG_SND_HRTIMER=y
+CONFIG_SND_SEQ_HRTIMER_DEFAULT=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_VMASTER=y
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC_AU1XAUDIO=y
+CONFIG_SND_SOC_AU1XAC97C=y
+CONFIG_SND_SOC_DB1000=y
+CONFIG_SND_SOC_AC97_CODEC=y
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+CONFIG_USB_HID=y
+CONFIG_USB_SUPPORT=y
CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_DYNAMIC_MINORS=y
CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
-# CONFIG_EXT3_FS_XATTR is not set
-# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_JBD2=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_GENERIC_ACL=y
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
CONFIG_TMPFS=y
-CONFIG_CRAMFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_MISC_FILESYSTEMS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_JFFS2_CMODE_PRIORITY=y
CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_ZLIB=y
+CONFIG_SQUASHFS_LZO=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_PNFS_FILE_LAYOUT=y
+CONFIG_PNFS_BLOCK=y
CONFIG_ROOT_NFS=y
+CONFIG_NFS_USE_KERNEL_DNS=y
+CONFIG_NFS_USE_NEW_IDMAPPER=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_SUNRPC_BACKCHANNEL=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_CODEPAGE_1250=y
+CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_UTF8=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_FTRACE is not set
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="noirqdebug rootwait root=/dev/sda1 rootfstype=ext4 console=ttyS0,115200 video=au1100fb:panel:CRT_800x600_16"
CONFIG_DEBUG_ZBOOT=y
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
+CONFIG_SECURITYFS=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+CONFIG_CRYPTO_WORKQUEUE=y
+CONFIG_CRYPTO_ECB=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_AES=y
+CONFIG_CRYPTO_ANSI_CPRNG=y
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=y
+CONFIG_CRC16=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
diff --git a/arch/mips/configs/db1100_defconfig b/arch/mips/configs/db1100_defconfig
deleted file mode 100644
index c6b49938ee84..000000000000
--- a/arch/mips/configs/db1100_defconfig
+++ /dev/null
@@ -1,122 +0,0 @@
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_MIPS_DB1100=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-db1100"
-CONFIG_KERNEL_LZMA=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_PCCARD=y
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_PM=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=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_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-# CONFIG_BLK_DEV is not set
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_IDE_TASK_IOCTL=y
-CONFIG_NETDEVICES=y
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_STE10XP=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_AU1100=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x16=y
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_SQUASHFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_ZBOOT=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/db1300_defconfig b/arch/mips/configs/db1300_defconfig
new file mode 100644
index 000000000000..c38b190151c4
--- /dev/null
+++ b/arch/mips/configs/db1300_defconfig
@@ -0,0 +1,391 @@
+CONFIG_MIPS=y
+CONFIG_MIPS_ALCHEMY=y
+CONFIG_ALCHEMY_GPIOINT_AU1300=y
+CONFIG_MIPS_DB1300=y
+CONFIG_SOC_AU1300=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_CEVT_R4K_LIB=y
+CONFIG_CSRC_R4K_LIB=y
+CONFIG_DMA_COHERENT=y
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+CONFIG_MIPS_DISABLE_OBSOLETE_IDE=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y
+CONFIG_IRQ_CPU=y
+CONFIG_MIPS_L1_CACHE_SHIFT=5
+CONFIG_CPU_MIPS32_R1=y
+CONFIG_SYS_SUPPORTS_ZBOOT=y
+CONFIG_SYS_HAS_CPU_MIPS32_R1=y
+CONFIG_CPU_MIPS32=y
+CONFIG_CPU_MIPSR1=y
+CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
+CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
+CONFIG_HARDWARE_WATCHPOINTS=y
+CONFIG_32BIT=y
+CONFIG_PAGE_SIZE_4KB=y
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_CPU_HAS_PREFETCH=y
+CONFIG_MIPS_MT_DISABLED=y
+CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_ARCH_PHYS_ADDR_T_64BIT=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_HZ_100=y
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=100
+CONFIG_PREEMPT_NONE=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION="-db1300"
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_BZIP2=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_LZMA=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_FHANDLE=y
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_TINY_RCU=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+CONFIG_SLAB=y
+CONFIG_HAVE_OPROFILE=y
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_DMA_ATTRS=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_ARCH_JUMP_LABEL=y
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_INLINE_SPIN_UNLOCK=y
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+CONFIG_INLINE_READ_UNLOCK=y
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+CONFIG_INLINE_WRITE_UNLOCK=y
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+CONFIG_MMU=y
+CONFIG_PCCARD=y
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
+CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
+CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_TRAD_SIGNALS=y
+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+CONFIG_INET_TUNNEL=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+CONFIG_MTD=y
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_MTD_CFI=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_BLK_DEV=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_UB=y
+CONFIG_HAVE_IDE=y
+CONFIG_IDE=y
+CONFIG_IDE_GD=y
+CONFIG_IDE_GD_ATA=y
+CONFIG_BLK_DEV_IDECS=y
+CONFIG_IDE_TASK_IOCTL=y
+CONFIG_IDE_PROC_FS=y
+CONFIG_BLK_DEV_PLATFORM=y
+CONFIG_SCSI_MOD=y
+CONFIG_NETDEVICES=y
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+CONFIG_SMSC_PHY=y
+CONFIG_NET_ETHERNET=y
+CONFIG_SMSC911X=y
+CONFIG_INPUT=y
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_KEYBOARD=y
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_WM97XX=y
+CONFIG_TOUCHSCREEN_WM9712=y
+CONFIG_TOUCHSCREEN_WM9713=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_SMBUS=y
+CONFIG_I2C_AU1550=y
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+CONFIG_SPI_AU1550=y
+CONFIG_SPI_BITBANG=y
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+CONFIG_HWMON=y
+CONFIG_HWMON_VID=y
+CONFIG_SENSORS_ADM1025=y
+CONFIG_FB=y
+CONFIG_FB_AU1200=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_FONTS=y
+CONFIG_FONT_ACORN_8x8=y
+CONFIG_LOGO=y
+CONFIG_LOGO_LINUX_CLUT224=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_HRTIMER=y
+CONFIG_SND_DYNAMIC_MINORS=y
+CONFIG_SND_VERBOSE_PROCFS=y
+CONFIG_SND_VERBOSE_PRINTK=y
+CONFIG_SND_VMASTER=y
+CONFIG_SND_AC97_CODEC=y
+CONFIG_SND_SOC=y
+CONFIG_SND_SOC_CACHE_LZO=y
+CONFIG_SND_SOC_AC97_BUS=y
+CONFIG_SND_SOC_AU1XPSC=y
+CONFIG_SND_SOC_AU1XPSC_I2S=y
+CONFIG_SND_SOC_AU1XPSC_AC97=y
+CONFIG_SND_SOC_DB1300=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_WM8731=y
+CONFIG_SND_SOC_WM9712=y
+CONFIG_AC97_BUS=y
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+CONFIG_HIDRAW=y
+CONFIG_USB_HID=y
+CONFIG_USB_HIDDEV=y
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+CONFIG_USB_DYNAMIC_MINORS=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_AU1XXX=y
+CONFIG_EXT2_FS=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_GENERIC_ACL=y
+CONFIG_FAT_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+CONFIG_MISC_FILESYSTEMS=y
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+CONFIG_JFFS2_SUMMARY=y
+CONFIG_JFFS2_FS_XATTR=y
+CONFIG_JFFS2_FS_POSIX_ACL=y
+CONFIG_JFFS2_FS_SECURITY=y
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+CONFIG_JFFS2_RUBIN=y
+CONFIG_JFFS2_CMODE_PRIORITY=y
+CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_XZ=y
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_CODEPAGE_850=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=y
+CONFIG_NLS_UTF8=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_EARLY_PRINTK=y
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="video=au1200fb:panel:bs console=tty console=ttyS2,115200"
+CONFIG_DEBUG_ZBOOT=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+CONFIG_BITREVERSE=y
+CONFIG_CRC32=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_GENERIC_ATOMIC64=y
diff --git a/arch/mips/configs/db1500_defconfig b/arch/mips/configs/db1500_defconfig
deleted file mode 100644
index b6e21c7cb6bd..000000000000
--- a/arch/mips/configs/db1500_defconfig
+++ /dev/null
@@ -1,128 +0,0 @@
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_MIPS_DB1500=y
-CONFIG_CPU_LITTLE_ENDIAN=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-db1500"
-CONFIG_KERNEL_LZMA=y
-CONFIG_SYSVIPC=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EXPERT=y
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_PCI=y
-CONFIG_PCCARD=y
-# CONFIG_CARDBUS is not set
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_PM=y
-CONFIG_PM_RUNTIME=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=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_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_INTELEXT=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_HPT366=y
-CONFIG_NETDEVICES=y
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_STE10XP=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_NET_ETHERNET=y
-CONFIG_MII=y
-CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_SERIAL_8250_PCI is not set
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-# CONFIG_VGA_ARB is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_HID_SUPPORT is not set
-CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_FS_XATTR=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_SQUASHFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_ZBOOT=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITYFS=y
diff --git a/arch/mips/configs/db1550_defconfig b/arch/mips/configs/db1550_defconfig
index 798a553c9e80..36cda27725e7 100644
--- a/arch/mips/configs/db1550_defconfig
+++ b/arch/mips/configs/db1550_defconfig
@@ -1,145 +1,262 @@
+CONFIG_MIPS=y
CONFIG_MIPS_ALCHEMY=y
CONFIG_MIPS_DB1550=y
+CONFIG_SCHED_OMIT_FRAME_POINTER=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_TICK_ONESHOT=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
+CONFIG_HZ=100
CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION="-db1550"
+CONFIG_LOCALVERSION_AUTO=y
CONFIG_KERNEL_LZMA=y
+CONFIG_DEFAULT_HOSTNAME="db1550"
+CONFIG_SWAP=y
CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+CONFIG_FHANDLE=y
+CONFIG_AUDIT=y
CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_USER_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+CONFIG_PCI_QUIRKS=y
CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_IOSCHED_NOOP=y
+CONFIG_DEFAULT_NOOP=y
+CONFIG_DEFAULT_IOSCHED="noop"
CONFIG_PCI=y
CONFIG_PCCARD=y
-# CONFIG_CARDBUS is not set
+CONFIG_PCMCIA=y
+CONFIG_PCMCIA_LOAD_CIS=y
CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_PM=y
+CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_BINFMT_MISC=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_PM_SLEEP=y
CONFIG_PM_RUNTIME=y
+CONFIG_PM=y
CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=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_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_LRO=y
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+CONFIG_IPV6=y
+CONFIG_INET6_XFRM_MODE_TRANSPORT=y
+CONFIG_INET6_XFRM_MODE_TUNNEL=y
+CONFIG_INET6_XFRM_MODE_BEET=y
+CONFIG_IPV6_SIT=y
+CONFIG_IPV6_NDISC_NODETYPE=y
+CONFIG_DNS_RESOLVER=y
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
CONFIG_MTD_BLOCK=y
CONFIG_MTD_CFI=y
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
CONFIG_MTD_CFI_AMDSTD=y
+CONFIG_MTD_CFI_UTIL=y
CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND_ECC=y
CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_AU1550=y
-CONFIG_BLK_DEV_UB=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_BLK_DEV_IDECD=y
-# CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS is not set
-CONFIG_IDE_TASK_IOCTL=y
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
-CONFIG_BLK_DEV_HPT366=y
+CONFIG_MTD_NAND_IDS=y
+CONFIG_MTD_NAND_PLATFORM=y
+CONFIG_MISC_DEVICES=y
+CONFIG_EEPROM_AT24=y
+CONFIG_SCSI_MOD=y
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_ATA=y
+CONFIG_ATA_SFF=y
+CONFIG_ATA_BMDMA=y
+CONFIG_PATA_HPT37X=y
+CONFIG_PATA_PCMCIA=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
CONFIG_NETDEVICES=y
-CONFIG_MARVELL_PHY=y
-CONFIG_DAVICOM_PHY=y
-CONFIG_QSEMI_PHY=y
-CONFIG_LXT_PHY=y
-CONFIG_CICADA_PHY=y
-CONFIG_VITESSE_PHY=y
-CONFIG_SMSC_PHY=y
-CONFIG_BROADCOM_PHY=y
-CONFIG_ICPLUS_PHY=y
-CONFIG_REALTEK_PHY=y
-CONFIG_NATIONAL_PHY=y
-CONFIG_STE10XP=y
-CONFIG_LSI_ET1011C_PHY=y
-CONFIG_NET_ETHERNET=y
CONFIG_MII=y
+CONFIG_PHYLIB=y
+CONFIG_NET_ETHERNET=y
CONFIG_MIPS_AU1X00_ENET=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_NET_PCMCIA=y
+CONFIG_PCMCIA_3C589=y
+CONFIG_PCMCIA_PCNET=y
+CONFIG_INPUT=y
CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_DEVKMEM=y
CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_DEVPORT=y
CONFIG_I2C=y
-# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_HELPER_AUTO is not set
CONFIG_I2C_AU1550=y
CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
CONFIG_SPI_AU1550=y
-# CONFIG_HWMON is not set
-# CONFIG_VGA_ARB is not set
-# CONFIG_VGA_CONSOLE is not set
+CONFIG_SPI_BITBANG=y
+CONFIG_HWMON=y
+CONFIG_SENSORS_ADM1025=y
+CONFIG_SENSORS_LM70=y
+CONFIG_DUMMY_CONSOLE=y
CONFIG_SOUND=y
CONFIG_SND=y
-CONFIG_SND_HRTIMER=y
-CONFIG_SND_DYNAMIC_MINORS=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
-# CONFIG_SND_DRIVERS is not set
-# CONFIG_SND_PCI is not set
-# CONFIG_SND_SPI is not set
-# CONFIG_SND_MIPS is not set
-# CONFIG_SND_PCMCIA is not set
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+CONFIG_SND_VMASTER=y
+CONFIG_SND_AC97_CODEC=y
CONFIG_SND_SOC=y
+CONFIG_SND_SOC_AC97_BUS=y
CONFIG_SND_SOC_AU1XPSC=y
-# CONFIG_HID_SUPPORT is not set
+CONFIG_SND_SOC_AU1XPSC_I2S=y
+CONFIG_SND_SOC_AU1XPSC_AC97=y
+CONFIG_SND_SOC_DB1200=y
+CONFIG_SND_SOC_I2C_AND_SPI=y
+CONFIG_SND_SOC_AC97_CODEC=y
+CONFIG_SND_SOC_WM8731=y
+CONFIG_SND_SOC_WM9712=y
+CONFIG_AC97_BUS=y
CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_SUSPEND=y
CONFIG_USB_EHCI_HCD=y
CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
CONFIG_USB_OHCI_HCD=y
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+CONFIG_USB_UHCI_HCD=y
+CONFIG_USB_STORAGE=y
+CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-# CONFIG_PROC_PAGE_MONITOR is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_USE_FOR_EXT23=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_JBD2=y
+CONFIG_FS_MBCACHE=y
+CONFIG_FS_POSIX_ACL=y
+CONFIG_EXPORTFS=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
CONFIG_TMPFS=y
CONFIG_CONFIGFS_FS=y
+CONFIG_MISC_FILESYSTEMS=y
CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
CONFIG_JFFS2_SUMMARY=y
CONFIG_JFFS2_FS_XATTR=y
-# CONFIG_JFFS2_FS_POSIX_ACL is not set
-# CONFIG_JFFS2_FS_SECURITY is not set
CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
CONFIG_JFFS2_RUBIN=y
+CONFIG_JFFS2_CMODE_PRIORITY=y
CONFIG_SQUASHFS=y
+CONFIG_SQUASHFS_ZLIB=y
+CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3
+CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_PNFS_FILE_LAYOUT=y
+CONFIG_PNFS_BLOCK=y
CONFIG_ROOT_NFS=y
+CONFIG_NFS_USE_KERNEL_DNS=y
+CONFIG_NFS_USE_NEW_IDMAPPER=y
+CONFIG_NFSD=y
+CONFIG_NFSD_V2_ACL=y
+CONFIG_NFSD_V3=y
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_SUNRPC_BACKCHANNEL=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_850=y
CONFIG_NLS_CODEPAGE_852=y
@@ -148,10 +265,21 @@ CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_ISO8859_15=y
CONFIG_NLS_UTF8=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_ZBOOT=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_FRAME_WARN=1024
+CONFIG_CMDLINE_BOOL=y
+CONFIG_CMDLINE="noirqdebug console=ttyS0,115200 root=/dev/sda1 rootfstype=ext4"
CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_SECURITYFS=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_BITREVERSE=y
+CONFIG_CRC16=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_BCH=y
+CONFIG_NLATTR=y
diff --git a/arch/mips/configs/nlm_xlp_defconfig b/arch/mips/configs/nlm_xlp_defconfig
new file mode 100644
index 000000000000..4479fd669ac1
--- /dev/null
+++ b/arch/mips/configs/nlm_xlp_defconfig
@@ -0,0 +1,570 @@
+CONFIG_NLM_XLP_BOARD=y
+CONFIG_64BIT=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=65536
+CONFIG_SMP=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+# CONFIG_SECCOMP is not set
+CONFIG_USE_OF=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_CROSS_COMPILE="mips-linux-gnu-"
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_CGROUPS=y
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs.xlp"
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_INITRAMFS_COMPRESSION_LZMA=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_EMBEDDED=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_PROFILING=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_INTEGRITY=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_BINFMT_MISC=y
+CONFIG_MIPS32_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_PM_RUNTIME=y
+CONFIG_PM_DEBUG=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM_USER=m
+CONFIG_NET_KEY=m
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_NET_IPIP=m
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_TCP_CONG_ADVANCED=y
+CONFIG_TCP_CONG_HSTCP=m
+CONFIG_TCP_CONG_HYBLA=m
+CONFIG_TCP_CONG_SCALABLE=m
+CONFIG_TCP_CONG_LP=m
+CONFIG_TCP_CONG_VENO=m
+CONFIG_TCP_CONG_YEAH=m
+CONFIG_TCP_CONG_ILLINOIS=m
+CONFIG_TCP_MD5SIG=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_INET6_AH=m
+CONFIG_INET6_ESP=m
+CONFIG_INET6_IPCOMP=m
+CONFIG_INET6_XFRM_MODE_TRANSPORT=m
+CONFIG_INET6_XFRM_MODE_TUNNEL=m
+CONFIG_INET6_XFRM_MODE_BEET=m
+CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION=m
+CONFIG_IPV6_SIT=m
+CONFIG_IPV6_TUNNEL=m
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_NETLABEL=y
+CONFIG_NETFILTER=y
+CONFIG_NF_CONNTRACK=m
+CONFIG_NF_CONNTRACK_SECMARK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_UDPLITE=m
+CONFIG_NF_CONNTRACK_AMANDA=m
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_H323=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_NETBIOS_NS=m
+CONFIG_NF_CONNTRACK_PPTP=m
+CONFIG_NF_CONNTRACK_SANE=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CONNTRACK_TFTP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=m
+CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=m
+CONFIG_NETFILTER_XT_TARGET_DSCP=m
+CONFIG_NETFILTER_XT_TARGET_MARK=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=m
+CONFIG_NETFILTER_XT_TARGET_NOTRACK=m
+CONFIG_NETFILTER_XT_TARGET_TPROXY=m
+CONFIG_NETFILTER_XT_TARGET_TRACE=m
+CONFIG_NETFILTER_XT_TARGET_SECMARK=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_CLUSTER=m
+CONFIG_NETFILTER_XT_MATCH_COMMENT=m
+CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_DSCP=m
+CONFIG_NETFILTER_XT_MATCH_ESP=m
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=m
+CONFIG_NETFILTER_XT_MATCH_HELPER=m
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
+CONFIG_NETFILTER_XT_MATCH_LENGTH=m
+CONFIG_NETFILTER_XT_MATCH_LIMIT=m
+CONFIG_NETFILTER_XT_MATCH_MAC=m
+CONFIG_NETFILTER_XT_MATCH_MARK=m
+CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
+CONFIG_NETFILTER_XT_MATCH_OSF=m
+CONFIG_NETFILTER_XT_MATCH_OWNER=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
+CONFIG_NETFILTER_XT_MATCH_QUOTA=m
+CONFIG_NETFILTER_XT_MATCH_RATEEST=m
+CONFIG_NETFILTER_XT_MATCH_REALM=m
+CONFIG_NETFILTER_XT_MATCH_RECENT=m
+CONFIG_NETFILTER_XT_MATCH_SOCKET=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=m
+CONFIG_NETFILTER_XT_MATCH_STRING=m
+CONFIG_NETFILTER_XT_MATCH_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_TIME=m
+CONFIG_NETFILTER_XT_MATCH_U32=m
+CONFIG_IP_VS=m
+CONFIG_IP_VS_IPV6=y
+CONFIG_IP_VS_PROTO_TCP=y
+CONFIG_IP_VS_PROTO_UDP=y
+CONFIG_IP_VS_PROTO_ESP=y
+CONFIG_IP_VS_PROTO_AH=y
+CONFIG_IP_VS_RR=m
+CONFIG_IP_VS_WRR=m
+CONFIG_IP_VS_LC=m
+CONFIG_IP_VS_WLC=m
+CONFIG_IP_VS_LBLC=m
+CONFIG_IP_VS_LBLCR=m
+CONFIG_IP_VS_DH=m
+CONFIG_IP_VS_SH=m
+CONFIG_IP_VS_SED=m
+CONFIG_IP_VS_NQ=m
+CONFIG_IP_VS_FTP=m
+CONFIG_NF_CONNTRACK_IPV4=m
+CONFIG_IP_NF_QUEUE=m
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_TARGET_LOG=m
+CONFIG_IP_NF_TARGET_ULOG=m
+CONFIG_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_TARGET_NETMAP=m
+CONFIG_IP_NF_TARGET_REDIRECT=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_IP_NF_TARGET_CLUSTERIP=m
+CONFIG_IP_NF_TARGET_ECN=m
+CONFIG_IP_NF_TARGET_TTL=m
+CONFIG_IP_NF_RAW=m
+CONFIG_IP_NF_SECURITY=m
+CONFIG_IP_NF_ARPTABLES=m
+CONFIG_IP_NF_ARPFILTER=m
+CONFIG_IP_NF_ARP_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_QUEUE=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_MH=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_TARGET_LOG=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_IP6_NF_RAW=m
+CONFIG_IP6_NF_SECURITY=m
+CONFIG_DECNET_NF_GRABULATOR=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_ULOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_IP_DCCP=m
+CONFIG_RDS=m
+CONFIG_RDS_TCP=m
+CONFIG_TIPC=m
+CONFIG_ATM=m
+CONFIG_ATM_CLIP=m
+CONFIG_ATM_LANE=m
+CONFIG_ATM_MPOA=m
+CONFIG_ATM_BR2684=m
+CONFIG_BRIDGE=m
+CONFIG_VLAN_8021Q=m
+CONFIG_VLAN_8021Q_GVRP=y
+CONFIG_DECNET=m
+CONFIG_LLC2=m
+CONFIG_IPX=m
+CONFIG_ATALK=m
+CONFIG_DEV_APPLETALK=m
+CONFIG_IPDDP=m
+CONFIG_IPDDP_ENCAP=y
+CONFIG_IPDDP_DECAP=y
+CONFIG_X25=m
+CONFIG_LAPB=m
+CONFIG_ECONET=m
+CONFIG_ECONET_AUNUDP=y
+CONFIG_ECONET_NATIVE=y
+CONFIG_WAN_ROUTER=m
+CONFIG_PHONET=m
+CONFIG_IEEE802154=m
+CONFIG_NET_SCHED=y
+CONFIG_NET_SCH_CBQ=m
+CONFIG_NET_SCH_HTB=m
+CONFIG_NET_SCH_HFSC=m
+CONFIG_NET_SCH_ATM=m
+CONFIG_NET_SCH_PRIO=m
+CONFIG_NET_SCH_MULTIQ=m
+CONFIG_NET_SCH_RED=m
+CONFIG_NET_SCH_SFQ=m
+CONFIG_NET_SCH_TEQL=m
+CONFIG_NET_SCH_TBF=m
+CONFIG_NET_SCH_GRED=m
+CONFIG_NET_SCH_DSMARK=m
+CONFIG_NET_SCH_NETEM=m
+CONFIG_NET_SCH_DRR=m
+CONFIG_NET_SCH_INGRESS=m
+CONFIG_NET_CLS_BASIC=m
+CONFIG_NET_CLS_TCINDEX=m
+CONFIG_NET_CLS_ROUTE4=m
+CONFIG_NET_CLS_FW=m
+CONFIG_NET_CLS_U32=m
+CONFIG_CLS_U32_MARK=y
+CONFIG_NET_CLS_RSVP=m
+CONFIG_NET_CLS_RSVP6=m
+CONFIG_NET_CLS_FLOW=m
+CONFIG_NET_EMATCH=y
+CONFIG_NET_EMATCH_CMP=m
+CONFIG_NET_EMATCH_NBYTE=m
+CONFIG_NET_EMATCH_U32=m
+CONFIG_NET_EMATCH_META=m
+CONFIG_NET_EMATCH_TEXT=m
+CONFIG_NET_CLS_ACT=y
+CONFIG_NET_ACT_POLICE=m
+CONFIG_NET_ACT_GACT=m
+CONFIG_GACT_PROB=y
+CONFIG_NET_ACT_MIRRED=m
+CONFIG_NET_ACT_IPT=m
+CONFIG_NET_ACT_NAT=m
+CONFIG_NET_ACT_PEDIT=m
+CONFIG_NET_ACT_SIMP=m
+CONFIG_NET_ACT_SKBEDIT=m
+CONFIG_DCB=y
+CONFIG_NET_PKTGEN=m
+# CONFIG_WIRELESS is not set
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_CONNECTOR=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=m
+CONFIG_BLK_DEV_NBD=m
+CONFIG_BLK_DEV_OSD=m
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=65536
+CONFIG_CDROM_PKTCDVD=y
+CONFIG_RAID_ATTRS=m
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=m
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_ST=m
+CONFIG_CHR_DEV_OSST=m
+CONFIG_BLK_DEV_SR=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=m
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_SPI_ATTRS=m
+CONFIG_SCSI_FC_TGT_ATTRS=y
+CONFIG_SCSI_SAS_LIBSAS=m
+CONFIG_SCSI_SRP_ATTRS=m
+CONFIG_SCSI_SRP_TGT_ATTRS=y
+CONFIG_ISCSI_TCP=m
+CONFIG_LIBFCOE=m
+CONFIG_SCSI_DEBUG=m
+CONFIG_SCSI_DH=y
+CONFIG_SCSI_DH_RDAC=m
+CONFIG_SCSI_DH_HP_SW=m
+CONFIG_SCSI_DH_EMC=m
+CONFIG_SCSI_DH_ALUA=m
+CONFIG_SCSI_OSD_INITIATOR=m
+CONFIG_SCSI_OSD_ULD=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO_I8042 is not set
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=y
+CONFIG_SERIO_RAW=m
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+CONFIG_LEGACY_PTY_COUNT=0
+CONFIG_SERIAL_NONSTANDARD=y
+CONFIG_N_HDLC=m
+# CONFIG_DEVKMEM is not set
+CONFIG_STALDRV=y
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=48
+CONFIG_SERIAL_8250_EXTENDED=y
+CONFIG_SERIAL_8250_MANY_PORTS=y
+CONFIG_SERIAL_8250_SHARE_IRQ=y
+CONFIG_SERIAL_8250_RSA=y
+CONFIG_HW_RANDOM=y
+CONFIG_HW_RANDOM_TIMERIOMEM=m
+CONFIG_RAW_DRIVER=m
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_UIO=y
+CONFIG_UIO_PDRV=m
+CONFIG_UIO_PDRV_GENIRQ=m
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_GFS2_FS=m
+CONFIG_GFS2_FS_LOCKING_DLM=y
+CONFIG_OCFS2_FS=m
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_NILFS2_FS=m
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_QFMT_V1=m
+CONFIG_QFMT_V2=m
+CONFIG_AUTOFS4_FS=m
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=m
+CONFIG_FSCACHE=m
+CONFIG_FSCACHE_STATS=y
+CONFIG_FSCACHE_HISTOGRAM=y
+CONFIG_CACHEFILES=m
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=m
+CONFIG_NTFS_FS=m
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_ADFS_FS=m
+CONFIG_AFFS_FS=m
+CONFIG_ECRYPT_FS=y
+CONFIG_HFS_FS=m
+CONFIG_HFSPLUS_FS=m
+CONFIG_BEFS_FS=m
+CONFIG_BFS_FS=m
+CONFIG_EFS_FS=m
+CONFIG_CRAMFS=m
+CONFIG_SQUASHFS=m
+CONFIG_VXFS_FS=m
+CONFIG_MINIX_FS=m
+CONFIG_OMFS_FS=m
+CONFIG_HPFS_FS=m
+CONFIG_QNX4FS_FS=m
+CONFIG_ROMFS_FS=m
+CONFIG_SYSV_FS=m
+CONFIG_UFS_FS=m
+CONFIG_EXOFS_FS=m
+CONFIG_NFS_FS=m
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NFS_FSCACHE=y
+CONFIG_NFSD=m
+CONFIG_NFSD_V3_ACL=y
+CONFIG_NFSD_V4=y
+CONFIG_CIFS=m
+CONFIG_CIFS_WEAK_PW_HASH=y
+CONFIG_CIFS_UPCALL=y
+CONFIG_CIFS_XATTR=y
+CONFIG_CIFS_POSIX=y
+CONFIG_CIFS_DFS_UPCALL=y
+CONFIG_NCP_FS=m
+CONFIG_NCPFS_PACKET_SIGNING=y
+CONFIG_NCPFS_IOCTL_LOCKING=y
+CONFIG_NCPFS_STRONG=y
+CONFIG_NCPFS_NFS_NS=y
+CONFIG_NCPFS_OS2_NS=y
+CONFIG_NCPFS_NLS=y
+CONFIG_NCPFS_EXTRAS=y
+CONFIG_CODA_FS=m
+CONFIG_AFS_FS=m
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_ACORN_PARTITION=y
+CONFIG_ACORN_PARTITION_ICS=y
+CONFIG_ACORN_PARTITION_RISCIX=y
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+CONFIG_ATARI_PARTITION=y
+CONFIG_MAC_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+CONFIG_LDM_PARTITION=y
+CONFIG_SGI_PARTITION=y
+CONFIG_ULTRIX_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+CONFIG_SYSV68_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_737=m
+CONFIG_NLS_CODEPAGE_775=m
+CONFIG_NLS_CODEPAGE_850=m
+CONFIG_NLS_CODEPAGE_852=m
+CONFIG_NLS_CODEPAGE_855=m
+CONFIG_NLS_CODEPAGE_857=m
+CONFIG_NLS_CODEPAGE_860=m
+CONFIG_NLS_CODEPAGE_861=m
+CONFIG_NLS_CODEPAGE_862=m
+CONFIG_NLS_CODEPAGE_863=m
+CONFIG_NLS_CODEPAGE_864=m
+CONFIG_NLS_CODEPAGE_865=m
+CONFIG_NLS_CODEPAGE_866=m
+CONFIG_NLS_CODEPAGE_869=m
+CONFIG_NLS_CODEPAGE_936=m
+CONFIG_NLS_CODEPAGE_950=m
+CONFIG_NLS_CODEPAGE_932=m
+CONFIG_NLS_CODEPAGE_949=m
+CONFIG_NLS_CODEPAGE_874=m
+CONFIG_NLS_ISO8859_8=m
+CONFIG_NLS_CODEPAGE_1250=m
+CONFIG_NLS_CODEPAGE_1251=m
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=m
+CONFIG_NLS_ISO8859_2=m
+CONFIG_NLS_ISO8859_3=m
+CONFIG_NLS_ISO8859_4=m
+CONFIG_NLS_ISO8859_5=m
+CONFIG_NLS_ISO8859_6=m
+CONFIG_NLS_ISO8859_7=m
+CONFIG_NLS_ISO8859_9=m
+CONFIG_NLS_ISO8859_13=m
+CONFIG_NLS_ISO8859_14=m
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_KOI8_R=m
+CONFIG_NLS_KOI8_U=m
+CONFIG_PRINTK_TIME=y
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_INFO=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_SCHED_TRACER=y
+CONFIG_BLK_DEV_IO_TRACE=y
+CONFIG_KGDB=y
+CONFIG_SECURITY=y
+CONFIG_SECURITY_NETWORK=y
+CONFIG_LSM_MMAP_MIN_ADDR=0
+CONFIG_SECURITY_SELINUX=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=0
+CONFIG_SECURITY_SELINUX_DISABLE=y
+CONFIG_SECURITY_SMACK=y
+CONFIG_SECURITY_TOMOYO=y
+CONFIG_CRYPTO_NULL=m
+CONFIG_CRYPTO_CRYPTD=m
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CCM=m
+CONFIG_CRYPTO_GCM=m
+CONFIG_CRYPTO_CTS=m
+CONFIG_CRYPTO_LRW=m
+CONFIG_CRYPTO_PCBC=m
+CONFIG_CRYPTO_XTS=m
+CONFIG_CRYPTO_HMAC=y
+CONFIG_CRYPTO_XCBC=m
+CONFIG_CRYPTO_VMAC=m
+CONFIG_CRYPTO_MICHAEL_MIC=m
+CONFIG_CRYPTO_RMD128=m
+CONFIG_CRYPTO_RMD160=m
+CONFIG_CRYPTO_RMD256=m
+CONFIG_CRYPTO_RMD320=m
+CONFIG_CRYPTO_SHA256=m
+CONFIG_CRYPTO_SHA512=m
+CONFIG_CRYPTO_TGR192=m
+CONFIG_CRYPTO_WP512=m
+CONFIG_CRYPTO_ANUBIS=m
+CONFIG_CRYPTO_BLOWFISH=m
+CONFIG_CRYPTO_CAMELLIA=m
+CONFIG_CRYPTO_CAST5=m
+CONFIG_CRYPTO_CAST6=m
+CONFIG_CRYPTO_FCRYPT=m
+CONFIG_CRYPTO_KHAZAD=m
+CONFIG_CRYPTO_SALSA20=m
+CONFIG_CRYPTO_SEED=m
+CONFIG_CRYPTO_SERPENT=m
+CONFIG_CRYPTO_TEA=m
+CONFIG_CRYPTO_TWOFISH=m
+CONFIG_CRYPTO_ZLIB=m
+CONFIG_CRYPTO_LZO=m
+CONFIG_CRC_CCITT=m
+CONFIG_CRC7=m
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig
index e4b399fdaa61..7c68666fdd64 100644
--- a/arch/mips/configs/nlm_xlr_defconfig
+++ b/arch/mips/configs/nlm_xlr_defconfig
@@ -8,7 +8,7 @@ CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT_VOLUNTARY=y
CONFIG_KEXEC=y
CONFIG_EXPERIMENTAL=y
-CONFIG_CROSS_COMPILE="mips64-unknown-linux-gnu-"
+CONFIG_CROSS_COMPILE="mips-linux-gnu-"
# CONFIG_LOCALVERSION_AUTO is not set
CONFIG_SYSVIPC=y
CONFIG_POSIX_MQUEUE=y
@@ -22,15 +22,13 @@ CONFIG_AUDIT=y
CONFIG_NAMESPACES=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_BLK_DEV_INITRD=y
-CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs"
+CONFIG_INITRAMFS_SOURCE="usr/dev_file_list usr/rootfs.xlr"
CONFIG_RD_BZIP2=y
CONFIG_RD_LZMA=y
CONFIG_INITRAMFS_COMPRESSION_GZIP=y
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
CONFIG_EXPERT=y
CONFIG_KALLSYMS_ALL=y
# CONFIG_ELF_CORE is not set
-# CONFIG_PCSPKR_PLATFORM is not set
# CONFIG_PERF_EVENTS is not set
# CONFIG_COMPAT_BRK is not set
CONFIG_PROFILING=y
@@ -39,6 +37,9 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODVERSIONS=y
CONFIG_MODULE_SRCVERSION_ALL=y
CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
+CONFIG_PCI_DEBUG=y
CONFIG_BINFMT_MISC=m
CONFIG_PM_RUNTIME=y
CONFIG_PM_DEBUG=y
@@ -297,12 +298,10 @@ CONFIG_NET_ACT_SIMP=m
CONFIG_NET_ACT_SKBEDIT=m
CONFIG_DCB=y
CONFIG_NET_PKTGEN=m
-# CONFIG_WIRELESS is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_STANDALONE is not set
CONFIG_CONNECTOR=y
-CONFIG_MTD=m
CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_CRYPTOLOOP=m
CONFIG_BLK_DEV_NBD=m
@@ -339,6 +338,9 @@ CONFIG_SCSI_DH_EMC=m
CONFIG_SCSI_DH_ALUA=m
CONFIG_SCSI_OSD_INITIATOR=m
CONFIG_SCSI_OSD_ULD=m
+CONFIG_NETDEVICES=y
+CONFIG_E1000E=y
+CONFIG_SKY2=y
# CONFIG_INPUT_MOUSEDEV is not set
CONFIG_INPUT_EVDEV=y
CONFIG_INPUT_EVBUG=m
@@ -443,7 +445,6 @@ CONFIG_CIFS_UPCALL=y
CONFIG_CIFS_XATTR=y
CONFIG_CIFS_POSIX=y
CONFIG_CIFS_DFS_UPCALL=y
-CONFIG_CIFS_EXPERIMENTAL=y
CONFIG_NCP_FS=m
CONFIG_NCPFS_PACKET_SIGNING=y
CONFIG_NCPFS_IOCTL_LOCKING=y
@@ -516,7 +517,6 @@ CONFIG_PRINTK_TIME=y
# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
CONFIG_UNUSED_SYMBOLS=y
-CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_HUNG_TASK=y
CONFIG_SCHEDSTATS=y
CONFIG_TIMER_STATS=y
diff --git a/arch/mips/configs/pb1200_defconfig b/arch/mips/configs/pb1200_defconfig
deleted file mode 100644
index dcbe2704e5ed..000000000000
--- a/arch/mips/configs/pb1200_defconfig
+++ /dev/null
@@ -1,170 +0,0 @@
-CONFIG_MIPS_ALCHEMY=y
-CONFIG_MIPS_PB1200=y
-CONFIG_KSM=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
-CONFIG_HZ_100=y
-# CONFIG_SECCOMP is not set
-CONFIG_EXPERIMENTAL=y
-CONFIG_LOCALVERSION="-pb1200"
-CONFIG_KERNEL_LZMA=y
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_TINY_RCU=y
-CONFIG_LOG_BUF_SHIFT=14
-CONFIG_EXPERT=y
-# CONFIG_SYSCTL_SYSCALL is not set
-# CONFIG_KALLSYMS is not set
-# CONFIG_PCSPKR_PLATFORM is not set
-# CONFIG_VM_EVENT_COUNTERS is not set
-# CONFIG_COMPAT_BRK is not set
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_PCCARD=y
-CONFIG_PCMCIA_ALCHEMY_DEVBOARD=y
-CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
-CONFIG_BINFMT_MISC=y
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=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_DIAG is not set
-# CONFIG_IPV6 is not set
-# CONFIG_WIRELESS is not set
-CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
-CONFIG_MTD=y
-CONFIG_MTD_PARTITIONS=y
-CONFIG_MTD_CMDLINE_PARTS=y
-CONFIG_MTD_CHAR=y
-CONFIG_MTD_BLOCK=y
-CONFIG_MTD_CFI=y
-CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_NAND=y
-CONFIG_MTD_NAND_PLATFORM=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_UB=y
-# CONFIG_MISC_DEVICES is not set
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_IDE_TASK_IOCTL=y
-# CONFIG_IDE_PROC_FS is not set
-CONFIG_BLK_DEV_IDE_AU1XXX=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_SMC91X=y
-# CONFIG_NETDEV_1000 is not set
-# CONFIG_NETDEV_10000 is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-CONFIG_VT_HW_CONSOLE_BINDING=y
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=2
-CONFIG_SERIAL_8250_RUNTIME_UARTS=2
-# CONFIG_LEGACY_PTYS is not set
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C=y
-# CONFIG_I2C_COMPAT is not set
-CONFIG_I2C_CHARDEV=y
-# CONFIG_I2C_HELPER_AUTO is not set
-CONFIG_I2C_AU1550=y
-CONFIG_SPI=y
-CONFIG_SPI_AU1550=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_SYSFS=y
-CONFIG_SENSORS_ADM1025=y
-CONFIG_SENSORS_LM70=y
-CONFIG_FB=y
-CONFIG_FB_AU1200=y
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_FONTS=y
-CONFIG_FONT_8x16=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_DYNAMIC_MINORS=y
-# CONFIG_SND_SUPPORT_OLD_API is not set
-# CONFIG_SND_VERBOSE_PROCFS is not set
-# CONFIG_SND_DRIVERS is not set
-# CONFIG_SND_SPI is not set
-# CONFIG_SND_MIPS is not set
-# CONFIG_SND_USB is not set
-# CONFIG_SND_PCMCIA is not set
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_AU1XPSC=y
-CONFIG_SND_SOC_DB1200=y
-CONFIG_HIDRAW=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_DEBUG=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-# CONFIG_USB_DEVICE_CLASS is not set
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_ROOT_HUB_TT=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_MMC=y
-# CONFIG_MMC_BLOCK_BOUNCE is not set
-CONFIG_MMC_AU1X=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_RTC_CLASS=y
-CONFIG_RTC_DRV_AU1XXX=y
-CONFIG_EXT2_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_ZISOFS=y
-CONFIG_UDF_FS=y
-CONFIG_VFAT_FS=y
-# CONFIG_PROC_PAGE_MONITOR is not set
-CONFIG_TMPFS=y
-CONFIG_JFFS2_FS=y
-CONFIG_JFFS2_SUMMARY=y
-CONFIG_JFFS2_COMPRESSION_OPTIONS=y
-CONFIG_JFFS2_LZO=y
-CONFIG_JFFS2_RUBIN=y
-CONFIG_SQUASHFS=y
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
-CONFIG_ROOT_NFS=y
-CONFIG_PARTITION_ADVANCED=y
-CONFIG_EFI_PARTITION=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_850=y
-CONFIG_NLS_CODEPAGE_852=y
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_ASCII=y
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=y
-CONFIG_NLS_ISO8859_15=y
-CONFIG_NLS_UTF8=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_KERNEL=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_FTRACE is not set
-CONFIG_CMDLINE_BOOL=y
-CONFIG_CMDLINE="console=ttyS0,115200"
-CONFIG_DEBUG_ZBOOT=y
-CONFIG_KEYS=y
-CONFIG_KEYS_DEBUG_PROC_KEYS=y
-CONFIG_SECURITYFS=y
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index f7b7ba6d5c45..b874accd878a 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -110,7 +110,6 @@ static struct irqaction fpuirq = {
};
static struct irqaction busirq = {
- .flags = IRQF_DISABLED,
.name = "bus error",
.flags = IRQF_NO_THREAD,
};
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild
index 7897f05e3165..f53f9ca73996 100644
--- a/arch/mips/include/asm/Kbuild
+++ b/arch/mips/include/asm/Kbuild
@@ -1,3 +1,5 @@
include include/asm-generic/Kbuild.asm
-header-y += cachectl.h sgidefs.h sysmips.h
+header-y += cachectl.h
+header-y += sgidefs.h
+header-y += sysmips.h
diff --git a/arch/mips/include/asm/bmips.h b/arch/mips/include/asm/bmips.h
new file mode 100644
index 000000000000..552a65a0cf2b
--- /dev/null
+++ b/arch/mips/include/asm/bmips.h
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2011 by Kevin Cernekee (cernekee@gmail.com)
+ *
+ * Definitions for BMIPS processors
+ */
+#ifndef _ASM_BMIPS_H
+#define _ASM_BMIPS_H
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <asm/addrspace.h>
+#include <asm/mipsregs.h>
+#include <asm/hazards.h>
+
+/* NOTE: the CBR register returns a PA, and it can be above 0xff00_0000 */
+#define BMIPS_GET_CBR() ((void __iomem *)(CKSEG1 | \
+ (unsigned long) \
+ ((read_c0_brcm_cbr() >> 18) << 18)))
+
+#define BMIPS_RAC_CONFIG 0x00000000
+#define BMIPS_RAC_ADDRESS_RANGE 0x00000004
+#define BMIPS_RAC_CONFIG_1 0x00000008
+#define BMIPS_L2_CONFIG 0x0000000c
+#define BMIPS_LMB_CONTROL 0x0000001c
+#define BMIPS_SYSTEM_BASE 0x00000020
+#define BMIPS_PERF_GLOBAL_CONTROL 0x00020000
+#define BMIPS_PERF_CONTROL_0 0x00020004
+#define BMIPS_PERF_CONTROL_1 0x00020008
+#define BMIPS_PERF_COUNTER_0 0x00020010
+#define BMIPS_PERF_COUNTER_1 0x00020014
+#define BMIPS_PERF_COUNTER_2 0x00020018
+#define BMIPS_PERF_COUNTER_3 0x0002001c
+#define BMIPS_RELO_VECTOR_CONTROL_0 0x00030000
+#define BMIPS_RELO_VECTOR_CONTROL_1 0x00038000
+
+#define BMIPS_NMI_RESET_VEC 0x80000000
+#define BMIPS_WARM_RESTART_VEC 0x80000380
+
+#define ZSCM_REG_BASE 0x97000000
+
+#if !defined(__ASSEMBLY__)
+
+#include <linux/cpumask.h>
+#include <asm/r4kcache.h>
+
+extern struct plat_smp_ops bmips_smp_ops;
+extern char bmips_reset_nmi_vec;
+extern char bmips_reset_nmi_vec_end;
+extern char bmips_smp_movevec;
+extern char bmips_smp_int_vec;
+extern char bmips_smp_int_vec_end;
+
+extern int bmips_smp_enabled;
+extern int bmips_cpu_offset;
+extern cpumask_t bmips_booted_mask;
+
+extern void bmips_ebase_setup(void);
+extern asmlinkage void plat_wired_tlb_setup(void);
+
+static inline unsigned long bmips_read_zscm_reg(unsigned int offset)
+{
+ unsigned long ret;
+
+ __asm__ __volatile__(
+ ".set push\n"
+ ".set noreorder\n"
+ "cache %1, 0(%2)\n"
+ "sync\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "mfc0 %0, $28, 3\n"
+ "_ssnop\n"
+ ".set pop\n"
+ : "=&r" (ret)
+ : "i" (Index_Load_Tag_S), "r" (ZSCM_REG_BASE + offset)
+ : "memory");
+ return ret;
+}
+
+static inline void bmips_write_zscm_reg(unsigned int offset, unsigned long data)
+{
+ __asm__ __volatile__(
+ ".set push\n"
+ ".set noreorder\n"
+ "mtc0 %0, $28, 3\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "cache %1, 0(%2)\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ "_ssnop\n"
+ : /* no outputs */
+ : "r" (data),
+ "i" (Index_Store_Tag_S), "r" (ZSCM_REG_BASE + offset)
+ : "memory");
+}
+
+#endif /* !defined(__ASSEMBLY__) */
+
+#endif /* _ASM_BMIPS_H */
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 35cd1bab69c3..7a51d879e6ca 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -86,6 +86,7 @@ extern unsigned long mips_machtype;
#define BOOT_MEM_RAM 1
#define BOOT_MEM_ROM_DATA 2
#define BOOT_MEM_RESERVED 3
+#define BOOT_MEM_INIT_RAM 4
/*
* A memory map that's built upon what was determined
diff --git a/arch/mips/include/asm/branch.h b/arch/mips/include/asm/branch.h
index 37c6857c8d4a..888766ae1f85 100644
--- a/arch/mips/include/asm/branch.h
+++ b/arch/mips/include/asm/branch.h
@@ -9,6 +9,7 @@
#define _ASM_BRANCH_H
#include <asm/ptrace.h>
+#include <asm/inst.h>
static inline int delay_slot(struct pt_regs *regs)
{
@@ -23,7 +24,11 @@ static inline unsigned long exception_epc(struct pt_regs *regs)
return regs->cp0_epc + 4;
}
+#define BRANCH_LIKELY_TAKEN 0x0001
+
extern int __compute_return_epc(struct pt_regs *regs);
+extern int __compute_return_epc_for_insn(struct pt_regs *regs,
+ union mips_instruction insn);
static inline int compute_return_epc(struct pt_regs *regs)
{
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 2f7f41873f24..f9fa2a479dd0 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -169,6 +169,10 @@
#define PRID_IMP_NETLOGIC_XLS412B 0x4c00
#define PRID_IMP_NETLOGIC_XLS408B 0x4e00
#define PRID_IMP_NETLOGIC_XLS404B 0x4f00
+#define PRID_IMP_NETLOGIC_AU13XX 0x8000
+
+#define PRID_IMP_NETLOGIC_XLP8XX 0x1000
+#define PRID_IMP_NETLOGIC_XLP3XX 0x1100
/*
* Definitions for 7:0 on legacy processors
@@ -263,7 +267,7 @@ enum cpu_type_enum {
*/
CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
CPU_CAVIUM_OCTEON, CPU_CAVIUM_OCTEON_PLUS, CPU_CAVIUM_OCTEON2,
- CPU_XLR,
+ CPU_XLR, CPU_XLP,
CPU_LAST
};
diff --git a/arch/mips/include/asm/gio_device.h b/arch/mips/include/asm/gio_device.h
new file mode 100644
index 000000000000..5437c84664bf
--- /dev/null
+++ b/arch/mips/include/asm/gio_device.h
@@ -0,0 +1,56 @@
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+struct gio_device_id {
+ __u8 id;
+};
+
+struct gio_device {
+ struct device dev;
+ struct resource resource;
+ unsigned int irq;
+ unsigned int slotno;
+
+ const char *name;
+ struct gio_device_id id;
+ unsigned id32:1;
+ unsigned gio64:1;
+};
+#define to_gio_device(d) container_of(d, struct gio_device, dev)
+
+struct gio_driver {
+ const char *name;
+ struct module *owner;
+ const struct gio_device_id *id_table;
+
+ int (*probe)(struct gio_device *, const struct gio_device_id *);
+ void (*remove)(struct gio_device *);
+ int (*suspend)(struct gio_device *, pm_message_t);
+ int (*resume)(struct gio_device *);
+ void (*shutdown)(struct gio_device *);
+
+ struct device_driver driver;
+};
+#define to_gio_driver(drv) container_of(drv, struct gio_driver, driver)
+
+extern const struct gio_device_id *gio_match_device(const struct gio_device_id *,
+ const struct gio_device *);
+extern struct gio_device *gio_dev_get(struct gio_device *);
+extern void gio_dev_put(struct gio_device *);
+
+extern int gio_device_register(struct gio_device *);
+extern void gio_device_unregister(struct gio_device *);
+extern void gio_release_dev(struct device *);
+
+static inline void gio_device_free(struct gio_device *dev)
+{
+ gio_release_dev(&dev->dev);
+}
+
+extern int gio_register_driver(struct gio_driver *);
+extern void gio_unregister_driver(struct gio_driver *);
+
+#define gio_get_drvdata(_dev) drv_get_drvdata(&(_dev)->dev)
+#define gio_set_drvdata(_dev, data) drv_set_drvdata(&(_dev)->dev, (data))
+
+extern void gio_set_master(struct gio_device *);
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
index 4e332165d7b7..b4c20e4f87cd 100644
--- a/arch/mips/include/asm/hazards.h
+++ b/arch/mips/include/asm/hazards.h
@@ -87,7 +87,8 @@ do { \
: "=r" (tmp)); \
} while (0)
-#elif defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MIPS_ALCHEMY)
+#elif (defined(CONFIG_CPU_MIPSR1) && !defined(CONFIG_MIPS_ALCHEMY)) || \
+ defined(CONFIG_CPU_BMIPS)
/*
* These are slightly complicated by the fact that we guarantee R1 kernels to
@@ -139,8 +140,8 @@ do { \
} while (0)
#elif defined(CONFIG_MIPS_ALCHEMY) || defined(CONFIG_CPU_CAVIUM_OCTEON) || \
- defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
- defined(CONFIG_CPU_R5500)
+ defined(CONFIG_CPU_LOONGSON2) || defined(CONFIG_CPU_R10000) || \
+ defined(CONFIG_CPU_R5500)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
diff --git a/arch/mips/include/asm/hugetlb.h b/arch/mips/include/asm/hugetlb.h
index c565b7c3f0b5..58d36889f09b 100644
--- a/arch/mips/include/asm/hugetlb.h
+++ b/arch/mips/include/asm/hugetlb.h
@@ -70,7 +70,7 @@ static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm,
static inline void huge_ptep_clear_flush(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep)
{
- flush_tlb_mm(vma->vm_mm);
+ flush_tlb_page(vma, addr & huge_page_mask(hstate_vma(vma)));
}
static inline int huge_pte_none(pte_t pte)
diff --git a/arch/mips/include/asm/kprobes.h b/arch/mips/include/asm/kprobes.h
index e6ea4d4d7205..1fbbca01e681 100644
--- a/arch/mips/include/asm/kprobes.h
+++ b/arch/mips/include/asm/kprobes.h
@@ -74,6 +74,8 @@ struct prev_kprobe {
: MAX_JPROBES_STACK_SIZE)
+#define SKIP_DELAYSLOT 0x0001
+
/* per-cpu kprobe control block */
struct kprobe_ctlblk {
unsigned long kprobe_status;
@@ -82,6 +84,9 @@ struct kprobe_ctlblk {
unsigned long kprobe_saved_epc;
unsigned long jprobe_saved_sp;
struct pt_regs jprobe_saved_regs;
+ /* Per-thread fields, used while emulating branches */
+ unsigned long flags;
+ unsigned long target_epc;
u8 jprobes_stack[MAX_JPROBES_STACK_SIZE];
struct prev_kprobe prev_kprobe;
};
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index cda1c8070b27..2f0becb4ec8f 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -20,6 +20,10 @@
#include <linux/bitops.h>
#define AR71XX_APB_BASE 0x18000000
+#define AR71XX_EHCI_BASE 0x1b000000
+#define AR71XX_EHCI_SIZE 0x1000
+#define AR71XX_OHCI_BASE 0x1c000000
+#define AR71XX_OHCI_SIZE 0x1000
#define AR71XX_SPI_BASE 0x1f000000
#define AR71XX_SPI_SIZE 0x01000000
@@ -27,6 +31,8 @@
#define AR71XX_DDR_CTRL_SIZE 0x100
#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
#define AR71XX_UART_SIZE 0x100
+#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
+#define AR71XX_USB_CTRL_SIZE 0x100
#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
#define AR71XX_GPIO_SIZE 0x100
#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
@@ -34,9 +40,26 @@
#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
#define AR71XX_RESET_SIZE 0x100
+#define AR7240_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
+#define AR7240_USB_CTRL_SIZE 0x100
+#define AR7240_OHCI_BASE 0x1b000000
+#define AR7240_OHCI_SIZE 0x1000
+
+#define AR724X_EHCI_BASE 0x1b000000
+#define AR724X_EHCI_SIZE 0x1000
+
+#define AR913X_EHCI_BASE 0x1b000000
+#define AR913X_EHCI_SIZE 0x1000
#define AR913X_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
#define AR913X_WMAC_SIZE 0x30000
+#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000)
+#define AR933X_UART_SIZE 0x14
+#define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
+#define AR933X_WMAC_SIZE 0x20000
+#define AR933X_EHCI_BASE 0x1b000000
+#define AR933X_EHCI_SIZE 0x1000
+
/*
* DDR_CTRL block
*/
@@ -63,6 +86,11 @@
#define AR913X_DDR_REG_FLUSH_USB 0x84
#define AR913X_DDR_REG_FLUSH_WMAC 0x88
+#define AR933X_DDR_REG_FLUSH_GE0 0x7c
+#define AR933X_DDR_REG_FLUSH_GE1 0x80
+#define AR933X_DDR_REG_FLUSH_USB 0x84
+#define AR933X_DDR_REG_FLUSH_WMAC 0x88
+
/*
* PLL block
*/
@@ -104,6 +132,30 @@
#define AR913X_AHB_DIV_SHIFT 19
#define AR913X_AHB_DIV_MASK 0x1
+#define AR933X_PLL_CPU_CONFIG_REG 0x00
+#define AR933X_PLL_CLOCK_CTRL_REG 0x08
+
+#define AR933X_PLL_CPU_CONFIG_NINT_SHIFT 10
+#define AR933X_PLL_CPU_CONFIG_NINT_MASK 0x3f
+#define AR933X_PLL_CPU_CONFIG_REFDIV_SHIFT 16
+#define AR933X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
+#define AR933X_PLL_CPU_CONFIG_OUTDIV_SHIFT 23
+#define AR933X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
+
+#define AR933X_PLL_CLOCK_CTRL_BYPASS BIT(2)
+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_SHIFT 5
+#define AR933X_PLL_CLOCK_CTRL_CPU_DIV_MASK 0x3
+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_SHIFT 10
+#define AR933X_PLL_CLOCK_CTRL_DDR_DIV_MASK 0x3
+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15
+#define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7
+
+/*
+ * USB_CONFIG block
+ */
+#define AR71XX_USB_CTRL_REG_FLADJ 0x00
+#define AR71XX_USB_CTRL_REG_CONFIG 0x04
+
/*
* RESET block
*/
@@ -130,6 +182,13 @@
#define AR724X_RESET_REG_RESET_MODULE 0x1c
+#define AR933X_RESET_REG_RESET_MODULE 0x1c
+#define AR933X_RESET_REG_BOOTSTRAP 0xac
+
+#define MISC_INT_ETHSW BIT(12)
+#define MISC_INT_TIMER4 BIT(10)
+#define MISC_INT_TIMER3 BIT(9)
+#define MISC_INT_TIMER2 BIT(8)
#define MISC_INT_DMA BIT(7)
#define MISC_INT_OHCI BIT(6)
#define MISC_INT_PERFC BIT(5)
@@ -158,14 +217,29 @@
#define AR71XX_RESET_PCI_BUS BIT(1)
#define AR71XX_RESET_PCI_CORE BIT(0)
+#define AR7240_RESET_USB_HOST BIT(5)
+#define AR7240_RESET_OHCI_DLL BIT(3)
+
#define AR724X_RESET_GE1_MDIO BIT(23)
#define AR724X_RESET_GE0_MDIO BIT(22)
#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
#define AR724X_RESET_PCIE_PHY BIT(7)
#define AR724X_RESET_PCIE BIT(6)
-#define AR724X_RESET_OHCI_DLL BIT(3)
+#define AR724X_RESET_USB_HOST BIT(5)
+#define AR724X_RESET_USB_PHY BIT(4)
+#define AR724X_RESET_USBSUS_OVERRIDE BIT(3)
#define AR913X_RESET_AMBA2WMAC BIT(22)
+#define AR913X_RESET_USBSUS_OVERRIDE BIT(10)
+#define AR913X_RESET_USB_HOST BIT(5)
+#define AR913X_RESET_USB_PHY BIT(4)
+
+#define AR933X_RESET_WMAC BIT(11)
+#define AR933X_RESET_USB_HOST BIT(5)
+#define AR933X_RESET_USB_PHY BIT(4)
+#define AR933X_RESET_USBSUS_OVERRIDE BIT(3)
+
+#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0)
#define REV_ID_MAJOR_MASK 0xfff0
#define REV_ID_MAJOR_AR71XX 0x00a0
@@ -173,6 +247,8 @@
#define REV_ID_MAJOR_AR7240 0x00c0
#define REV_ID_MAJOR_AR7241 0x0100
#define REV_ID_MAJOR_AR7242 0x1100
+#define REV_ID_MAJOR_AR9330 0x0110
+#define REV_ID_MAJOR_AR9331 0x1110
#define AR71XX_REV_ID_MINOR_MASK 0x3
#define AR71XX_REV_ID_MINOR_AR7130 0x0
@@ -187,6 +263,8 @@
#define AR913X_REV_ID_REVISION_MASK 0x3
#define AR913X_REV_ID_REVISION_SHIFT 2
+#define AR933X_REV_ID_REVISION_MASK 0x3
+
#define AR724X_REV_ID_REVISION_MASK 0x3
/*
@@ -229,5 +307,6 @@
#define AR71XX_GPIO_COUNT 16
#define AR724X_GPIO_COUNT 18
#define AR913X_GPIO_COUNT 22
+#define AR933X_GPIO_COUNT 30
#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/ar933x_uart.h b/arch/mips/include/asm/mach-ath79/ar933x_uart.h
new file mode 100644
index 000000000000..52730555937f
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ar933x_uart.h
@@ -0,0 +1,67 @@
+/*
+ * Atheros AR933X UART defines
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __AR933X_UART_H
+#define __AR933X_UART_H
+
+#define AR933X_UART_REGS_SIZE 20
+#define AR933X_UART_FIFO_SIZE 16
+
+#define AR933X_UART_DATA_REG 0x00
+#define AR933X_UART_CS_REG 0x04
+#define AR933X_UART_CLOCK_REG 0x08
+#define AR933X_UART_INT_REG 0x0c
+#define AR933X_UART_INT_EN_REG 0x10
+
+#define AR933X_UART_DATA_TX_RX_MASK 0xff
+#define AR933X_UART_DATA_RX_CSR BIT(8)
+#define AR933X_UART_DATA_TX_CSR BIT(9)
+
+#define AR933X_UART_CS_PARITY_S 0
+#define AR933X_UART_CS_PARITY_M 0x3
+#define AR933X_UART_CS_PARITY_NONE 0
+#define AR933X_UART_CS_PARITY_ODD 1
+#define AR933X_UART_CS_PARITY_EVEN 2
+#define AR933X_UART_CS_IF_MODE_S 2
+#define AR933X_UART_CS_IF_MODE_M 0x3
+#define AR933X_UART_CS_IF_MODE_NONE 0
+#define AR933X_UART_CS_IF_MODE_DTE 1
+#define AR933X_UART_CS_IF_MODE_DCE 2
+#define AR933X_UART_CS_FLOW_CTRL_S 4
+#define AR933X_UART_CS_FLOW_CTRL_M 0x3
+#define AR933X_UART_CS_DMA_EN BIT(6)
+#define AR933X_UART_CS_TX_READY_ORIDE BIT(7)
+#define AR933X_UART_CS_RX_READY_ORIDE BIT(8)
+#define AR933X_UART_CS_TX_READY BIT(9)
+#define AR933X_UART_CS_RX_BREAK BIT(10)
+#define AR933X_UART_CS_TX_BREAK BIT(11)
+#define AR933X_UART_CS_HOST_INT BIT(12)
+#define AR933X_UART_CS_HOST_INT_EN BIT(13)
+#define AR933X_UART_CS_TX_BUSY BIT(14)
+#define AR933X_UART_CS_RX_BUSY BIT(15)
+
+#define AR933X_UART_CLOCK_STEP_M 0xffff
+#define AR933X_UART_CLOCK_SCALE_M 0xfff
+#define AR933X_UART_CLOCK_SCALE_S 16
+#define AR933X_UART_CLOCK_STEP_M 0xffff
+
+#define AR933X_UART_INT_RX_VALID BIT(0)
+#define AR933X_UART_INT_TX_READY BIT(1)
+#define AR933X_UART_INT_RX_FRAMING_ERR BIT(2)
+#define AR933X_UART_INT_RX_OFLOW_ERR BIT(3)
+#define AR933X_UART_INT_TX_OFLOW_ERR BIT(4)
+#define AR933X_UART_INT_RX_PARITY_ERR BIT(5)
+#define AR933X_UART_INT_RX_BREAK_ON BIT(6)
+#define AR933X_UART_INT_RX_BREAK_OFF BIT(7)
+#define AR933X_UART_INT_RX_FULL BIT(8)
+#define AR933X_UART_INT_TX_EMPTY BIT(9)
+#define AR933X_UART_INT_ALLINTS 0x3ff
+
+#endif /* __AR933X_UART_H */
diff --git a/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h b/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h
new file mode 100644
index 000000000000..6cb30f2b7198
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ar933x_uart_platform.h
@@ -0,0 +1,18 @@
+/*
+ * Platform data definition for Atheros AR933X UART
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef _AR933X_UART_PLATFORM_H
+#define _AR933X_UART_PLATFORM_H
+
+struct ar933x_uart_platform_data {
+ unsigned uartclk;
+};
+
+#endif /* _AR933X_UART_PLATFORM_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
index 6a9f168506fe..6d0c6c9d5622 100644
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -26,10 +26,13 @@ enum ath79_soc_type {
ATH79_SOC_AR7241,
ATH79_SOC_AR7242,
ATH79_SOC_AR9130,
- ATH79_SOC_AR9132
+ ATH79_SOC_AR9132,
+ ATH79_SOC_AR9330,
+ ATH79_SOC_AR9331,
};
extern enum ath79_soc_type ath79_soc;
+extern unsigned int ath79_soc_rev;
static inline int soc_is_ar71xx(void)
{
@@ -66,6 +69,12 @@ static inline int soc_is_ar913x(void)
ath79_soc == ATH79_SOC_AR9132);
}
+static inline int soc_is_ar933x(void)
+{
+ return (ath79_soc == ATH79_SOC_AR9330 ||
+ ath79_soc == ATH79_SOC_AR9331);
+}
+
extern void __iomem *ath79_ddr_base;
extern void __iomem *ath79_pll_base;
extern void __iomem *ath79_reset_base;
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
index 189bc6eb9c10..519958fe4e3c 100644
--- a/arch/mips/include/asm/mach-ath79/irq.h
+++ b/arch/mips/include/asm/mach-ath79/irq.h
@@ -10,10 +10,10 @@
#define __ASM_MACH_ATH79_IRQ_H
#define MIPS_CPU_IRQ_BASE 0
-#define NR_IRQS 16
+#define NR_IRQS 40
#define ATH79_MISC_IRQ_BASE 8
-#define ATH79_MISC_IRQ_COUNT 8
+#define ATH79_MISC_IRQ_COUNT 32
#define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2)
#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3)
@@ -30,6 +30,10 @@
#define ATH79_MISC_IRQ_PERFC (ATH79_MISC_IRQ_BASE + 5)
#define ATH79_MISC_IRQ_OHCI (ATH79_MISC_IRQ_BASE + 6)
#define ATH79_MISC_IRQ_DMA (ATH79_MISC_IRQ_BASE + 7)
+#define ATH79_MISC_IRQ_TIMER2 (ATH79_MISC_IRQ_BASE + 8)
+#define ATH79_MISC_IRQ_TIMER3 (ATH79_MISC_IRQ_BASE + 9)
+#define ATH79_MISC_IRQ_TIMER4 (ATH79_MISC_IRQ_BASE + 10)
+#define ATH79_MISC_IRQ_ETHSW (ATH79_MISC_IRQ_BASE + 12)
#include_next <irq.h>
diff --git a/arch/mips/include/asm/mach-ath79/pci-ath724x.h b/arch/mips/include/asm/mach-ath79/pci-ath724x.h
new file mode 100644
index 000000000000..454885fa30c3
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/pci-ath724x.h
@@ -0,0 +1,21 @@
+/*
+ * Atheros 724x PCI support
+ *
+ * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#ifndef __ASM_MACH_ATH79_PCI_ATH724X_H
+#define __ASM_MACH_ATH79_PCI_ATH724X_H
+
+struct ath724x_pci_data {
+ int irq;
+ void *pdata;
+};
+
+void ath724x_pci_add_data(struct ath724x_pci_data *data, int size);
+
+#endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h
index de24ec57dd2f..569828d3ccab 100644
--- a/arch/mips/include/asm/mach-au1x00/au1000.h
+++ b/arch/mips/include/asm/mach-au1x00/au1000.h
@@ -136,6 +136,7 @@ static inline int au1xxx_cpu_needs_config_od(void)
#define ALCHEMY_CPU_AU1100 2
#define ALCHEMY_CPU_AU1550 3
#define ALCHEMY_CPU_AU1200 4
+#define ALCHEMY_CPU_AU1300 5
static inline int alchemy_get_cputype(void)
{
@@ -156,6 +157,9 @@ static inline int alchemy_get_cputype(void)
case 0x05030000:
return ALCHEMY_CPU_AU1200;
break;
+ case 0x800c0000:
+ return ALCHEMY_CPU_AU1300;
+ break;
}
return ALCHEMY_CPU_UNKNOWN;
@@ -166,6 +170,7 @@ static inline int alchemy_get_uarts(int type)
{
switch (type) {
case ALCHEMY_CPU_AU1000:
+ case ALCHEMY_CPU_AU1300:
return 4;
case ALCHEMY_CPU_AU1500:
case ALCHEMY_CPU_AU1200:
@@ -243,6 +248,7 @@ extern unsigned long au1xxx_calc_clock(void);
/* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */
void alchemy_sleep_au1000(void);
void alchemy_sleep_au1550(void);
+void alchemy_sleep_au1300(void);
void au_sleep(void);
/* USB: drivers/usb/host/alchemy-common.c */
@@ -251,6 +257,7 @@ enum alchemy_usb_block {
ALCHEMY_USB_UDC0,
ALCHEMY_USB_EHCI0,
ALCHEMY_USB_OTG0,
+ ALCHEMY_USB_OHCI1,
};
int alchemy_usb_control(int block, int enable);
@@ -263,14 +270,92 @@ struct alchemy_pci_platdata {
unsigned long pci_cfg_clr;
};
-/* SOC Interrupt numbers */
+/* Multifunction pins: Each of these pins can either be assigned to the
+ * GPIO controller or a on-chip peripheral.
+ * Call "au1300_pinfunc_to_dev()" or "au1300_pinfunc_to_gpio()" to
+ * assign one of these to either the GPIO controller or the device.
+ */
+enum au1300_multifunc_pins {
+ /* wake-from-str pins 0-3 */
+ AU1300_PIN_WAKE0 = 0, AU1300_PIN_WAKE1, AU1300_PIN_WAKE2,
+ AU1300_PIN_WAKE3,
+ /* external clock sources for PSCs: 4-5 */
+ AU1300_PIN_EXTCLK0, AU1300_PIN_EXTCLK1,
+ /* 8bit MMC interface on SD0: 6-9 */
+ AU1300_PIN_SD0DAT4, AU1300_PIN_SD0DAT5, AU1300_PIN_SD0DAT6,
+ AU1300_PIN_SD0DAT7,
+ /* aux clk input for freqgen 3: 10 */
+ AU1300_PIN_FG3AUX,
+ /* UART1 pins: 11-18 */
+ AU1300_PIN_U1RI, AU1300_PIN_U1DCD, AU1300_PIN_U1DSR,
+ AU1300_PIN_U1CTS, AU1300_PIN_U1RTS, AU1300_PIN_U1DTR,
+ AU1300_PIN_U1RX, AU1300_PIN_U1TX,
+ /* UART0 pins: 19-24 */
+ AU1300_PIN_U0RI, AU1300_PIN_U0DCD, AU1300_PIN_U0DSR,
+ AU1300_PIN_U0CTS, AU1300_PIN_U0RTS, AU1300_PIN_U0DTR,
+ /* UART2: 25-26 */
+ AU1300_PIN_U2RX, AU1300_PIN_U2TX,
+ /* UART3: 27-28 */
+ AU1300_PIN_U3RX, AU1300_PIN_U3TX,
+ /* LCD controller PWMs, ext pixclock: 29-31 */
+ AU1300_PIN_LCDPWM0, AU1300_PIN_LCDPWM1, AU1300_PIN_LCDCLKIN,
+ /* SD1 interface: 32-37 */
+ AU1300_PIN_SD1DAT0, AU1300_PIN_SD1DAT1, AU1300_PIN_SD1DAT2,
+ AU1300_PIN_SD1DAT3, AU1300_PIN_SD1CMD, AU1300_PIN_SD1CLK,
+ /* SD2 interface: 38-43 */
+ AU1300_PIN_SD2DAT0, AU1300_PIN_SD2DAT1, AU1300_PIN_SD2DAT2,
+ AU1300_PIN_SD2DAT3, AU1300_PIN_SD2CMD, AU1300_PIN_SD2CLK,
+ /* PSC0/1 clocks: 44-45 */
+ AU1300_PIN_PSC0CLK, AU1300_PIN_PSC1CLK,
+ /* PSCs: 46-49/50-53/54-57/58-61 */
+ AU1300_PIN_PSC0SYNC0, AU1300_PIN_PSC0SYNC1, AU1300_PIN_PSC0D0,
+ AU1300_PIN_PSC0D1,
+ AU1300_PIN_PSC1SYNC0, AU1300_PIN_PSC1SYNC1, AU1300_PIN_PSC1D0,
+ AU1300_PIN_PSC1D1,
+ AU1300_PIN_PSC2SYNC0, AU1300_PIN_PSC2SYNC1, AU1300_PIN_PSC2D0,
+ AU1300_PIN_PSC2D1,
+ AU1300_PIN_PSC3SYNC0, AU1300_PIN_PSC3SYNC1, AU1300_PIN_PSC3D0,
+ AU1300_PIN_PSC3D1,
+ /* PCMCIA interface: 62-70 */
+ AU1300_PIN_PCE2, AU1300_PIN_PCE1, AU1300_PIN_PIOS16,
+ AU1300_PIN_PIOR, AU1300_PIN_PWE, AU1300_PIN_PWAIT,
+ AU1300_PIN_PREG, AU1300_PIN_POE, AU1300_PIN_PIOW,
+ /* camera interface H/V sync inputs: 71-72 */
+ AU1300_PIN_CIMLS, AU1300_PIN_CIMFS,
+ /* PSC2/3 clocks: 73-74 */
+ AU1300_PIN_PSC2CLK, AU1300_PIN_PSC3CLK,
+};
+
+/* GPIC (Au1300) pin management: arch/mips/alchemy/common/gpioint.c */
+extern void au1300_pinfunc_to_gpio(enum au1300_multifunc_pins gpio);
+extern void au1300_pinfunc_to_dev(enum au1300_multifunc_pins gpio);
+extern void au1300_set_irq_priority(unsigned int irq, int p);
+extern void au1300_set_dbdma_gpio(int dchan, unsigned int gpio);
+
+/* Au1300 allows to disconnect certain blocks from internal power supply */
+enum au1300_vss_block {
+ AU1300_VSS_MPE = 0,
+ AU1300_VSS_BSA,
+ AU1300_VSS_GPE,
+ AU1300_VSS_MGP,
+};
+extern void au1300_vss_block_control(int block, int enable);
+
+
+/* SOC Interrupt numbers */
+/* Au1000-style (IC0/1): 2 controllers with 32 sources each */
#define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 8)
#define AU1000_INTC0_INT_LAST (AU1000_INTC0_INT_BASE + 31)
#define AU1000_INTC1_INT_BASE (AU1000_INTC0_INT_LAST + 1)
#define AU1000_INTC1_INT_LAST (AU1000_INTC1_INT_BASE + 31)
#define AU1000_MAX_INTR AU1000_INTC1_INT_LAST
+/* Au1300-style (GPIC): 1 controller with up to 128 sources */
+#define ALCHEMY_GPIC_INT_BASE (MIPS_CPU_IRQ_BASE + 8)
+#define ALCHEMY_GPIC_INT_NUM 128
+#define ALCHEMY_GPIC_INT_LAST (ALCHEMY_GPIC_INT_BASE + ALCHEMY_GPIC_INT_NUM - 1)
+
enum soc_au1000_ints {
AU1000_FIRST_INT = AU1000_INTC0_INT_BASE,
AU1000_UART0_INT = AU1000_FIRST_INT,
@@ -591,24 +676,77 @@ enum soc_au1200_ints {
#endif /* !defined (_LANGUAGE_ASSEMBLY) */
+/* Au1300 peripheral interrupt numbers */
+#define AU1300_FIRST_INT (ALCHEMY_GPIC_INT_BASE)
+#define AU1300_UART1_INT (AU1300_FIRST_INT + 17)
+#define AU1300_UART2_INT (AU1300_FIRST_INT + 25)
+#define AU1300_UART3_INT (AU1300_FIRST_INT + 27)
+#define AU1300_SD1_INT (AU1300_FIRST_INT + 32)
+#define AU1300_SD2_INT (AU1300_FIRST_INT + 38)
+#define AU1300_PSC0_INT (AU1300_FIRST_INT + 48)
+#define AU1300_PSC1_INT (AU1300_FIRST_INT + 52)
+#define AU1300_PSC2_INT (AU1300_FIRST_INT + 56)
+#define AU1300_PSC3_INT (AU1300_FIRST_INT + 60)
+#define AU1300_NAND_INT (AU1300_FIRST_INT + 62)
+#define AU1300_DDMA_INT (AU1300_FIRST_INT + 75)
+#define AU1300_MMU_INT (AU1300_FIRST_INT + 76)
+#define AU1300_MPU_INT (AU1300_FIRST_INT + 77)
+#define AU1300_GPU_INT (AU1300_FIRST_INT + 78)
+#define AU1300_UDMA_INT (AU1300_FIRST_INT + 79)
+#define AU1300_TOY_INT (AU1300_FIRST_INT + 80)
+#define AU1300_TOY_MATCH0_INT (AU1300_FIRST_INT + 81)
+#define AU1300_TOY_MATCH1_INT (AU1300_FIRST_INT + 82)
+#define AU1300_TOY_MATCH2_INT (AU1300_FIRST_INT + 83)
+#define AU1300_RTC_INT (AU1300_FIRST_INT + 84)
+#define AU1300_RTC_MATCH0_INT (AU1300_FIRST_INT + 85)
+#define AU1300_RTC_MATCH1_INT (AU1300_FIRST_INT + 86)
+#define AU1300_RTC_MATCH2_INT (AU1300_FIRST_INT + 87)
+#define AU1300_UART0_INT (AU1300_FIRST_INT + 88)
+#define AU1300_SD0_INT (AU1300_FIRST_INT + 89)
+#define AU1300_USB_INT (AU1300_FIRST_INT + 90)
+#define AU1300_LCD_INT (AU1300_FIRST_INT + 91)
+#define AU1300_BSA_INT (AU1300_FIRST_INT + 92)
+#define AU1300_MPE_INT (AU1300_FIRST_INT + 93)
+#define AU1300_ITE_INT (AU1300_FIRST_INT + 94)
+#define AU1300_AES_INT (AU1300_FIRST_INT + 95)
+#define AU1300_CIM_INT (AU1300_FIRST_INT + 96)
+
+/**********************************************************************/
+
/*
* Physical base addresses for integrated peripherals
- * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200
+ * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200 5..au1300
*/
#define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */
+#define AU1300_ROM_PHYS_ADDR 0x10000000 /* 5 */
+#define AU1300_OTP_PHYS_ADDR 0x10002000 /* 5 */
+#define AU1300_VSS_PHYS_ADDR 0x10003000 /* 5 */
+#define AU1300_UART0_PHYS_ADDR 0x10100000 /* 5 */
+#define AU1300_UART1_PHYS_ADDR 0x10101000 /* 5 */
+#define AU1300_UART2_PHYS_ADDR 0x10102000 /* 5 */
+#define AU1300_UART3_PHYS_ADDR 0x10103000 /* 5 */
#define AU1000_USB_OHCI_PHYS_ADDR 0x10100000 /* 012 */
#define AU1000_USB_UDC_PHYS_ADDR 0x10200000 /* 0123 */
+#define AU1300_GPIC_PHYS_ADDR 0x10200000 /* 5 */
#define AU1000_IRDA_PHYS_ADDR 0x10300000 /* 02 */
-#define AU1200_AES_PHYS_ADDR 0x10300000 /* 4 */
+#define AU1200_AES_PHYS_ADDR 0x10300000 /* 45 */
#define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */
+#define AU1300_GPU_PHYS_ADDR 0x10500000 /* 5 */
#define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */
#define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */
#define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */
-#define AU1100_SD0_PHYS_ADDR 0x10600000 /* 24 */
+#define AU1100_SD0_PHYS_ADDR 0x10600000 /* 245 */
+#define AU1300_SD1_PHYS_ADDR 0x10601000 /* 5 */
+#define AU1300_SD2_PHYS_ADDR 0x10602000 /* 5 */
#define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */
+#define AU1300_SYS_PHYS_ADDR 0x10900000 /* 5 */
#define AU1550_PSC2_PHYS_ADDR 0x10A00000 /* 3 */
#define AU1550_PSC3_PHYS_ADDR 0x10B00000 /* 3 */
+#define AU1300_PSC0_PHYS_ADDR 0x10A00000 /* 5 */
+#define AU1300_PSC1_PHYS_ADDR 0x10A01000 /* 5 */
+#define AU1300_PSC2_PHYS_ADDR 0x10A02000 /* 5 */
+#define AU1300_PSC3_PHYS_ADDR 0x10A03000 /* 5 */
#define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */
#define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */
#define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */
@@ -622,37 +760,96 @@ enum soc_au1200_ints {
#define AU1000_SSI1_PHYS_ADDR 0x11680000 /* 02 */
#define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */
#define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */
-#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 01234 */
+#define AU1000_SYS_PHYS_ADDR 0x11900000 /* 012345 */
#define AU1550_PSC0_PHYS_ADDR 0x11A00000 /* 34 */
#define AU1550_PSC1_PHYS_ADDR 0x11B00000 /* 34 */
#define AU1000_MEM_PHYS_ADDR 0x14000000 /* 01234 */
#define AU1000_STATIC_MEM_PHYS_ADDR 0x14001000 /* 01234 */
+#define AU1300_UDMA_PHYS_ADDR 0x14001800 /* 5 */
#define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */
-#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 34 */
-#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 34 */
+#define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 345 */
+#define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 345 */
#define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */
#define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */
-#define AU1200_CIM_PHYS_ADDR 0x14004000 /* 4 */
+#define AU1200_CIM_PHYS_ADDR 0x14004000 /* 45 */
#define AU1500_PCI_PHYS_ADDR 0x14005000 /* 13 */
#define AU1550_PE_PHYS_ADDR 0x14008000 /* 3 */
#define AU1200_MAEBE_PHYS_ADDR 0x14010000 /* 4 */
#define AU1200_MAEFE_PHYS_ADDR 0x14012000 /* 4 */
+#define AU1300_MAEITE_PHYS_ADDR 0x14010000 /* 5 */
+#define AU1300_MAEMPE_PHYS_ADDR 0x14014000 /* 5 */
#define AU1550_USB_OHCI_PHYS_ADDR 0x14020000 /* 3 */
#define AU1200_USB_CTL_PHYS_ADDR 0x14020000 /* 4 */
#define AU1200_USB_OTG_PHYS_ADDR 0x14020020 /* 4 */
#define AU1200_USB_OHCI_PHYS_ADDR 0x14020100 /* 4 */
#define AU1200_USB_EHCI_PHYS_ADDR 0x14020200 /* 4 */
#define AU1200_USB_UDC_PHYS_ADDR 0x14022000 /* 4 */
+#define AU1300_USB_EHCI_PHYS_ADDR 0x14020000 /* 5 */
+#define AU1300_USB_OHCI0_PHYS_ADDR 0x14020400 /* 5 */
+#define AU1300_USB_OHCI1_PHYS_ADDR 0x14020800 /* 5 */
+#define AU1300_USB_CTL_PHYS_ADDR 0x14021000 /* 5 */
+#define AU1300_USB_OTG_PHYS_ADDR 0x14022000 /* 5 */
+#define AU1300_MAEBSA_PHYS_ADDR 0x14030000 /* 5 */
#define AU1100_LCD_PHYS_ADDR 0x15000000 /* 2 */
-#define AU1200_LCD_PHYS_ADDR 0x15000000 /* 4 */
+#define AU1200_LCD_PHYS_ADDR 0x15000000 /* 45 */
#define AU1500_PCI_MEM_PHYS_ADDR 0x400000000ULL /* 13 */
#define AU1500_PCI_IO_PHYS_ADDR 0x500000000ULL /* 13 */
#define AU1500_PCI_CONFIG0_PHYS_ADDR 0x600000000ULL /* 13 */
#define AU1500_PCI_CONFIG1_PHYS_ADDR 0x680000000ULL /* 13 */
-#define AU1000_PCMCIA_IO_PHYS_ADDR 0xF00000000ULL /* 01234 */
-#define AU1000_PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL /* 01234 */
-#define AU1000_PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL /* 01234 */
+#define AU1000_PCMCIA_IO_PHYS_ADDR 0xF00000000ULL /* 012345 */
+#define AU1000_PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL /* 012345 */
+#define AU1000_PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL /* 012345 */
+/**********************************************************************/
+
+
+/*
+ * Au1300 GPIO+INT controller (GPIC) register offsets and bits
+ * Registers are 128bits (0x10 bytes), divided into 4 "banks".
+ */
+#define AU1300_GPIC_PINVAL 0x0000
+#define AU1300_GPIC_PINVALCLR 0x0010
+#define AU1300_GPIC_IPEND 0x0020
+#define AU1300_GPIC_PRIENC 0x0030
+#define AU1300_GPIC_IEN 0x0040 /* int_mask in manual */
+#define AU1300_GPIC_IDIS 0x0050 /* int_maskclr in manual */
+#define AU1300_GPIC_DMASEL 0x0060
+#define AU1300_GPIC_DEVSEL 0x0080
+#define AU1300_GPIC_DEVCLR 0x0090
+#define AU1300_GPIC_RSTVAL 0x00a0
+/* pin configuration space. one 32bit register for up to 128 IRQs */
+#define AU1300_GPIC_PINCFG 0x1000
+
+#define GPIC_GPIO_TO_BIT(gpio) \
+ (1 << ((gpio) & 0x1f))
+
+#define GPIC_GPIO_BANKOFF(gpio) \
+ (((gpio) >> 5) * 4)
+
+/* Pin Control bits: who owns the pin, what does it do */
+#define GPIC_CFG_PC_GPIN 0
+#define GPIC_CFG_PC_DEV 1
+#define GPIC_CFG_PC_GPOLOW 2
+#define GPIC_CFG_PC_GPOHIGH 3
+#define GPIC_CFG_PC_MASK 3
+
+/* assign pin to MIPS IRQ line */
+#define GPIC_CFG_IL_SET(x) (((x) & 3) << 2)
+#define GPIC_CFG_IL_MASK (3 << 2)
+
+/* pin interrupt type setup */
+#define GPIC_CFG_IC_OFF (0 << 4)
+#define GPIC_CFG_IC_LEVEL_LOW (1 << 4)
+#define GPIC_CFG_IC_LEVEL_HIGH (2 << 4)
+#define GPIC_CFG_IC_EDGE_FALL (5 << 4)
+#define GPIC_CFG_IC_EDGE_RISE (6 << 4)
+#define GPIC_CFG_IC_EDGE_BOTH (7 << 4)
+#define GPIC_CFG_IC_MASK (7 << 4)
+
+/* allow interrupt to wake cpu from 'wait' */
+#define GPIC_CFG_IDLEWAKE (1 << 7)
+
+/***********************************************************************/
/* Au1000 SDRAM memory controller register offsets */
#define AU1000_MEM_SDMODE0 0x0000
@@ -1068,44 +1265,20 @@ enum soc_au1200_ints {
#define SSI_ENABLE_CD (1 << 1)
#define SSI_ENABLE_E (1 << 0)
-/* IrDA Controller */
-#define IRDA_BASE 0xB0300000
-#define IR_RING_PTR_STATUS (IRDA_BASE + 0x00)
-#define IR_RING_BASE_ADDR_H (IRDA_BASE + 0x04)
-#define IR_RING_BASE_ADDR_L (IRDA_BASE + 0x08)
-#define IR_RING_SIZE (IRDA_BASE + 0x0C)
-#define IR_RING_PROMPT (IRDA_BASE + 0x10)
-#define IR_RING_ADDR_CMPR (IRDA_BASE + 0x14)
-#define IR_INT_CLEAR (IRDA_BASE + 0x18)
-#define IR_CONFIG_1 (IRDA_BASE + 0x20)
-# define IR_RX_INVERT_LED (1 << 0)
-# define IR_TX_INVERT_LED (1 << 1)
-# define IR_ST (1 << 2)
-# define IR_SF (1 << 3)
-# define IR_SIR (1 << 4)
-# define IR_MIR (1 << 5)
-# define IR_FIR (1 << 6)
-# define IR_16CRC (1 << 7)
-# define IR_TD (1 << 8)
-# define IR_RX_ALL (1 << 9)
-# define IR_DMA_ENABLE (1 << 10)
-# define IR_RX_ENABLE (1 << 11)
-# define IR_TX_ENABLE (1 << 12)
-# define IR_LOOPBACK (1 << 14)
-# define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \
- IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
-#define IR_SIR_FLAGS (IRDA_BASE + 0x24)
-#define IR_ENABLE (IRDA_BASE + 0x28)
-# define IR_RX_STATUS (1 << 9)
-# define IR_TX_STATUS (1 << 10)
-#define IR_READ_PHY_CONFIG (IRDA_BASE + 0x2C)
-#define IR_WRITE_PHY_CONFIG (IRDA_BASE + 0x30)
-#define IR_MAX_PKT_LEN (IRDA_BASE + 0x34)
-#define IR_RX_BYTE_CNT (IRDA_BASE + 0x38)
-#define IR_CONFIG_2 (IRDA_BASE + 0x3C)
-# define IR_MODE_INV (1 << 0)
-# define IR_ONE_PIN (1 << 1)
-#define IR_INTERFACE_CONFIG (IRDA_BASE + 0x40)
+
+/*
+ * The IrDA peripheral has an IRFIRSEL pin, but on the DB/PB boards it's not
+ * used to select FIR/SIR mode on the transceiver but as a GPIO. Instead a
+ * CPLD has to be told about the mode.
+ */
+#define AU1000_IRDA_PHY_MODE_OFF 0
+#define AU1000_IRDA_PHY_MODE_SIR 1
+#define AU1000_IRDA_PHY_MODE_FIR 2
+
+struct au1k_irda_platform_data {
+ void(*set_phy_mode)(int mode);
+};
+
/* GPIO */
#define SYS_PINFUNC 0xB190002C
diff --git a/arch/mips/include/asm/mach-au1x00/au1100_mmc.h b/arch/mips/include/asm/mach-au1x00/au1100_mmc.h
index 94000a3b6f0b..e221659f1bca 100644
--- a/arch/mips/include/asm/mach-au1x00/au1100_mmc.h
+++ b/arch/mips/include/asm/mach-au1x00/au1100_mmc.h
@@ -130,8 +130,10 @@ struct au1xmmc_platform_data {
#define SD_CONFIG2_DF (0x00000008)
#define SD_CONFIG2_DC (0x00000010)
#define SD_CONFIG2_xx2 (0x000000e0)
+#define SD_CONFIG2_BB (0x00000080)
#define SD_CONFIG2_WB (0x00000100)
#define SD_CONFIG2_RW (0x00000200)
+#define SD_CONFIG2_DP (0x00000400)
/*
diff --git a/arch/mips/include/asm/mach-au1x00/au1200fb.h b/arch/mips/include/asm/mach-au1x00/au1200fb.h
new file mode 100644
index 000000000000..b3c87cc64bb9
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1200fb.h
@@ -0,0 +1,14 @@
+/*
+ * platform data for au1200fb driver.
+ */
+
+#ifndef _AU1200FB_PLAT_H_
+#define _AU1200FB_PLAT_H_
+
+struct au1200fb_platdata {
+ int (*panel_index)(void);
+ int (*panel_init)(void);
+ int (*panel_shutdown)(void);
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-au1x00/au1550nd.h b/arch/mips/include/asm/mach-au1x00/au1550nd.h
new file mode 100644
index 000000000000..ad4c0a03afef
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/au1550nd.h
@@ -0,0 +1,16 @@
+/*
+ * platform data for the Au1550 NAND driver
+ */
+
+#ifndef _AU1550ND_H_
+#define _AU1550ND_H_
+
+#include <linux/mtd/partitions.h>
+
+struct au1550nd_platdata {
+ struct mtd_partition *parts;
+ int num_parts;
+ int devwidth; /* 0 = 8bit device, 1 = 16bit device */
+};
+
+#endif
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
index 323ce2d145f2..217810e18361 100644
--- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
@@ -183,6 +183,37 @@ typedef volatile struct au1xxx_ddma_desc {
#define AU1200_DSCR_CMD0_PSC1_SYNC 25
#define AU1200_DSCR_CMD0_CIM_SYNC 26
+#define AU1300_DSCR_CMD0_UART0_TX 0
+#define AU1300_DSCR_CMD0_UART0_RX 1
+#define AU1300_DSCR_CMD0_UART1_TX 2
+#define AU1300_DSCR_CMD0_UART1_RX 3
+#define AU1300_DSCR_CMD0_UART2_TX 4
+#define AU1300_DSCR_CMD0_UART2_RX 5
+#define AU1300_DSCR_CMD0_UART3_TX 6
+#define AU1300_DSCR_CMD0_UART3_RX 7
+#define AU1300_DSCR_CMD0_SDMS_TX0 8
+#define AU1300_DSCR_CMD0_SDMS_RX0 9
+#define AU1300_DSCR_CMD0_SDMS_TX1 10
+#define AU1300_DSCR_CMD0_SDMS_RX1 11
+#define AU1300_DSCR_CMD0_AES_TX 12
+#define AU1300_DSCR_CMD0_AES_RX 13
+#define AU1300_DSCR_CMD0_PSC0_TX 14
+#define AU1300_DSCR_CMD0_PSC0_RX 15
+#define AU1300_DSCR_CMD0_PSC1_TX 16
+#define AU1300_DSCR_CMD0_PSC1_RX 17
+#define AU1300_DSCR_CMD0_PSC2_TX 18
+#define AU1300_DSCR_CMD0_PSC2_RX 19
+#define AU1300_DSCR_CMD0_PSC3_TX 20
+#define AU1300_DSCR_CMD0_PSC3_RX 21
+#define AU1300_DSCR_CMD0_LCD 22
+#define AU1300_DSCR_CMD0_NAND_FLASH 23
+#define AU1300_DSCR_CMD0_SDMS_TX2 24
+#define AU1300_DSCR_CMD0_SDMS_RX2 25
+#define AU1300_DSCR_CMD0_CIM_SYNC 26
+#define AU1300_DSCR_CMD0_UDMA 27
+#define AU1300_DSCR_CMD0_DMA_REQ0 28
+#define AU1300_DSCR_CMD0_DMA_REQ1 29
+
#define DSCR_CMD0_THROTTLE 30
#define DSCR_CMD0_ALWAYS 31
#define DSCR_NDEV_IDS 32
diff --git a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
index d5df0cab9b87..3f741af37d47 100644
--- a/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-au1x00/cpu-feature-overrides.h
@@ -13,12 +13,14 @@
#define cpu_has_4k_cache 1
#define cpu_has_tx39_cache 0
#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
#define cpu_has_counter 1
#define cpu_has_watch 1
#define cpu_has_divec 1
#define cpu_has_vce 0
#define cpu_has_cache_cdex_p 0
#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
#define cpu_has_mcheck 1
#define cpu_has_ejtag 1
#define cpu_has_llsc 1
@@ -29,6 +31,7 @@
#define cpu_has_vtag_icache 0
#define cpu_has_dc_aliases 0
#define cpu_has_ic_fills_f_dc 1
+#define cpu_has_pindexed_dcache 0
#define cpu_has_mips32r1 1
#define cpu_has_mips32r2 0
#define cpu_has_mips64r1 0
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1300.h b/arch/mips/include/asm/mach-au1x00/gpio-au1300.h
new file mode 100644
index 000000000000..556e1be20bf6
--- /dev/null
+++ b/arch/mips/include/asm/mach-au1x00/gpio-au1300.h
@@ -0,0 +1,241 @@
+/*
+ * gpio-au1300.h -- GPIO control for Au1300 GPIC and compatibles.
+ *
+ * Copyright (c) 2009-2011 Manuel Lauss <manuel.lauss@googlemail.com>
+ */
+
+#ifndef _GPIO_AU1300_H_
+#define _GPIO_AU1300_H_
+
+#include <asm/addrspace.h>
+#include <asm/io.h>
+#include <asm/mach-au1x00/au1000.h>
+
+/* with the current GPIC design, up to 128 GPIOs are possible.
+ * The only implementation so far is in the Au1300, which has 75 externally
+ * available GPIOs.
+ */
+#define AU1300_GPIO_BASE 0
+#define AU1300_GPIO_NUM 75
+#define AU1300_GPIO_MAX (AU1300_GPIO_BASE + AU1300_GPIO_NUM - 1)
+
+#define AU1300_GPIC_ADDR \
+ (void __iomem *)KSEG1ADDR(AU1300_GPIC_PHYS_ADDR)
+
+static inline int au1300_gpio_get_value(unsigned int gpio)
+{
+ void __iomem *roff = AU1300_GPIC_ADDR;
+ int bit;
+
+ gpio -= AU1300_GPIO_BASE;
+ roff += GPIC_GPIO_BANKOFF(gpio);
+ bit = GPIC_GPIO_TO_BIT(gpio);
+ return __raw_readl(roff + AU1300_GPIC_PINVAL) & bit;
+}
+
+static inline int au1300_gpio_direction_input(unsigned int gpio)
+{
+ void __iomem *roff = AU1300_GPIC_ADDR;
+ unsigned long bit;
+
+ gpio -= AU1300_GPIO_BASE;
+
+ roff += GPIC_GPIO_BANKOFF(gpio);
+ bit = GPIC_GPIO_TO_BIT(gpio);
+ __raw_writel(bit, roff + AU1300_GPIC_DEVCLR);
+ wmb();
+
+ return 0;
+}
+
+static inline int au1300_gpio_set_value(unsigned int gpio, int v)
+{
+ void __iomem *roff = AU1300_GPIC_ADDR;
+ unsigned long bit;
+
+ gpio -= AU1300_GPIO_BASE;
+
+ roff += GPIC_GPIO_BANKOFF(gpio);
+ bit = GPIC_GPIO_TO_BIT(gpio);
+ __raw_writel(bit, roff + (v ? AU1300_GPIC_PINVAL
+ : AU1300_GPIC_PINVALCLR));
+ wmb();
+
+ return 0;
+}
+
+static inline int au1300_gpio_direction_output(unsigned int gpio, int v)
+{
+ /* hw switches to output automatically */
+ return au1300_gpio_set_value(gpio, v);
+}
+
+static inline int au1300_gpio_to_irq(unsigned int gpio)
+{
+ return AU1300_FIRST_INT + (gpio - AU1300_GPIO_BASE);
+}
+
+static inline int au1300_irq_to_gpio(unsigned int irq)
+{
+ return (irq - AU1300_FIRST_INT) + AU1300_GPIO_BASE;
+}
+
+static inline int au1300_gpio_is_valid(unsigned int gpio)
+{
+ int ret;
+
+ switch (alchemy_get_cputype()) {
+ case ALCHEMY_CPU_AU1300:
+ ret = ((gpio >= AU1300_GPIO_BASE) && (gpio <= AU1300_GPIO_MAX));
+ break;
+ default:
+ ret = 0;
+ }
+ return ret;
+}
+
+static inline int au1300_gpio_cansleep(unsigned int gpio)
+{
+ return 0;
+}
+
+/* hardware remembers gpio 0-63 levels on powerup */
+static inline int au1300_gpio_getinitlvl(unsigned int gpio)
+{
+ void __iomem *roff = AU1300_GPIC_ADDR;
+ unsigned long v;
+
+ if (unlikely(gpio > 63))
+ return 0;
+ else if (gpio > 31) {
+ gpio -= 32;
+ roff += 4;
+ }
+
+ v = __raw_readl(roff + AU1300_GPIC_RSTVAL);
+ return (v >> gpio) & 1;
+}
+
+/**********************************************************************/
+
+/* Linux gpio framework integration.
+*
+* 4 use cases of Alchemy GPIOS:
+*(1) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=y:
+* Board must register gpiochips.
+*(2) GPIOLIB=y, ALCHEMY_GPIO_INDIRECT=n:
+* A gpiochip for the 75 GPIOs is registered.
+*
+*(3) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=y:
+* the boards' gpio.h must provide the linux gpio wrapper functions,
+*
+*(4) GPIOLIB=n, ALCHEMY_GPIO_INDIRECT=n:
+* inlinable gpio functions are provided which enable access to the
+* Au1300 gpios only by using the numbers straight out of the data-
+* sheets.
+
+* Cases 1 and 3 are intended for boards which want to provide their own
+* GPIO namespace and -operations (i.e. for example you have 8 GPIOs
+* which are in part provided by spare Au1300 GPIO pins and in part by
+* an external FPGA but you still want them to be accssible in linux
+* as gpio0-7. The board can of course use the alchemy_gpioX_* functions
+* as required).
+*/
+
+#ifndef CONFIG_GPIOLIB
+
+#ifdef CONFIG_ALCHEMY_GPIOINT_AU1300
+
+#ifndef CONFIG_ALCHEMY_GPIO_INDIRECT /* case (4) */
+
+static inline int gpio_direction_input(unsigned int gpio)
+{
+ return au1300_gpio_direction_input(gpio);
+}
+
+static inline int gpio_direction_output(unsigned int gpio, int v)
+{
+ return au1300_gpio_direction_output(gpio, v);
+}
+
+static inline int gpio_get_value(unsigned int gpio)
+{
+ return au1300_gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value(unsigned int gpio, int v)
+{
+ au1300_gpio_set_value(gpio, v);
+}
+
+static inline int gpio_get_value_cansleep(unsigned gpio)
+{
+ return gpio_get_value(gpio);
+}
+
+static inline void gpio_set_value_cansleep(unsigned gpio, int value)
+{
+ gpio_set_value(gpio, value);
+}
+
+static inline int gpio_is_valid(unsigned int gpio)
+{
+ return au1300_gpio_is_valid(gpio);
+}
+
+static inline int gpio_cansleep(unsigned int gpio)
+{
+ return au1300_gpio_cansleep(gpio);
+}
+
+static inline int gpio_to_irq(unsigned int gpio)
+{
+ return au1300_gpio_to_irq(gpio);
+}
+
+static inline int irq_to_gpio(unsigned int irq)
+{
+ return au1300_irq_to_gpio(irq);
+}
+
+static inline int gpio_request(unsigned int gpio, const char *label)
+{
+ return 0;
+}
+
+static inline void gpio_free(unsigned int gpio)
+{
+}
+
+static inline int gpio_set_debounce(unsigned gpio, unsigned debounce)
+{
+ return -ENOSYS;
+}
+
+static inline void gpio_unexport(unsigned gpio)
+{
+}
+
+static inline int gpio_export(unsigned gpio, bool direction_may_change)
+{
+ return -ENOSYS;
+}
+
+static inline int gpio_sysfs_set_active_low(unsigned gpio, int value)
+{
+ return -ENOSYS;
+}
+
+static inline int gpio_export_link(struct device *dev, const char *name,
+ unsigned gpio)
+{
+ return -ENOSYS;
+}
+
+#endif /* !CONFIG_ALCHEMY_GPIO_INDIRECT */
+
+#endif /* CONFIG_ALCHEMY_GPIOINT_AU1300 */
+
+#endif /* CONFIG GPIOLIB */
+
+#endif /* _GPIO_AU1300_H_ */
diff --git a/arch/mips/include/asm/mach-au1x00/gpio.h b/arch/mips/include/asm/mach-au1x00/gpio.h
index fcdc8c4809db..22e7ff17fc48 100644
--- a/arch/mips/include/asm/mach-au1x00/gpio.h
+++ b/arch/mips/include/asm/mach-au1x00/gpio.h
@@ -12,6 +12,7 @@
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-au1x00/gpio-au1000.h>
+#include <asm/mach-au1x00/gpio-au1300.h>
/* On Au1000, Au1500 and Au1100 GPIOs won't work as inputs before
* SYS_PININPUTEN is written to at least once. On Au1550/Au1200/Au1300 this
@@ -58,6 +59,8 @@ static inline int __au_irq_to_gpio(unsigned int irq)
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200:
return alchemy_irq_to_gpio(irq);
+ case ALCHEMY_CPU_AU1300:
+ return au1300_irq_to_gpio(irq);
}
return -EINVAL;
}
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
index 96a2391ad85b..5b8d15bb5fe8 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -13,6 +13,7 @@
#define BCM6345_CPU_ID 0x6345
#define BCM6348_CPU_ID 0x6348
#define BCM6358_CPU_ID 0x6358
+#define BCM6368_CPU_ID 0x6368
void __init bcm63xx_cpu_init(void);
u16 __bcm63xx_get_cpu_id(void);
@@ -71,6 +72,19 @@ unsigned int bcm63xx_get_cpu_freq(void);
# define BCMCPU_IS_6358() (0)
#endif
+#ifdef CONFIG_BCM63XX_CPU_6368
+# ifdef bcm63xx_get_cpu_id
+# undef bcm63xx_get_cpu_id
+# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+# define BCMCPU_RUNTIME_DETECT
+# else
+# define bcm63xx_get_cpu_id() BCM6368_CPU_ID
+# endif
+# define BCMCPU_IS_6368() (bcm63xx_get_cpu_id() == BCM6368_CPU_ID)
+#else
+# define BCMCPU_IS_6368() (0)
+#endif
+
#ifndef bcm63xx_get_cpu_id
#error "No CPU support configured"
#endif
@@ -88,6 +102,7 @@ enum bcm63xx_regs_set {
RSET_UART1,
RSET_GPIO,
RSET_SPI,
+ RSET_SPI2,
RSET_UDC0,
RSET_OHCI0,
RSET_OHCI_PRIV,
@@ -98,10 +113,23 @@ enum bcm63xx_regs_set {
RSET_ENET0,
RSET_ENET1,
RSET_ENETDMA,
+ RSET_ENETDMAC,
+ RSET_ENETDMAS,
+ RSET_ENETSW,
RSET_EHCI0,
RSET_SDRAM,
RSET_MEMC,
RSET_DDR,
+ RSET_M2M,
+ RSET_ATM,
+ RSET_XTM,
+ RSET_XTMDMA,
+ RSET_XTMDMAC,
+ RSET_XTMDMAS,
+ RSET_PCM,
+ RSET_PCMDMA,
+ RSET_PCMDMAC,
+ RSET_PCMDMAS,
};
#define RSET_DSL_LMEM_SIZE (64 * 1024 * 4)
@@ -109,11 +137,18 @@ enum bcm63xx_regs_set {
#define RSET_WDT_SIZE 12
#define RSET_ENET_SIZE 2048
#define RSET_ENETDMA_SIZE 2048
+#define RSET_ENETSW_SIZE 65536
#define RSET_UART_SIZE 24
#define RSET_UDC_SIZE 256
#define RSET_OHCI_SIZE 256
#define RSET_EHCI_SIZE 256
#define RSET_PCMCIA_SIZE 12
+#define RSET_M2M_SIZE 256
+#define RSET_ATM_SIZE 4096
+#define RSET_XTM_SIZE 10240
+#define RSET_XTMDMA_SIZE 256
+#define RSET_XTMDMAC_SIZE(chans) (16 * (chans))
+#define RSET_XTMDMAS_SIZE(chans) (16 * (chans))
/*
* 6338 register sets base address
@@ -127,6 +162,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_UART1_BASE (0xdeadbeef)
#define BCM_6338_GPIO_BASE (0xfffe0400)
#define BCM_6338_SPI_BASE (0xfffe0c00)
+#define BCM_6338_SPI2_BASE (0xdeadbeef)
#define BCM_6338_UDC0_BASE (0xdeadbeef)
#define BCM_6338_USBDMA_BASE (0xfffe2400)
#define BCM_6338_OHCI0_BASE (0xdeadbeef)
@@ -136,15 +172,27 @@ enum bcm63xx_regs_set {
#define BCM_6338_PCMCIA_BASE (0xdeadbeef)
#define BCM_6338_SDRAM_REGS_BASE (0xfffe3100)
#define BCM_6338_DSL_BASE (0xfffe1000)
-#define BCM_6338_SAR_BASE (0xfffe2000)
#define BCM_6338_UBUS_BASE (0xdeadbeef)
#define BCM_6338_ENET0_BASE (0xfffe2800)
#define BCM_6338_ENET1_BASE (0xdeadbeef)
#define BCM_6338_ENETDMA_BASE (0xfffe2400)
+#define BCM_6338_ENETDMAC_BASE (0xfffe2500)
+#define BCM_6338_ENETDMAS_BASE (0xfffe2600)
+#define BCM_6338_ENETSW_BASE (0xdeadbeef)
#define BCM_6338_EHCI0_BASE (0xdeadbeef)
#define BCM_6338_SDRAM_BASE (0xfffe3100)
#define BCM_6338_MEMC_BASE (0xdeadbeef)
#define BCM_6338_DDR_BASE (0xdeadbeef)
+#define BCM_6338_M2M_BASE (0xdeadbeef)
+#define BCM_6338_ATM_BASE (0xfffe2000)
+#define BCM_6338_XTM_BASE (0xdeadbeef)
+#define BCM_6338_XTMDMA_BASE (0xdeadbeef)
+#define BCM_6338_XTMDMAC_BASE (0xdeadbeef)
+#define BCM_6338_XTMDMAS_BASE (0xdeadbeef)
+#define BCM_6338_PCM_BASE (0xdeadbeef)
+#define BCM_6338_PCMDMA_BASE (0xdeadbeef)
+#define BCM_6338_PCMDMAC_BASE (0xdeadbeef)
+#define BCM_6338_PCMDMAS_BASE (0xdeadbeef)
/*
* 6345 register sets base address
@@ -158,24 +206,37 @@ enum bcm63xx_regs_set {
#define BCM_6345_UART1_BASE (0xdeadbeef)
#define BCM_6345_GPIO_BASE (0xfffe0400)
#define BCM_6345_SPI_BASE (0xdeadbeef)
+#define BCM_6345_SPI2_BASE (0xdeadbeef)
#define BCM_6345_UDC0_BASE (0xdeadbeef)
#define BCM_6345_USBDMA_BASE (0xfffe2800)
#define BCM_6345_ENET0_BASE (0xfffe1800)
#define BCM_6345_ENETDMA_BASE (0xfffe2800)
+#define BCM_6345_ENETDMAC_BASE (0xfffe2900)
+#define BCM_6345_ENETDMAS_BASE (0xfffe2a00)
+#define BCM_6345_ENETSW_BASE (0xdeadbeef)
#define BCM_6345_PCMCIA_BASE (0xfffe2028)
-#define BCM_6345_MPI_BASE (0xdeadbeef)
+#define BCM_6345_MPI_BASE (0xfffe2000)
#define BCM_6345_OHCI0_BASE (0xfffe2100)
#define BCM_6345_OHCI_PRIV_BASE (0xfffe2200)
#define BCM_6345_USBH_PRIV_BASE (0xdeadbeef)
#define BCM_6345_SDRAM_REGS_BASE (0xfffe2300)
#define BCM_6345_DSL_BASE (0xdeadbeef)
-#define BCM_6345_SAR_BASE (0xdeadbeef)
#define BCM_6345_UBUS_BASE (0xdeadbeef)
#define BCM_6345_ENET1_BASE (0xdeadbeef)
#define BCM_6345_EHCI0_BASE (0xdeadbeef)
#define BCM_6345_SDRAM_BASE (0xfffe2300)
#define BCM_6345_MEMC_BASE (0xdeadbeef)
#define BCM_6345_DDR_BASE (0xdeadbeef)
+#define BCM_6345_M2M_BASE (0xdeadbeef)
+#define BCM_6345_ATM_BASE (0xfffe4000)
+#define BCM_6345_XTM_BASE (0xdeadbeef)
+#define BCM_6345_XTMDMA_BASE (0xdeadbeef)
+#define BCM_6345_XTMDMAC_BASE (0xdeadbeef)
+#define BCM_6345_XTMDMAS_BASE (0xdeadbeef)
+#define BCM_6345_PCM_BASE (0xdeadbeef)
+#define BCM_6345_PCMDMA_BASE (0xdeadbeef)
+#define BCM_6345_PCMDMAC_BASE (0xdeadbeef)
+#define BCM_6345_PCMDMAS_BASE (0xdeadbeef)
/*
* 6348 register sets base address
@@ -188,6 +249,7 @@ enum bcm63xx_regs_set {
#define BCM_6348_UART1_BASE (0xdeadbeef)
#define BCM_6348_GPIO_BASE (0xfffe0400)
#define BCM_6348_SPI_BASE (0xfffe0c00)
+#define BCM_6348_SPI2_BASE (0xdeadbeef)
#define BCM_6348_UDC0_BASE (0xfffe1000)
#define BCM_6348_OHCI0_BASE (0xfffe1b00)
#define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00)
@@ -195,14 +257,27 @@ enum bcm63xx_regs_set {
#define BCM_6348_MPI_BASE (0xfffe2000)
#define BCM_6348_PCMCIA_BASE (0xfffe2054)
#define BCM_6348_SDRAM_REGS_BASE (0xfffe2300)
+#define BCM_6348_M2M_BASE (0xfffe2800)
#define BCM_6348_DSL_BASE (0xfffe3000)
#define BCM_6348_ENET0_BASE (0xfffe6000)
#define BCM_6348_ENET1_BASE (0xfffe6800)
#define BCM_6348_ENETDMA_BASE (0xfffe7000)
+#define BCM_6348_ENETDMAC_BASE (0xfffe7100)
+#define BCM_6348_ENETDMAS_BASE (0xfffe7200)
+#define BCM_6348_ENETSW_BASE (0xdeadbeef)
#define BCM_6348_EHCI0_BASE (0xdeadbeef)
#define BCM_6348_SDRAM_BASE (0xfffe2300)
#define BCM_6348_MEMC_BASE (0xdeadbeef)
#define BCM_6348_DDR_BASE (0xdeadbeef)
+#define BCM_6348_ATM_BASE (0xfffe4000)
+#define BCM_6348_XTM_BASE (0xdeadbeef)
+#define BCM_6348_XTMDMA_BASE (0xdeadbeef)
+#define BCM_6348_XTMDMAC_BASE (0xdeadbeef)
+#define BCM_6348_XTMDMAS_BASE (0xdeadbeef)
+#define BCM_6348_PCM_BASE (0xdeadbeef)
+#define BCM_6348_PCMDMA_BASE (0xdeadbeef)
+#define BCM_6348_PCMDMAC_BASE (0xdeadbeef)
+#define BCM_6348_PCMDMAS_BASE (0xdeadbeef)
/*
* 6358 register sets base address
@@ -215,6 +290,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_UART1_BASE (0xfffe0120)
#define BCM_6358_GPIO_BASE (0xfffe0080)
#define BCM_6358_SPI_BASE (0xdeadbeef)
+#define BCM_6358_SPI2_BASE (0xfffe0800)
#define BCM_6358_UDC0_BASE (0xfffe0800)
#define BCM_6358_OHCI0_BASE (0xfffe1400)
#define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef)
@@ -222,214 +298,175 @@ enum bcm63xx_regs_set {
#define BCM_6358_MPI_BASE (0xfffe1000)
#define BCM_6358_PCMCIA_BASE (0xfffe1054)
#define BCM_6358_SDRAM_REGS_BASE (0xfffe2300)
+#define BCM_6358_M2M_BASE (0xdeadbeef)
#define BCM_6358_DSL_BASE (0xfffe3000)
#define BCM_6358_ENET0_BASE (0xfffe4000)
#define BCM_6358_ENET1_BASE (0xfffe4800)
#define BCM_6358_ENETDMA_BASE (0xfffe5000)
+#define BCM_6358_ENETDMAC_BASE (0xfffe5100)
+#define BCM_6358_ENETDMAS_BASE (0xfffe5200)
+#define BCM_6358_ENETSW_BASE (0xdeadbeef)
#define BCM_6358_EHCI0_BASE (0xfffe1300)
#define BCM_6358_SDRAM_BASE (0xdeadbeef)
#define BCM_6358_MEMC_BASE (0xfffe1200)
#define BCM_6358_DDR_BASE (0xfffe12a0)
+#define BCM_6358_ATM_BASE (0xfffe2000)
+#define BCM_6358_XTM_BASE (0xdeadbeef)
+#define BCM_6358_XTMDMA_BASE (0xdeadbeef)
+#define BCM_6358_XTMDMAC_BASE (0xdeadbeef)
+#define BCM_6358_XTMDMAS_BASE (0xdeadbeef)
+#define BCM_6358_PCM_BASE (0xfffe1600)
+#define BCM_6358_PCMDMA_BASE (0xfffe1800)
+#define BCM_6358_PCMDMAC_BASE (0xfffe1900)
+#define BCM_6358_PCMDMAS_BASE (0xfffe1a00)
+
+
+/*
+ * 6368 register sets base address
+ */
+#define BCM_6368_DSL_LMEM_BASE (0xdeadbeef)
+#define BCM_6368_PERF_BASE (0xb0000000)
+#define BCM_6368_TIMER_BASE (0xb0000040)
+#define BCM_6368_WDT_BASE (0xb000005c)
+#define BCM_6368_UART0_BASE (0xb0000100)
+#define BCM_6368_UART1_BASE (0xb0000120)
+#define BCM_6368_GPIO_BASE (0xb0000080)
+#define BCM_6368_SPI_BASE (0xdeadbeef)
+#define BCM_6368_SPI2_BASE (0xb0000800)
+#define BCM_6368_UDC0_BASE (0xdeadbeef)
+#define BCM_6368_OHCI0_BASE (0xb0001600)
+#define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef)
+#define BCM_6368_USBH_PRIV_BASE (0xb0001700)
+#define BCM_6368_MPI_BASE (0xb0001000)
+#define BCM_6368_PCMCIA_BASE (0xb0001054)
+#define BCM_6368_SDRAM_REGS_BASE (0xdeadbeef)
+#define BCM_6368_M2M_BASE (0xdeadbeef)
+#define BCM_6368_DSL_BASE (0xdeadbeef)
+#define BCM_6368_ENET0_BASE (0xdeadbeef)
+#define BCM_6368_ENET1_BASE (0xdeadbeef)
+#define BCM_6368_ENETDMA_BASE (0xb0006800)
+#define BCM_6368_ENETDMAC_BASE (0xb0006a00)
+#define BCM_6368_ENETDMAS_BASE (0xb0006c00)
+#define BCM_6368_ENETSW_BASE (0xb0f00000)
+#define BCM_6368_EHCI0_BASE (0xb0001500)
+#define BCM_6368_SDRAM_BASE (0xdeadbeef)
+#define BCM_6368_MEMC_BASE (0xb0001200)
+#define BCM_6368_DDR_BASE (0xb0001280)
+#define BCM_6368_ATM_BASE (0xdeadbeef)
+#define BCM_6368_XTM_BASE (0xb0001800)
+#define BCM_6368_XTMDMA_BASE (0xb0005000)
+#define BCM_6368_XTMDMAC_BASE (0xb0005200)
+#define BCM_6368_XTMDMAS_BASE (0xb0005400)
+#define BCM_6368_PCM_BASE (0xb0004000)
+#define BCM_6368_PCMDMA_BASE (0xb0005800)
+#define BCM_6368_PCMDMAC_BASE (0xb0005a00)
+#define BCM_6368_PCMDMAS_BASE (0xb0005c00)
extern const unsigned long *bcm63xx_regs_base;
+#define __GEN_RSET_BASE(__cpu, __rset) \
+ case RSET_## __rset : \
+ return BCM_## __cpu ##_## __rset ##_BASE;
+
+#define __GEN_RSET(__cpu) \
+ switch (set) { \
+ __GEN_RSET_BASE(__cpu, DSL_LMEM) \
+ __GEN_RSET_BASE(__cpu, PERF) \
+ __GEN_RSET_BASE(__cpu, TIMER) \
+ __GEN_RSET_BASE(__cpu, WDT) \
+ __GEN_RSET_BASE(__cpu, UART0) \
+ __GEN_RSET_BASE(__cpu, UART1) \
+ __GEN_RSET_BASE(__cpu, GPIO) \
+ __GEN_RSET_BASE(__cpu, SPI) \
+ __GEN_RSET_BASE(__cpu, SPI2) \
+ __GEN_RSET_BASE(__cpu, UDC0) \
+ __GEN_RSET_BASE(__cpu, OHCI0) \
+ __GEN_RSET_BASE(__cpu, OHCI_PRIV) \
+ __GEN_RSET_BASE(__cpu, USBH_PRIV) \
+ __GEN_RSET_BASE(__cpu, MPI) \
+ __GEN_RSET_BASE(__cpu, PCMCIA) \
+ __GEN_RSET_BASE(__cpu, DSL) \
+ __GEN_RSET_BASE(__cpu, ENET0) \
+ __GEN_RSET_BASE(__cpu, ENET1) \
+ __GEN_RSET_BASE(__cpu, ENETDMA) \
+ __GEN_RSET_BASE(__cpu, ENETDMAC) \
+ __GEN_RSET_BASE(__cpu, ENETDMAS) \
+ __GEN_RSET_BASE(__cpu, ENETSW) \
+ __GEN_RSET_BASE(__cpu, EHCI0) \
+ __GEN_RSET_BASE(__cpu, SDRAM) \
+ __GEN_RSET_BASE(__cpu, MEMC) \
+ __GEN_RSET_BASE(__cpu, DDR) \
+ __GEN_RSET_BASE(__cpu, M2M) \
+ __GEN_RSET_BASE(__cpu, ATM) \
+ __GEN_RSET_BASE(__cpu, XTM) \
+ __GEN_RSET_BASE(__cpu, XTMDMA) \
+ __GEN_RSET_BASE(__cpu, XTMDMAC) \
+ __GEN_RSET_BASE(__cpu, XTMDMAS) \
+ __GEN_RSET_BASE(__cpu, PCM) \
+ __GEN_RSET_BASE(__cpu, PCMDMA) \
+ __GEN_RSET_BASE(__cpu, PCMDMAC) \
+ __GEN_RSET_BASE(__cpu, PCMDMAS) \
+ }
+
+#define __GEN_CPU_REGS_TABLE(__cpu) \
+ [RSET_DSL_LMEM] = BCM_## __cpu ##_DSL_LMEM_BASE, \
+ [RSET_PERF] = BCM_## __cpu ##_PERF_BASE, \
+ [RSET_TIMER] = BCM_## __cpu ##_TIMER_BASE, \
+ [RSET_WDT] = BCM_## __cpu ##_WDT_BASE, \
+ [RSET_UART0] = BCM_## __cpu ##_UART0_BASE, \
+ [RSET_UART1] = BCM_## __cpu ##_UART1_BASE, \
+ [RSET_GPIO] = BCM_## __cpu ##_GPIO_BASE, \
+ [RSET_SPI] = BCM_## __cpu ##_SPI_BASE, \
+ [RSET_SPI2] = BCM_## __cpu ##_SPI2_BASE, \
+ [RSET_UDC0] = BCM_## __cpu ##_UDC0_BASE, \
+ [RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \
+ [RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \
+ [RSET_USBH_PRIV] = BCM_## __cpu ##_USBH_PRIV_BASE, \
+ [RSET_MPI] = BCM_## __cpu ##_MPI_BASE, \
+ [RSET_PCMCIA] = BCM_## __cpu ##_PCMCIA_BASE, \
+ [RSET_DSL] = BCM_## __cpu ##_DSL_BASE, \
+ [RSET_ENET0] = BCM_## __cpu ##_ENET0_BASE, \
+ [RSET_ENET1] = BCM_## __cpu ##_ENET1_BASE, \
+ [RSET_ENETDMA] = BCM_## __cpu ##_ENETDMA_BASE, \
+ [RSET_ENETDMAC] = BCM_## __cpu ##_ENETDMAC_BASE, \
+ [RSET_ENETDMAS] = BCM_## __cpu ##_ENETDMAS_BASE, \
+ [RSET_ENETSW] = BCM_## __cpu ##_ENETSW_BASE, \
+ [RSET_EHCI0] = BCM_## __cpu ##_EHCI0_BASE, \
+ [RSET_SDRAM] = BCM_## __cpu ##_SDRAM_BASE, \
+ [RSET_MEMC] = BCM_## __cpu ##_MEMC_BASE, \
+ [RSET_DDR] = BCM_## __cpu ##_DDR_BASE, \
+ [RSET_M2M] = BCM_## __cpu ##_M2M_BASE, \
+ [RSET_ATM] = BCM_## __cpu ##_ATM_BASE, \
+ [RSET_XTM] = BCM_## __cpu ##_XTM_BASE, \
+ [RSET_XTMDMA] = BCM_## __cpu ##_XTMDMA_BASE, \
+ [RSET_XTMDMAC] = BCM_## __cpu ##_XTMDMAC_BASE, \
+ [RSET_XTMDMAS] = BCM_## __cpu ##_XTMDMAS_BASE, \
+ [RSET_PCM] = BCM_## __cpu ##_PCM_BASE, \
+ [RSET_PCMDMA] = BCM_## __cpu ##_PCMDMA_BASE, \
+ [RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \
+ [RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \
+
+
static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
{
#ifdef BCMCPU_RUNTIME_DETECT
return bcm63xx_regs_base[set];
#else
#ifdef CONFIG_BCM63XX_CPU_6338
- switch (set) {
- case RSET_DSL_LMEM:
- return BCM_6338_DSL_LMEM_BASE;
- case RSET_PERF:
- return BCM_6338_PERF_BASE;
- case RSET_TIMER:
- return BCM_6338_TIMER_BASE;
- case RSET_WDT:
- return BCM_6338_WDT_BASE;
- case RSET_UART0:
- return BCM_6338_UART0_BASE;
- case RSET_UART1:
- return BCM_6338_UART1_BASE;
- case RSET_GPIO:
- return BCM_6338_GPIO_BASE;
- case RSET_SPI:
- return BCM_6338_SPI_BASE;
- case RSET_UDC0:
- return BCM_6338_UDC0_BASE;
- case RSET_OHCI0:
- return BCM_6338_OHCI0_BASE;
- case RSET_OHCI_PRIV:
- return BCM_6338_OHCI_PRIV_BASE;
- case RSET_USBH_PRIV:
- return BCM_6338_USBH_PRIV_BASE;
- case RSET_MPI:
- return BCM_6338_MPI_BASE;
- case RSET_PCMCIA:
- return BCM_6338_PCMCIA_BASE;
- case RSET_DSL:
- return BCM_6338_DSL_BASE;
- case RSET_ENET0:
- return BCM_6338_ENET0_BASE;
- case RSET_ENET1:
- return BCM_6338_ENET1_BASE;
- case RSET_ENETDMA:
- return BCM_6338_ENETDMA_BASE;
- case RSET_EHCI0:
- return BCM_6338_EHCI0_BASE;
- case RSET_SDRAM:
- return BCM_6338_SDRAM_BASE;
- case RSET_MEMC:
- return BCM_6338_MEMC_BASE;
- case RSET_DDR:
- return BCM_6338_DDR_BASE;
- }
+ __GEN_RSET(6338)
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
- switch (set) {
- case RSET_DSL_LMEM:
- return BCM_6345_DSL_LMEM_BASE;
- case RSET_PERF:
- return BCM_6345_PERF_BASE;
- case RSET_TIMER:
- return BCM_6345_TIMER_BASE;
- case RSET_WDT:
- return BCM_6345_WDT_BASE;
- case RSET_UART0:
- return BCM_6345_UART0_BASE;
- case RSET_UART1:
- return BCM_6345_UART1_BASE;
- case RSET_GPIO:
- return BCM_6345_GPIO_BASE;
- case RSET_SPI:
- return BCM_6345_SPI_BASE;
- case RSET_UDC0:
- return BCM_6345_UDC0_BASE;
- case RSET_OHCI0:
- return BCM_6345_OHCI0_BASE;
- case RSET_OHCI_PRIV:
- return BCM_6345_OHCI_PRIV_BASE;
- case RSET_USBH_PRIV:
- return BCM_6345_USBH_PRIV_BASE;
- case RSET_MPI:
- return BCM_6345_MPI_BASE;
- case RSET_PCMCIA:
- return BCM_6345_PCMCIA_BASE;
- case RSET_DSL:
- return BCM_6345_DSL_BASE;
- case RSET_ENET0:
- return BCM_6345_ENET0_BASE;
- case RSET_ENET1:
- return BCM_6345_ENET1_BASE;
- case RSET_ENETDMA:
- return BCM_6345_ENETDMA_BASE;
- case RSET_EHCI0:
- return BCM_6345_EHCI0_BASE;
- case RSET_SDRAM:
- return BCM_6345_SDRAM_BASE;
- case RSET_MEMC:
- return BCM_6345_MEMC_BASE;
- case RSET_DDR:
- return BCM_6345_DDR_BASE;
- }
+ __GEN_RSET(6345)
#endif
#ifdef CONFIG_BCM63XX_CPU_6348
- switch (set) {
- case RSET_DSL_LMEM:
- return BCM_6348_DSL_LMEM_BASE;
- case RSET_PERF:
- return BCM_6348_PERF_BASE;
- case RSET_TIMER:
- return BCM_6348_TIMER_BASE;
- case RSET_WDT:
- return BCM_6348_WDT_BASE;
- case RSET_UART0:
- return BCM_6348_UART0_BASE;
- case RSET_UART1:
- return BCM_6348_UART1_BASE;
- case RSET_GPIO:
- return BCM_6348_GPIO_BASE;
- case RSET_SPI:
- return BCM_6348_SPI_BASE;
- case RSET_UDC0:
- return BCM_6348_UDC0_BASE;
- case RSET_OHCI0:
- return BCM_6348_OHCI0_BASE;
- case RSET_OHCI_PRIV:
- return BCM_6348_OHCI_PRIV_BASE;
- case RSET_USBH_PRIV:
- return BCM_6348_USBH_PRIV_BASE;
- case RSET_MPI:
- return BCM_6348_MPI_BASE;
- case RSET_PCMCIA:
- return BCM_6348_PCMCIA_BASE;
- case RSET_DSL:
- return BCM_6348_DSL_BASE;
- case RSET_ENET0:
- return BCM_6348_ENET0_BASE;
- case RSET_ENET1:
- return BCM_6348_ENET1_BASE;
- case RSET_ENETDMA:
- return BCM_6348_ENETDMA_BASE;
- case RSET_EHCI0:
- return BCM_6348_EHCI0_BASE;
- case RSET_SDRAM:
- return BCM_6348_SDRAM_BASE;
- case RSET_MEMC:
- return BCM_6348_MEMC_BASE;
- case RSET_DDR:
- return BCM_6348_DDR_BASE;
- }
+ __GEN_RSET(6348)
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
- switch (set) {
- case RSET_DSL_LMEM:
- return BCM_6358_DSL_LMEM_BASE;
- case RSET_PERF:
- return BCM_6358_PERF_BASE;
- case RSET_TIMER:
- return BCM_6358_TIMER_BASE;
- case RSET_WDT:
- return BCM_6358_WDT_BASE;
- case RSET_UART0:
- return BCM_6358_UART0_BASE;
- case RSET_UART1:
- return BCM_6358_UART1_BASE;
- case RSET_GPIO:
- return BCM_6358_GPIO_BASE;
- case RSET_SPI:
- return BCM_6358_SPI_BASE;
- case RSET_UDC0:
- return BCM_6358_UDC0_BASE;
- case RSET_OHCI0:
- return BCM_6358_OHCI0_BASE;
- case RSET_OHCI_PRIV:
- return BCM_6358_OHCI_PRIV_BASE;
- case RSET_USBH_PRIV:
- return BCM_6358_USBH_PRIV_BASE;
- case RSET_MPI:
- return BCM_6358_MPI_BASE;
- case RSET_PCMCIA:
- return BCM_6358_PCMCIA_BASE;
- case RSET_ENET0:
- return BCM_6358_ENET0_BASE;
- case RSET_ENET1:
- return BCM_6358_ENET1_BASE;
- case RSET_ENETDMA:
- return BCM_6358_ENETDMA_BASE;
- case RSET_DSL:
- return BCM_6358_DSL_BASE;
- case RSET_EHCI0:
- return BCM_6358_EHCI0_BASE;
- case RSET_SDRAM:
- return BCM_6358_SDRAM_BASE;
- case RSET_MEMC:
- return BCM_6358_MEMC_BASE;
- case RSET_DDR:
- return BCM_6358_DDR_BASE;
- }
+ __GEN_RSET(6358)
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6368
+ __GEN_RSET(6368)
#endif
#endif
/* unreached */
@@ -449,75 +486,114 @@ enum bcm63xx_irq {
IRQ_ENET_PHY,
IRQ_OHCI0,
IRQ_EHCI0,
- IRQ_PCMCIA0,
IRQ_ENET0_RXDMA,
IRQ_ENET0_TXDMA,
IRQ_ENET1_RXDMA,
IRQ_ENET1_TXDMA,
IRQ_PCI,
IRQ_PCMCIA,
+ IRQ_ATM,
+ IRQ_ENETSW_RXDMA0,
+ IRQ_ENETSW_RXDMA1,
+ IRQ_ENETSW_RXDMA2,
+ IRQ_ENETSW_RXDMA3,
+ IRQ_ENETSW_TXDMA0,
+ IRQ_ENETSW_TXDMA1,
+ IRQ_ENETSW_TXDMA2,
+ IRQ_ENETSW_TXDMA3,
+ IRQ_XTM,
+ IRQ_XTM_DMA0,
};
/*
* 6338 irqs
*/
#define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
-#define BCM_6338_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6338_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
-#define BCM_6338_DG_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6338_UART1_IRQ 0
#define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5)
-#define BCM_6338_ATM_IRQ (IRQ_INTERNAL_BASE + 6)
-#define BCM_6338_UDC0_IRQ (IRQ_INTERNAL_BASE + 7)
#define BCM_6338_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6338_ENET1_IRQ 0
#define BCM_6338_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
-#define BCM_6338_SDRAM_IRQ (IRQ_INTERNAL_BASE + 10)
-#define BCM_6338_USB_CNTL_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 11)
-#define BCM_6338_USB_CNTL_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 12)
-#define BCM_6338_USB_BULK_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13)
-#define BCM_6338_USB_BULK_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 14)
+#define BCM_6338_OHCI0_IRQ 0
+#define BCM_6338_EHCI0_IRQ 0
#define BCM_6338_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
#define BCM_6338_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16)
-#define BCM_6338_SDIO_IRQ (IRQ_INTERNAL_BASE + 17)
+#define BCM_6338_ENET1_RXDMA_IRQ 0
+#define BCM_6338_ENET1_TXDMA_IRQ 0
+#define BCM_6338_PCI_IRQ 0
+#define BCM_6338_PCMCIA_IRQ 0
+#define BCM_6338_ATM_IRQ 0
+#define BCM_6338_ENETSW_RXDMA0_IRQ 0
+#define BCM_6338_ENETSW_RXDMA1_IRQ 0
+#define BCM_6338_ENETSW_RXDMA2_IRQ 0
+#define BCM_6338_ENETSW_RXDMA3_IRQ 0
+#define BCM_6338_ENETSW_TXDMA0_IRQ 0
+#define BCM_6338_ENETSW_TXDMA1_IRQ 0
+#define BCM_6338_ENETSW_TXDMA2_IRQ 0
+#define BCM_6338_ENETSW_TXDMA3_IRQ 0
+#define BCM_6338_XTM_IRQ 0
+#define BCM_6338_XTM_DMA0_IRQ 0
/*
* 6345 irqs
*/
#define BCM_6345_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
#define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6345_UART1_IRQ 0
#define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3)
-#define BCM_6345_ATM_IRQ (IRQ_INTERNAL_BASE + 4)
-#define BCM_6345_USB_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6345_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6345_ENET1_IRQ 0
#define BCM_6345_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6345_OHCI0_IRQ 0
+#define BCM_6345_EHCI0_IRQ 0
#define BCM_6345_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 1)
#define BCM_6345_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 2)
-#define BCM_6345_EBI_RX_IRQ (IRQ_INTERNAL_BASE + 13 + 5)
-#define BCM_6345_EBI_TX_IRQ (IRQ_INTERNAL_BASE + 13 + 6)
-#define BCM_6345_RESERVED_RX_IRQ (IRQ_INTERNAL_BASE + 13 + 9)
-#define BCM_6345_RESERVED_TX_IRQ (IRQ_INTERNAL_BASE + 13 + 10)
-#define BCM_6345_USB_BULK_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 13)
-#define BCM_6345_USB_BULK_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 14)
-#define BCM_6345_USB_CNTL_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 15)
-#define BCM_6345_USB_CNTL_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 16)
-#define BCM_6345_USB_ISO_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 17)
-#define BCM_6345_USB_ISO_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 13 + 18)
+#define BCM_6345_ENET1_RXDMA_IRQ 0
+#define BCM_6345_ENET1_TXDMA_IRQ 0
+#define BCM_6345_PCI_IRQ 0
+#define BCM_6345_PCMCIA_IRQ 0
+#define BCM_6345_ATM_IRQ 0
+#define BCM_6345_ENETSW_RXDMA0_IRQ 0
+#define BCM_6345_ENETSW_RXDMA1_IRQ 0
+#define BCM_6345_ENETSW_RXDMA2_IRQ 0
+#define BCM_6345_ENETSW_RXDMA3_IRQ 0
+#define BCM_6345_ENETSW_TXDMA0_IRQ 0
+#define BCM_6345_ENETSW_TXDMA1_IRQ 0
+#define BCM_6345_ENETSW_TXDMA2_IRQ 0
+#define BCM_6345_ENETSW_TXDMA3_IRQ 0
+#define BCM_6345_XTM_IRQ 0
+#define BCM_6345_XTM_DMA0_IRQ 0
/*
* 6348 irqs
*/
#define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
#define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6348_UART1_IRQ 0
#define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
-#define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7)
#define BCM_6348_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7)
#define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6348_EHCI0_IRQ 0
#define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20)
#define BCM_6348_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 21)
#define BCM_6348_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 22)
#define BCM_6348_ENET1_TXDMA_IRQ (IRQ_INTERNAL_BASE + 23)
-#define BCM_6348_PCMCIA_IRQ (IRQ_INTERNAL_BASE + 24)
#define BCM_6348_PCI_IRQ (IRQ_INTERNAL_BASE + 24)
+#define BCM_6348_PCMCIA_IRQ (IRQ_INTERNAL_BASE + 24)
+#define BCM_6348_ATM_IRQ (IRQ_INTERNAL_BASE + 5)
+#define BCM_6348_ENETSW_RXDMA0_IRQ 0
+#define BCM_6348_ENETSW_RXDMA1_IRQ 0
+#define BCM_6348_ENETSW_RXDMA2_IRQ 0
+#define BCM_6348_ENETSW_RXDMA3_IRQ 0
+#define BCM_6348_ENETSW_TXDMA0_IRQ 0
+#define BCM_6348_ENETSW_TXDMA1_IRQ 0
+#define BCM_6348_ENETSW_TXDMA2_IRQ 0
+#define BCM_6348_ENETSW_TXDMA3_IRQ 0
+#define BCM_6348_XTM_IRQ 0
+#define BCM_6348_XTM_DMA0_IRQ 0
/*
* 6358 irqs
@@ -525,21 +601,108 @@ enum bcm63xx_irq {
#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
-#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
-#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
+#define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29)
#define BCM_6358_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
+#define BCM_6358_ENET1_IRQ (IRQ_INTERNAL_BASE + 6)
#define BCM_6358_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6358_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6358_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
#define BCM_6358_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 15)
#define BCM_6358_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 16)
#define BCM_6358_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 17)
#define BCM_6358_ENET1_TXDMA_IRQ (IRQ_INTERNAL_BASE + 18)
-#define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29)
#define BCM_6358_PCI_IRQ (IRQ_INTERNAL_BASE + 31)
#define BCM_6358_PCMCIA_IRQ (IRQ_INTERNAL_BASE + 24)
+#define BCM_6358_ATM_IRQ (IRQ_INTERNAL_BASE + 19)
+#define BCM_6358_ENETSW_RXDMA0_IRQ 0
+#define BCM_6358_ENETSW_RXDMA1_IRQ 0
+#define BCM_6358_ENETSW_RXDMA2_IRQ 0
+#define BCM_6358_ENETSW_RXDMA3_IRQ 0
+#define BCM_6358_ENETSW_TXDMA0_IRQ 0
+#define BCM_6358_ENETSW_TXDMA1_IRQ 0
+#define BCM_6358_ENETSW_TXDMA2_IRQ 0
+#define BCM_6358_ENETSW_TXDMA3_IRQ 0
+#define BCM_6358_XTM_IRQ 0
+#define BCM_6358_XTM_DMA0_IRQ 0
+
+#define BCM_6358_PCM_DMA0_IRQ (IRQ_INTERNAL_BASE + 23)
+#define BCM_6358_PCM_DMA1_IRQ (IRQ_INTERNAL_BASE + 24)
+#define BCM_6358_EXT_IRQ0 (IRQ_INTERNAL_BASE + 25)
+#define BCM_6358_EXT_IRQ1 (IRQ_INTERNAL_BASE + 26)
+#define BCM_6358_EXT_IRQ2 (IRQ_INTERNAL_BASE + 27)
+#define BCM_6358_EXT_IRQ3 (IRQ_INTERNAL_BASE + 28)
+
+/*
+ * 6368 irqs
+ */
+#define BCM_6368_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32)
+
+#define BCM_6368_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6368_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6368_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
+#define BCM_6368_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6368_ENET0_IRQ 0
+#define BCM_6368_ENET1_IRQ 0
+#define BCM_6368_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 15)
+#define BCM_6368_OHCI0_IRQ (IRQ_INTERNAL_BASE + 5)
+#define BCM_6368_EHCI0_IRQ (IRQ_INTERNAL_BASE + 7)
+#define BCM_6368_PCMCIA_IRQ 0
+#define BCM_6368_ENET0_RXDMA_IRQ 0
+#define BCM_6368_ENET0_TXDMA_IRQ 0
+#define BCM_6368_ENET1_RXDMA_IRQ 0
+#define BCM_6368_ENET1_TXDMA_IRQ 0
+#define BCM_6368_PCI_IRQ (IRQ_INTERNAL_BASE + 13)
+#define BCM_6368_ATM_IRQ 0
+#define BCM_6368_ENETSW_RXDMA0_IRQ (BCM_6368_HIGH_IRQ_BASE + 0)
+#define BCM_6368_ENETSW_RXDMA1_IRQ (BCM_6368_HIGH_IRQ_BASE + 1)
+#define BCM_6368_ENETSW_RXDMA2_IRQ (BCM_6368_HIGH_IRQ_BASE + 2)
+#define BCM_6368_ENETSW_RXDMA3_IRQ (BCM_6368_HIGH_IRQ_BASE + 3)
+#define BCM_6368_ENETSW_TXDMA0_IRQ (BCM_6368_HIGH_IRQ_BASE + 4)
+#define BCM_6368_ENETSW_TXDMA1_IRQ (BCM_6368_HIGH_IRQ_BASE + 5)
+#define BCM_6368_ENETSW_TXDMA2_IRQ (BCM_6368_HIGH_IRQ_BASE + 6)
+#define BCM_6368_ENETSW_TXDMA3_IRQ (BCM_6368_HIGH_IRQ_BASE + 7)
+#define BCM_6368_XTM_IRQ (IRQ_INTERNAL_BASE + 11)
+#define BCM_6368_XTM_DMA0_IRQ (BCM_6368_HIGH_IRQ_BASE + 8)
+
+#define BCM_6368_PCM_DMA0_IRQ (BCM_6368_HIGH_IRQ_BASE + 30)
+#define BCM_6368_PCM_DMA1_IRQ (BCM_6368_HIGH_IRQ_BASE + 31)
+#define BCM_6368_EXT_IRQ0 (IRQ_INTERNAL_BASE + 20)
+#define BCM_6368_EXT_IRQ1 (IRQ_INTERNAL_BASE + 21)
+#define BCM_6368_EXT_IRQ2 (IRQ_INTERNAL_BASE + 22)
+#define BCM_6368_EXT_IRQ3 (IRQ_INTERNAL_BASE + 23)
+#define BCM_6368_EXT_IRQ4 (IRQ_INTERNAL_BASE + 24)
+#define BCM_6368_EXT_IRQ5 (IRQ_INTERNAL_BASE + 25)
extern const int *bcm63xx_irqs;
+#define __GEN_CPU_IRQ_TABLE(__cpu) \
+ [IRQ_TIMER] = BCM_## __cpu ##_TIMER_IRQ, \
+ [IRQ_UART0] = BCM_## __cpu ##_UART0_IRQ, \
+ [IRQ_UART1] = BCM_## __cpu ##_UART1_IRQ, \
+ [IRQ_DSL] = BCM_## __cpu ##_DSL_IRQ, \
+ [IRQ_ENET0] = BCM_## __cpu ##_ENET0_IRQ, \
+ [IRQ_ENET1] = BCM_## __cpu ##_ENET1_IRQ, \
+ [IRQ_ENET_PHY] = BCM_## __cpu ##_ENET_PHY_IRQ, \
+ [IRQ_OHCI0] = BCM_## __cpu ##_OHCI0_IRQ, \
+ [IRQ_EHCI0] = BCM_## __cpu ##_EHCI0_IRQ, \
+ [IRQ_ENET0_RXDMA] = BCM_## __cpu ##_ENET0_RXDMA_IRQ, \
+ [IRQ_ENET0_TXDMA] = BCM_## __cpu ##_ENET0_TXDMA_IRQ, \
+ [IRQ_ENET1_RXDMA] = BCM_## __cpu ##_ENET1_RXDMA_IRQ, \
+ [IRQ_ENET1_TXDMA] = BCM_## __cpu ##_ENET1_TXDMA_IRQ, \
+ [IRQ_PCI] = BCM_## __cpu ##_PCI_IRQ, \
+ [IRQ_PCMCIA] = BCM_## __cpu ##_PCMCIA_IRQ, \
+ [IRQ_ATM] = BCM_## __cpu ##_ATM_IRQ, \
+ [IRQ_ENETSW_RXDMA0] = BCM_## __cpu ##_ENETSW_RXDMA0_IRQ, \
+ [IRQ_ENETSW_RXDMA1] = BCM_## __cpu ##_ENETSW_RXDMA1_IRQ, \
+ [IRQ_ENETSW_RXDMA2] = BCM_## __cpu ##_ENETSW_RXDMA2_IRQ, \
+ [IRQ_ENETSW_RXDMA3] = BCM_## __cpu ##_ENETSW_RXDMA3_IRQ, \
+ [IRQ_ENETSW_TXDMA0] = BCM_## __cpu ##_ENETSW_TXDMA0_IRQ, \
+ [IRQ_ENETSW_TXDMA1] = BCM_## __cpu ##_ENETSW_TXDMA1_IRQ, \
+ [IRQ_ENETSW_TXDMA2] = BCM_## __cpu ##_ENETSW_TXDMA2_IRQ, \
+ [IRQ_ENETSW_TXDMA3] = BCM_## __cpu ##_ENETSW_TXDMA3_IRQ, \
+ [IRQ_XTM] = BCM_## __cpu ##_XTM_IRQ, \
+ [IRQ_XTM_DMA0] = BCM_## __cpu ##_XTM_DMA0_IRQ, \
+
static inline int bcm63xx_get_irq_number(enum bcm63xx_irq irq)
{
return bcm63xx_irqs[irq];
@@ -550,4 +713,8 @@ static inline int bcm63xx_get_irq_number(enum bcm63xx_irq irq)
*/
unsigned int bcm63xx_get_memory_size(void);
+void bcm63xx_machine_halt(void);
+
+void bcm63xx_machine_reboot(void);
+
#endif /* !BCM63XX_CPU_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
index 3999ec0aa7f5..3d5de96d4036 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -14,6 +14,8 @@ static inline unsigned long bcm63xx_gpio_count(void)
return 8;
case BCM6345_CPU_ID:
return 16;
+ case BCM6368_CPU_ID:
+ return 38;
case BCM6348_CPU_ID:
default:
return 37;
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
index 91180fac6ed9..72477a6441dd 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
@@ -49,9 +49,11 @@
#define bcm_readb(a) (*(volatile unsigned char *) BCM_REGS_VA(a))
#define bcm_readw(a) (*(volatile unsigned short *) BCM_REGS_VA(a))
#define bcm_readl(a) (*(volatile unsigned int *) BCM_REGS_VA(a))
+#define bcm_readq(a) (*(volatile u64 *) BCM_REGS_VA(a))
#define bcm_writeb(v, a) (*(volatile unsigned char *) BCM_REGS_VA((a)) = (v))
#define bcm_writew(v, a) (*(volatile unsigned short *) BCM_REGS_VA((a)) = (v))
#define bcm_writel(v, a) (*(volatile unsigned int *) BCM_REGS_VA((a)) = (v))
+#define bcm_writeq(v, a) (*(volatile u64 *) BCM_REGS_VA((a)) = (v))
/*
* IO helpers to access register set for current CPU
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
index 5f95577c8213..0c3074b871b8 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_irq.h
@@ -3,13 +3,11 @@
#include <bcm63xx_cpu.h>
-#define IRQ_MIPS_BASE 0
#define IRQ_INTERNAL_BASE 8
-
-#define IRQ_EXT_BASE (IRQ_MIPS_BASE + 3)
-#define IRQ_EXT_0 (IRQ_EXT_BASE + 0)
-#define IRQ_EXT_1 (IRQ_EXT_BASE + 1)
-#define IRQ_EXT_2 (IRQ_EXT_BASE + 2)
-#define IRQ_EXT_3 (IRQ_EXT_BASE + 3)
+#define IRQ_EXTERNAL_BASE 100
+#define IRQ_EXT_0 (IRQ_EXTERNAL_BASE + 0)
+#define IRQ_EXT_1 (IRQ_EXTERNAL_BASE + 1)
+#define IRQ_EXT_2 (IRQ_EXTERNAL_BASE + 2)
+#define IRQ_EXT_3 (IRQ_EXTERNAL_BASE + 3)
#endif /* ! BCM63XX_IRQ_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
index 0ed5230243c9..94d4faad29a1 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -83,30 +83,86 @@
CKCTL_6358_USBSU_EN | \
CKCTL_6358_EPHY_EN)
+#define CKCTL_6368_VDSL_QPROC_EN (1 << 2)
+#define CKCTL_6368_VDSL_AFE_EN (1 << 3)
+#define CKCTL_6368_VDSL_BONDING_EN (1 << 4)
+#define CKCTL_6368_VDSL_EN (1 << 5)
+#define CKCTL_6368_PHYMIPS_EN (1 << 6)
+#define CKCTL_6368_SWPKT_USB_EN (1 << 7)
+#define CKCTL_6368_SWPKT_SAR_EN (1 << 8)
+#define CKCTL_6368_SPI_CLK_EN (1 << 9)
+#define CKCTL_6368_USBD_CLK_EN (1 << 10)
+#define CKCTL_6368_SAR_CLK_EN (1 << 11)
+#define CKCTL_6368_ROBOSW_CLK_EN (1 << 12)
+#define CKCTL_6368_UTOPIA_CLK_EN (1 << 13)
+#define CKCTL_6368_PCM_CLK_EN (1 << 14)
+#define CKCTL_6368_USBH_CLK_EN (1 << 15)
+#define CKCTL_6368_DISABLE_GLESS_EN (1 << 16)
+#define CKCTL_6368_NAND_CLK_EN (1 << 17)
+#define CKCTL_6368_IPSEC_CLK_EN (1 << 17)
+
+#define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \
+ CKCTL_6368_SWPKT_SAR_EN | \
+ CKCTL_6368_SPI_CLK_EN | \
+ CKCTL_6368_USBD_CLK_EN | \
+ CKCTL_6368_SAR_CLK_EN | \
+ CKCTL_6368_ROBOSW_CLK_EN | \
+ CKCTL_6368_UTOPIA_CLK_EN | \
+ CKCTL_6368_PCM_CLK_EN | \
+ CKCTL_6368_USBH_CLK_EN | \
+ CKCTL_6368_DISABLE_GLESS_EN | \
+ CKCTL_6368_NAND_CLK_EN | \
+ CKCTL_6368_IPSEC_CLK_EN)
+
/* System PLL Control register */
#define PERF_SYS_PLL_CTL_REG 0x8
#define SYS_PLL_SOFT_RESET 0x1
/* Interrupt Mask register */
-#define PERF_IRQMASK_REG 0xc
+#define PERF_IRQMASK_6338_REG 0xc
+#define PERF_IRQMASK_6345_REG 0xc
+#define PERF_IRQMASK_6348_REG 0xc
+#define PERF_IRQMASK_6358_REG 0xc
+#define PERF_IRQMASK_6368_REG 0x20
/* Interrupt Status register */
-#define PERF_IRQSTAT_REG 0x10
+#define PERF_IRQSTAT_6338_REG 0x10
+#define PERF_IRQSTAT_6345_REG 0x10
+#define PERF_IRQSTAT_6348_REG 0x10
+#define PERF_IRQSTAT_6358_REG 0x10
+#define PERF_IRQSTAT_6368_REG 0x28
/* External Interrupt Configuration register */
-#define PERF_EXTIRQ_CFG_REG 0x14
+#define PERF_EXTIRQ_CFG_REG_6338 0x14
+#define PERF_EXTIRQ_CFG_REG_6348 0x14
+#define PERF_EXTIRQ_CFG_REG_6358 0x14
+#define PERF_EXTIRQ_CFG_REG_6368 0x18
+
+#define PERF_EXTIRQ_CFG_REG2_6368 0x1c
+
+/* for 6348 only */
+#define EXTIRQ_CFG_SENSE_6348(x) (1 << (x))
+#define EXTIRQ_CFG_STAT_6348(x) (1 << (x + 5))
+#define EXTIRQ_CFG_CLEAR_6348(x) (1 << (x + 10))
+#define EXTIRQ_CFG_MASK_6348(x) (1 << (x + 15))
+#define EXTIRQ_CFG_BOTHEDGE_6348(x) (1 << (x + 20))
+#define EXTIRQ_CFG_LEVELSENSE_6348(x) (1 << (x + 25))
+#define EXTIRQ_CFG_CLEAR_ALL_6348 (0xf << 10)
+#define EXTIRQ_CFG_MASK_ALL_6348 (0xf << 15)
+
+/* for all others */
#define EXTIRQ_CFG_SENSE(x) (1 << (x))
-#define EXTIRQ_CFG_STAT(x) (1 << (x + 5))
-#define EXTIRQ_CFG_CLEAR(x) (1 << (x + 10))
-#define EXTIRQ_CFG_MASK(x) (1 << (x + 15))
-#define EXTIRQ_CFG_BOTHEDGE(x) (1 << (x + 20))
-#define EXTIRQ_CFG_LEVELSENSE(x) (1 << (x + 25))
-
-#define EXTIRQ_CFG_CLEAR_ALL (0xf << 10)
-#define EXTIRQ_CFG_MASK_ALL (0xf << 15)
+#define EXTIRQ_CFG_STAT(x) (1 << (x + 4))
+#define EXTIRQ_CFG_CLEAR(x) (1 << (x + 8))
+#define EXTIRQ_CFG_MASK(x) (1 << (x + 12))
+#define EXTIRQ_CFG_BOTHEDGE(x) (1 << (x + 16))
+#define EXTIRQ_CFG_LEVELSENSE(x) (1 << (x + 20))
+#define EXTIRQ_CFG_CLEAR_ALL (0xf << 8)
+#define EXTIRQ_CFG_MASK_ALL (0xf << 12)
/* Soft Reset register */
#define PERF_SOFTRESET_REG 0x28
+#define PERF_SOFTRESET_6368_REG 0x10
#define SOFTRESET_6338_SPI_MASK (1 << 0)
#define SOFTRESET_6338_ENET_MASK (1 << 2)
@@ -147,6 +203,15 @@
SOFTRESET_6348_ACLC_MASK | \
SOFTRESET_6348_ADSLMIPSPLL_MASK)
+#define SOFTRESET_6368_SPI_MASK (1 << 0)
+#define SOFTRESET_6368_MPI_MASK (1 << 3)
+#define SOFTRESET_6368_EPHY_MASK (1 << 6)
+#define SOFTRESET_6368_SAR_MASK (1 << 7)
+#define SOFTRESET_6368_ENETSW_MASK (1 << 10)
+#define SOFTRESET_6368_USBS_MASK (1 << 11)
+#define SOFTRESET_6368_USBH_MASK (1 << 12)
+#define SOFTRESET_6368_PCM_MASK (1 << 13)
+
/* MIPS PLL control register */
#define PERF_MIPSPLLCTL_REG 0x34
#define MIPSPLLCTL_N1_SHIFT 20
@@ -372,6 +437,7 @@
#define GPIO_CTL_LO_REG 0x4
#define GPIO_DATA_HI_REG 0x8
#define GPIO_DATA_LO_REG 0xC
+#define GPIO_DATA_LO_REG_6345 0x8
/* GPIO mux registers and constants */
#define GPIO_MODE_REG 0x18
@@ -402,6 +468,44 @@
#define GPIO_MODE_6358_SERIAL_LED (1 << 10)
#define GPIO_MODE_6358_UTOPIA (1 << 12)
+#define GPIO_MODE_6368_ANALOG_AFE_0 (1 << 0)
+#define GPIO_MODE_6368_ANALOG_AFE_1 (1 << 1)
+#define GPIO_MODE_6368_SYS_IRQ (1 << 2)
+#define GPIO_MODE_6368_SERIAL_LED_DATA (1 << 3)
+#define GPIO_MODE_6368_SERIAL_LED_CLK (1 << 4)
+#define GPIO_MODE_6368_INET_LED (1 << 5)
+#define GPIO_MODE_6368_EPHY0_LED (1 << 6)
+#define GPIO_MODE_6368_EPHY1_LED (1 << 7)
+#define GPIO_MODE_6368_EPHY2_LED (1 << 8)
+#define GPIO_MODE_6368_EPHY3_LED (1 << 9)
+#define GPIO_MODE_6368_ROBOSW_LED_DAT (1 << 10)
+#define GPIO_MODE_6368_ROBOSW_LED_CLK (1 << 11)
+#define GPIO_MODE_6368_ROBOSW_LED0 (1 << 12)
+#define GPIO_MODE_6368_ROBOSW_LED1 (1 << 13)
+#define GPIO_MODE_6368_USBD_LED (1 << 14)
+#define GPIO_MODE_6368_NTR_PULSE (1 << 15)
+#define GPIO_MODE_6368_PCI_REQ1 (1 << 16)
+#define GPIO_MODE_6368_PCI_GNT1 (1 << 17)
+#define GPIO_MODE_6368_PCI_INTB (1 << 18)
+#define GPIO_MODE_6368_PCI_REQ0 (1 << 19)
+#define GPIO_MODE_6368_PCI_GNT0 (1 << 20)
+#define GPIO_MODE_6368_PCMCIA_CD1 (1 << 22)
+#define GPIO_MODE_6368_PCMCIA_CD2 (1 << 23)
+#define GPIO_MODE_6368_PCMCIA_VS1 (1 << 24)
+#define GPIO_MODE_6368_PCMCIA_VS2 (1 << 25)
+#define GPIO_MODE_6368_EBI_CS2 (1 << 26)
+#define GPIO_MODE_6368_EBI_CS3 (1 << 27)
+#define GPIO_MODE_6368_SPI_SSN2 (1 << 28)
+#define GPIO_MODE_6368_SPI_SSN3 (1 << 29)
+#define GPIO_MODE_6368_SPI_SSN4 (1 << 30)
+#define GPIO_MODE_6368_SPI_SSN5 (1 << 31)
+
+
+#define GPIO_BASEMODE_6368_REG 0x38
+#define GPIO_BASEMODE_6368_UART2 0x1
+#define GPIO_BASEMODE_6368_GPIO 0x0
+#define GPIO_BASEMODE_6368_MASK 0x7
+/* those bits must be kept as read in gpio basemode register*/
/*************************************************************************
* _REG relative to RSET_ENET
@@ -548,6 +652,56 @@
/*************************************************************************
+ * _REG relative to RSET_ENETDMAC
+ *************************************************************************/
+
+/* Channel Configuration register */
+#define ENETDMAC_CHANCFG_REG(x) ((x) * 0x10)
+#define ENETDMAC_CHANCFG_EN_SHIFT 0
+#define ENETDMAC_CHANCFG_EN_MASK (1 << ENETDMA_CHANCFG_EN_SHIFT)
+#define ENETDMAC_CHANCFG_PKTHALT_SHIFT 1
+#define ENETDMAC_CHANCFG_PKTHALT_MASK (1 << ENETDMA_CHANCFG_PKTHALT_SHIFT)
+
+/* Interrupt Control/Status register */
+#define ENETDMAC_IR_REG(x) (0x4 + (x) * 0x10)
+#define ENETDMAC_IR_BUFDONE_MASK (1 << 0)
+#define ENETDMAC_IR_PKTDONE_MASK (1 << 1)
+#define ENETDMAC_IR_NOTOWNER_MASK (1 << 2)
+
+/* Interrupt Mask register */
+#define ENETDMAC_IRMASK_REG(x) (0x8 + (x) * 0x10)
+
+/* Maximum Burst Length */
+#define ENETDMAC_MAXBURST_REG(x) (0xc + (x) * 0x10)
+
+
+/*************************************************************************
+ * _REG relative to RSET_ENETDMAS
+ *************************************************************************/
+
+/* Ring Start Address register */
+#define ENETDMAS_RSTART_REG(x) ((x) * 0x10)
+
+/* State Ram Word 2 */
+#define ENETDMAS_SRAM2_REG(x) (0x4 + (x) * 0x10)
+
+/* State Ram Word 3 */
+#define ENETDMAS_SRAM3_REG(x) (0x8 + (x) * 0x10)
+
+/* State Ram Word 4 */
+#define ENETDMAS_SRAM4_REG(x) (0xc + (x) * 0x10)
+
+
+/*************************************************************************
+ * _REG relative to RSET_ENETSW
+ *************************************************************************/
+
+/* MIB register */
+#define ENETSW_MIB_REG(x) (0x2800 + (x) * 4)
+#define ENETSW_MIB_REG_COUNT 47
+
+
+/*************************************************************************
* _REG relative to RSET_OHCI_PRIV
*************************************************************************/
@@ -562,7 +716,9 @@
* _REG relative to RSET_USBH_PRIV
*************************************************************************/
-#define USBH_PRIV_SWAP_REG 0x0
+#define USBH_PRIV_SWAP_6358_REG 0x0
+#define USBH_PRIV_SWAP_6368_REG 0x1c
+
#define USBH_PRIV_SWAP_EHCI_ENDN_SHIFT 4
#define USBH_PRIV_SWAP_EHCI_ENDN_MASK (1 << USBH_PRIV_SWAP_EHCI_ENDN_SHIFT)
#define USBH_PRIV_SWAP_EHCI_DATA_SHIFT 3
@@ -572,7 +728,13 @@
#define USBH_PRIV_SWAP_OHCI_DATA_SHIFT 0
#define USBH_PRIV_SWAP_OHCI_DATA_MASK (1 << USBH_PRIV_SWAP_OHCI_DATA_SHIFT)
-#define USBH_PRIV_TEST_REG 0x24
+#define USBH_PRIV_TEST_6358_REG 0x24
+#define USBH_PRIV_TEST_6368_REG 0x14
+
+#define USBH_PRIV_SETUP_6368_REG 0x28
+#define USBH_PRIV_SETUP_IOC_SHIFT 4
+#define USBH_PRIV_SETUP_IOC_MASK (1 << USBH_PRIV_SETUP_IOC_SHIFT)
+
/*************************************************************************
@@ -734,6 +896,8 @@
#define SDRAM_CFG_BANK_SHIFT 13
#define SDRAM_CFG_BANK_MASK (1 << SDRAM_CFG_BANK_SHIFT)
+#define SDRAM_MBASE_REG 0xc
+
#define SDRAM_PRIO_REG 0x2C
#define SDRAM_PRIO_MIPS_SHIFT 29
#define SDRAM_PRIO_MIPS_MASK (1 << SDRAM_PRIO_MIPS_SHIFT)
@@ -768,4 +932,45 @@
#define DMIPSPLLCFG_N2_SHIFT 29
#define DMIPSPLLCFG_N2_MASK (0x7 << DMIPSPLLCFG_N2_SHIFT)
+#define DDR_DMIPSPLLCFG_6368_REG 0x20
+#define DMIPSPLLCFG_6368_P1_SHIFT 0
+#define DMIPSPLLCFG_6368_P1_MASK (0xf << DMIPSPLLCFG_6368_P1_SHIFT)
+#define DMIPSPLLCFG_6368_P2_SHIFT 4
+#define DMIPSPLLCFG_6368_P2_MASK (0xf << DMIPSPLLCFG_6368_P2_SHIFT)
+#define DMIPSPLLCFG_6368_NDIV_SHIFT 16
+#define DMIPSPLLCFG_6368_NDIV_MASK (0x1ff << DMIPSPLLCFG_6368_NDIV_SHIFT)
+
+#define DDR_DMIPSPLLDIV_6368_REG 0x24
+#define DMIPSPLLDIV_6368_MDIV_SHIFT 0
+#define DMIPSPLLDIV_6368_MDIV_MASK (0xff << DMIPSPLLDIV_6368_MDIV_SHIFT)
+
+
+/*************************************************************************
+ * _REG relative to RSET_M2M
+ *************************************************************************/
+
+#define M2M_RX 0
+#define M2M_TX 1
+
+#define M2M_SRC_REG(x) ((x) * 0x40 + 0x00)
+#define M2M_DST_REG(x) ((x) * 0x40 + 0x04)
+#define M2M_SIZE_REG(x) ((x) * 0x40 + 0x08)
+
+#define M2M_CTRL_REG(x) ((x) * 0x40 + 0x0c)
+#define M2M_CTRL_ENABLE_MASK (1 << 0)
+#define M2M_CTRL_IRQEN_MASK (1 << 1)
+#define M2M_CTRL_ERROR_CLR_MASK (1 << 6)
+#define M2M_CTRL_DONE_CLR_MASK (1 << 7)
+#define M2M_CTRL_NOINC_MASK (1 << 8)
+#define M2M_CTRL_PCMCIASWAP_MASK (1 << 9)
+#define M2M_CTRL_SWAPBYTE_MASK (1 << 10)
+#define M2M_CTRL_ENDIAN_MASK (1 << 11)
+
+#define M2M_STAT_REG(x) ((x) * 0x40 + 0x10)
+#define M2M_STAT_DONE (1 << 0)
+#define M2M_STAT_ERROR (1 << 1)
+
+#define M2M_SRCID_REG(x) ((x) * 0x40 + 0x14)
+#define M2M_DSTID_REG(x) ((x) * 0x40 + 0x18)
+
#endif /* BCM63XX_REGS_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
new file mode 100644
index 000000000000..ef94ba73646e
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
@@ -0,0 +1,42 @@
+#ifndef BCM63XX_IOREMAP_H_
+#define BCM63XX_IOREMAP_H_
+
+#include <bcm63xx_cpu.h>
+
+static inline phys_t fixup_bigphys_addr(phys_t phys_addr, phys_t size)
+{
+ return phys_addr;
+}
+
+static inline int is_bcm63xx_internal_registers(phys_t offset)
+{
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6338_CPU_ID:
+ case BCM6345_CPU_ID:
+ case BCM6348_CPU_ID:
+ case BCM6358_CPU_ID:
+ if (offset >= 0xfff00000)
+ return 1;
+ break;
+ case BCM6368_CPU_ID:
+ if (offset >= 0xb0000000 && offset < 0xb1000000)
+ return 1;
+ break;
+ }
+ return 0;
+}
+
+static inline void __iomem *plat_ioremap(phys_t offset, unsigned long size,
+ unsigned long flags)
+{
+ if (is_bcm63xx_internal_registers(offset))
+ return (void __iomem *)offset;
+ return NULL;
+}
+
+static inline int plat_iounmap(const volatile void __iomem *addr)
+{
+ return is_bcm63xx_internal_registers((unsigned long)addr);
+}
+
+#endif /* BCM63XX_IOREMAP_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/irq.h b/arch/mips/include/asm/mach-bcm63xx/irq.h
new file mode 100644
index 000000000000..9332e788a5c9
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/irq.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_BCM63XX_IRQ_H
+#define __ASM_MACH_BCM63XX_IRQ_H
+
+#define NR_IRQS 128
+#define MIPS_CPU_IRQ_BASE 0
+
+#endif
diff --git a/arch/mips/include/asm/mach-db1x00/bcsr.h b/arch/mips/include/asm/mach-db1x00/bcsr.h
index 618d2de02ed3..bb9fc23d853a 100644
--- a/arch/mips/include/asm/mach-db1x00/bcsr.h
+++ b/arch/mips/include/asm/mach-db1x00/bcsr.h
@@ -34,6 +34,8 @@
#define PB1200_BCSR_PHYS_ADDR 0x0D800000
#define PB1200_BCSR_HEXLED_OFS 0x00400000
+#define DB1300_BCSR_PHYS_ADDR 0x19800000
+#define DB1300_BCSR_HEXLED_OFS 0x00400000
enum bcsr_id {
/* BCSR base 1 */
@@ -105,6 +107,7 @@ enum bcsr_whoami_boards {
BCSR_WHOAMI_PB1200 = BCSR_WHOAMI_PB1200_DDR1,
BCSR_WHOAMI_PB1200_DDR2,
BCSR_WHOAMI_DB1200,
+ BCSR_WHOAMI_DB1300,
};
/* STATUS reg. Unless otherwise noted, they're valid on all boards.
@@ -118,12 +121,12 @@ enum bcsr_whoami_boards {
#define BCSR_STATUS_SRAMWIDTH 0x0080
#define BCSR_STATUS_FLASHBUSY 0x0100
#define BCSR_STATUS_ROMBUSY 0x0400
-#define BCSR_STATUS_SD0WP 0x0400 /* DB1200 */
+#define BCSR_STATUS_SD0WP 0x0400 /* DB1200/DB1300:SD1 */
#define BCSR_STATUS_SD1WP 0x0800
#define BCSR_STATUS_USBOTGID 0x0800 /* PB/DB1550 */
#define BCSR_STATUS_DB1000_SWAPBOOT 0x2000
-#define BCSR_STATUS_DB1200_SWAPBOOT 0x0040 /* DB1200 */
-#define BCSR_STATUS_IDECBLID 0x0200 /* DB1200 */
+#define BCSR_STATUS_DB1200_SWAPBOOT 0x0040 /* DB1200/1300 */
+#define BCSR_STATUS_IDECBLID 0x0200 /* DB1200/1300 */
#define BCSR_STATUS_DB1200_U0RXD 0x1000 /* DB1200 */
#define BCSR_STATUS_DB1200_U1RXD 0x2000 /* DB1200 */
#define BCSR_STATUS_FLASHDEN 0xC000
@@ -133,6 +136,11 @@ enum bcsr_whoami_boards {
#define BCSR_STATUS_PB1550_U1RXD 0x2000 /* PB1550 */
#define BCSR_STATUS_PB1550_U3RXD 0x8000 /* PB1550 */
+#define BCSR_STATUS_CFWP 0x4000 /* DB1300 */
+#define BCSR_STATUS_USBOCn 0x2000 /* DB1300 */
+#define BCSR_STATUS_OTGOCn 0x1000 /* DB1300 */
+#define BCSR_STATUS_DCDMARQ 0x0010 /* DB1300 */
+#define BCSR_STATUS_IDEDMARQ 0x0020 /* DB1300 */
/* DB/PB1000,1100,1500,1550 */
#define BCSR_RESETS_PHY0 0x0001
@@ -155,17 +163,17 @@ enum bcsr_whoami_boards {
#define BCSR_BOARD_GPIO200RST 0x0400
#define BCSR_BOARD_PCICLKOUT 0x0800
#define BCSR_BOARD_PCICFG 0x1000
-#define BCSR_BOARD_SPISEL 0x4000 /* PB/DB1550 */
+#define BCSR_BOARD_SPISEL 0x2000 /* PB/DB1550 */
#define BCSR_BOARD_SD0WP 0x4000 /* DB1100 */
#define BCSR_BOARD_SD1WP 0x8000 /* DB1100 */
-/* DB/PB1200 */
+/* DB/PB1200/1300 */
#define BCSR_RESETS_ETH 0x0001
#define BCSR_RESETS_CAMERA 0x0002
#define BCSR_RESETS_DC 0x0004
#define BCSR_RESETS_IDE 0x0008
-#define BCSR_RESETS_TV 0x0010 /* DB1200 */
+#define BCSR_RESETS_TV 0x0010 /* DB1200/1300 */
/* Not resets but in the same register */
#define BCSR_RESETS_PWMR1MUX 0x0800 /* DB1200 */
#define BCSR_RESETS_PB1200_WSCFSM 0x0800 /* PB1200 */
@@ -174,13 +182,22 @@ enum bcsr_whoami_boards {
#define BCSR_RESETS_SPISEL 0x4000
#define BCSR_RESETS_SD1MUX 0x8000 /* PB1200 */
+#define BCSR_RESETS_VDDQSHDN 0x0200 /* DB1300 */
+#define BCSR_RESETS_OTPPGM 0x0400 /* DB1300 */
+#define BCSR_RESETS_OTPSCLK 0x0800 /* DB1300 */
+#define BCSR_RESETS_OTPWRPROT 0x1000 /* DB1300 */
+#define BCSR_RESETS_OTPCSB 0x2000 /* DB1300 */
+#define BCSR_RESETS_OTGPWR 0x4000 /* DB1300 */
+#define BCSR_RESETS_USBHPWR 0x8000 /* DB1300 */
+
#define BCSR_BOARD_LCDVEE 0x0001
#define BCSR_BOARD_LCDVDD 0x0002
#define BCSR_BOARD_LCDBL 0x0004
#define BCSR_BOARD_CAMSNAP 0x0010
#define BCSR_BOARD_CAMPWR 0x0020
#define BCSR_BOARD_SD0PWR 0x0040
-
+#define BCSR_BOARD_CAMCS 0x0010 /* DB1300 */
+#define BCSR_BOARD_HDMI_DE 0x0040 /* DB1300 */
#define BCSR_SWITCHES_DIP 0x00FF
#define BCSR_SWITCHES_DIP_1 0x0080
@@ -214,7 +231,10 @@ enum bcsr_whoami_boards {
#define BCSR_SYSTEM_RESET 0x8000 /* clear to reset */
#define BCSR_SYSTEM_PWROFF 0x4000 /* set to power off */
#define BCSR_SYSTEM_VDDI 0x001F /* PB1xxx boards */
-
+#define BCSR_SYSTEM_DEBUGCSMASK 0x003F /* DB1300 */
+#define BCSR_SYSTEM_UDMAMODE 0x0100 /* DB1300 */
+#define BCSR_SYSTEM_WAKEONIRQ 0x0200 /* DB1300 */
+#define BCSR_SYSTEM_VDDI1300 0x3C00 /* DB1300 */
diff --git a/arch/mips/include/asm/mach-db1x00/db1200.h b/arch/mips/include/asm/mach-db1x00/db1200.h
index 7a39657108c4..b2a8319521e5 100644
--- a/arch/mips/include/asm/mach-db1x00/db1200.h
+++ b/arch/mips/include/asm/mach-db1x00/db1200.h
@@ -43,15 +43,20 @@
#define BCSR_INT_PC1EJECT 0x0800
#define BCSR_INT_SD0INSERT 0x1000
#define BCSR_INT_SD0EJECT 0x2000
+#define BCSR_INT_SD1INSERT 0x4000
+#define BCSR_INT_SD1EJECT 0x8000
-#define IDE_PHYS_ADDR 0x18800000
#define IDE_REG_SHIFT 5
-#define DB1200_IDE_PHYS_ADDR IDE_PHYS_ADDR
+#define DB1200_IDE_PHYS_ADDR 0x18800000
#define DB1200_IDE_PHYS_LEN (16 << IDE_REG_SHIFT)
#define DB1200_ETH_PHYS_ADDR 0x19000300
#define DB1200_NAND_PHYS_ADDR 0x20000000
+#define PB1200_IDE_PHYS_ADDR 0x0C800000
+#define PB1200_ETH_PHYS_ADDR 0x0D000300
+#define PB1200_NAND_PHYS_ADDR 0x1C000000
+
/*
* External Interrupts for DBAu1200 as of 8/6/2004.
* Bit positions in the CPLD registers can be calculated by taking
@@ -77,6 +82,8 @@ enum external_db1200_ints {
DB1200_PC1_EJECT_INT,
DB1200_SD0_INSERT_INT,
DB1200_SD0_EJECT_INT,
+ PB1200_SD1_INSERT_INT,
+ PB1200_SD1_EJECT_INT,
DB1200_INT_END = DB1200_INT_BEGIN + 15,
};
diff --git a/arch/mips/include/asm/mach-db1x00/db1300.h b/arch/mips/include/asm/mach-db1x00/db1300.h
new file mode 100644
index 000000000000..7fe5fb3ba877
--- /dev/null
+++ b/arch/mips/include/asm/mach-db1x00/db1300.h
@@ -0,0 +1,40 @@
+/*
+ * NetLogic DB1300 board constants
+ */
+
+#ifndef _DB1300_H_
+#define _DB1300_H_
+
+/* FPGA (external mux) interrupt sources */
+#define DB1300_FIRST_INT (ALCHEMY_GPIC_INT_LAST + 1)
+#define DB1300_IDE_INT (DB1300_FIRST_INT + 0)
+#define DB1300_ETH_INT (DB1300_FIRST_INT + 1)
+#define DB1300_CF_INT (DB1300_FIRST_INT + 2)
+#define DB1300_VIDEO_INT (DB1300_FIRST_INT + 4)
+#define DB1300_HDMI_INT (DB1300_FIRST_INT + 5)
+#define DB1300_DC_INT (DB1300_FIRST_INT + 6)
+#define DB1300_FLASH_INT (DB1300_FIRST_INT + 7)
+#define DB1300_CF_INSERT_INT (DB1300_FIRST_INT + 8)
+#define DB1300_CF_EJECT_INT (DB1300_FIRST_INT + 9)
+#define DB1300_AC97_INT (DB1300_FIRST_INT + 10)
+#define DB1300_AC97_PEN_INT (DB1300_FIRST_INT + 11)
+#define DB1300_SD1_INSERT_INT (DB1300_FIRST_INT + 12)
+#define DB1300_SD1_EJECT_INT (DB1300_FIRST_INT + 13)
+#define DB1300_OTG_VBUS_OC_INT (DB1300_FIRST_INT + 14)
+#define DB1300_HOST_VBUS_OC_INT (DB1300_FIRST_INT + 15)
+#define DB1300_LAST_INT (DB1300_FIRST_INT + 15)
+
+/* SMSC9210 CS */
+#define DB1300_ETH_PHYS_ADDR 0x19000000
+#define DB1300_ETH_PHYS_END 0x197fffff
+
+/* ATA CS */
+#define DB1300_IDE_PHYS_ADDR 0x18800000
+#define DB1300_IDE_REG_SHIFT 5
+#define DB1300_IDE_PHYS_LEN (16 << DB1300_IDE_REG_SHIFT)
+
+/* NAND CS */
+#define DB1300_NAND_PHYS_ADDR 0x20000000
+#define DB1300_NAND_PHYS_END 0x20000fff
+
+#endif /* _DB1300_H_ */
diff --git a/arch/mips/include/asm/mach-db1x00/db1x00.h b/arch/mips/include/asm/mach-db1x00/db1x00.h
deleted file mode 100644
index a5affb0568ef..000000000000
--- a/arch/mips/include/asm/mach-db1x00/db1x00.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * AMD Alchemy DBAu1x00 Reference Boards
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org)
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-#ifndef __ASM_DB1X00_H
-#define __ASM_DB1X00_H
-
-#include <asm/mach-au1x00/au1xxx_psc.h>
-
-#ifdef CONFIG_MIPS_DB1550
-
-#define DBDMA_AC97_TX_CHAN AU1550_DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN AU1550_DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN AU1550_DSCR_CMD0_PSC3_TX
-#define DBDMA_I2S_RX_CHAN AU1550_DSCR_CMD0_PSC3_RX
-
-#define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR
-#define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR
-#define SMBUS_PSC_BASE AU1550_PSC2_PHYS_ADDR
-#define I2S_PSC_BASE AU1550_PSC3_PHYS_ADDR
-
-#define NAND_PHYS_ADDR 0x20000000
-
-#endif
-
-/*
- * NAND defines
- *
- * Timing values as described in databook, * ns value stripped of the
- * lower 2 bits.
- * These defines are here rather than an Au1550 generic file because
- * the parts chosen on another board may be different and may require
- * different timings.
- */
-#define NAND_T_H (18 >> 2)
-#define NAND_T_PUL (30 >> 2)
-#define NAND_T_SU (30 >> 2)
-#define NAND_T_WH (30 >> 2)
-
-/* Bitfield shift amounts */
-#define NAND_T_H_SHIFT 0
-#define NAND_T_PUL_SHIFT 4
-#define NAND_T_SU_SHIFT 8
-#define NAND_T_WH_SHIFT 12
-
-#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
- ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
- ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
- ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT))
-#define NAND_CS 1
-
-/* Should be done by YAMON */
-#define NAND_STCFG 0x00400005 /* 8-bit NAND */
-#define NAND_STTIME 0x00007774 /* valid for 396 MHz SD=2 only */
-#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
-
-#endif /* __ASM_DB1X00_H */
diff --git a/arch/mips/include/asm/mach-db1x00/irq.h b/arch/mips/include/asm/mach-db1x00/irq.h
new file mode 100644
index 000000000000..15b26693238f
--- /dev/null
+++ b/arch/mips/include/asm/mach-db1x00/irq.h
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2003 by Ralf Baechle
+ */
+#ifndef __ASM_MACH_GENERIC_IRQ_H
+#define __ASM_MACH_GENERIC_IRQ_H
+
+
+#ifdef NR_IRQS
+#undef NR_IRQS
+#endif
+
+#ifndef MIPS_CPU_IRQ_BASE
+#define MIPS_CPU_IRQ_BASE 0
+#endif
+
+/* 8 (MIPS) + 128 (au1300) + 16 (cpld) */
+#define NR_IRQS 152
+
+#endif /* __ASM_MACH_GENERIC_IRQ_H */
diff --git a/arch/mips/include/asm/mach-generic/floppy.h b/arch/mips/include/asm/mach-generic/floppy.h
index 001a8ce17c17..a38f4d43e5e5 100644
--- a/arch/mips/include/asm/mach-generic/floppy.h
+++ b/arch/mips/include/asm/mach-generic/floppy.h
@@ -98,7 +98,7 @@ static inline void fd_disable_irq(void)
static inline int fd_request_irq(void)
{
return request_irq(FLOPPY_IRQ, floppy_interrupt,
- IRQF_DISABLED, "floppy", NULL);
+ 0, "floppy", NULL);
}
static inline void fd_free_irq(void)
diff --git a/arch/mips/include/asm/mach-jazz/floppy.h b/arch/mips/include/asm/mach-jazz/floppy.h
index 56e9ca6ae426..88b5acb75145 100644
--- a/arch/mips/include/asm/mach-jazz/floppy.h
+++ b/arch/mips/include/asm/mach-jazz/floppy.h
@@ -90,7 +90,7 @@ static inline void fd_disable_irq(void)
static inline int fd_request_irq(void)
{
return request_irq(FLOPPY_IRQ, floppy_interrupt,
- IRQF_DISABLED, "floppy", NULL);
+ 0, "floppy", NULL);
}
static inline void fd_free_irq(void)
diff --git a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
index 3b728275b9b0..d193fb68cf27 100644
--- a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
@@ -24,24 +24,33 @@
#define cpu_has_llsc 1
#define cpu_has_vtag_icache 0
-#define cpu_has_dc_aliases 0
-#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_ic_fills_f_dc 1
#define cpu_has_dsp 0
#define cpu_has_mipsmt 0
-#define cpu_has_userlocal 0
-#define cpu_icache_snoops_remote_store 0
+#define cpu_icache_snoops_remote_store 1
-#define cpu_has_nofpuex 0
#define cpu_has_64bits 1
#define cpu_has_mips32r1 1
-#define cpu_has_mips32r2 0
#define cpu_has_mips64r1 1
-#define cpu_has_mips64r2 0
#define cpu_has_inclusive_pcaches 0
#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
+#if defined(CONFIG_CPU_XLR)
+#define cpu_has_userlocal 0
+#define cpu_has_dc_aliases 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r2 0
+#elif defined(CONFIG_CPU_XLP)
+#define cpu_has_userlocal 1
+#define cpu_has_mips32r2 1
+#define cpu_has_mips64r2 1
+#define cpu_has_dc_aliases 1
+#else
+#error "Unknown Netlogic CPU"
+#endif
+
#endif /* __ASM_MACH_NETLOGIC_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-pb1x00/mc146818rtc.h b/arch/mips/include/asm/mach-pb1x00/mc146818rtc.h
deleted file mode 100644
index 622c58710e5b..000000000000
--- a/arch/mips/include/asm/mach-pb1x00/mc146818rtc.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- *
- * Copyright (C) 1998, 2001, 03 by Ralf Baechle
- *
- * RTC routines for PC style attached Dallas chip.
- */
-#ifndef __ASM_MACH_AU1XX_MC146818RTC_H
-#define __ASM_MACH_AU1XX_MC146818RTC_H
-
-#include <asm/io.h>
-#include <asm/mach-au1x00/au1000.h>
-
-#define RTC_PORT(x) (0x0c000000 + (x))
-#define RTC_IRQ 8
-#define PB1500_RTC_ADDR 0x0c000000
-
-static inline unsigned char CMOS_READ(unsigned long offset)
-{
- offset <<= 2;
- return (u8)(au_readl(offset + PB1500_RTC_ADDR) & 0xff);
-}
-
-static inline void CMOS_WRITE(unsigned char data, unsigned long offset)
-{
- offset <<= 2;
- au_writel(data, offset + PB1500_RTC_ADDR);
-}
-
-#define RTC_ALWAYS_BCD 1
-
-#endif /* __ASM_MACH_AU1XX_MC146818RTC_H */
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1000.h b/arch/mips/include/asm/mach-pb1x00/pb1000.h
deleted file mode 100644
index 65059255dc1e..000000000000
--- a/arch/mips/include/asm/mach-pb1x00/pb1000.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Alchemy Semi Pb1000 Reference Board
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <source@mvista.com>
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-#ifndef __ASM_PB1000_H
-#define __ASM_PB1000_H
-
-/* PCMCIA PB1000 specific defines */
-#define PCMCIA_MAX_SOCK 1
-#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
-
-#define PB1000_PCR 0xBE000000
-# define PCR_SLOT_0_VPP0 (1 << 0)
-# define PCR_SLOT_0_VPP1 (1 << 1)
-# define PCR_SLOT_0_VCC0 (1 << 2)
-# define PCR_SLOT_0_VCC1 (1 << 3)
-# define PCR_SLOT_0_RST (1 << 4)
-# define PCR_SLOT_1_VPP0 (1 << 8)
-# define PCR_SLOT_1_VPP1 (1 << 9)
-# define PCR_SLOT_1_VCC0 (1 << 10)
-# define PCR_SLOT_1_VCC1 (1 << 11)
-# define PCR_SLOT_1_RST (1 << 12)
-
-#define PB1000_MDR 0xBE000004
-# define MDR_PI (1 << 5) /* PCMCIA int latch */
-# define MDR_EPI (1 << 14) /* enable PCMCIA int */
-# define MDR_CPI (1 << 15) /* clear PCMCIA int */
-
-#define PB1000_ACR1 0xBE000008
-# define ACR1_SLOT_0_CD1 (1 << 0) /* card detect 1 */
-# define ACR1_SLOT_0_CD2 (1 << 1) /* card detect 2 */
-# define ACR1_SLOT_0_READY (1 << 2) /* ready */
-# define ACR1_SLOT_0_STATUS (1 << 3) /* status change */
-# define ACR1_SLOT_0_VS1 (1 << 4) /* voltage sense 1 */
-# define ACR1_SLOT_0_VS2 (1 << 5) /* voltage sense 2 */
-# define ACR1_SLOT_0_INPACK (1 << 6) /* inpack pin status */
-# define ACR1_SLOT_1_CD1 (1 << 8) /* card detect 1 */
-# define ACR1_SLOT_1_CD2 (1 << 9) /* card detect 2 */
-# define ACR1_SLOT_1_READY (1 << 10) /* ready */
-# define ACR1_SLOT_1_STATUS (1 << 11) /* status change */
-# define ACR1_SLOT_1_VS1 (1 << 12) /* voltage sense 1 */
-# define ACR1_SLOT_1_VS2 (1 << 13) /* voltage sense 2 */
-# define ACR1_SLOT_1_INPACK (1 << 14) /* inpack pin status */
-
-#define CPLD_AUX0 0xBE00000C
-#define CPLD_AUX1 0xBE000010
-#define CPLD_AUX2 0xBE000014
-
-/* Voltage levels */
-
-/* VPPEN1 - VPPEN0 */
-#define VPP_GND ((0 << 1) | (0 << 0))
-#define VPP_5V ((1 << 1) | (0 << 0))
-#define VPP_3V ((0 << 1) | (1 << 0))
-#define VPP_12V ((0 << 1) | (1 << 0))
-#define VPP_HIZ ((1 << 1) | (1 << 0))
-
-/* VCCEN1 - VCCEN0 */
-#define VCC_3V ((0 << 1) | (1 << 0))
-#define VCC_5V ((1 << 1) | (0 << 0))
-#define VCC_HIZ ((0 << 1) | (0 << 0))
-
-/* VPP/VCC */
-#define SET_VCC_VPP(VCC, VPP, SLOT) \
- ((((VCC) << 2) | ((VPP) << 0)) << ((SLOT) * 8))
-#endif /* __ASM_PB1000_H */
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1200.h b/arch/mips/include/asm/mach-pb1x00/pb1200.h
deleted file mode 100644
index 374416adb65b..000000000000
--- a/arch/mips/include/asm/mach-pb1x00/pb1200.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * AMD Alchemy Pb1200 Reference Board
- * Board Registers defines.
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-#ifndef __ASM_PB1200_H
-#define __ASM_PB1200_H
-
-#include <linux/types.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_psc.h>
-
-#define DBDMA_AC97_TX_CHAN AU1200_DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN AU1200_DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN AU1200_DSCR_CMD0_PSC1_TX
-#define DBDMA_I2S_RX_CHAN AU1200_DSCR_CMD0_PSC1_RX
-
-/*
- * SPI and SMB are muxed on the Pb1200 board.
- * Refer to board documentation.
- */
-#define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR
-#define SMBUS_PSC_BASE AU1550_PSC0_PHYS_ADDR
-/*
- * AC97 and I2S are muxed on the Pb1200 board.
- * Refer to board documentation.
- */
-#define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR
-#define I2S_PSC_BASE AU1550_PSC1_PHYS_ADDR
-
-
-#define BCSR_SYSTEM_VDDI 0x001F
-#define BCSR_SYSTEM_POWEROFF 0x4000
-#define BCSR_SYSTEM_RESET 0x8000
-
-/* Bit positions for the different interrupt sources */
-#define BCSR_INT_IDE 0x0001
-#define BCSR_INT_ETH 0x0002
-#define BCSR_INT_PC0 0x0004
-#define BCSR_INT_PC0STSCHG 0x0008
-#define BCSR_INT_PC1 0x0010
-#define BCSR_INT_PC1STSCHG 0x0020
-#define BCSR_INT_DC 0x0040
-#define BCSR_INT_FLASHBUSY 0x0080
-#define BCSR_INT_PC0INSERT 0x0100
-#define BCSR_INT_PC0EJECT 0x0200
-#define BCSR_INT_PC1INSERT 0x0400
-#define BCSR_INT_PC1EJECT 0x0800
-#define BCSR_INT_SD0INSERT 0x1000
-#define BCSR_INT_SD0EJECT 0x2000
-#define BCSR_INT_SD1INSERT 0x4000
-#define BCSR_INT_SD1EJECT 0x8000
-
-#define SMC91C111_PHYS_ADDR 0x0D000300
-#define SMC91C111_INT PB1200_ETH_INT
-
-#define IDE_PHYS_ADDR 0x0C800000
-#define IDE_REG_SHIFT 5
-#define IDE_PHYS_LEN (16 << IDE_REG_SHIFT)
-#define IDE_INT PB1200_IDE_INT
-
-#define NAND_PHYS_ADDR 0x1C000000
-
-/*
- * Timing values as described in databook, * ns value stripped of
- * lower 2 bits.
- * These defines are here rather than an Au1200 generic file because
- * the parts chosen on another board may be different and may require
- * different timings.
- */
-#define NAND_T_H (18 >> 2)
-#define NAND_T_PUL (30 >> 2)
-#define NAND_T_SU (30 >> 2)
-#define NAND_T_WH (30 >> 2)
-
-/* Bitfield shift amounts */
-#define NAND_T_H_SHIFT 0
-#define NAND_T_PUL_SHIFT 4
-#define NAND_T_SU_SHIFT 8
-#define NAND_T_WH_SHIFT 12
-
-#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
- ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
- ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
- ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT))
-
-/*
- * External Interrupts for Pb1200 as of 8/6/2004.
- * Bit positions in the CPLD registers can be calculated by taking
- * the interrupt define and subtracting the PB1200_INT_BEGIN value.
- *
- * Example: IDE bis pos is = 64 - 64
- * ETH bit pos is = 65 - 64
- */
-enum external_pb1200_ints {
- PB1200_INT_BEGIN = AU1000_MAX_INTR + 1,
-
- PB1200_IDE_INT = PB1200_INT_BEGIN,
- PB1200_ETH_INT,
- PB1200_PC0_INT,
- PB1200_PC0_STSCHG_INT,
- PB1200_PC1_INT,
- PB1200_PC1_STSCHG_INT,
- PB1200_DC_INT,
- PB1200_FLASHBUSY_INT,
- PB1200_PC0_INSERT_INT,
- PB1200_PC0_EJECT_INT,
- PB1200_PC1_INSERT_INT,
- PB1200_PC1_EJECT_INT,
- PB1200_SD0_INSERT_INT,
- PB1200_SD0_EJECT_INT,
- PB1200_SD1_INSERT_INT,
- PB1200_SD1_EJECT_INT,
-
- PB1200_INT_END = PB1200_INT_BEGIN + 15
-};
-
-/* NAND chip select */
-#define NAND_CS 1
-
-#endif /* __ASM_PB1200_H */
diff --git a/arch/mips/include/asm/mach-pb1x00/pb1550.h b/arch/mips/include/asm/mach-pb1x00/pb1550.h
deleted file mode 100644
index 443b88adebf1..000000000000
--- a/arch/mips/include/asm/mach-pb1x00/pb1550.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * AMD Alchemy Semi PB1550 Reference Board
- * Board Registers defines.
- *
- * Copyright 2004 Embedded Edge LLC.
- * Copyright 2005 Ralf Baechle (ralf@linux-mips.org)
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-#ifndef __ASM_PB1550_H
-#define __ASM_PB1550_H
-
-#include <linux/types.h>
-#include <asm/mach-au1x00/au1xxx_psc.h>
-
-#define DBDMA_AC97_TX_CHAN AU1550_DSCR_CMD0_PSC1_TX
-#define DBDMA_AC97_RX_CHAN AU1550_DSCR_CMD0_PSC1_RX
-#define DBDMA_I2S_TX_CHAN AU1550_DSCR_CMD0_PSC3_TX
-#define DBDMA_I2S_RX_CHAN AU1550_DSCR_CMD0_PSC3_RX
-
-#define SPI_PSC_BASE AU1550_PSC0_PHYS_ADDR
-#define AC97_PSC_BASE AU1550_PSC1_PHYS_ADDR
-#define SMBUS_PSC_BASE AU1550_PSC2_PHYS_ADDR
-#define I2S_PSC_BASE AU1550_PSC3_PHYS_ADDR
-
-/*
- * Timing values as described in databook, * ns value stripped of
- * lower 2 bits.
- * These defines are here rather than an SOC1550 generic file because
- * the parts chosen on another board may be different and may require
- * different timings.
- */
-#define NAND_T_H (18 >> 2)
-#define NAND_T_PUL (30 >> 2)
-#define NAND_T_SU (30 >> 2)
-#define NAND_T_WH (30 >> 2)
-
-/* Bitfield shift amounts */
-#define NAND_T_H_SHIFT 0
-#define NAND_T_PUL_SHIFT 4
-#define NAND_T_SU_SHIFT 8
-#define NAND_T_WH_SHIFT 12
-
-#define NAND_TIMING (((NAND_T_H & 0xF) << NAND_T_H_SHIFT) | \
- ((NAND_T_PUL & 0xF) << NAND_T_PUL_SHIFT) | \
- ((NAND_T_SU & 0xF) << NAND_T_SU_SHIFT) | \
- ((NAND_T_WH & 0xF) << NAND_T_WH_SHIFT))
-
-#define NAND_CS 1
-
-/* Should be done by YAMON */
-#define NAND_STCFG 0x00400005 /* 8-bit NAND */
-#define NAND_STTIME 0x00007774 /* valid for 396 MHz SD=2 only */
-#define NAND_STADDR 0x12000FFF /* physical address 0x20000000 */
-
-#endif /* __ASM_PB1550_H */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 2ea7b817feb8..7f87d824eeb0 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1106,7 +1106,7 @@ do { \
#define read_c0_brcm_reset() __read_32bit_c0_register($22, 5)
#define write_c0_brcm_reset(val) __write_32bit_c0_register($22, 5, val)
-/* BMIPS4380 */
+/* BMIPS43xx */
#define read_c0_brcm_cmt_intr() __read_32bit_c0_register($22, 1)
#define write_c0_brcm_cmt_intr(val) __write_32bit_c0_register($22, 1, val)
@@ -1667,6 +1667,13 @@ __BUILD_SET_C0(config)
__BUILD_SET_C0(intcontrol)
__BUILD_SET_C0(intctl)
__BUILD_SET_C0(srsmap)
+__BUILD_SET_C0(brcm_config_0)
+__BUILD_SET_C0(brcm_bus_pll)
+__BUILD_SET_C0(brcm_reset)
+__BUILD_SET_C0(brcm_cmt_intr)
+__BUILD_SET_C0(brcm_cmt_ctrl)
+__BUILD_SET_C0(brcm_config)
+__BUILD_SET_C0(brcm_mode)
#endif /* !__ASSEMBLY__ */
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index bc01a02cacd8..7467d1d933d5 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -74,7 +74,9 @@ search_module_dbetables(unsigned long addr)
}
#endif
-#ifdef CONFIG_CPU_MIPS32_R1
+#ifdef CONFIG_CPU_BMIPS
+#define MODULE_PROC_FAMILY "BMIPS "
+#elif defined CONFIG_CPU_MIPS32_R1
#define MODULE_PROC_FAMILY "MIPS32_R1 "
#elif defined CONFIG_CPU_MIPS32_R2
#define MODULE_PROC_FAMILY "MIPS32_R2 "
@@ -120,6 +122,8 @@ search_module_dbetables(unsigned long addr)
#define MODULE_PROC_FAMILY "OCTEON "
#elif defined CONFIG_CPU_XLR
#define MODULE_PROC_FAMILY "XLR "
+#elif defined CONFIG_CPU_XLP
+#define MODULE_PROC_FAMILY "XLP "
#else
#error MODULE_PROC_FAMILY undefined for your processor configuration
#endif
diff --git a/arch/mips/include/asm/netlogic/common.h b/arch/mips/include/asm/netlogic/common.h
new file mode 100644
index 000000000000..fdd2f44c7b59
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/common.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NETLOGIC_COMMON_H_
+#define _NETLOGIC_COMMON_H_
+
+/*
+ * Common SMP definitions
+ */
+#define RESET_VEC_PHYS 0x1fc00000
+#define RESET_DATA_PHYS (RESET_VEC_PHYS + (1<<10))
+#define BOOT_THREAD_MODE 0
+#define BOOT_NMI_LOCK 4
+#define BOOT_NMI_HANDLER 8
+
+#ifndef __ASSEMBLY__
+struct irq_desc;
+extern struct plat_smp_ops nlm_smp_ops;
+extern char nlm_reset_entry[], nlm_reset_entry_end[];
+void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
+void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
+void nlm_smp_irq_init(void);
+void nlm_boot_secondary_cpus(void);
+int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
+void nlm_rmiboot_preboot(void);
+
+static inline void
+nlm_set_nmi_handler(void *handler)
+{
+ char *reset_data;
+
+ reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
+ *(int64_t *)(reset_data + BOOT_NMI_HANDLER) = (long)handler;
+}
+
+/*
+ * Misc.
+ */
+unsigned int nlm_get_cpu_frequency(void);
+
+extern unsigned long nlm_common_ebase;
+extern int nlm_threads_per_core;
+extern uint32_t nlm_cpumask, nlm_coremask;
+#endif
+#endif /* _NETLOGIC_COMMON_H_ */
diff --git a/arch/mips/include/asm/netlogic/haldefs.h b/arch/mips/include/asm/netlogic/haldefs.h
new file mode 100644
index 000000000000..72a0c788b472
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/haldefs.h
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NLM_HAL_HALDEFS_H__
+#define __NLM_HAL_HALDEFS_H__
+
+/*
+ * This file contains platform specific memory mapped IO implementation
+ * and will provide a way to read 32/64 bit memory mapped registers in
+ * all ABIs
+ */
+#if !defined(CONFIG_64BIT) && defined(CONFIG_CPU_XLP)
+#error "o32 compile not supported on XLP yet"
+#endif
+/*
+ * For o32 compilation, we have to disable interrupts and enable KX bit to
+ * access 64 bit addresses or data.
+ *
+ * We need to disable interrupts because we save just the lower 32 bits of
+ * registers in interrupt handling. So if we get hit by an interrupt while
+ * using the upper 32 bits of a register, we lose.
+ */
+static inline uint32_t nlm_save_flags_kx(void)
+{
+ return change_c0_status(ST0_KX | ST0_IE, ST0_KX);
+}
+
+static inline uint32_t nlm_save_flags_cop2(void)
+{
+ return change_c0_status(ST0_CU2 | ST0_IE, ST0_CU2);
+}
+
+static inline void nlm_restore_flags(uint32_t sr)
+{
+ write_c0_status(sr);
+}
+
+/*
+ * The n64 implementations are simple, the o32 implementations when they
+ * are added, will have to disable interrupts and enable KX before doing
+ * 64 bit ops.
+ */
+static inline uint32_t
+nlm_read_reg(uint64_t base, uint32_t reg)
+{
+ volatile uint32_t *addr = (volatile uint32_t *)(long)base + reg;
+
+ return *addr;
+}
+
+static inline void
+nlm_write_reg(uint64_t base, uint32_t reg, uint32_t val)
+{
+ volatile uint32_t *addr = (volatile uint32_t *)(long)base + reg;
+
+ *addr = val;
+}
+
+static inline uint64_t
+nlm_read_reg64(uint64_t base, uint32_t reg)
+{
+ uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
+ volatile uint64_t *ptr = (volatile uint64_t *)(long)addr;
+
+ return *ptr;
+}
+
+static inline void
+nlm_write_reg64(uint64_t base, uint32_t reg, uint64_t val)
+{
+ uint64_t addr = base + (reg >> 1) * sizeof(uint64_t);
+ volatile uint64_t *ptr = (volatile uint64_t *)(long)addr;
+
+ *ptr = val;
+}
+
+/*
+ * Routines to store 32/64 bit values to 64 bit addresses,
+ * used when going thru XKPHYS to access registers
+ */
+static inline uint32_t
+nlm_read_reg_xkphys(uint64_t base, uint32_t reg)
+{
+ return nlm_read_reg(base, reg);
+}
+
+static inline void
+nlm_write_reg_xkphys(uint64_t base, uint32_t reg, uint32_t val)
+{
+ nlm_write_reg(base, reg, val);
+}
+
+static inline uint64_t
+nlm_read_reg64_xkphys(uint64_t base, uint32_t reg)
+{
+ return nlm_read_reg64(base, reg);
+}
+
+static inline void
+nlm_write_reg64_xkphys(uint64_t base, uint32_t reg, uint64_t val)
+{
+ nlm_write_reg64(base, reg, val);
+}
+
+/* Location where IO base is mapped */
+extern uint64_t nlm_io_base;
+
+#if defined(CONFIG_CPU_XLP)
+static inline uint64_t
+nlm_pcicfg_base(uint32_t devoffset)
+{
+ return nlm_io_base + devoffset;
+}
+
+static inline uint64_t
+nlm_xkphys_map_pcibar0(uint64_t pcibase)
+{
+ uint64_t paddr;
+
+ paddr = nlm_read_reg(pcibase, 0x4) & ~0xfu;
+ return (uint64_t)0x9000000000000000 | paddr;
+}
+#elif defined(CONFIG_CPU_XLR)
+
+static inline uint64_t
+nlm_mmio_base(uint32_t devoffset)
+{
+ return nlm_io_base + devoffset;
+}
+#endif
+
+#endif
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/bridge.h b/arch/mips/include/asm/netlogic/xlp-hal/bridge.h
new file mode 100644
index 000000000000..ca95133f1ad1
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlp-hal/bridge.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NLM_HAL_BRIDGE_H__
+#define __NLM_HAL_BRIDGE_H__
+
+/**
+* @file_name mio.h
+* @author Netlogic Microsystems
+* @brief Basic definitions of XLP memory and io subsystem
+*/
+
+/*
+ * BRIDGE specific registers
+ *
+ * These registers start after the PCIe header, which has 0x40
+ * standard entries
+ */
+#define BRIDGE_MODE 0x00
+#define BRIDGE_PCI_CFG_BASE 0x01
+#define BRIDGE_PCI_CFG_LIMIT 0x02
+#define BRIDGE_PCIE_CFG_BASE 0x03
+#define BRIDGE_PCIE_CFG_LIMIT 0x04
+#define BRIDGE_BUSNUM_BAR0 0x05
+#define BRIDGE_BUSNUM_BAR1 0x06
+#define BRIDGE_BUSNUM_BAR2 0x07
+#define BRIDGE_BUSNUM_BAR3 0x08
+#define BRIDGE_BUSNUM_BAR4 0x09
+#define BRIDGE_BUSNUM_BAR5 0x0a
+#define BRIDGE_BUSNUM_BAR6 0x0b
+#define BRIDGE_FLASH_BAR0 0x0c
+#define BRIDGE_FLASH_BAR1 0x0d
+#define BRIDGE_FLASH_BAR2 0x0e
+#define BRIDGE_FLASH_BAR3 0x0f
+#define BRIDGE_FLASH_LIMIT0 0x10
+#define BRIDGE_FLASH_LIMIT1 0x11
+#define BRIDGE_FLASH_LIMIT2 0x12
+#define BRIDGE_FLASH_LIMIT3 0x13
+
+#define BRIDGE_DRAM_BAR(i) (0x14 + (i))
+#define BRIDGE_DRAM_BAR0 0x14
+#define BRIDGE_DRAM_BAR1 0x15
+#define BRIDGE_DRAM_BAR2 0x16
+#define BRIDGE_DRAM_BAR3 0x17
+#define BRIDGE_DRAM_BAR4 0x18
+#define BRIDGE_DRAM_BAR5 0x19
+#define BRIDGE_DRAM_BAR6 0x1a
+#define BRIDGE_DRAM_BAR7 0x1b
+
+#define BRIDGE_DRAM_LIMIT(i) (0x1c + (i))
+#define BRIDGE_DRAM_LIMIT0 0x1c
+#define BRIDGE_DRAM_LIMIT1 0x1d
+#define BRIDGE_DRAM_LIMIT2 0x1e
+#define BRIDGE_DRAM_LIMIT3 0x1f
+#define BRIDGE_DRAM_LIMIT4 0x20
+#define BRIDGE_DRAM_LIMIT5 0x21
+#define BRIDGE_DRAM_LIMIT6 0x22
+#define BRIDGE_DRAM_LIMIT7 0x23
+
+#define BRIDGE_DRAM_NODE_TRANSLN0 0x24
+#define BRIDGE_DRAM_NODE_TRANSLN1 0x25
+#define BRIDGE_DRAM_NODE_TRANSLN2 0x26
+#define BRIDGE_DRAM_NODE_TRANSLN3 0x27
+#define BRIDGE_DRAM_NODE_TRANSLN4 0x28
+#define BRIDGE_DRAM_NODE_TRANSLN5 0x29
+#define BRIDGE_DRAM_NODE_TRANSLN6 0x2a
+#define BRIDGE_DRAM_NODE_TRANSLN7 0x2b
+#define BRIDGE_DRAM_CHNL_TRANSLN0 0x2c
+#define BRIDGE_DRAM_CHNL_TRANSLN1 0x2d
+#define BRIDGE_DRAM_CHNL_TRANSLN2 0x2e
+#define BRIDGE_DRAM_CHNL_TRANSLN3 0x2f
+#define BRIDGE_DRAM_CHNL_TRANSLN4 0x30
+#define BRIDGE_DRAM_CHNL_TRANSLN5 0x31
+#define BRIDGE_DRAM_CHNL_TRANSLN6 0x32
+#define BRIDGE_DRAM_CHNL_TRANSLN7 0x33
+#define BRIDGE_PCIEMEM_BASE0 0x34
+#define BRIDGE_PCIEMEM_BASE1 0x35
+#define BRIDGE_PCIEMEM_BASE2 0x36
+#define BRIDGE_PCIEMEM_BASE3 0x37
+#define BRIDGE_PCIEMEM_LIMIT0 0x38
+#define BRIDGE_PCIEMEM_LIMIT1 0x39
+#define BRIDGE_PCIEMEM_LIMIT2 0x3a
+#define BRIDGE_PCIEMEM_LIMIT3 0x3b
+#define BRIDGE_PCIEIO_BASE0 0x3c
+#define BRIDGE_PCIEIO_BASE1 0x3d
+#define BRIDGE_PCIEIO_BASE2 0x3e
+#define BRIDGE_PCIEIO_BASE3 0x3f
+#define BRIDGE_PCIEIO_LIMIT0 0x40
+#define BRIDGE_PCIEIO_LIMIT1 0x41
+#define BRIDGE_PCIEIO_LIMIT2 0x42
+#define BRIDGE_PCIEIO_LIMIT3 0x43
+#define BRIDGE_PCIEMEM_BASE4 0x44
+#define BRIDGE_PCIEMEM_BASE5 0x45
+#define BRIDGE_PCIEMEM_BASE6 0x46
+#define BRIDGE_PCIEMEM_LIMIT4 0x47
+#define BRIDGE_PCIEMEM_LIMIT5 0x48
+#define BRIDGE_PCIEMEM_LIMIT6 0x49
+#define BRIDGE_PCIEIO_BASE4 0x4a
+#define BRIDGE_PCIEIO_BASE5 0x4b
+#define BRIDGE_PCIEIO_BASE6 0x4c
+#define BRIDGE_PCIEIO_LIMIT4 0x4d
+#define BRIDGE_PCIEIO_LIMIT5 0x4e
+#define BRIDGE_PCIEIO_LIMIT6 0x4f
+#define BRIDGE_NBU_EVENT_CNT_CTL 0x50
+#define BRIDGE_EVNTCTR1_LOW 0x51
+#define BRIDGE_EVNTCTR1_HI 0x52
+#define BRIDGE_EVNT_CNT_CTL2 0x53
+#define BRIDGE_EVNTCTR2_LOW 0x54
+#define BRIDGE_EVNTCTR2_HI 0x55
+#define BRIDGE_TRACEBUF_MATCH0 0x56
+#define BRIDGE_TRACEBUF_MATCH1 0x57
+#define BRIDGE_TRACEBUF_MATCH_LOW 0x58
+#define BRIDGE_TRACEBUF_MATCH_HI 0x59
+#define BRIDGE_TRACEBUF_CTRL 0x5a
+#define BRIDGE_TRACEBUF_INIT 0x5b
+#define BRIDGE_TRACEBUF_ACCESS 0x5c
+#define BRIDGE_TRACEBUF_READ_DATA0 0x5d
+#define BRIDGE_TRACEBUF_READ_DATA1 0x5d
+#define BRIDGE_TRACEBUF_READ_DATA2 0x5f
+#define BRIDGE_TRACEBUF_READ_DATA3 0x60
+#define BRIDGE_TRACEBUF_STATUS 0x61
+#define BRIDGE_ADDRESS_ERROR0 0x62
+#define BRIDGE_ADDRESS_ERROR1 0x63
+#define BRIDGE_ADDRESS_ERROR2 0x64
+#define BRIDGE_TAG_ECC_ADDR_ERROR0 0x65
+#define BRIDGE_TAG_ECC_ADDR_ERROR1 0x66
+#define BRIDGE_TAG_ECC_ADDR_ERROR2 0x67
+#define BRIDGE_LINE_FLUSH0 0x68
+#define BRIDGE_LINE_FLUSH1 0x69
+#define BRIDGE_NODE_ID 0x6a
+#define BRIDGE_ERROR_INTERRUPT_EN 0x6b
+#define BRIDGE_PCIE0_WEIGHT 0x2c0
+#define BRIDGE_PCIE1_WEIGHT 0x2c1
+#define BRIDGE_PCIE2_WEIGHT 0x2c2
+#define BRIDGE_PCIE3_WEIGHT 0x2c3
+#define BRIDGE_USB_WEIGHT 0x2c4
+#define BRIDGE_NET_WEIGHT 0x2c5
+#define BRIDGE_POE_WEIGHT 0x2c6
+#define BRIDGE_CMS_WEIGHT 0x2c7
+#define BRIDGE_DMAENG_WEIGHT 0x2c8
+#define BRIDGE_SEC_WEIGHT 0x2c9
+#define BRIDGE_COMP_WEIGHT 0x2ca
+#define BRIDGE_GIO_WEIGHT 0x2cb
+#define BRIDGE_FLASH_WEIGHT 0x2cc
+
+#ifndef __ASSEMBLY__
+
+#define nlm_read_bridge_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_bridge_reg(b, r, v) nlm_write_reg(b, r, v)
+#define nlm_get_bridge_pcibase(node) \
+ nlm_pcicfg_base(XLP_IO_BRIDGE_OFFSET(node))
+#define nlm_get_bridge_regbase(node) \
+ (nlm_get_bridge_pcibase(node) + XLP_IO_PCI_HDRSZ)
+
+#endif /* __ASSEMBLY__ */
+#endif /* __NLM_HAL_BRIDGE_H__ */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
new file mode 100644
index 000000000000..bf7d41deb9be
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NLM_HAL_CPUCONTROL_H__
+#define __NLM_HAL_CPUCONTROL_H__
+
+#define CPU_BLOCKID_IFU 0
+#define CPU_BLOCKID_ICU 1
+#define CPU_BLOCKID_IEU 2
+#define CPU_BLOCKID_LSU 3
+#define CPU_BLOCKID_MMU 4
+#define CPU_BLOCKID_PRF 5
+#define CPU_BLOCKID_SCH 7
+#define CPU_BLOCKID_SCU 8
+#define CPU_BLOCKID_FPU 9
+#define CPU_BLOCKID_MAP 10
+
+#define LSU_DEFEATURE 0x304
+#define LSU_CERRLOG_REGID 0x09
+#define SCHED_DEFEATURE 0x700
+
+/* Offsets of interest from the 'MAP' Block */
+#define MAP_THREADMODE 0x00
+#define MAP_EXT_EBASE_ENABLE 0x04
+#define MAP_CCDI_CONFIG 0x08
+#define MAP_THRD0_CCDI_STATUS 0x0c
+#define MAP_THRD1_CCDI_STATUS 0x10
+#define MAP_THRD2_CCDI_STATUS 0x14
+#define MAP_THRD3_CCDI_STATUS 0x18
+#define MAP_THRD0_DEBUG_MODE 0x1c
+#define MAP_THRD1_DEBUG_MODE 0x20
+#define MAP_THRD2_DEBUG_MODE 0x24
+#define MAP_THRD3_DEBUG_MODE 0x28
+#define MAP_MISC_STATE 0x60
+#define MAP_DEBUG_READ_CTL 0x64
+#define MAP_DEBUG_READ_REG0 0x68
+#define MAP_DEBUG_READ_REG1 0x6c
+
+#define MMU_SETUP 0x400
+#define MMU_LFSRSEED 0x401
+#define MMU_HPW_NUM_PAGE_LVL 0x410
+#define MMU_PGWKR_PGDBASE 0x411
+#define MMU_PGWKR_PGDSHFT 0x412
+#define MMU_PGWKR_PGDMASK 0x413
+#define MMU_PGWKR_PUDSHFT 0x414
+#define MMU_PGWKR_PUDMASK 0x415
+#define MMU_PGWKR_PMDSHFT 0x416
+#define MMU_PGWKR_PMDMASK 0x417
+#define MMU_PGWKR_PTESHFT 0x418
+#define MMU_PGWKR_PTEMASK 0x419
+
+#endif /* __NLM_CPUCONTROL_H__ */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/iomap.h b/arch/mips/include/asm/netlogic/xlp-hal/iomap.h
new file mode 100644
index 000000000000..86cc3391e50c
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlp-hal/iomap.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NLM_HAL_IOMAP_H__
+#define __NLM_HAL_IOMAP_H__
+
+#define XLP_DEFAULT_IO_BASE 0x18000000
+#define NMI_BASE 0xbfc00000
+#define XLP_IO_CLK 133333333
+
+#define XLP_PCIE_CFG_SIZE 0x1000 /* 4K */
+#define XLP_PCIE_DEV_BLK_SIZE (8 * XLP_PCIE_CFG_SIZE)
+#define XLP_PCIE_BUS_BLK_SIZE (256 * XLP_PCIE_DEV_BLK_SIZE)
+#define XLP_IO_SIZE (64 << 20) /* ECFG space size */
+#define XLP_IO_PCI_HDRSZ 0x100
+#define XLP_IO_DEV(node, dev) ((dev) + (node) * 8)
+#define XLP_HDR_OFFSET(node, bus, dev, fn) (((bus) << 20) | \
+ ((XLP_IO_DEV(node, dev)) << 15) | ((fn) << 12))
+
+#define XLP_IO_BRIDGE_OFFSET(node) XLP_HDR_OFFSET(node, 0, 0, 0)
+/* coherent inter chip */
+#define XLP_IO_CIC0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 0, 1)
+#define XLP_IO_CIC1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 0, 2)
+#define XLP_IO_CIC2_OFFSET(node) XLP_HDR_OFFSET(node, 0, 0, 3)
+#define XLP_IO_PIC_OFFSET(node) XLP_HDR_OFFSET(node, 0, 0, 4)
+
+#define XLP_IO_PCIE_OFFSET(node, i) XLP_HDR_OFFSET(node, 0, 1, i)
+#define XLP_IO_PCIE0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 1, 0)
+#define XLP_IO_PCIE1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 1, 1)
+#define XLP_IO_PCIE2_OFFSET(node) XLP_HDR_OFFSET(node, 0, 1, 2)
+#define XLP_IO_PCIE3_OFFSET(node) XLP_HDR_OFFSET(node, 0, 1, 3)
+
+#define XLP_IO_USB_OFFSET(node, i) XLP_HDR_OFFSET(node, 0, 2, i)
+#define XLP_IO_USB_EHCI0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 0)
+#define XLP_IO_USB_OHCI0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 1)
+#define XLP_IO_USB_OHCI1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 2)
+#define XLP_IO_USB_EHCI1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 3)
+#define XLP_IO_USB_OHCI2_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 4)
+#define XLP_IO_USB_OHCI3_OFFSET(node) XLP_HDR_OFFSET(node, 0, 2, 5)
+
+#define XLP_IO_NAE_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 0)
+#define XLP_IO_POE_OFFSET(node) XLP_HDR_OFFSET(node, 0, 3, 1)
+
+#define XLP_IO_CMS_OFFSET(node) XLP_HDR_OFFSET(node, 0, 4, 0)
+
+#define XLP_IO_DMA_OFFSET(node) XLP_HDR_OFFSET(node, 0, 5, 1)
+#define XLP_IO_SEC_OFFSET(node) XLP_HDR_OFFSET(node, 0, 5, 2)
+#define XLP_IO_CMP_OFFSET(node) XLP_HDR_OFFSET(node, 0, 5, 3)
+
+#define XLP_IO_UART_OFFSET(node, i) XLP_HDR_OFFSET(node, 0, 6, i)
+#define XLP_IO_UART0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 0)
+#define XLP_IO_UART1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 1)
+#define XLP_IO_I2C_OFFSET(node, i) XLP_HDR_OFFSET(node, 0, 6, 2 + i)
+#define XLP_IO_I2C0_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 2)
+#define XLP_IO_I2C1_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 3)
+#define XLP_IO_GPIO_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 4)
+/* system management */
+#define XLP_IO_SYS_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 5)
+#define XLP_IO_JTAG_OFFSET(node) XLP_HDR_OFFSET(node, 0, 6, 6)
+
+#define XLP_IO_NOR_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 0)
+#define XLP_IO_NAND_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 1)
+#define XLP_IO_SPI_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 2)
+/* SD flash */
+#define XLP_IO_SD_OFFSET(node) XLP_HDR_OFFSET(node, 0, 7, 3)
+#define XLP_IO_MMC_OFFSET(node, slot) \
+ ((XLP_IO_SD_OFFSET(node))+(slot*0x100)+XLP_IO_PCI_HDRSZ)
+
+/* PCI config header register id's */
+#define XLP_PCI_CFGREG0 0x00
+#define XLP_PCI_CFGREG1 0x01
+#define XLP_PCI_CFGREG2 0x02
+#define XLP_PCI_CFGREG3 0x03
+#define XLP_PCI_CFGREG4 0x04
+#define XLP_PCI_CFGREG5 0x05
+#define XLP_PCI_DEVINFO_REG0 0x30
+#define XLP_PCI_DEVINFO_REG1 0x31
+#define XLP_PCI_DEVINFO_REG2 0x32
+#define XLP_PCI_DEVINFO_REG3 0x33
+#define XLP_PCI_DEVINFO_REG4 0x34
+#define XLP_PCI_DEVINFO_REG5 0x35
+#define XLP_PCI_DEVINFO_REG6 0x36
+#define XLP_PCI_DEVINFO_REG7 0x37
+#define XLP_PCI_DEVSCRATCH_REG0 0x38
+#define XLP_PCI_DEVSCRATCH_REG1 0x39
+#define XLP_PCI_DEVSCRATCH_REG2 0x3a
+#define XLP_PCI_DEVSCRATCH_REG3 0x3b
+#define XLP_PCI_MSGSTN_REG 0x3c
+#define XLP_PCI_IRTINFO_REG 0x3d
+#define XLP_PCI_UCODEINFO_REG 0x3e
+#define XLP_PCI_SBB_WT_REG 0x3f
+
+/* PCI IDs for SoC device */
+#define PCI_VENDOR_NETLOGIC 0x184e
+
+#define PCI_DEVICE_ID_NLM_ROOT 0x1001
+#define PCI_DEVICE_ID_NLM_ICI 0x1002
+#define PCI_DEVICE_ID_NLM_PIC 0x1003
+#define PCI_DEVICE_ID_NLM_PCIE 0x1004
+#define PCI_DEVICE_ID_NLM_EHCI 0x1007
+#define PCI_DEVICE_ID_NLM_ILK 0x1008
+#define PCI_DEVICE_ID_NLM_NAE 0x1009
+#define PCI_DEVICE_ID_NLM_POE 0x100A
+#define PCI_DEVICE_ID_NLM_FMN 0x100B
+#define PCI_DEVICE_ID_NLM_RAID 0x100D
+#define PCI_DEVICE_ID_NLM_SAE 0x100D
+#define PCI_DEVICE_ID_NLM_RSA 0x100E
+#define PCI_DEVICE_ID_NLM_CMP 0x100F
+#define PCI_DEVICE_ID_NLM_UART 0x1010
+#define PCI_DEVICE_ID_NLM_I2C 0x1011
+#define PCI_DEVICE_ID_NLM_NOR 0x1015
+#define PCI_DEVICE_ID_NLM_NAND 0x1016
+#define PCI_DEVICE_ID_NLM_MMC 0x1018
+
+#ifndef __ASSEMBLY__
+
+#define nlm_read_pci_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_pci_reg(b, r, v) nlm_write_reg(b, r, v)
+
+#endif /* !__ASSEMBLY */
+
+#endif /* __NLM_HAL_IOMAP_H__ */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
new file mode 100644
index 000000000000..b6628f7ccf74
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
@@ -0,0 +1,411 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _NLM_HAL_PIC_H
+#define _NLM_HAL_PIC_H
+
+/* PIC Specific registers */
+#define PIC_CTRL 0x00
+
+/* PIC control register defines */
+#define PIC_CTRL_ITV 32 /* interrupt timeout value */
+#define PIC_CTRL_ICI 19 /* ICI interrupt timeout enable */
+#define PIC_CTRL_ITE 18 /* interrupt timeout enable */
+#define PIC_CTRL_STE 10 /* system timer interrupt enable */
+#define PIC_CTRL_WWR1 8 /* watchdog 1 wraparound count for reset */
+#define PIC_CTRL_WWR0 6 /* watchdog 0 wraparound count for reset */
+#define PIC_CTRL_WWN1 4 /* watchdog 1 wraparound count for NMI */
+#define PIC_CTRL_WWN0 2 /* watchdog 0 wraparound count for NMI */
+#define PIC_CTRL_WTE 0 /* watchdog timer enable */
+
+/* PIC Status register defines */
+#define PIC_ICI_STATUS 33 /* ICI interrupt timeout status */
+#define PIC_ITE_STATUS 32 /* interrupt timeout status */
+#define PIC_STS_STATUS 4 /* System timer interrupt status */
+#define PIC_WNS_STATUS 2 /* NMI status for watchdog timers */
+#define PIC_WIS_STATUS 0 /* Interrupt status for watchdog timers */
+
+/* PIC IPI control register offsets */
+#define PIC_IPICTRL_NMI 32
+#define PIC_IPICTRL_RIV 20 /* received interrupt vector */
+#define PIC_IPICTRL_IDB 16 /* interrupt destination base */
+#define PIC_IPICTRL_DTE 0 /* interrupt destination thread enables */
+
+/* PIC IRT register offsets */
+#define PIC_IRT_ENABLE 31
+#define PIC_IRT_NMI 29
+#define PIC_IRT_SCH 28 /* Scheduling scheme */
+#define PIC_IRT_RVEC 20 /* Interrupt receive vectors */
+#define PIC_IRT_DT 19 /* Destination type */
+#define PIC_IRT_DB 16 /* Destination base */
+#define PIC_IRT_DTE 0 /* Destination thread enables */
+
+#define PIC_BYTESWAP 0x02
+#define PIC_STATUS 0x04
+#define PIC_INTR_TIMEOUT 0x06
+#define PIC_ICI0_INTR_TIMEOUT 0x08
+#define PIC_ICI1_INTR_TIMEOUT 0x0a
+#define PIC_ICI2_INTR_TIMEOUT 0x0c
+#define PIC_IPI_CTL 0x0e
+#define PIC_INT_ACK 0x10
+#define PIC_INT_PENDING0 0x12
+#define PIC_INT_PENDING1 0x14
+#define PIC_INT_PENDING2 0x16
+
+#define PIC_WDOG0_MAXVAL 0x18
+#define PIC_WDOG0_COUNT 0x1a
+#define PIC_WDOG0_ENABLE0 0x1c
+#define PIC_WDOG0_ENABLE1 0x1e
+#define PIC_WDOG0_BEATCMD 0x20
+#define PIC_WDOG0_BEAT0 0x22
+#define PIC_WDOG0_BEAT1 0x24
+
+#define PIC_WDOG1_MAXVAL 0x26
+#define PIC_WDOG1_COUNT 0x28
+#define PIC_WDOG1_ENABLE0 0x2a
+#define PIC_WDOG1_ENABLE1 0x2c
+#define PIC_WDOG1_BEATCMD 0x2e
+#define PIC_WDOG1_BEAT0 0x30
+#define PIC_WDOG1_BEAT1 0x32
+
+#define PIC_WDOG_MAXVAL(i) (PIC_WDOG0_MAXVAL + ((i) ? 7 : 0))
+#define PIC_WDOG_COUNT(i) (PIC_WDOG0_COUNT + ((i) ? 7 : 0))
+#define PIC_WDOG_ENABLE0(i) (PIC_WDOG0_ENABLE0 + ((i) ? 7 : 0))
+#define PIC_WDOG_ENABLE1(i) (PIC_WDOG0_ENABLE1 + ((i) ? 7 : 0))
+#define PIC_WDOG_BEATCMD(i) (PIC_WDOG0_BEATCMD + ((i) ? 7 : 0))
+#define PIC_WDOG_BEAT0(i) (PIC_WDOG0_BEAT0 + ((i) ? 7 : 0))
+#define PIC_WDOG_BEAT1(i) (PIC_WDOG0_BEAT1 + ((i) ? 7 : 0))
+
+#define PIC_TIMER0_MAXVAL 0x34
+#define PIC_TIMER1_MAXVAL 0x36
+#define PIC_TIMER2_MAXVAL 0x38
+#define PIC_TIMER3_MAXVAL 0x3a
+#define PIC_TIMER4_MAXVAL 0x3c
+#define PIC_TIMER5_MAXVAL 0x3e
+#define PIC_TIMER6_MAXVAL 0x40
+#define PIC_TIMER7_MAXVAL 0x42
+#define PIC_TIMER_MAXVAL(i) (PIC_TIMER0_MAXVAL + ((i) * 2))
+
+#define PIC_TIMER0_COUNT 0x44
+#define PIC_TIMER1_COUNT 0x46
+#define PIC_TIMER2_COUNT 0x48
+#define PIC_TIMER3_COUNT 0x4a
+#define PIC_TIMER4_COUNT 0x4c
+#define PIC_TIMER5_COUNT 0x4e
+#define PIC_TIMER6_COUNT 0x50
+#define PIC_TIMER7_COUNT 0x52
+#define PIC_TIMER_COUNT(i) (PIC_TIMER0_COUNT + ((i) * 2))
+
+#define PIC_ITE0_N0_N1 0x54
+#define PIC_ITE1_N0_N1 0x58
+#define PIC_ITE2_N0_N1 0x5c
+#define PIC_ITE3_N0_N1 0x60
+#define PIC_ITE4_N0_N1 0x64
+#define PIC_ITE5_N0_N1 0x68
+#define PIC_ITE6_N0_N1 0x6c
+#define PIC_ITE7_N0_N1 0x70
+#define PIC_ITE_N0_N1(i) (PIC_ITE0_N0_N1 + ((i) * 4))
+
+#define PIC_ITE0_N2_N3 0x56
+#define PIC_ITE1_N2_N3 0x5a
+#define PIC_ITE2_N2_N3 0x5e
+#define PIC_ITE3_N2_N3 0x62
+#define PIC_ITE4_N2_N3 0x66
+#define PIC_ITE5_N2_N3 0x6a
+#define PIC_ITE6_N2_N3 0x6e
+#define PIC_ITE7_N2_N3 0x72
+#define PIC_ITE_N2_N3(i) (PIC_ITE0_N2_N3 + ((i) * 4))
+
+#define PIC_IRT0 0x74
+#define PIC_IRT(i) (PIC_IRT0 + ((i) * 2))
+
+#define TIMER_CYCLES_MAXVAL 0xffffffffffffffffULL
+
+/*
+ * IRT Map
+ */
+#define PIC_NUM_IRTS 160
+
+#define PIC_IRT_WD_0_INDEX 0
+#define PIC_IRT_WD_1_INDEX 1
+#define PIC_IRT_WD_NMI_0_INDEX 2
+#define PIC_IRT_WD_NMI_1_INDEX 3
+#define PIC_IRT_TIMER_0_INDEX 4
+#define PIC_IRT_TIMER_1_INDEX 5
+#define PIC_IRT_TIMER_2_INDEX 6
+#define PIC_IRT_TIMER_3_INDEX 7
+#define PIC_IRT_TIMER_4_INDEX 8
+#define PIC_IRT_TIMER_5_INDEX 9
+#define PIC_IRT_TIMER_6_INDEX 10
+#define PIC_IRT_TIMER_7_INDEX 11
+#define PIC_IRT_CLOCK_INDEX PIC_IRT_TIMER_7_INDEX
+#define PIC_IRT_TIMER_INDEX(num) ((num) + PIC_IRT_TIMER_0_INDEX)
+
+
+/* 11 and 12 */
+#define PIC_NUM_MSG_Q_IRTS 32
+#define PIC_IRT_MSG_Q0_INDEX 12
+#define PIC_IRT_MSG_Q_INDEX(qid) ((qid) + PIC_IRT_MSG_Q0_INDEX)
+/* 12 to 43 */
+#define PIC_IRT_MSG_0_INDEX 44
+#define PIC_IRT_MSG_1_INDEX 45
+/* 44 and 45 */
+#define PIC_NUM_PCIE_MSIX_IRTS 32
+#define PIC_IRT_PCIE_MSIX_0_INDEX 46
+#define PIC_IRT_PCIE_MSIX_INDEX(num) ((num) + PIC_IRT_PCIE_MSIX_0_INDEX)
+/* 46 to 77 */
+#define PIC_NUM_PCIE_LINK_IRTS 4
+#define PIC_IRT_PCIE_LINK_0_INDEX 78
+#define PIC_IRT_PCIE_LINK_1_INDEX 79
+#define PIC_IRT_PCIE_LINK_2_INDEX 80
+#define PIC_IRT_PCIE_LINK_3_INDEX 81
+#define PIC_IRT_PCIE_LINK_INDEX(num) ((num) + PIC_IRT_PCIE_LINK_0_INDEX)
+/* 78 to 81 */
+#define PIC_NUM_NA_IRTS 32
+/* 82 to 113 */
+#define PIC_IRT_NA_0_INDEX 82
+#define PIC_IRT_NA_INDEX(num) ((num) + PIC_IRT_NA_0_INDEX)
+#define PIC_IRT_POE_INDEX 114
+
+#define PIC_NUM_USB_IRTS 6
+#define PIC_IRT_USB_0_INDEX 115
+#define PIC_IRT_EHCI_0_INDEX 115
+#define PIC_IRT_EHCI_1_INDEX 118
+#define PIC_IRT_USB_INDEX(num) ((num) + PIC_IRT_USB_0_INDEX)
+/* 115 to 120 */
+#define PIC_IRT_GDX_INDEX 121
+#define PIC_IRT_SEC_INDEX 122
+#define PIC_IRT_RSA_INDEX 123
+
+#define PIC_NUM_COMP_IRTS 4
+#define PIC_IRT_COMP_0_INDEX 124
+#define PIC_IRT_COMP_INDEX(num) ((num) + PIC_IRT_COMP_0_INDEX)
+/* 124 to 127 */
+#define PIC_IRT_GBU_INDEX 128
+#define PIC_IRT_ICC_0_INDEX 129 /* ICC - Inter Chip Coherency */
+#define PIC_IRT_ICC_1_INDEX 130
+#define PIC_IRT_ICC_2_INDEX 131
+#define PIC_IRT_CAM_INDEX 132
+#define PIC_IRT_UART_0_INDEX 133
+#define PIC_IRT_UART_1_INDEX 134
+#define PIC_IRT_I2C_0_INDEX 135
+#define PIC_IRT_I2C_1_INDEX 136
+#define PIC_IRT_SYS_0_INDEX 137
+#define PIC_IRT_SYS_1_INDEX 138
+#define PIC_IRT_JTAG_INDEX 139
+#define PIC_IRT_PIC_INDEX 140
+#define PIC_IRT_NBU_INDEX 141
+#define PIC_IRT_TCU_INDEX 142
+#define PIC_IRT_GCU_INDEX 143 /* GBC - Global Coherency */
+#define PIC_IRT_DMC_0_INDEX 144
+#define PIC_IRT_DMC_1_INDEX 145
+
+#define PIC_NUM_GPIO_IRTS 4
+#define PIC_IRT_GPIO_0_INDEX 146
+#define PIC_IRT_GPIO_INDEX(num) ((num) + PIC_IRT_GPIO_0_INDEX)
+
+/* 146 to 149 */
+#define PIC_IRT_NOR_INDEX 150
+#define PIC_IRT_NAND_INDEX 151
+#define PIC_IRT_SPI_INDEX 152
+#define PIC_IRT_MMC_INDEX 153
+
+#define PIC_CLOCK_TIMER 7
+#define PIC_IRQ_BASE 8
+
+#if !defined(LOCORE) && !defined(__ASSEMBLY__)
+
+#define PIC_IRT_FIRST_IRQ (PIC_IRQ_BASE)
+#define PIC_IRT_LAST_IRQ 63
+#define PIC_IRQ_IS_IRT(irq) ((irq) >= PIC_IRT_FIRST_IRQ)
+
+/*
+ * Misc
+ */
+#define PIC_IRT_VALID 1
+#define PIC_LOCAL_SCHEDULING 1
+#define PIC_GLOBAL_SCHEDULING 0
+
+#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r)
+#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v)
+#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
+#define nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ)
+
+/* IRT and h/w interrupt routines */
+static inline int
+nlm_pic_read_irt(uint64_t base, int irt_index)
+{
+ return nlm_read_pic_reg(base, PIC_IRT(irt_index));
+}
+
+static inline uint64_t
+nlm_pic_read_control(uint64_t base)
+{
+ return nlm_read_pic_reg(base, PIC_CTRL);
+}
+
+static inline void
+nlm_pic_write_control(uint64_t base, uint64_t control)
+{
+ nlm_write_pic_reg(base, PIC_CTRL, control);
+}
+
+static inline void
+nlm_pic_update_control(uint64_t base, uint64_t control)
+{
+ uint64_t val;
+
+ val = nlm_read_pic_reg(base, PIC_CTRL);
+ nlm_write_pic_reg(base, PIC_CTRL, control | val);
+}
+
+static inline void
+nlm_set_irt_to_cpu(uint64_t base, int irt, int cpu)
+{
+ uint64_t val;
+
+ val = nlm_read_pic_reg(base, PIC_IRT(irt));
+ val |= cpu & 0xf;
+ if (cpu > 15)
+ val |= 1 << 16;
+ nlm_write_pic_reg(base, PIC_IRT(irt), val);
+}
+
+static inline void
+nlm_pic_write_irt(uint64_t base, int irt_num, int en, int nmi,
+ int sch, int vec, int dt, int db, int dte)
+{
+ uint64_t val;
+
+ val = (((uint64_t)en & 0x1) << 31) | ((nmi & 0x1) << 29) |
+ ((sch & 0x1) << 28) | ((vec & 0x3f) << 20) |
+ ((dt & 0x1) << 19) | ((db & 0x7) << 16) |
+ (dte & 0xffff);
+
+ nlm_write_pic_reg(base, PIC_IRT(irt_num), val);
+}
+
+static inline void
+nlm_pic_write_irt_direct(uint64_t base, int irt_num, int en, int nmi,
+ int sch, int vec, int cpu)
+{
+ nlm_pic_write_irt(base, irt_num, en, nmi, sch, vec, 1,
+ (cpu >> 4), /* thread group */
+ 1 << (cpu & 0xf)); /* thread mask */
+}
+
+static inline uint64_t
+nlm_pic_read_timer(uint64_t base, int timer)
+{
+ return nlm_read_pic_reg(base, PIC_TIMER_COUNT(timer));
+}
+
+static inline void
+nlm_pic_write_timer(uint64_t base, int timer, uint64_t value)
+{
+ nlm_write_pic_reg(base, PIC_TIMER_COUNT(timer), value);
+}
+
+static inline void
+nlm_pic_set_timer(uint64_t base, int timer, uint64_t value, int irq, int cpu)
+{
+ uint64_t pic_ctrl = nlm_read_pic_reg(base, PIC_CTRL);
+ int en;
+
+ en = (irq > 0);
+ nlm_write_pic_reg(base, PIC_TIMER_MAXVAL(timer), value);
+ nlm_pic_write_irt_direct(base, PIC_IRT_TIMER_INDEX(timer),
+ en, 0, 0, irq, cpu);
+
+ /* enable the timer */
+ pic_ctrl |= (1 << (PIC_CTRL_STE + timer));
+ nlm_write_pic_reg(base, PIC_CTRL, pic_ctrl);
+}
+
+static inline void
+nlm_pic_enable_irt(uint64_t base, int irt)
+{
+ uint64_t reg;
+
+ reg = nlm_read_pic_reg(base, PIC_IRT(irt));
+ nlm_write_pic_reg(base, PIC_IRT(irt), reg | (1u << 31));
+}
+
+static inline void
+nlm_pic_disable_irt(uint64_t base, int irt)
+{
+ uint32_t reg;
+
+ reg = nlm_read_pic_reg(base, PIC_IRT(irt));
+ nlm_write_pic_reg(base, PIC_IRT(irt), reg & ~((uint64_t)1 << 31));
+}
+
+static inline void
+nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi)
+{
+ uint64_t ipi;
+ int node, ncpu;
+
+ node = hwt / 32;
+ ncpu = hwt & 0x1f;
+ ipi = ((uint64_t)nmi << 31) | (irq << 20) | (node << 17) |
+ (1 << (ncpu & 0xf));
+ if (ncpu > 15)
+ ipi |= 0x10000; /* Setting bit 16 to select cpus 16-31 */
+
+ nlm_write_pic_reg(base, PIC_IPI_CTL, ipi);
+}
+
+static inline void
+nlm_pic_ack(uint64_t base, int irt_num)
+{
+ nlm_write_pic_reg(base, PIC_INT_ACK, irt_num);
+
+ /* Ack the Status register for Watchdog & System timers */
+ if (irt_num < 12)
+ nlm_write_pic_reg(base, PIC_STATUS, (1 << irt_num));
+}
+
+static inline void
+nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
+{
+ nlm_pic_write_irt_direct(base, irt, 0, 0, 0, irq, 0);
+}
+
+extern uint64_t nlm_pic_base;
+int nlm_irq_to_irt(int irq);
+int nlm_irt_to_irq(int irt);
+
+#endif /* __ASSEMBLY__ */
+#endif /* _NLM_HAL_PIC_H */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/sys.h b/arch/mips/include/asm/netlogic/xlp-hal/sys.h
new file mode 100644
index 000000000000..21432f7d89b9
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlp-hal/sys.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __NLM_HAL_SYS_H__
+#define __NLM_HAL_SYS_H__
+
+/**
+* @file_name sys.h
+* @author Netlogic Microsystems
+* @brief HAL for System configuration registers
+*/
+#define SYS_CHIP_RESET 0x00
+#define SYS_POWER_ON_RESET_CFG 0x01
+#define SYS_EFUSE_DEVICE_CFG_STATUS0 0x02
+#define SYS_EFUSE_DEVICE_CFG_STATUS1 0x03
+#define SYS_EFUSE_DEVICE_CFG_STATUS2 0x04
+#define SYS_EFUSE_DEVICE_CFG3 0x05
+#define SYS_EFUSE_DEVICE_CFG4 0x06
+#define SYS_EFUSE_DEVICE_CFG5 0x07
+#define SYS_EFUSE_DEVICE_CFG6 0x08
+#define SYS_EFUSE_DEVICE_CFG7 0x09
+#define SYS_PLL_CTRL 0x0a
+#define SYS_CPU_RESET 0x0b
+#define SYS_CPU_NONCOHERENT_MODE 0x0d
+#define SYS_CORE_DFS_DIS_CTRL 0x0e
+#define SYS_CORE_DFS_RST_CTRL 0x0f
+#define SYS_CORE_DFS_BYP_CTRL 0x10
+#define SYS_CORE_DFS_PHA_CTRL 0x11
+#define SYS_CORE_DFS_DIV_INC_CTRL 0x12
+#define SYS_CORE_DFS_DIV_DEC_CTRL 0x13
+#define SYS_CORE_DFS_DIV_VALUE 0x14
+#define SYS_RESET 0x15
+#define SYS_DFS_DIS_CTRL 0x16
+#define SYS_DFS_RST_CTRL 0x17
+#define SYS_DFS_BYP_CTRL 0x18
+#define SYS_DFS_DIV_INC_CTRL 0x19
+#define SYS_DFS_DIV_DEC_CTRL 0x1a
+#define SYS_DFS_DIV_VALUE0 0x1b
+#define SYS_DFS_DIV_VALUE1 0x1c
+#define SYS_SENSE_AMP_DLY 0x1d
+#define SYS_SOC_SENSE_AMP_DLY 0x1e
+#define SYS_CTRL0 0x1f
+#define SYS_CTRL1 0x20
+#define SYS_TIMEOUT_BS1 0x21
+#define SYS_BYTE_SWAP 0x22
+#define SYS_VRM_VID 0x23
+#define SYS_PWR_RAM_CMD 0x24
+#define SYS_PWR_RAM_ADDR 0x25
+#define SYS_PWR_RAM_DATA0 0x26
+#define SYS_PWR_RAM_DATA1 0x27
+#define SYS_PWR_RAM_DATA2 0x28
+#define SYS_PWR_UCODE 0x29
+#define SYS_CPU0_PWR_STATUS 0x2a
+#define SYS_CPU1_PWR_STATUS 0x2b
+#define SYS_CPU2_PWR_STATUS 0x2c
+#define SYS_CPU3_PWR_STATUS 0x2d
+#define SYS_CPU4_PWR_STATUS 0x2e
+#define SYS_CPU5_PWR_STATUS 0x2f
+#define SYS_CPU6_PWR_STATUS 0x30
+#define SYS_CPU7_PWR_STATUS 0x31
+#define SYS_STATUS 0x32
+#define SYS_INT_POL 0x33
+#define SYS_INT_TYPE 0x34
+#define SYS_INT_STATUS 0x35
+#define SYS_INT_MASK0 0x36
+#define SYS_INT_MASK1 0x37
+#define SYS_UCO_S_ECC 0x38
+#define SYS_UCO_M_ECC 0x39
+#define SYS_UCO_ADDR 0x3a
+#define SYS_UCO_INSTR 0x3b
+#define SYS_MEM_BIST0 0x3c
+#define SYS_MEM_BIST1 0x3d
+#define SYS_MEM_BIST2 0x3e
+#define SYS_MEM_BIST3 0x3f
+#define SYS_MEM_BIST4 0x40
+#define SYS_MEM_BIST5 0x41
+#define SYS_MEM_BIST6 0x42
+#define SYS_MEM_BIST7 0x43
+#define SYS_MEM_BIST8 0x44
+#define SYS_MEM_BIST9 0x45
+#define SYS_MEM_BIST10 0x46
+#define SYS_MEM_BIST11 0x47
+#define SYS_MEM_BIST12 0x48
+#define SYS_SCRTCH0 0x49
+#define SYS_SCRTCH1 0x4a
+#define SYS_SCRTCH2 0x4b
+#define SYS_SCRTCH3 0x4c
+
+#ifndef __ASSEMBLY__
+
+#define nlm_read_sys_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_sys_reg(b, r, v) nlm_write_reg(b, r, v)
+#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
+#define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
+
+extern uint64_t nlm_sys_base;
+#endif
+#endif
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/uart.h b/arch/mips/include/asm/netlogic/xlp-hal/uart.h
new file mode 100644
index 000000000000..6a7046ca094d
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlp-hal/uart.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __XLP_HAL_UART_H__
+#define __XLP_HAL_UART_H__
+
+/* UART Specific registers */
+#define UART_RX_DATA 0x00
+#define UART_TX_DATA 0x00
+
+#define UART_INT_EN 0x01
+#define UART_INT_ID 0x02
+#define UART_FIFO_CTL 0x02
+#define UART_LINE_CTL 0x03
+#define UART_MODEM_CTL 0x04
+#define UART_LINE_STS 0x05
+#define UART_MODEM_STS 0x06
+
+#define UART_DIVISOR0 0x00
+#define UART_DIVISOR1 0x01
+
+#define BASE_BAUD (XLP_IO_CLK/16)
+#define BAUD_DIVISOR(baud) (BASE_BAUD / baud)
+
+/* LCR mask values */
+#define LCR_5BITS 0x00
+#define LCR_6BITS 0x01
+#define LCR_7BITS 0x02
+#define LCR_8BITS 0x03
+#define LCR_STOPB 0x04
+#define LCR_PENAB 0x08
+#define LCR_PODD 0x00
+#define LCR_PEVEN 0x10
+#define LCR_PONE 0x20
+#define LCR_PZERO 0x30
+#define LCR_SBREAK 0x40
+#define LCR_EFR_ENABLE 0xbf
+#define LCR_DLAB 0x80
+
+/* MCR mask values */
+#define MCR_DTR 0x01
+#define MCR_RTS 0x02
+#define MCR_DRS 0x04
+#define MCR_IE 0x08
+#define MCR_LOOPBACK 0x10
+
+/* FCR mask values */
+#define FCR_RCV_RST 0x02
+#define FCR_XMT_RST 0x04
+#define FCR_RX_LOW 0x00
+#define FCR_RX_MEDL 0x40
+#define FCR_RX_MEDH 0x80
+#define FCR_RX_HIGH 0xc0
+
+/* IER mask values */
+#define IER_ERXRDY 0x1
+#define IER_ETXRDY 0x2
+#define IER_ERLS 0x4
+#define IER_EMSC 0x8
+
+#if !defined(LOCORE) && !defined(__ASSEMBLY__)
+
+#define nlm_read_uart_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_uart_reg(b, r, v) nlm_write_reg(b, r, v)
+#define nlm_get_uart_pcibase(node, inst) \
+ nlm_pcicfg_base(XLP_IO_UART_OFFSET(node, inst))
+#define nlm_get_uart_regbase(node, inst) \
+ (nlm_get_uart_pcibase(node, inst) + XLP_IO_PCI_HDRSZ)
+
+static inline void
+nlm_uart_set_baudrate(uint64_t base, int baud)
+{
+ uint32_t lcr;
+
+ lcr = nlm_read_uart_reg(base, UART_LINE_CTL);
+
+ /* enable divisor register, and write baud values */
+ nlm_write_uart_reg(base, UART_LINE_CTL, lcr | (1 << 7));
+ nlm_write_uart_reg(base, UART_DIVISOR0,
+ (BAUD_DIVISOR(baud) & 0xff));
+ nlm_write_uart_reg(base, UART_DIVISOR1,
+ ((BAUD_DIVISOR(baud) >> 8) & 0xff));
+
+ /* restore default lcr */
+ nlm_write_uart_reg(base, UART_LINE_CTL, lcr);
+}
+
+static inline void
+nlm_uart_outbyte(uint64_t base, char c)
+{
+ uint32_t lsr;
+
+ for (;;) {
+ lsr = nlm_read_uart_reg(base, UART_LINE_STS);
+ if (lsr & 0x20)
+ break;
+ }
+
+ nlm_write_uart_reg(base, UART_TX_DATA, (int)c);
+}
+
+static inline char
+nlm_uart_inbyte(uint64_t base)
+{
+ int data, lsr;
+
+ for (;;) {
+ lsr = nlm_read_uart_reg(base, UART_LINE_STS);
+ if (lsr & 0x80) { /* parity/frame/break-error - push a zero */
+ data = 0;
+ break;
+ }
+ if (lsr & 0x01) { /* Rx data */
+ data = nlm_read_uart_reg(base, UART_RX_DATA);
+ break;
+ }
+ }
+
+ return (char)data;
+}
+
+static inline int
+nlm_uart_init(uint64_t base, int baud, int databits, int stopbits,
+ int parity, int int_en, int loopback)
+{
+ uint32_t lcr;
+
+ lcr = 0;
+ if (databits >= 8)
+ lcr |= LCR_8BITS;
+ else if (databits == 7)
+ lcr |= LCR_7BITS;
+ else if (databits == 6)
+ lcr |= LCR_6BITS;
+ else
+ lcr |= LCR_5BITS;
+
+ if (stopbits > 1)
+ lcr |= LCR_STOPB;
+
+ lcr |= parity << 3;
+
+ /* setup default lcr */
+ nlm_write_uart_reg(base, UART_LINE_CTL, lcr);
+
+ /* Reset the FIFOs */
+ nlm_write_uart_reg(base, UART_LINE_CTL, FCR_RCV_RST | FCR_XMT_RST);
+
+ nlm_uart_set_baudrate(base, baud);
+
+ if (loopback)
+ nlm_write_uart_reg(base, UART_MODEM_CTL, 0x1f);
+
+ if (int_en)
+ nlm_write_uart_reg(base, UART_INT_EN, IER_ERXRDY | IER_ETXRDY);
+
+ return 0;
+}
+#endif /* !LOCORE && !__ASSEMBLY__ */
+#endif /* __XLP_HAL_UART_H__ */
diff --git a/arch/mips/netlogic/xlr/xlr_console.c b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
index 759df0692201..1540588e396d 100644
--- a/arch/mips/netlogic/xlr/xlr_console.c
+++ b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
@@ -32,15 +32,20 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <linux/types.h>
-#include <asm/netlogic/xlr/iomap.h>
+#ifndef _NLM_HAL_XLP_H
+#define _NLM_HAL_XLP_H
-void prom_putchar(char c)
-{
- nlm_reg_t *mmio;
+#define PIC_UART_0_IRQ 17
+#define PIC_UART_1_IRQ 18
- mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
- while (netlogic_read_reg(mmio, 0x5) == 0)
- ;
- netlogic_write_reg(mmio, 0x0, c);
-}
+#ifndef __ASSEMBLY__
+
+/* SMP support functions */
+void xlp_boot_core0_siblings(void);
+void xlp_wakeup_secondary_cpus(void);
+
+void xlp_mmu_init(void);
+void nlm_hal_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_NLM_XLP_H */
diff --git a/arch/mips/include/asm/netlogic/xlr/iomap.h b/arch/mips/include/asm/netlogic/xlr/iomap.h
index 2e3a4dd53045..2e768f032e83 100644
--- a/arch/mips/include/asm/netlogic/xlr/iomap.h
+++ b/arch/mips/include/asm/netlogic/xlr/iomap.h
@@ -106,26 +106,4 @@
#define DEFAULT_HT_TYPE0_CFG_BASE 0x16000000
#define DEFAULT_HT_TYPE1_CFG_BASE 0x17000000
-#ifndef __ASSEMBLY__
-#include <linux/types.h>
-#include <asm/byteorder.h>
-
-typedef volatile __u32 nlm_reg_t;
-extern unsigned long netlogic_io_base;
-
-/* FIXME read once in write_reg */
-#ifdef CONFIG_CPU_LITTLE_ENDIAN
-#define netlogic_read_reg(base, offset) ((base)[(offset)])
-#define netlogic_write_reg(base, offset, value) ((base)[(offset)] = (value))
-#else
-#define netlogic_read_reg(base, offset) (be32_to_cpu((base)[(offset)]))
-#define netlogic_write_reg(base, offset, value) \
- ((base)[(offset)] = cpu_to_be32((value)))
-#endif
-
-#define netlogic_read_reg_le32(base, offset) (le32_to_cpu((base)[(offset)]))
-#define netlogic_write_reg_le32(base, offset, value) \
- ((base)[(offset)] = cpu_to_le32((value)))
-#define netlogic_io_mmio(offset) ((nlm_reg_t *)(netlogic_io_base+(offset)))
-#endif /* __ASSEMBLY__ */
#endif
diff --git a/arch/mips/include/asm/netlogic/xlr/msidef.h b/arch/mips/include/asm/netlogic/xlr/msidef.h
new file mode 100644
index 000000000000..7e39d40be4f5
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlr/msidef.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef ASM_RMI_MSIDEF_H
+#define ASM_RMI_MSIDEF_H
+
+/*
+ * Constants for Intel APIC based MSI messages.
+ * Adapted for the RMI XLR using identical defines
+ */
+
+/*
+ * Shifts for MSI data
+ */
+
+#define MSI_DATA_VECTOR_SHIFT 0
+#define MSI_DATA_VECTOR_MASK 0x000000ff
+#define MSI_DATA_VECTOR(v) (((v) << MSI_DATA_VECTOR_SHIFT) & \
+ MSI_DATA_VECTOR_MASK)
+
+#define MSI_DATA_DELIVERY_MODE_SHIFT 8
+#define MSI_DATA_DELIVERY_FIXED (0 << MSI_DATA_DELIVERY_MODE_SHIFT)
+#define MSI_DATA_DELIVERY_LOWPRI (1 << MSI_DATA_DELIVERY_MODE_SHIFT)
+
+#define MSI_DATA_LEVEL_SHIFT 14
+#define MSI_DATA_LEVEL_DEASSERT (0 << MSI_DATA_LEVEL_SHIFT)
+#define MSI_DATA_LEVEL_ASSERT (1 << MSI_DATA_LEVEL_SHIFT)
+
+#define MSI_DATA_TRIGGER_SHIFT 15
+#define MSI_DATA_TRIGGER_EDGE (0 << MSI_DATA_TRIGGER_SHIFT)
+#define MSI_DATA_TRIGGER_LEVEL (1 << MSI_DATA_TRIGGER_SHIFT)
+
+/*
+ * Shift/mask fields for msi address
+ */
+
+#define MSI_ADDR_BASE_HI 0
+#define MSI_ADDR_BASE_LO 0xfee00000
+
+#define MSI_ADDR_DEST_MODE_SHIFT 2
+#define MSI_ADDR_DEST_MODE_PHYSICAL (0 << MSI_ADDR_DEST_MODE_SHIFT)
+#define MSI_ADDR_DEST_MODE_LOGICAL (1 << MSI_ADDR_DEST_MODE_SHIFT)
+
+#define MSI_ADDR_REDIRECTION_SHIFT 3
+#define MSI_ADDR_REDIRECTION_CPU (0 << MSI_ADDR_REDIRECTION_SHIFT)
+#define MSI_ADDR_REDIRECTION_LOWPRI (1 << MSI_ADDR_REDIRECTION_SHIFT)
+
+#define MSI_ADDR_DEST_ID_SHIFT 12
+#define MSI_ADDR_DEST_ID_MASK 0x00ffff0
+#define MSI_ADDR_DEST_ID(dest) (((dest) << MSI_ADDR_DEST_ID_SHIFT) & \
+ MSI_ADDR_DEST_ID_MASK)
+
+#endif /* ASM_RMI_MSIDEF_H */
diff --git a/arch/mips/include/asm/netlogic/xlr/pic.h b/arch/mips/include/asm/netlogic/xlr/pic.h
index 5cceb746f080..868013e62f32 100644
--- a/arch/mips/include/asm/netlogic/xlr/pic.h
+++ b/arch/mips/include/asm/netlogic/xlr/pic.h
@@ -193,39 +193,72 @@
/* end XLS */
#ifndef __ASSEMBLY__
-static inline void pic_send_ipi(u32 ipi)
+
+#define PIC_IRQ_IS_EDGE_TRIGGERED(irq) (((irq) >= PIC_TIMER_0_IRQ) && \
+ ((irq) <= PIC_TIMER_7_IRQ))
+#define PIC_IRQ_IS_IRT(irq) (((irq) >= PIC_IRT_FIRST_IRQ) && \
+ ((irq) <= PIC_IRT_LAST_IRQ))
+
+static inline int
+nlm_irq_to_irt(int irq)
{
- nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+ if (PIC_IRQ_IS_IRT(irq) == 0)
+ return -1;
- netlogic_write_reg(mmio, PIC_IPI, ipi);
+ return PIC_IRQ_TO_INTR(irq);
}
-static inline u32 pic_read_control(void)
+static inline int
+nlm_irt_to_irq(int irt)
{
- nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
- return netlogic_read_reg(mmio, PIC_CTRL);
+ return PIC_INTR_TO_IRQ(irt);
}
-static inline void pic_write_control(u32 control)
+static inline void
+nlm_pic_enable_irt(uint64_t base, int irt)
{
- nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+ uint32_t reg;
- netlogic_write_reg(mmio, PIC_CTRL, control);
+ reg = nlm_read_reg(base, PIC_IRT_1(irt));
+ nlm_write_reg(base, PIC_IRT_1(irt), reg | (1u << 31));
}
-static inline void pic_update_control(u32 control)
+static inline void
+nlm_pic_disable_irt(uint64_t base, int irt)
{
- nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
+ uint32_t reg;
- netlogic_write_reg(mmio, PIC_CTRL,
- (control | netlogic_read_reg(mmio, PIC_CTRL)));
+ reg = nlm_read_reg(base, PIC_IRT_1(irt));
+ nlm_write_reg(base, PIC_IRT_1(irt), reg & ~(1u << 31));
}
-#define PIC_IRQ_IS_EDGE_TRIGGERED(irq) (((irq) >= PIC_TIMER_0_IRQ) && \
- ((irq) <= PIC_TIMER_7_IRQ))
-#define PIC_IRQ_IS_IRT(irq) (((irq) >= PIC_IRT_FIRST_IRQ) && \
- ((irq) <= PIC_IRT_LAST_IRQ))
-#endif
+static inline void
+nlm_pic_send_ipi(uint64_t base, int hwt, int irq, int nmi)
+{
+ unsigned int tid, pid;
+
+ tid = hwt & 0x3;
+ pid = (hwt >> 2) & 0x07;
+ nlm_write_reg(base, PIC_IPI,
+ (pid << 20) | (tid << 16) | (nmi << 8) | irq);
+}
+
+static inline void
+nlm_pic_ack(uint64_t base, int irt)
+{
+ nlm_write_reg(base, PIC_INT_ACK, 1u << irt);
+}
+static inline void
+nlm_pic_init_irt(uint64_t base, int irt, int irq, int hwt)
+{
+ nlm_write_reg(base, PIC_IRT_0(irt), (1u << hwt));
+ /* local scheduling, invalid, level by default */
+ nlm_write_reg(base, PIC_IRT_1(irt),
+ (1 << 30) | (1 << 6) | irq);
+}
+
+extern uint64_t nlm_pic_base;
+#endif
#endif /* _ASM_NLM_XLR_PIC_H */
diff --git a/arch/mips/include/asm/netlogic/xlr/xlr.h b/arch/mips/include/asm/netlogic/xlr/xlr.h
index 3e6372692a04..ff4a17b0bf78 100644
--- a/arch/mips/include/asm/netlogic/xlr/xlr.h
+++ b/arch/mips/include/asm/netlogic/xlr/xlr.h
@@ -40,17 +40,8 @@ struct uart_port;
unsigned int nlm_xlr_uart_in(struct uart_port *, int);
void nlm_xlr_uart_out(struct uart_port *, int, int);
-/* SMP support functions */
-struct irq_desc;
-void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc);
-void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc);
-int nlm_wakeup_secondary_cpus(u32 wakeup_mask);
-void nlm_smp_irq_init(void);
-void nlm_boot_smp_nmi(void);
-void prom_pre_boot_secondary_cpus(void);
-
-extern struct plat_smp_ops nlm_smp_ops;
-extern unsigned long nlm_common_ebase;
+/* SMP helpers */
+void xlr_wakeup_secondary_cpus(void);
/* XLS B silicon "Rook" */
static inline unsigned int nlm_chip_is_xls_b(void)
diff --git a/drivers/staging/octeon/cvmx-address.h b/arch/mips/include/asm/octeon/cvmx-address.h
index 3c74d826e2e6..3c74d826e2e6 100644
--- a/drivers/staging/octeon/cvmx-address.h
+++ b/arch/mips/include/asm/octeon/cvmx-address.h
diff --git a/drivers/staging/octeon/cvmx-asxx-defs.h b/arch/mips/include/asm/octeon/cvmx-asxx-defs.h
index 91415a85e8d2..91415a85e8d2 100644
--- a/drivers/staging/octeon/cvmx-asxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-asxx-defs.h
diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
index 4e4c3a8282d6..1db1dc2724cb 100644
--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h
+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
@@ -39,7 +39,7 @@
* versions.
*/
#define CVMX_BOOTINFO_MAJ_VER 1
-#define CVMX_BOOTINFO_MIN_VER 2
+#define CVMX_BOOTINFO_MIN_VER 3
#if (CVMX_BOOTINFO_MAJ_VER == 1)
#define CVMX_BOOTINFO_OCTEON_SERIAL_LEN 20
@@ -116,7 +116,13 @@ struct cvmx_bootinfo {
*/
uint32_t config_flags;
#endif
-
+#if (CVMX_BOOTINFO_MIN_VER >= 3)
+ /*
+ * Address of the OF Flattened Device Tree structure
+ * describing the board.
+ */
+ uint64_t fdt_addr;
+#endif
};
#define CVMX_BOOTINFO_CFG_FLAG_PCI_HOST (1ull << 0)
@@ -164,6 +170,22 @@ enum cvmx_board_types_enum {
/* Special 'generic' board type, supports many boards */
CVMX_BOARD_TYPE_GENERIC = 28,
CVMX_BOARD_TYPE_EBH5610 = 29,
+ CVMX_BOARD_TYPE_LANAI2_A = 30,
+ CVMX_BOARD_TYPE_LANAI2_U = 31,
+ CVMX_BOARD_TYPE_EBB5600 = 32,
+ CVMX_BOARD_TYPE_EBB6300 = 33,
+ CVMX_BOARD_TYPE_NIC_XLE_10G = 34,
+ CVMX_BOARD_TYPE_LANAI2_G = 35,
+ CVMX_BOARD_TYPE_EBT5810 = 36,
+ CVMX_BOARD_TYPE_NIC10E = 37,
+ CVMX_BOARD_TYPE_EP6300C = 38,
+ CVMX_BOARD_TYPE_EBB6800 = 39,
+ CVMX_BOARD_TYPE_NIC4E = 40,
+ CVMX_BOARD_TYPE_NIC2E = 41,
+ CVMX_BOARD_TYPE_EBB6600 = 42,
+ CVMX_BOARD_TYPE_REDWING = 43,
+ CVMX_BOARD_TYPE_NIC68_4 = 44,
+ CVMX_BOARD_TYPE_NIC10E_66 = 45,
CVMX_BOARD_TYPE_MAX,
/*
@@ -181,6 +203,23 @@ enum cvmx_board_types_enum {
CVMX_BOARD_TYPE_CUST_NS0216 = 10002,
CVMX_BOARD_TYPE_CUST_NB5 = 10003,
CVMX_BOARD_TYPE_CUST_WMR500 = 10004,
+ CVMX_BOARD_TYPE_CUST_ITB101 = 10005,
+ CVMX_BOARD_TYPE_CUST_NTE102 = 10006,
+ CVMX_BOARD_TYPE_CUST_AGS103 = 10007,
+ CVMX_BOARD_TYPE_CUST_GST104 = 10008,
+ CVMX_BOARD_TYPE_CUST_GCT105 = 10009,
+ CVMX_BOARD_TYPE_CUST_AGS106 = 10010,
+ CVMX_BOARD_TYPE_CUST_SGM107 = 10011,
+ CVMX_BOARD_TYPE_CUST_GCT108 = 10012,
+ CVMX_BOARD_TYPE_CUST_AGS109 = 10013,
+ CVMX_BOARD_TYPE_CUST_GCT110 = 10014,
+ CVMX_BOARD_TYPE_CUST_L2_AIR_SENDER = 10015,
+ CVMX_BOARD_TYPE_CUST_L2_AIR_RECEIVER = 10016,
+ CVMX_BOARD_TYPE_CUST_L2_ACCTON2_TX = 10017,
+ CVMX_BOARD_TYPE_CUST_L2_ACCTON2_RX = 10018,
+ CVMX_BOARD_TYPE_CUST_L2_WSTRNSNIC_TX = 10019,
+ CVMX_BOARD_TYPE_CUST_L2_WSTRNSNIC_RX = 10020,
+ CVMX_BOARD_TYPE_CUST_L2_ZINWELL = 10021,
CVMX_BOARD_TYPE_CUST_DEFINED_MAX = 20000,
/*
@@ -241,6 +280,22 @@ static inline const char *cvmx_board_type_to_string(enum
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CB5200)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_GENERIC)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5610)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_LANAI2_A)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_LANAI2_U)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBB5600)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBB6300)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC_XLE_10G)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_LANAI2_G)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5810)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC10E)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EP6300C)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBB6800)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC4E)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC2E)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBB6600)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_REDWING)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC68_4)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC10E_66)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_MAX)
/* Customer boards listed here */
@@ -249,6 +304,23 @@ static inline const char *cvmx_board_type_to_string(enum
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NS0216)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NB5)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_WMR500)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_ITB101)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NTE102)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_AGS103)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_GST104)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_GCT105)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_AGS106)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_SGM107)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_GCT108)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_AGS109)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_GCT110)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_L2_AIR_SENDER)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_L2_AIR_RECEIVER)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_L2_ACCTON2_TX)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_L2_ACCTON2_RX)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_L2_WSTRNSNIC_TX)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_L2_WSTRNSNIC_RX)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_L2_ZINWELL)
ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DEFINED_MAX)
/* Customer private range */
@@ -265,9 +337,9 @@ static inline const char *cvmx_chip_type_to_string(enum
{
switch (type) {
ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_NULL)
- ENUM_CHIP_TYPE_CASE(CVMX_CHIP_SIM_TYPE_DEPRECATED)
- ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_OCTEON_SAMPLE)
- ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_MAX)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_SIM_TYPE_DEPRECATED)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_OCTEON_SAMPLE)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_MAX)
}
return "Unsupported Chip";
}
diff --git a/drivers/staging/octeon/cvmx-cmd-queue.h b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
index 614653b686a0..614653b686a0 100644
--- a/drivers/staging/octeon/cvmx-cmd-queue.h
+++ b/arch/mips/include/asm/octeon/cvmx-cmd-queue.h
diff --git a/drivers/staging/octeon/cvmx-config.h b/arch/mips/include/asm/octeon/cvmx-config.h
index 078a520481cf..26835d1b43b8 100644
--- a/drivers/staging/octeon/cvmx-config.h
+++ b/arch/mips/include/asm/octeon/cvmx-config.h
@@ -166,4 +166,3 @@ typedef enum {
#define CVMX_HELPER_DISABLE_RGMII_BACKPRESSURE 0
#endif /* __CVMX_CONFIG_H__ */
-
diff --git a/drivers/staging/octeon/cvmx-dbg-defs.h b/arch/mips/include/asm/octeon/cvmx-dbg-defs.h
index abbf42d05e5a..abbf42d05e5a 100644
--- a/drivers/staging/octeon/cvmx-dbg-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-dbg-defs.h
diff --git a/arch/mips/include/asm/octeon/cvmx-dpi-defs.h b/arch/mips/include/asm/octeon/cvmx-dpi-defs.h
new file mode 100644
index 000000000000..c34ad04789ce
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-dpi-defs.h
@@ -0,0 +1,643 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2011 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.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_DPI_DEFS_H__
+#define __CVMX_DPI_DEFS_H__
+
+#define CVMX_DPI_BIST_STATUS (CVMX_ADD_IO_SEG(0x0001DF0000000000ull))
+#define CVMX_DPI_CTL (CVMX_ADD_IO_SEG(0x0001DF0000000040ull))
+#define CVMX_DPI_DMAX_COUNTS(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000300ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMAX_DBELL(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000200ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMAX_ERR_RSP_STATUS(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000A80ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMAX_IBUFF_SADDR(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000280ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMAX_IFLIGHT(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000A00ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMAX_NADDR(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000380ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMAX_REQBNK0(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000400ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMAX_REQBNK1(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000480ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMA_CONTROL (CVMX_ADD_IO_SEG(0x0001DF0000000048ull))
+#define CVMX_DPI_DMA_ENGX_EN(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000080ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_DMA_PPX_CNT(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000B00ull) + ((offset) & 31) * 8)
+#define CVMX_DPI_ENGX_BUF(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000880ull) + ((offset) & 7) * 8)
+#define CVMX_DPI_INFO_REG (CVMX_ADD_IO_SEG(0x0001DF0000000980ull))
+#define CVMX_DPI_INT_EN (CVMX_ADD_IO_SEG(0x0001DF0000000010ull))
+#define CVMX_DPI_INT_REG (CVMX_ADD_IO_SEG(0x0001DF0000000008ull))
+#define CVMX_DPI_NCBX_CFG(block_id) (CVMX_ADD_IO_SEG(0x0001DF0000000800ull))
+#define CVMX_DPI_PINT_INFO (CVMX_ADD_IO_SEG(0x0001DF0000000830ull))
+#define CVMX_DPI_PKT_ERR_RSP (CVMX_ADD_IO_SEG(0x0001DF0000000078ull))
+#define CVMX_DPI_REQ_ERR_RSP (CVMX_ADD_IO_SEG(0x0001DF0000000058ull))
+#define CVMX_DPI_REQ_ERR_RSP_EN (CVMX_ADD_IO_SEG(0x0001DF0000000068ull))
+#define CVMX_DPI_REQ_ERR_RST (CVMX_ADD_IO_SEG(0x0001DF0000000060ull))
+#define CVMX_DPI_REQ_ERR_RST_EN (CVMX_ADD_IO_SEG(0x0001DF0000000070ull))
+#define CVMX_DPI_REQ_ERR_SKIP_COMP (CVMX_ADD_IO_SEG(0x0001DF0000000838ull))
+#define CVMX_DPI_REQ_GBL_EN (CVMX_ADD_IO_SEG(0x0001DF0000000050ull))
+#define CVMX_DPI_SLI_PRTX_CFG(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000900ull) + ((offset) & 3) * 8)
+#define CVMX_DPI_SLI_PRTX_ERR_INFO(offset) (CVMX_ADD_IO_SEG(0x0001DF0000000940ull) + ((offset) & 3) * 8)
+
+union cvmx_dpi_bist_status {
+ uint64_t u64;
+ struct cvmx_dpi_bist_status_s {
+ uint64_t reserved_47_63:17;
+ uint64_t bist:47;
+ } s;
+ struct cvmx_dpi_bist_status_s cn61xx;
+ struct cvmx_dpi_bist_status_cn63xx {
+ uint64_t reserved_45_63:19;
+ uint64_t bist:45;
+ } cn63xx;
+ struct cvmx_dpi_bist_status_cn63xxp1 {
+ uint64_t reserved_37_63:27;
+ uint64_t bist:37;
+ } cn63xxp1;
+ struct cvmx_dpi_bist_status_s cn66xx;
+ struct cvmx_dpi_bist_status_cn63xx cn68xx;
+ struct cvmx_dpi_bist_status_cn63xx cn68xxp1;
+};
+
+union cvmx_dpi_ctl {
+ uint64_t u64;
+ struct cvmx_dpi_ctl_s {
+ uint64_t reserved_2_63:62;
+ uint64_t clk:1;
+ uint64_t en:1;
+ } s;
+ struct cvmx_dpi_ctl_cn61xx {
+ uint64_t reserved_1_63:63;
+ uint64_t en:1;
+ } cn61xx;
+ struct cvmx_dpi_ctl_s cn63xx;
+ struct cvmx_dpi_ctl_s cn63xxp1;
+ struct cvmx_dpi_ctl_s cn66xx;
+ struct cvmx_dpi_ctl_s cn68xx;
+ struct cvmx_dpi_ctl_s cn68xxp1;
+};
+
+union cvmx_dpi_dmax_counts {
+ uint64_t u64;
+ struct cvmx_dpi_dmax_counts_s {
+ uint64_t reserved_39_63:25;
+ uint64_t fcnt:7;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_dpi_dmax_counts_s cn61xx;
+ struct cvmx_dpi_dmax_counts_s cn63xx;
+ struct cvmx_dpi_dmax_counts_s cn63xxp1;
+ struct cvmx_dpi_dmax_counts_s cn66xx;
+ struct cvmx_dpi_dmax_counts_s cn68xx;
+ struct cvmx_dpi_dmax_counts_s cn68xxp1;
+};
+
+union cvmx_dpi_dmax_dbell {
+ uint64_t u64;
+ struct cvmx_dpi_dmax_dbell_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dbell:16;
+ } s;
+ struct cvmx_dpi_dmax_dbell_s cn61xx;
+ struct cvmx_dpi_dmax_dbell_s cn63xx;
+ struct cvmx_dpi_dmax_dbell_s cn63xxp1;
+ struct cvmx_dpi_dmax_dbell_s cn66xx;
+ struct cvmx_dpi_dmax_dbell_s cn68xx;
+ struct cvmx_dpi_dmax_dbell_s cn68xxp1;
+};
+
+union cvmx_dpi_dmax_err_rsp_status {
+ uint64_t u64;
+ struct cvmx_dpi_dmax_err_rsp_status_s {
+ uint64_t reserved_6_63:58;
+ uint64_t status:6;
+ } s;
+ struct cvmx_dpi_dmax_err_rsp_status_s cn61xx;
+ struct cvmx_dpi_dmax_err_rsp_status_s cn66xx;
+ struct cvmx_dpi_dmax_err_rsp_status_s cn68xx;
+ struct cvmx_dpi_dmax_err_rsp_status_s cn68xxp1;
+};
+
+union cvmx_dpi_dmax_ibuff_saddr {
+ uint64_t u64;
+ struct cvmx_dpi_dmax_ibuff_saddr_s {
+ uint64_t reserved_62_63:2;
+ uint64_t csize:14;
+ uint64_t reserved_41_47:7;
+ uint64_t idle:1;
+ uint64_t saddr:33;
+ uint64_t reserved_0_6:7;
+ } s;
+ struct cvmx_dpi_dmax_ibuff_saddr_cn61xx {
+ uint64_t reserved_62_63:2;
+ uint64_t csize:14;
+ uint64_t reserved_41_47:7;
+ uint64_t idle:1;
+ uint64_t reserved_36_39:4;
+ uint64_t saddr:29;
+ uint64_t reserved_0_6:7;
+ } cn61xx;
+ struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn63xx;
+ struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn63xxp1;
+ struct cvmx_dpi_dmax_ibuff_saddr_cn61xx cn66xx;
+ struct cvmx_dpi_dmax_ibuff_saddr_s cn68xx;
+ struct cvmx_dpi_dmax_ibuff_saddr_s cn68xxp1;
+};
+
+union cvmx_dpi_dmax_iflight {
+ uint64_t u64;
+ struct cvmx_dpi_dmax_iflight_s {
+ uint64_t reserved_3_63:61;
+ uint64_t cnt:3;
+ } s;
+ struct cvmx_dpi_dmax_iflight_s cn61xx;
+ struct cvmx_dpi_dmax_iflight_s cn66xx;
+ struct cvmx_dpi_dmax_iflight_s cn68xx;
+ struct cvmx_dpi_dmax_iflight_s cn68xxp1;
+};
+
+union cvmx_dpi_dmax_naddr {
+ uint64_t u64;
+ struct cvmx_dpi_dmax_naddr_s {
+ uint64_t reserved_40_63:24;
+ uint64_t addr:40;
+ } s;
+ struct cvmx_dpi_dmax_naddr_cn61xx {
+ uint64_t reserved_36_63:28;
+ uint64_t addr:36;
+ } cn61xx;
+ struct cvmx_dpi_dmax_naddr_cn61xx cn63xx;
+ struct cvmx_dpi_dmax_naddr_cn61xx cn63xxp1;
+ struct cvmx_dpi_dmax_naddr_cn61xx cn66xx;
+ struct cvmx_dpi_dmax_naddr_s cn68xx;
+ struct cvmx_dpi_dmax_naddr_s cn68xxp1;
+};
+
+union cvmx_dpi_dmax_reqbnk0 {
+ uint64_t u64;
+ struct cvmx_dpi_dmax_reqbnk0_s {
+ uint64_t state:64;
+ } s;
+ struct cvmx_dpi_dmax_reqbnk0_s cn61xx;
+ struct cvmx_dpi_dmax_reqbnk0_s cn63xx;
+ struct cvmx_dpi_dmax_reqbnk0_s cn63xxp1;
+ struct cvmx_dpi_dmax_reqbnk0_s cn66xx;
+ struct cvmx_dpi_dmax_reqbnk0_s cn68xx;
+ struct cvmx_dpi_dmax_reqbnk0_s cn68xxp1;
+};
+
+union cvmx_dpi_dmax_reqbnk1 {
+ uint64_t u64;
+ struct cvmx_dpi_dmax_reqbnk1_s {
+ uint64_t state:64;
+ } s;
+ struct cvmx_dpi_dmax_reqbnk1_s cn61xx;
+ struct cvmx_dpi_dmax_reqbnk1_s cn63xx;
+ struct cvmx_dpi_dmax_reqbnk1_s cn63xxp1;
+ struct cvmx_dpi_dmax_reqbnk1_s cn66xx;
+ struct cvmx_dpi_dmax_reqbnk1_s cn68xx;
+ struct cvmx_dpi_dmax_reqbnk1_s cn68xxp1;
+};
+
+union cvmx_dpi_dma_control {
+ uint64_t u64;
+ struct cvmx_dpi_dma_control_s {
+ uint64_t reserved_62_63:2;
+ uint64_t dici_mode:1;
+ uint64_t pkt_en1:1;
+ uint64_t ffp_dis:1;
+ uint64_t commit_mode:1;
+ uint64_t pkt_hp:1;
+ uint64_t pkt_en:1;
+ uint64_t reserved_54_55:2;
+ uint64_t dma_enb:6;
+ uint64_t reserved_34_47:14;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t reserved_0_13:14;
+ } s;
+ struct cvmx_dpi_dma_control_s cn61xx;
+ struct cvmx_dpi_dma_control_cn63xx {
+ uint64_t reserved_61_63:3;
+ uint64_t pkt_en1:1;
+ uint64_t ffp_dis:1;
+ uint64_t commit_mode:1;
+ uint64_t pkt_hp:1;
+ uint64_t pkt_en:1;
+ uint64_t reserved_54_55:2;
+ uint64_t dma_enb:6;
+ uint64_t reserved_34_47:14;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t reserved_0_13:14;
+ } cn63xx;
+ struct cvmx_dpi_dma_control_cn63xxp1 {
+ uint64_t reserved_59_63:5;
+ uint64_t commit_mode:1;
+ uint64_t pkt_hp:1;
+ uint64_t pkt_en:1;
+ uint64_t reserved_54_55:2;
+ uint64_t dma_enb:6;
+ uint64_t reserved_34_47:14;
+ uint64_t b0_lend:1;
+ uint64_t dwb_denb:1;
+ uint64_t dwb_ichk:9;
+ uint64_t fpa_que:3;
+ uint64_t o_add1:1;
+ uint64_t o_ro:1;
+ uint64_t o_ns:1;
+ uint64_t o_es:2;
+ uint64_t o_mode:1;
+ uint64_t reserved_0_13:14;
+ } cn63xxp1;
+ struct cvmx_dpi_dma_control_cn63xx cn66xx;
+ struct cvmx_dpi_dma_control_s cn68xx;
+ struct cvmx_dpi_dma_control_cn63xx cn68xxp1;
+};
+
+union cvmx_dpi_dma_engx_en {
+ uint64_t u64;
+ struct cvmx_dpi_dma_engx_en_s {
+ uint64_t reserved_8_63:56;
+ uint64_t qen:8;
+ } s;
+ struct cvmx_dpi_dma_engx_en_s cn61xx;
+ struct cvmx_dpi_dma_engx_en_s cn63xx;
+ struct cvmx_dpi_dma_engx_en_s cn63xxp1;
+ struct cvmx_dpi_dma_engx_en_s cn66xx;
+ struct cvmx_dpi_dma_engx_en_s cn68xx;
+ struct cvmx_dpi_dma_engx_en_s cn68xxp1;
+};
+
+union cvmx_dpi_dma_ppx_cnt {
+ uint64_t u64;
+ struct cvmx_dpi_dma_ppx_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt:16;
+ } s;
+ struct cvmx_dpi_dma_ppx_cnt_s cn61xx;
+ struct cvmx_dpi_dma_ppx_cnt_s cn68xx;
+};
+
+union cvmx_dpi_engx_buf {
+ uint64_t u64;
+ struct cvmx_dpi_engx_buf_s {
+ uint64_t reserved_37_63:27;
+ uint64_t compblks:5;
+ uint64_t reserved_9_31:23;
+ uint64_t base:5;
+ uint64_t blks:4;
+ } s;
+ struct cvmx_dpi_engx_buf_s cn61xx;
+ struct cvmx_dpi_engx_buf_cn63xx {
+ uint64_t reserved_8_63:56;
+ uint64_t base:4;
+ uint64_t blks:4;
+ } cn63xx;
+ struct cvmx_dpi_engx_buf_cn63xx cn63xxp1;
+ struct cvmx_dpi_engx_buf_s cn66xx;
+ struct cvmx_dpi_engx_buf_s cn68xx;
+ struct cvmx_dpi_engx_buf_s cn68xxp1;
+};
+
+union cvmx_dpi_info_reg {
+ uint64_t u64;
+ struct cvmx_dpi_info_reg_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ffp:4;
+ uint64_t reserved_2_3:2;
+ uint64_t ncb:1;
+ uint64_t rsl:1;
+ } s;
+ struct cvmx_dpi_info_reg_s cn61xx;
+ struct cvmx_dpi_info_reg_s cn63xx;
+ struct cvmx_dpi_info_reg_cn63xxp1 {
+ uint64_t reserved_2_63:62;
+ uint64_t ncb:1;
+ uint64_t rsl:1;
+ } cn63xxp1;
+ struct cvmx_dpi_info_reg_s cn66xx;
+ struct cvmx_dpi_info_reg_s cn68xx;
+ struct cvmx_dpi_info_reg_s cn68xxp1;
+};
+
+union cvmx_dpi_int_en {
+ uint64_t u64;
+ struct cvmx_dpi_int_en_s {
+ uint64_t reserved_28_63:36;
+ uint64_t sprt3_rst:1;
+ uint64_t sprt2_rst:1;
+ uint64_t sprt1_rst:1;
+ uint64_t sprt0_rst:1;
+ uint64_t reserved_23_23:1;
+ uint64_t req_badfil:1;
+ uint64_t req_inull:1;
+ uint64_t req_anull:1;
+ uint64_t req_undflw:1;
+ uint64_t req_ovrflw:1;
+ uint64_t req_badlen:1;
+ uint64_t req_badadr:1;
+ uint64_t dmadbo:8;
+ uint64_t reserved_2_7:6;
+ uint64_t nfovr:1;
+ uint64_t nderr:1;
+ } s;
+ struct cvmx_dpi_int_en_s cn61xx;
+ struct cvmx_dpi_int_en_cn63xx {
+ uint64_t reserved_26_63:38;
+ uint64_t sprt1_rst:1;
+ uint64_t sprt0_rst:1;
+ uint64_t reserved_23_23:1;
+ uint64_t req_badfil:1;
+ uint64_t req_inull:1;
+ uint64_t req_anull:1;
+ uint64_t req_undflw:1;
+ uint64_t req_ovrflw:1;
+ uint64_t req_badlen:1;
+ uint64_t req_badadr:1;
+ uint64_t dmadbo:8;
+ uint64_t reserved_2_7:6;
+ uint64_t nfovr:1;
+ uint64_t nderr:1;
+ } cn63xx;
+ struct cvmx_dpi_int_en_cn63xx cn63xxp1;
+ struct cvmx_dpi_int_en_s cn66xx;
+ struct cvmx_dpi_int_en_cn63xx cn68xx;
+ struct cvmx_dpi_int_en_cn63xx cn68xxp1;
+};
+
+union cvmx_dpi_int_reg {
+ uint64_t u64;
+ struct cvmx_dpi_int_reg_s {
+ uint64_t reserved_28_63:36;
+ uint64_t sprt3_rst:1;
+ uint64_t sprt2_rst:1;
+ uint64_t sprt1_rst:1;
+ uint64_t sprt0_rst:1;
+ uint64_t reserved_23_23:1;
+ uint64_t req_badfil:1;
+ uint64_t req_inull:1;
+ uint64_t req_anull:1;
+ uint64_t req_undflw:1;
+ uint64_t req_ovrflw:1;
+ uint64_t req_badlen:1;
+ uint64_t req_badadr:1;
+ uint64_t dmadbo:8;
+ uint64_t reserved_2_7:6;
+ uint64_t nfovr:1;
+ uint64_t nderr:1;
+ } s;
+ struct cvmx_dpi_int_reg_s cn61xx;
+ struct cvmx_dpi_int_reg_cn63xx {
+ uint64_t reserved_26_63:38;
+ uint64_t sprt1_rst:1;
+ uint64_t sprt0_rst:1;
+ uint64_t reserved_23_23:1;
+ uint64_t req_badfil:1;
+ uint64_t req_inull:1;
+ uint64_t req_anull:1;
+ uint64_t req_undflw:1;
+ uint64_t req_ovrflw:1;
+ uint64_t req_badlen:1;
+ uint64_t req_badadr:1;
+ uint64_t dmadbo:8;
+ uint64_t reserved_2_7:6;
+ uint64_t nfovr:1;
+ uint64_t nderr:1;
+ } cn63xx;
+ struct cvmx_dpi_int_reg_cn63xx cn63xxp1;
+ struct cvmx_dpi_int_reg_s cn66xx;
+ struct cvmx_dpi_int_reg_cn63xx cn68xx;
+ struct cvmx_dpi_int_reg_cn63xx cn68xxp1;
+};
+
+union cvmx_dpi_ncbx_cfg {
+ uint64_t u64;
+ struct cvmx_dpi_ncbx_cfg_s {
+ uint64_t reserved_6_63:58;
+ uint64_t molr:6;
+ } s;
+ struct cvmx_dpi_ncbx_cfg_s cn61xx;
+ struct cvmx_dpi_ncbx_cfg_s cn66xx;
+ struct cvmx_dpi_ncbx_cfg_s cn68xx;
+};
+
+union cvmx_dpi_pint_info {
+ uint64_t u64;
+ struct cvmx_dpi_pint_info_s {
+ uint64_t reserved_14_63:50;
+ uint64_t iinfo:6;
+ uint64_t reserved_6_7:2;
+ uint64_t sinfo:6;
+ } s;
+ struct cvmx_dpi_pint_info_s cn61xx;
+ struct cvmx_dpi_pint_info_s cn63xx;
+ struct cvmx_dpi_pint_info_s cn63xxp1;
+ struct cvmx_dpi_pint_info_s cn66xx;
+ struct cvmx_dpi_pint_info_s cn68xx;
+ struct cvmx_dpi_pint_info_s cn68xxp1;
+};
+
+union cvmx_dpi_pkt_err_rsp {
+ uint64_t u64;
+ struct cvmx_dpi_pkt_err_rsp_s {
+ uint64_t reserved_1_63:63;
+ uint64_t pkterr:1;
+ } s;
+ struct cvmx_dpi_pkt_err_rsp_s cn61xx;
+ struct cvmx_dpi_pkt_err_rsp_s cn63xx;
+ struct cvmx_dpi_pkt_err_rsp_s cn63xxp1;
+ struct cvmx_dpi_pkt_err_rsp_s cn66xx;
+ struct cvmx_dpi_pkt_err_rsp_s cn68xx;
+ struct cvmx_dpi_pkt_err_rsp_s cn68xxp1;
+};
+
+union cvmx_dpi_req_err_rsp {
+ uint64_t u64;
+ struct cvmx_dpi_req_err_rsp_s {
+ uint64_t reserved_8_63:56;
+ uint64_t qerr:8;
+ } s;
+ struct cvmx_dpi_req_err_rsp_s cn61xx;
+ struct cvmx_dpi_req_err_rsp_s cn63xx;
+ struct cvmx_dpi_req_err_rsp_s cn63xxp1;
+ struct cvmx_dpi_req_err_rsp_s cn66xx;
+ struct cvmx_dpi_req_err_rsp_s cn68xx;
+ struct cvmx_dpi_req_err_rsp_s cn68xxp1;
+};
+
+union cvmx_dpi_req_err_rsp_en {
+ uint64_t u64;
+ struct cvmx_dpi_req_err_rsp_en_s {
+ uint64_t reserved_8_63:56;
+ uint64_t en:8;
+ } s;
+ struct cvmx_dpi_req_err_rsp_en_s cn61xx;
+ struct cvmx_dpi_req_err_rsp_en_s cn63xx;
+ struct cvmx_dpi_req_err_rsp_en_s cn63xxp1;
+ struct cvmx_dpi_req_err_rsp_en_s cn66xx;
+ struct cvmx_dpi_req_err_rsp_en_s cn68xx;
+ struct cvmx_dpi_req_err_rsp_en_s cn68xxp1;
+};
+
+union cvmx_dpi_req_err_rst {
+ uint64_t u64;
+ struct cvmx_dpi_req_err_rst_s {
+ uint64_t reserved_8_63:56;
+ uint64_t qerr:8;
+ } s;
+ struct cvmx_dpi_req_err_rst_s cn61xx;
+ struct cvmx_dpi_req_err_rst_s cn63xx;
+ struct cvmx_dpi_req_err_rst_s cn63xxp1;
+ struct cvmx_dpi_req_err_rst_s cn66xx;
+ struct cvmx_dpi_req_err_rst_s cn68xx;
+ struct cvmx_dpi_req_err_rst_s cn68xxp1;
+};
+
+union cvmx_dpi_req_err_rst_en {
+ uint64_t u64;
+ struct cvmx_dpi_req_err_rst_en_s {
+ uint64_t reserved_8_63:56;
+ uint64_t en:8;
+ } s;
+ struct cvmx_dpi_req_err_rst_en_s cn61xx;
+ struct cvmx_dpi_req_err_rst_en_s cn63xx;
+ struct cvmx_dpi_req_err_rst_en_s cn63xxp1;
+ struct cvmx_dpi_req_err_rst_en_s cn66xx;
+ struct cvmx_dpi_req_err_rst_en_s cn68xx;
+ struct cvmx_dpi_req_err_rst_en_s cn68xxp1;
+};
+
+union cvmx_dpi_req_err_skip_comp {
+ uint64_t u64;
+ struct cvmx_dpi_req_err_skip_comp_s {
+ uint64_t reserved_24_63:40;
+ uint64_t en_rst:8;
+ uint64_t reserved_8_15:8;
+ uint64_t en_rsp:8;
+ } s;
+ struct cvmx_dpi_req_err_skip_comp_s cn61xx;
+ struct cvmx_dpi_req_err_skip_comp_s cn66xx;
+ struct cvmx_dpi_req_err_skip_comp_s cn68xx;
+ struct cvmx_dpi_req_err_skip_comp_s cn68xxp1;
+};
+
+union cvmx_dpi_req_gbl_en {
+ uint64_t u64;
+ struct cvmx_dpi_req_gbl_en_s {
+ uint64_t reserved_8_63:56;
+ uint64_t qen:8;
+ } s;
+ struct cvmx_dpi_req_gbl_en_s cn61xx;
+ struct cvmx_dpi_req_gbl_en_s cn63xx;
+ struct cvmx_dpi_req_gbl_en_s cn63xxp1;
+ struct cvmx_dpi_req_gbl_en_s cn66xx;
+ struct cvmx_dpi_req_gbl_en_s cn68xx;
+ struct cvmx_dpi_req_gbl_en_s cn68xxp1;
+};
+
+union cvmx_dpi_sli_prtx_cfg {
+ uint64_t u64;
+ struct cvmx_dpi_sli_prtx_cfg_s {
+ uint64_t reserved_25_63:39;
+ uint64_t halt:1;
+ uint64_t qlm_cfg:4;
+ uint64_t reserved_17_19:3;
+ uint64_t rd_mode:1;
+ uint64_t reserved_14_15:2;
+ uint64_t molr:6;
+ uint64_t mps_lim:1;
+ uint64_t reserved_5_6:2;
+ uint64_t mps:1;
+ uint64_t mrrs_lim:1;
+ uint64_t reserved_2_2:1;
+ uint64_t mrrs:2;
+ } s;
+ struct cvmx_dpi_sli_prtx_cfg_s cn61xx;
+ struct cvmx_dpi_sli_prtx_cfg_cn63xx {
+ uint64_t reserved_25_63:39;
+ uint64_t halt:1;
+ uint64_t reserved_21_23:3;
+ uint64_t qlm_cfg:1;
+ uint64_t reserved_17_19:3;
+ uint64_t rd_mode:1;
+ uint64_t reserved_14_15:2;
+ uint64_t molr:6;
+ uint64_t mps_lim:1;
+ uint64_t reserved_5_6:2;
+ uint64_t mps:1;
+ uint64_t mrrs_lim:1;
+ uint64_t reserved_2_2:1;
+ uint64_t mrrs:2;
+ } cn63xx;
+ struct cvmx_dpi_sli_prtx_cfg_cn63xx cn63xxp1;
+ struct cvmx_dpi_sli_prtx_cfg_s cn66xx;
+ struct cvmx_dpi_sli_prtx_cfg_cn63xx cn68xx;
+ struct cvmx_dpi_sli_prtx_cfg_cn63xx cn68xxp1;
+};
+
+union cvmx_dpi_sli_prtx_err {
+ uint64_t u64;
+ struct cvmx_dpi_sli_prtx_err_s {
+ uint64_t addr:61;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_dpi_sli_prtx_err_s cn61xx;
+ struct cvmx_dpi_sli_prtx_err_s cn63xx;
+ struct cvmx_dpi_sli_prtx_err_s cn63xxp1;
+ struct cvmx_dpi_sli_prtx_err_s cn66xx;
+ struct cvmx_dpi_sli_prtx_err_s cn68xx;
+ struct cvmx_dpi_sli_prtx_err_s cn68xxp1;
+};
+
+union cvmx_dpi_sli_prtx_err_info {
+ uint64_t u64;
+ struct cvmx_dpi_sli_prtx_err_info_s {
+ uint64_t reserved_9_63:55;
+ uint64_t lock:1;
+ uint64_t reserved_5_7:3;
+ uint64_t type:1;
+ uint64_t reserved_3_3:1;
+ uint64_t reqq:3;
+ } s;
+ struct cvmx_dpi_sli_prtx_err_info_s cn61xx;
+ struct cvmx_dpi_sli_prtx_err_info_s cn63xx;
+ struct cvmx_dpi_sli_prtx_err_info_s cn63xxp1;
+ struct cvmx_dpi_sli_prtx_err_info_s cn66xx;
+ struct cvmx_dpi_sli_prtx_err_info_s cn68xx;
+ struct cvmx_dpi_sli_prtx_err_info_s cn68xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-fau.h b/arch/mips/include/asm/octeon/cvmx-fau.h
index a6939fc8ba18..a6939fc8ba18 100644
--- a/drivers/staging/octeon/cvmx-fau.h
+++ b/arch/mips/include/asm/octeon/cvmx-fau.h
diff --git a/drivers/staging/octeon/cvmx-fpa-defs.h b/arch/mips/include/asm/octeon/cvmx-fpa-defs.h
index bf5546b90110..bf5546b90110 100644
--- a/drivers/staging/octeon/cvmx-fpa-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-fpa-defs.h
diff --git a/drivers/staging/octeon/cvmx-fpa.h b/arch/mips/include/asm/octeon/cvmx-fpa.h
index 1f04f9658736..1f04f9658736 100644
--- a/drivers/staging/octeon/cvmx-fpa.h
+++ b/arch/mips/include/asm/octeon/cvmx-fpa.h
diff --git a/drivers/staging/octeon/cvmx-gmxx-defs.h b/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h
index 946a43a73fd7..946a43a73fd7 100644
--- a/drivers/staging/octeon/cvmx-gmxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-gmxx-defs.h
diff --git a/drivers/staging/octeon/cvmx-helper-board.h b/arch/mips/include/asm/octeon/cvmx-helper-board.h
index b465bec43553..88527fa835c9 100644
--- a/drivers/staging/octeon/cvmx-helper-board.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-board.h
@@ -44,6 +44,12 @@ typedef enum {
set_phy_link_flags_flow_control_mask = 0x3 << 1, /* Mask for 2 bit wide flow control field */
} cvmx_helper_board_set_phy_link_flags_types_t;
+/*
+ * Fake IPD port, the RGMII/MII interface may use different PHY, use
+ * this macro to return appropriate MIX address to read the PHY.
+ */
+#define CVMX_HELPER_BOARD_MGMT_IPD_PORT -10
+
/**
* cvmx_override_board_link_get(int ipd_port) is a function
* pointer. It is meant to allow customization of the process of
diff --git a/drivers/staging/octeon/cvmx-helper-fpa.h b/arch/mips/include/asm/octeon/cvmx-helper-fpa.h
index 5ff8c93198de..5ff8c93198de 100644
--- a/drivers/staging/octeon/cvmx-helper-fpa.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-fpa.h
diff --git a/drivers/staging/octeon/cvmx-helper-loop.h b/arch/mips/include/asm/octeon/cvmx-helper-loop.h
index e646a6ccce75..077f0e9d3b2d 100644
--- a/drivers/staging/octeon/cvmx-helper-loop.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-loop.h
@@ -44,6 +44,7 @@
* Returns Number of ports on the interface. Zero to disable.
*/
extern int __cvmx_helper_loop_probe(int interface);
+static inline int __cvmx_helper_loop_enumerate(int interface) {return 4; }
/**
* Bringup and enable a LOOP interface. After this call packet
diff --git a/drivers/staging/octeon/cvmx-helper-npi.h b/arch/mips/include/asm/octeon/cvmx-helper-npi.h
index 908e7b08c214..8df4c7fafdba 100644
--- a/drivers/staging/octeon/cvmx-helper-npi.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-npi.h
@@ -45,6 +45,7 @@
* Returns Number of ports on the interface. Zero to disable.
*/
extern int __cvmx_helper_npi_probe(int interface);
+#define __cvmx_helper_npi_enumerate __cvmx_helper_npi_probe
/**
* Bringup and enable a NPI interface. After this call packet
diff --git a/drivers/staging/octeon/cvmx-helper-rgmii.h b/arch/mips/include/asm/octeon/cvmx-helper-rgmii.h
index ea2652604a57..78295ba0050f 100644
--- a/drivers/staging/octeon/cvmx-helper-rgmii.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-rgmii.h
@@ -43,6 +43,7 @@
* Returns Number of RGMII/GMII/MII ports (0-4).
*/
extern int __cvmx_helper_rgmii_probe(int interface);
+#define __cvmx_helper_rgmii_enumerate __cvmx_helper_rgmii_probe
/**
* Put an RGMII interface in loopback mode. Internal packets sent
diff --git a/drivers/staging/octeon/cvmx-helper-sgmii.h b/arch/mips/include/asm/octeon/cvmx-helper-sgmii.h
index 19b48d60857f..9a9b6c103ede 100644
--- a/drivers/staging/octeon/cvmx-helper-sgmii.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-sgmii.h
@@ -45,6 +45,7 @@
* Returns Number of ports on the interface. Zero to disable.
*/
extern int __cvmx_helper_sgmii_probe(int interface);
+extern int __cvmx_helper_sgmii_enumerate(int interface);
/**
* Bringup and enable a SGMII interface. After this call packet
diff --git a/drivers/staging/octeon/cvmx-helper-spi.h b/arch/mips/include/asm/octeon/cvmx-helper-spi.h
index 69bac036d10e..9f1c6b968f91 100644
--- a/drivers/staging/octeon/cvmx-helper-spi.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-spi.h
@@ -42,6 +42,7 @@
* Returns Number of ports on the interface. Zero to disable.
*/
extern int __cvmx_helper_spi_probe(int interface);
+extern int __cvmx_helper_spi_enumerate(int interface);
/**
* Bringup and enable a SPI interface. After this call packet I/O
diff --git a/drivers/staging/octeon/cvmx-helper-util.h b/arch/mips/include/asm/octeon/cvmx-helper-util.h
index 6a6e52fc22c1..6a6e52fc22c1 100644
--- a/drivers/staging/octeon/cvmx-helper-util.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-util.h
diff --git a/drivers/staging/octeon/cvmx-helper-xaui.h b/arch/mips/include/asm/octeon/cvmx-helper-xaui.h
index 4b4db2f93cd4..f6fbc4f45b56 100644
--- a/drivers/staging/octeon/cvmx-helper-xaui.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper-xaui.h
@@ -45,6 +45,7 @@
* Returns Number of ports on the interface. Zero to disable.
*/
extern int __cvmx_helper_xaui_probe(int interface);
+extern int __cvmx_helper_xaui_enumerate(int interface);
/**
* Bringup and enable a XAUI interface. After this call packet
diff --git a/drivers/staging/octeon/cvmx-helper.h b/arch/mips/include/asm/octeon/cvmx-helper.h
index 51916f3cc40c..3169cd79f2ac 100644
--- a/drivers/staging/octeon/cvmx-helper.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper.h
@@ -207,6 +207,7 @@ extern int cvmx_helper_link_set(int ipd_port,
* Returns Zero on success, negative on failure
*/
extern int cvmx_helper_interface_probe(int interface);
+extern int cvmx_helper_interface_enumerate(int interface);
/**
* Configure a port for internal and/or external loopback. Internal loopback
diff --git a/drivers/staging/octeon/cvmx-ipd.h b/arch/mips/include/asm/octeon/cvmx-ipd.h
index 115a552c5c7f..115a552c5c7f 100644
--- a/drivers/staging/octeon/cvmx-ipd.h
+++ b/arch/mips/include/asm/octeon/cvmx-ipd.h
diff --git a/drivers/staging/octeon/cvmx-mdio.h b/arch/mips/include/asm/octeon/cvmx-mdio.h
index d88ab8d8e37d..d88ab8d8e37d 100644
--- a/drivers/staging/octeon/cvmx-mdio.h
+++ b/arch/mips/include/asm/octeon/cvmx-mdio.h
diff --git a/arch/mips/include/asm/octeon/cvmx-mio-defs.h b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
index 52b14a333ad4..b1774126736d 100644
--- a/arch/mips/include/asm/octeon/cvmx-mio-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
@@ -43,6 +43,22 @@
#define CVMX_MIO_BOOT_REG_CFGX(offset) (CVMX_ADD_IO_SEG(0x0001180000000000ull) + ((offset) & 7) * 8)
#define CVMX_MIO_BOOT_REG_TIMX(offset) (CVMX_ADD_IO_SEG(0x0001180000000040ull) + ((offset) & 7) * 8)
#define CVMX_MIO_BOOT_THR (CVMX_ADD_IO_SEG(0x00011800000000B0ull))
+#define CVMX_MIO_EMM_BUF_DAT (CVMX_ADD_IO_SEG(0x00011800000020E8ull))
+#define CVMX_MIO_EMM_BUF_IDX (CVMX_ADD_IO_SEG(0x00011800000020E0ull))
+#define CVMX_MIO_EMM_CFG (CVMX_ADD_IO_SEG(0x0001180000002000ull))
+#define CVMX_MIO_EMM_CMD (CVMX_ADD_IO_SEG(0x0001180000002058ull))
+#define CVMX_MIO_EMM_DMA (CVMX_ADD_IO_SEG(0x0001180000002050ull))
+#define CVMX_MIO_EMM_INT (CVMX_ADD_IO_SEG(0x0001180000002078ull))
+#define CVMX_MIO_EMM_INT_EN (CVMX_ADD_IO_SEG(0x0001180000002080ull))
+#define CVMX_MIO_EMM_MODEX(offset) (CVMX_ADD_IO_SEG(0x0001180000002008ull) + ((offset) & 3) * 8)
+#define CVMX_MIO_EMM_RCA (CVMX_ADD_IO_SEG(0x00011800000020A0ull))
+#define CVMX_MIO_EMM_RSP_HI (CVMX_ADD_IO_SEG(0x0001180000002070ull))
+#define CVMX_MIO_EMM_RSP_LO (CVMX_ADD_IO_SEG(0x0001180000002068ull))
+#define CVMX_MIO_EMM_RSP_STS (CVMX_ADD_IO_SEG(0x0001180000002060ull))
+#define CVMX_MIO_EMM_SAMPLE (CVMX_ADD_IO_SEG(0x0001180000002090ull))
+#define CVMX_MIO_EMM_STS_MASK (CVMX_ADD_IO_SEG(0x0001180000002098ull))
+#define CVMX_MIO_EMM_SWITCH (CVMX_ADD_IO_SEG(0x0001180000002048ull))
+#define CVMX_MIO_EMM_WDOG (CVMX_ADD_IO_SEG(0x0001180000002088ull))
#define CVMX_MIO_FUS_BNK_DATX(offset) (CVMX_ADD_IO_SEG(0x0001180000001520ull) + ((offset) & 3) * 8)
#define CVMX_MIO_FUS_DAT0 (CVMX_ADD_IO_SEG(0x0001180000001400ull))
#define CVMX_MIO_FUS_DAT1 (CVMX_ADD_IO_SEG(0x0001180000001408ull))
@@ -60,6 +76,7 @@
#define CVMX_MIO_FUS_REPAIR_RES2 (CVMX_ADD_IO_SEG(0x0001180000001568ull))
#define CVMX_MIO_FUS_SPR_REPAIR_RES (CVMX_ADD_IO_SEG(0x0001180000001548ull))
#define CVMX_MIO_FUS_SPR_REPAIR_SUM (CVMX_ADD_IO_SEG(0x0001180000001540ull))
+#define CVMX_MIO_FUS_TGG (CVMX_ADD_IO_SEG(0x0001180000001428ull))
#define CVMX_MIO_FUS_UNLOCK (CVMX_ADD_IO_SEG(0x0001180000001578ull))
#define CVMX_MIO_FUS_WADR (CVMX_ADD_IO_SEG(0x0001180000001508ull))
#define CVMX_MIO_GPIO_COMP (CVMX_ADD_IO_SEG(0x00011800000000C8ull))
@@ -68,14 +85,25 @@
#define CVMX_MIO_NDF_DMA_INT_EN (CVMX_ADD_IO_SEG(0x0001180000000178ull))
#define CVMX_MIO_PLL_CTL (CVMX_ADD_IO_SEG(0x0001180000001448ull))
#define CVMX_MIO_PLL_SETTING (CVMX_ADD_IO_SEG(0x0001180000001440ull))
+#define CVMX_MIO_PTP_CKOUT_HI_INCR (CVMX_ADD_IO_SEG(0x0001070000000F40ull))
+#define CVMX_MIO_PTP_CKOUT_LO_INCR (CVMX_ADD_IO_SEG(0x0001070000000F48ull))
+#define CVMX_MIO_PTP_CKOUT_THRESH_HI (CVMX_ADD_IO_SEG(0x0001070000000F38ull))
+#define CVMX_MIO_PTP_CKOUT_THRESH_LO (CVMX_ADD_IO_SEG(0x0001070000000F30ull))
#define CVMX_MIO_PTP_CLOCK_CFG (CVMX_ADD_IO_SEG(0x0001070000000F00ull))
#define CVMX_MIO_PTP_CLOCK_COMP (CVMX_ADD_IO_SEG(0x0001070000000F18ull))
#define CVMX_MIO_PTP_CLOCK_HI (CVMX_ADD_IO_SEG(0x0001070000000F10ull))
#define CVMX_MIO_PTP_CLOCK_LO (CVMX_ADD_IO_SEG(0x0001070000000F08ull))
#define CVMX_MIO_PTP_EVT_CNT (CVMX_ADD_IO_SEG(0x0001070000000F28ull))
+#define CVMX_MIO_PTP_PPS_HI_INCR (CVMX_ADD_IO_SEG(0x0001070000000F60ull))
+#define CVMX_MIO_PTP_PPS_LO_INCR (CVMX_ADD_IO_SEG(0x0001070000000F68ull))
+#define CVMX_MIO_PTP_PPS_THRESH_HI (CVMX_ADD_IO_SEG(0x0001070000000F58ull))
+#define CVMX_MIO_PTP_PPS_THRESH_LO (CVMX_ADD_IO_SEG(0x0001070000000F50ull))
#define CVMX_MIO_PTP_TIMESTAMP (CVMX_ADD_IO_SEG(0x0001070000000F20ull))
+#define CVMX_MIO_QLMX_CFG(offset) (CVMX_ADD_IO_SEG(0x0001180000001590ull) + ((offset) & 7) * 8)
#define CVMX_MIO_RST_BOOT (CVMX_ADD_IO_SEG(0x0001180000001600ull))
#define CVMX_MIO_RST_CFG (CVMX_ADD_IO_SEG(0x0001180000001610ull))
+#define CVMX_MIO_RST_CKILL (CVMX_ADD_IO_SEG(0x0001180000001638ull))
+#define CVMX_MIO_RST_CNTLX(offset) (CVMX_ADD_IO_SEG(0x0001180000001648ull) + ((offset) & 3) * 8)
#define CVMX_MIO_RST_CTLX(offset) (CVMX_ADD_IO_SEG(0x0001180000001618ull) + ((offset) & 1) * 8)
#define CVMX_MIO_RST_DELAY (CVMX_ADD_IO_SEG(0x0001180000001608ull))
#define CVMX_MIO_RST_INT (CVMX_ADD_IO_SEG(0x0001180000001628ull))
@@ -183,11 +211,21 @@ union cvmx_mio_boot_bist_stat {
struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xxp1;
struct cvmx_mio_boot_bist_stat_cn38xx cn58xx;
struct cvmx_mio_boot_bist_stat_cn38xx cn58xxp1;
+ struct cvmx_mio_boot_bist_stat_cn61xx {
+ uint64_t reserved_12_63:52;
+ uint64_t stat:12;
+ } cn61xx;
struct cvmx_mio_boot_bist_stat_cn63xx {
uint64_t reserved_9_63:55;
uint64_t stat:9;
} cn63xx;
struct cvmx_mio_boot_bist_stat_cn63xx cn63xxp1;
+ struct cvmx_mio_boot_bist_stat_cn66xx {
+ uint64_t reserved_10_63:54;
+ uint64_t stat:10;
+ } cn66xx;
+ struct cvmx_mio_boot_bist_stat_cn66xx cn68xx;
+ struct cvmx_mio_boot_bist_stat_cn66xx cn68xxp1;
};
union cvmx_mio_boot_comp {
@@ -204,12 +242,16 @@ union cvmx_mio_boot_comp {
struct cvmx_mio_boot_comp_cn50xx cn52xxp1;
struct cvmx_mio_boot_comp_cn50xx cn56xx;
struct cvmx_mio_boot_comp_cn50xx cn56xxp1;
- struct cvmx_mio_boot_comp_cn63xx {
+ struct cvmx_mio_boot_comp_cn61xx {
uint64_t reserved_12_63:52;
uint64_t pctl:6;
uint64_t nctl:6;
- } cn63xx;
- struct cvmx_mio_boot_comp_cn63xx cn63xxp1;
+ } cn61xx;
+ struct cvmx_mio_boot_comp_cn61xx cn63xx;
+ struct cvmx_mio_boot_comp_cn61xx cn63xxp1;
+ struct cvmx_mio_boot_comp_cn61xx cn66xx;
+ struct cvmx_mio_boot_comp_cn61xx cn68xx;
+ struct cvmx_mio_boot_comp_cn61xx cn68xxp1;
};
union cvmx_mio_boot_dma_cfgx {
@@ -230,8 +272,12 @@ union cvmx_mio_boot_dma_cfgx {
struct cvmx_mio_boot_dma_cfgx_s cn52xxp1;
struct cvmx_mio_boot_dma_cfgx_s cn56xx;
struct cvmx_mio_boot_dma_cfgx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_cfgx_s cn61xx;
struct cvmx_mio_boot_dma_cfgx_s cn63xx;
struct cvmx_mio_boot_dma_cfgx_s cn63xxp1;
+ struct cvmx_mio_boot_dma_cfgx_s cn66xx;
+ struct cvmx_mio_boot_dma_cfgx_s cn68xx;
+ struct cvmx_mio_boot_dma_cfgx_s cn68xxp1;
};
union cvmx_mio_boot_dma_intx {
@@ -245,8 +291,12 @@ union cvmx_mio_boot_dma_intx {
struct cvmx_mio_boot_dma_intx_s cn52xxp1;
struct cvmx_mio_boot_dma_intx_s cn56xx;
struct cvmx_mio_boot_dma_intx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_intx_s cn61xx;
struct cvmx_mio_boot_dma_intx_s cn63xx;
struct cvmx_mio_boot_dma_intx_s cn63xxp1;
+ struct cvmx_mio_boot_dma_intx_s cn66xx;
+ struct cvmx_mio_boot_dma_intx_s cn68xx;
+ struct cvmx_mio_boot_dma_intx_s cn68xxp1;
};
union cvmx_mio_boot_dma_int_enx {
@@ -260,8 +310,12 @@ union cvmx_mio_boot_dma_int_enx {
struct cvmx_mio_boot_dma_int_enx_s cn52xxp1;
struct cvmx_mio_boot_dma_int_enx_s cn56xx;
struct cvmx_mio_boot_dma_int_enx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_int_enx_s cn61xx;
struct cvmx_mio_boot_dma_int_enx_s cn63xx;
struct cvmx_mio_boot_dma_int_enx_s cn63xxp1;
+ struct cvmx_mio_boot_dma_int_enx_s cn66xx;
+ struct cvmx_mio_boot_dma_int_enx_s cn68xx;
+ struct cvmx_mio_boot_dma_int_enx_s cn68xxp1;
};
union cvmx_mio_boot_dma_timx {
@@ -287,8 +341,12 @@ union cvmx_mio_boot_dma_timx {
struct cvmx_mio_boot_dma_timx_s cn52xxp1;
struct cvmx_mio_boot_dma_timx_s cn56xx;
struct cvmx_mio_boot_dma_timx_s cn56xxp1;
+ struct cvmx_mio_boot_dma_timx_s cn61xx;
struct cvmx_mio_boot_dma_timx_s cn63xx;
struct cvmx_mio_boot_dma_timx_s cn63xxp1;
+ struct cvmx_mio_boot_dma_timx_s cn66xx;
+ struct cvmx_mio_boot_dma_timx_s cn68xx;
+ struct cvmx_mio_boot_dma_timx_s cn68xxp1;
};
union cvmx_mio_boot_err {
@@ -309,8 +367,12 @@ union cvmx_mio_boot_err {
struct cvmx_mio_boot_err_s cn56xxp1;
struct cvmx_mio_boot_err_s cn58xx;
struct cvmx_mio_boot_err_s cn58xxp1;
+ struct cvmx_mio_boot_err_s cn61xx;
struct cvmx_mio_boot_err_s cn63xx;
struct cvmx_mio_boot_err_s cn63xxp1;
+ struct cvmx_mio_boot_err_s cn66xx;
+ struct cvmx_mio_boot_err_s cn68xx;
+ struct cvmx_mio_boot_err_s cn68xxp1;
};
union cvmx_mio_boot_int {
@@ -331,8 +393,12 @@ union cvmx_mio_boot_int {
struct cvmx_mio_boot_int_s cn56xxp1;
struct cvmx_mio_boot_int_s cn58xx;
struct cvmx_mio_boot_int_s cn58xxp1;
+ struct cvmx_mio_boot_int_s cn61xx;
struct cvmx_mio_boot_int_s cn63xx;
struct cvmx_mio_boot_int_s cn63xxp1;
+ struct cvmx_mio_boot_int_s cn66xx;
+ struct cvmx_mio_boot_int_s cn68xx;
+ struct cvmx_mio_boot_int_s cn68xxp1;
};
union cvmx_mio_boot_loc_adr {
@@ -353,8 +419,12 @@ union cvmx_mio_boot_loc_adr {
struct cvmx_mio_boot_loc_adr_s cn56xxp1;
struct cvmx_mio_boot_loc_adr_s cn58xx;
struct cvmx_mio_boot_loc_adr_s cn58xxp1;
+ struct cvmx_mio_boot_loc_adr_s cn61xx;
struct cvmx_mio_boot_loc_adr_s cn63xx;
struct cvmx_mio_boot_loc_adr_s cn63xxp1;
+ struct cvmx_mio_boot_loc_adr_s cn66xx;
+ struct cvmx_mio_boot_loc_adr_s cn68xx;
+ struct cvmx_mio_boot_loc_adr_s cn68xxp1;
};
union cvmx_mio_boot_loc_cfgx {
@@ -377,8 +447,12 @@ union cvmx_mio_boot_loc_cfgx {
struct cvmx_mio_boot_loc_cfgx_s cn56xxp1;
struct cvmx_mio_boot_loc_cfgx_s cn58xx;
struct cvmx_mio_boot_loc_cfgx_s cn58xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cn61xx;
struct cvmx_mio_boot_loc_cfgx_s cn63xx;
struct cvmx_mio_boot_loc_cfgx_s cn63xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cn66xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn68xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn68xxp1;
};
union cvmx_mio_boot_loc_dat {
@@ -397,14 +471,19 @@ union cvmx_mio_boot_loc_dat {
struct cvmx_mio_boot_loc_dat_s cn56xxp1;
struct cvmx_mio_boot_loc_dat_s cn58xx;
struct cvmx_mio_boot_loc_dat_s cn58xxp1;
+ struct cvmx_mio_boot_loc_dat_s cn61xx;
struct cvmx_mio_boot_loc_dat_s cn63xx;
struct cvmx_mio_boot_loc_dat_s cn63xxp1;
+ struct cvmx_mio_boot_loc_dat_s cn66xx;
+ struct cvmx_mio_boot_loc_dat_s cn68xx;
+ struct cvmx_mio_boot_loc_dat_s cn68xxp1;
};
union cvmx_mio_boot_pin_defs {
uint64_t u64;
struct cvmx_mio_boot_pin_defs_s {
- uint64_t reserved_16_63:48;
+ uint64_t reserved_32_63:32;
+ uint64_t user1:16;
uint64_t ale:1;
uint64_t width:1;
uint64_t dmack_p2:1;
@@ -412,7 +491,7 @@ union cvmx_mio_boot_pin_defs {
uint64_t dmack_p0:1;
uint64_t term:2;
uint64_t nand:1;
- uint64_t reserved_0_7:8;
+ uint64_t user0:8;
} s;
struct cvmx_mio_boot_pin_defs_cn52xx {
uint64_t reserved_16_63:48;
@@ -435,8 +514,23 @@ union cvmx_mio_boot_pin_defs {
uint64_t term:2;
uint64_t reserved_0_8:9;
} cn56xx;
+ struct cvmx_mio_boot_pin_defs_cn61xx {
+ uint64_t reserved_32_63:32;
+ uint64_t user1:16;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t reserved_13_13:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p0:1;
+ uint64_t term:2;
+ uint64_t nand:1;
+ uint64_t user0:8;
+ } cn61xx;
struct cvmx_mio_boot_pin_defs_cn52xx cn63xx;
struct cvmx_mio_boot_pin_defs_cn52xx cn63xxp1;
+ struct cvmx_mio_boot_pin_defs_cn52xx cn66xx;
+ struct cvmx_mio_boot_pin_defs_cn52xx cn68xx;
+ struct cvmx_mio_boot_pin_defs_cn52xx cn68xxp1;
};
union cvmx_mio_boot_reg_cfgx {
@@ -498,8 +592,12 @@ union cvmx_mio_boot_reg_cfgx {
struct cvmx_mio_boot_reg_cfgx_s cn56xxp1;
struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xx;
struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xxp1;
+ struct cvmx_mio_boot_reg_cfgx_s cn61xx;
struct cvmx_mio_boot_reg_cfgx_s cn63xx;
struct cvmx_mio_boot_reg_cfgx_s cn63xxp1;
+ struct cvmx_mio_boot_reg_cfgx_s cn66xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn68xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn68xxp1;
};
union cvmx_mio_boot_reg_timx {
@@ -544,8 +642,12 @@ union cvmx_mio_boot_reg_timx {
struct cvmx_mio_boot_reg_timx_s cn56xxp1;
struct cvmx_mio_boot_reg_timx_s cn58xx;
struct cvmx_mio_boot_reg_timx_s cn58xxp1;
+ struct cvmx_mio_boot_reg_timx_s cn61xx;
struct cvmx_mio_boot_reg_timx_s cn63xx;
struct cvmx_mio_boot_reg_timx_s cn63xxp1;
+ struct cvmx_mio_boot_reg_timx_s cn66xx;
+ struct cvmx_mio_boot_reg_timx_s cn68xx;
+ struct cvmx_mio_boot_reg_timx_s cn68xxp1;
};
union cvmx_mio_boot_thr {
@@ -574,8 +676,231 @@ union cvmx_mio_boot_thr {
struct cvmx_mio_boot_thr_s cn56xxp1;
struct cvmx_mio_boot_thr_cn30xx cn58xx;
struct cvmx_mio_boot_thr_cn30xx cn58xxp1;
+ struct cvmx_mio_boot_thr_s cn61xx;
struct cvmx_mio_boot_thr_s cn63xx;
struct cvmx_mio_boot_thr_s cn63xxp1;
+ struct cvmx_mio_boot_thr_s cn66xx;
+ struct cvmx_mio_boot_thr_s cn68xx;
+ struct cvmx_mio_boot_thr_s cn68xxp1;
+};
+
+union cvmx_mio_emm_buf_dat {
+ uint64_t u64;
+ struct cvmx_mio_emm_buf_dat_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_mio_emm_buf_dat_s cn61xx;
+};
+
+union cvmx_mio_emm_buf_idx {
+ uint64_t u64;
+ struct cvmx_mio_emm_buf_idx_s {
+ uint64_t reserved_17_63:47;
+ uint64_t inc:1;
+ uint64_t reserved_7_15:9;
+ uint64_t buf_num:1;
+ uint64_t offset:6;
+ } s;
+ struct cvmx_mio_emm_buf_idx_s cn61xx;
+};
+
+union cvmx_mio_emm_cfg {
+ uint64_t u64;
+ struct cvmx_mio_emm_cfg_s {
+ uint64_t reserved_17_63:47;
+ uint64_t boot_fail:1;
+ uint64_t reserved_4_15:12;
+ uint64_t bus_ena:4;
+ } s;
+ struct cvmx_mio_emm_cfg_s cn61xx;
+};
+
+union cvmx_mio_emm_cmd {
+ uint64_t u64;
+ struct cvmx_mio_emm_cmd_s {
+ uint64_t reserved_62_63:2;
+ uint64_t bus_id:2;
+ uint64_t cmd_val:1;
+ uint64_t reserved_56_58:3;
+ uint64_t dbuf:1;
+ uint64_t offset:6;
+ uint64_t reserved_43_48:6;
+ uint64_t ctype_xor:2;
+ uint64_t rtype_xor:3;
+ uint64_t cmd_idx:6;
+ uint64_t arg:32;
+ } s;
+ struct cvmx_mio_emm_cmd_s cn61xx;
+};
+
+union cvmx_mio_emm_dma {
+ uint64_t u64;
+ struct cvmx_mio_emm_dma_s {
+ uint64_t reserved_62_63:2;
+ uint64_t bus_id:2;
+ uint64_t dma_val:1;
+ uint64_t sector:1;
+ uint64_t dat_null:1;
+ uint64_t thres:6;
+ uint64_t rel_wr:1;
+ uint64_t rw:1;
+ uint64_t multi:1;
+ uint64_t block_cnt:16;
+ uint64_t card_addr:32;
+ } s;
+ struct cvmx_mio_emm_dma_s cn61xx;
+};
+
+union cvmx_mio_emm_int {
+ uint64_t u64;
+ struct cvmx_mio_emm_int_s {
+ uint64_t reserved_7_63:57;
+ uint64_t switch_err:1;
+ uint64_t switch_done:1;
+ uint64_t dma_err:1;
+ uint64_t cmd_err:1;
+ uint64_t dma_done:1;
+ uint64_t cmd_done:1;
+ uint64_t buf_done:1;
+ } s;
+ struct cvmx_mio_emm_int_s cn61xx;
+};
+
+union cvmx_mio_emm_int_en {
+ uint64_t u64;
+ struct cvmx_mio_emm_int_en_s {
+ uint64_t reserved_7_63:57;
+ uint64_t switch_err:1;
+ uint64_t switch_done:1;
+ uint64_t dma_err:1;
+ uint64_t cmd_err:1;
+ uint64_t dma_done:1;
+ uint64_t cmd_done:1;
+ uint64_t buf_done:1;
+ } s;
+ struct cvmx_mio_emm_int_en_s cn61xx;
+};
+
+union cvmx_mio_emm_modex {
+ uint64_t u64;
+ struct cvmx_mio_emm_modex_s {
+ uint64_t reserved_49_63:15;
+ uint64_t hs_timing:1;
+ uint64_t reserved_43_47:5;
+ uint64_t bus_width:3;
+ uint64_t reserved_36_39:4;
+ uint64_t power_class:4;
+ uint64_t clk_hi:16;
+ uint64_t clk_lo:16;
+ } s;
+ struct cvmx_mio_emm_modex_s cn61xx;
+};
+
+union cvmx_mio_emm_rca {
+ uint64_t u64;
+ struct cvmx_mio_emm_rca_s {
+ uint64_t reserved_16_63:48;
+ uint64_t card_rca:16;
+ } s;
+ struct cvmx_mio_emm_rca_s cn61xx;
+};
+
+union cvmx_mio_emm_rsp_hi {
+ uint64_t u64;
+ struct cvmx_mio_emm_rsp_hi_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_mio_emm_rsp_hi_s cn61xx;
+};
+
+union cvmx_mio_emm_rsp_lo {
+ uint64_t u64;
+ struct cvmx_mio_emm_rsp_lo_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_mio_emm_rsp_lo_s cn61xx;
+};
+
+union cvmx_mio_emm_rsp_sts {
+ uint64_t u64;
+ struct cvmx_mio_emm_rsp_sts_s {
+ uint64_t reserved_62_63:2;
+ uint64_t bus_id:2;
+ uint64_t cmd_val:1;
+ uint64_t switch_val:1;
+ uint64_t dma_val:1;
+ uint64_t dma_pend:1;
+ uint64_t reserved_29_55:27;
+ uint64_t dbuf_err:1;
+ uint64_t reserved_24_27:4;
+ uint64_t dbuf:1;
+ uint64_t blk_timeout:1;
+ uint64_t blk_crc_err:1;
+ uint64_t rsp_busybit:1;
+ uint64_t stp_timeout:1;
+ uint64_t stp_crc_err:1;
+ uint64_t stp_bad_sts:1;
+ uint64_t stp_val:1;
+ uint64_t rsp_timeout:1;
+ uint64_t rsp_crc_err:1;
+ uint64_t rsp_bad_sts:1;
+ uint64_t rsp_val:1;
+ uint64_t rsp_type:3;
+ uint64_t cmd_type:2;
+ uint64_t cmd_idx:6;
+ uint64_t cmd_done:1;
+ } s;
+ struct cvmx_mio_emm_rsp_sts_s cn61xx;
+};
+
+union cvmx_mio_emm_sample {
+ uint64_t u64;
+ struct cvmx_mio_emm_sample_s {
+ uint64_t reserved_26_63:38;
+ uint64_t cmd_cnt:10;
+ uint64_t reserved_10_15:6;
+ uint64_t dat_cnt:10;
+ } s;
+ struct cvmx_mio_emm_sample_s cn61xx;
+};
+
+union cvmx_mio_emm_sts_mask {
+ uint64_t u64;
+ struct cvmx_mio_emm_sts_mask_s {
+ uint64_t reserved_32_63:32;
+ uint64_t sts_msk:32;
+ } s;
+ struct cvmx_mio_emm_sts_mask_s cn61xx;
+};
+
+union cvmx_mio_emm_switch {
+ uint64_t u64;
+ struct cvmx_mio_emm_switch_s {
+ uint64_t reserved_62_63:2;
+ uint64_t bus_id:2;
+ uint64_t switch_exe:1;
+ uint64_t switch_err0:1;
+ uint64_t switch_err1:1;
+ uint64_t switch_err2:1;
+ uint64_t reserved_49_55:7;
+ uint64_t hs_timing:1;
+ uint64_t reserved_43_47:5;
+ uint64_t bus_width:3;
+ uint64_t reserved_36_39:4;
+ uint64_t power_class:4;
+ uint64_t clk_hi:16;
+ uint64_t clk_lo:16;
+ } s;
+ struct cvmx_mio_emm_switch_s cn61xx;
+};
+
+union cvmx_mio_emm_wdog {
+ uint64_t u64;
+ struct cvmx_mio_emm_wdog_s {
+ uint64_t reserved_26_63:38;
+ uint64_t clk_cnt:26;
+ } s;
+ struct cvmx_mio_emm_wdog_s cn61xx;
};
union cvmx_mio_fus_bnk_datx {
@@ -590,8 +915,12 @@ union cvmx_mio_fus_bnk_datx {
struct cvmx_mio_fus_bnk_datx_s cn56xxp1;
struct cvmx_mio_fus_bnk_datx_s cn58xx;
struct cvmx_mio_fus_bnk_datx_s cn58xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cn61xx;
struct cvmx_mio_fus_bnk_datx_s cn63xx;
struct cvmx_mio_fus_bnk_datx_s cn63xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cn66xx;
+ struct cvmx_mio_fus_bnk_datx_s cn68xx;
+ struct cvmx_mio_fus_bnk_datx_s cn68xxp1;
};
union cvmx_mio_fus_dat0 {
@@ -611,8 +940,12 @@ union cvmx_mio_fus_dat0 {
struct cvmx_mio_fus_dat0_s cn56xxp1;
struct cvmx_mio_fus_dat0_s cn58xx;
struct cvmx_mio_fus_dat0_s cn58xxp1;
+ struct cvmx_mio_fus_dat0_s cn61xx;
struct cvmx_mio_fus_dat0_s cn63xx;
struct cvmx_mio_fus_dat0_s cn63xxp1;
+ struct cvmx_mio_fus_dat0_s cn66xx;
+ struct cvmx_mio_fus_dat0_s cn68xx;
+ struct cvmx_mio_fus_dat0_s cn68xxp1;
};
union cvmx_mio_fus_dat1 {
@@ -632,14 +965,21 @@ union cvmx_mio_fus_dat1 {
struct cvmx_mio_fus_dat1_s cn56xxp1;
struct cvmx_mio_fus_dat1_s cn58xx;
struct cvmx_mio_fus_dat1_s cn58xxp1;
+ struct cvmx_mio_fus_dat1_s cn61xx;
struct cvmx_mio_fus_dat1_s cn63xx;
struct cvmx_mio_fus_dat1_s cn63xxp1;
+ struct cvmx_mio_fus_dat1_s cn66xx;
+ struct cvmx_mio_fus_dat1_s cn68xx;
+ struct cvmx_mio_fus_dat1_s cn68xxp1;
};
union cvmx_mio_fus_dat2 {
uint64_t u64;
struct cvmx_mio_fus_dat2_s {
- uint64_t reserved_35_63:29;
+ uint64_t reserved_48_63:16;
+ uint64_t fus118:1;
+ uint64_t rom_info:10;
+ uint64_t power_limit:2;
uint64_t dorm_crypto:1;
uint64_t fus318:1;
uint64_t raid_en:1;
@@ -747,6 +1087,23 @@ union cvmx_mio_fus_dat2 {
uint64_t pp_dis:16;
} cn58xx;
struct cvmx_mio_fus_dat2_cn58xx cn58xxp1;
+ struct cvmx_mio_fus_dat2_cn61xx {
+ uint64_t reserved_48_63:16;
+ uint64_t fus118:1;
+ uint64_t rom_info:10;
+ uint64_t power_limit:2;
+ uint64_t dorm_crypto:1;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_29_31:3;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t reserved_24_25:2;
+ uint64_t chip_id:8;
+ uint64_t reserved_4_15:12;
+ uint64_t pp_dis:4;
+ } cn61xx;
struct cvmx_mio_fus_dat2_cn63xx {
uint64_t reserved_35_63:29;
uint64_t dorm_crypto:1;
@@ -762,6 +1119,38 @@ union cvmx_mio_fus_dat2 {
uint64_t pp_dis:6;
} cn63xx;
struct cvmx_mio_fus_dat2_cn63xx cn63xxp1;
+ struct cvmx_mio_fus_dat2_cn66xx {
+ uint64_t reserved_48_63:16;
+ uint64_t fus118:1;
+ uint64_t rom_info:10;
+ uint64_t power_limit:2;
+ uint64_t dorm_crypto:1;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_29_31:3;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t reserved_24_25:2;
+ uint64_t chip_id:8;
+ uint64_t reserved_10_15:6;
+ uint64_t pp_dis:10;
+ } cn66xx;
+ struct cvmx_mio_fus_dat2_cn68xx {
+ uint64_t reserved_37_63:27;
+ uint64_t power_limit:2;
+ uint64_t dorm_crypto:1;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_29_31:3;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t reserved_24_25:2;
+ uint64_t chip_id:8;
+ uint64_t reserved_0_15:16;
+ } cn68xx;
+ struct cvmx_mio_fus_dat2_cn68xx cn68xxp1;
};
union cvmx_mio_fus_dat3 {
@@ -834,7 +1223,7 @@ union cvmx_mio_fus_dat3 {
struct cvmx_mio_fus_dat3_cn38xx cn56xxp1;
struct cvmx_mio_fus_dat3_cn38xx cn58xx;
struct cvmx_mio_fus_dat3_cn38xx cn58xxp1;
- struct cvmx_mio_fus_dat3_cn63xx {
+ struct cvmx_mio_fus_dat3_cn61xx {
uint64_t reserved_58_63:6;
uint64_t pll_ctl:10;
uint64_t dfa_info_dte:3;
@@ -853,8 +1242,12 @@ union cvmx_mio_fus_dat3 {
uint64_t nozip:1;
uint64_t nodfa_dte:1;
uint64_t reserved_0_23:24;
- } cn63xx;
- struct cvmx_mio_fus_dat3_cn63xx cn63xxp1;
+ } cn61xx;
+ struct cvmx_mio_fus_dat3_cn61xx cn63xx;
+ struct cvmx_mio_fus_dat3_cn61xx cn63xxp1;
+ struct cvmx_mio_fus_dat3_cn61xx cn66xx;
+ struct cvmx_mio_fus_dat3_cn61xx cn68xx;
+ struct cvmx_mio_fus_dat3_cn61xx cn68xxp1;
};
union cvmx_mio_fus_ema {
@@ -875,8 +1268,12 @@ union cvmx_mio_fus_ema {
uint64_t ema:2;
} cn58xx;
struct cvmx_mio_fus_ema_cn58xx cn58xxp1;
+ struct cvmx_mio_fus_ema_s cn61xx;
struct cvmx_mio_fus_ema_s cn63xx;
struct cvmx_mio_fus_ema_s cn63xxp1;
+ struct cvmx_mio_fus_ema_s cn66xx;
+ struct cvmx_mio_fus_ema_s cn68xx;
+ struct cvmx_mio_fus_ema_s cn68xxp1;
};
union cvmx_mio_fus_pdf {
@@ -890,14 +1287,21 @@ union cvmx_mio_fus_pdf {
struct cvmx_mio_fus_pdf_s cn56xx;
struct cvmx_mio_fus_pdf_s cn56xxp1;
struct cvmx_mio_fus_pdf_s cn58xx;
+ struct cvmx_mio_fus_pdf_s cn61xx;
struct cvmx_mio_fus_pdf_s cn63xx;
struct cvmx_mio_fus_pdf_s cn63xxp1;
+ struct cvmx_mio_fus_pdf_s cn66xx;
+ struct cvmx_mio_fus_pdf_s cn68xx;
+ struct cvmx_mio_fus_pdf_s cn68xxp1;
};
union cvmx_mio_fus_pll {
uint64_t u64;
struct cvmx_mio_fus_pll_s {
- uint64_t reserved_8_63:56;
+ uint64_t reserved_48_63:16;
+ uint64_t rclk_align_r:8;
+ uint64_t rclk_align_l:8;
+ uint64_t reserved_8_31:24;
uint64_t c_cout_rst:1;
uint64_t c_cout_sel:2;
uint64_t pnr_cout_rst:1;
@@ -916,8 +1320,20 @@ union cvmx_mio_fus_pll {
struct cvmx_mio_fus_pll_cn50xx cn56xxp1;
struct cvmx_mio_fus_pll_cn50xx cn58xx;
struct cvmx_mio_fus_pll_cn50xx cn58xxp1;
- struct cvmx_mio_fus_pll_s cn63xx;
- struct cvmx_mio_fus_pll_s cn63xxp1;
+ struct cvmx_mio_fus_pll_cn61xx {
+ uint64_t reserved_8_63:56;
+ uint64_t c_cout_rst:1;
+ uint64_t c_cout_sel:2;
+ uint64_t pnr_cout_rst:1;
+ uint64_t pnr_cout_sel:2;
+ uint64_t rfslip:1;
+ uint64_t fbslip:1;
+ } cn61xx;
+ struct cvmx_mio_fus_pll_cn61xx cn63xx;
+ struct cvmx_mio_fus_pll_cn61xx cn63xxp1;
+ struct cvmx_mio_fus_pll_cn61xx cn66xx;
+ struct cvmx_mio_fus_pll_s cn68xx;
+ struct cvmx_mio_fus_pll_s cn68xxp1;
};
union cvmx_mio_fus_prog {
@@ -941,8 +1357,12 @@ union cvmx_mio_fus_prog {
struct cvmx_mio_fus_prog_cn30xx cn56xxp1;
struct cvmx_mio_fus_prog_cn30xx cn58xx;
struct cvmx_mio_fus_prog_cn30xx cn58xxp1;
+ struct cvmx_mio_fus_prog_s cn61xx;
struct cvmx_mio_fus_prog_s cn63xx;
struct cvmx_mio_fus_prog_s cn63xxp1;
+ struct cvmx_mio_fus_prog_s cn66xx;
+ struct cvmx_mio_fus_prog_s cn68xx;
+ struct cvmx_mio_fus_prog_s cn68xxp1;
};
union cvmx_mio_fus_prog_times {
@@ -969,7 +1389,7 @@ union cvmx_mio_fus_prog_times {
struct cvmx_mio_fus_prog_times_cn50xx cn56xxp1;
struct cvmx_mio_fus_prog_times_cn50xx cn58xx;
struct cvmx_mio_fus_prog_times_cn50xx cn58xxp1;
- struct cvmx_mio_fus_prog_times_cn63xx {
+ struct cvmx_mio_fus_prog_times_cn61xx {
uint64_t reserved_35_63:29;
uint64_t vgate_pin:1;
uint64_t fsrc_pin:1;
@@ -978,8 +1398,12 @@ union cvmx_mio_fus_prog_times {
uint64_t sclk_lo:4;
uint64_t sclk_hi:15;
uint64_t setup:6;
- } cn63xx;
- struct cvmx_mio_fus_prog_times_cn63xx cn63xxp1;
+ } cn61xx;
+ struct cvmx_mio_fus_prog_times_cn61xx cn63xx;
+ struct cvmx_mio_fus_prog_times_cn61xx cn63xxp1;
+ struct cvmx_mio_fus_prog_times_cn61xx cn66xx;
+ struct cvmx_mio_fus_prog_times_cn61xx cn68xx;
+ struct cvmx_mio_fus_prog_times_cn61xx cn68xxp1;
};
union cvmx_mio_fus_rcmd {
@@ -1013,8 +1437,12 @@ union cvmx_mio_fus_rcmd {
struct cvmx_mio_fus_rcmd_s cn56xxp1;
struct cvmx_mio_fus_rcmd_cn30xx cn58xx;
struct cvmx_mio_fus_rcmd_cn30xx cn58xxp1;
+ struct cvmx_mio_fus_rcmd_s cn61xx;
struct cvmx_mio_fus_rcmd_s cn63xx;
struct cvmx_mio_fus_rcmd_s cn63xxp1;
+ struct cvmx_mio_fus_rcmd_s cn66xx;
+ struct cvmx_mio_fus_rcmd_s cn68xx;
+ struct cvmx_mio_fus_rcmd_s cn68xxp1;
};
union cvmx_mio_fus_read_times {
@@ -1027,8 +1455,12 @@ union cvmx_mio_fus_read_times {
uint64_t sdh:4;
uint64_t setup:10;
} s;
+ struct cvmx_mio_fus_read_times_s cn61xx;
struct cvmx_mio_fus_read_times_s cn63xx;
struct cvmx_mio_fus_read_times_s cn63xxp1;
+ struct cvmx_mio_fus_read_times_s cn66xx;
+ struct cvmx_mio_fus_read_times_s cn68xx;
+ struct cvmx_mio_fus_read_times_s cn68xxp1;
};
union cvmx_mio_fus_repair_res0 {
@@ -1040,8 +1472,12 @@ union cvmx_mio_fus_repair_res0 {
uint64_t repair1:18;
uint64_t repair0:18;
} s;
+ struct cvmx_mio_fus_repair_res0_s cn61xx;
struct cvmx_mio_fus_repair_res0_s cn63xx;
struct cvmx_mio_fus_repair_res0_s cn63xxp1;
+ struct cvmx_mio_fus_repair_res0_s cn66xx;
+ struct cvmx_mio_fus_repair_res0_s cn68xx;
+ struct cvmx_mio_fus_repair_res0_s cn68xxp1;
};
union cvmx_mio_fus_repair_res1 {
@@ -1052,8 +1488,12 @@ union cvmx_mio_fus_repair_res1 {
uint64_t repair4:18;
uint64_t repair3:18;
} s;
+ struct cvmx_mio_fus_repair_res1_s cn61xx;
struct cvmx_mio_fus_repair_res1_s cn63xx;
struct cvmx_mio_fus_repair_res1_s cn63xxp1;
+ struct cvmx_mio_fus_repair_res1_s cn66xx;
+ struct cvmx_mio_fus_repair_res1_s cn68xx;
+ struct cvmx_mio_fus_repair_res1_s cn68xxp1;
};
union cvmx_mio_fus_repair_res2 {
@@ -1062,8 +1502,12 @@ union cvmx_mio_fus_repair_res2 {
uint64_t reserved_18_63:46;
uint64_t repair6:18;
} s;
+ struct cvmx_mio_fus_repair_res2_s cn61xx;
struct cvmx_mio_fus_repair_res2_s cn63xx;
struct cvmx_mio_fus_repair_res2_s cn63xxp1;
+ struct cvmx_mio_fus_repair_res2_s cn66xx;
+ struct cvmx_mio_fus_repair_res2_s cn68xx;
+ struct cvmx_mio_fus_repair_res2_s cn68xxp1;
};
union cvmx_mio_fus_spr_repair_res {
@@ -1084,8 +1528,12 @@ union cvmx_mio_fus_spr_repair_res {
struct cvmx_mio_fus_spr_repair_res_s cn56xxp1;
struct cvmx_mio_fus_spr_repair_res_s cn58xx;
struct cvmx_mio_fus_spr_repair_res_s cn58xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cn61xx;
struct cvmx_mio_fus_spr_repair_res_s cn63xx;
struct cvmx_mio_fus_spr_repair_res_s cn63xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cn66xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn68xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn68xxp1;
};
union cvmx_mio_fus_spr_repair_sum {
@@ -1104,8 +1552,22 @@ union cvmx_mio_fus_spr_repair_sum {
struct cvmx_mio_fus_spr_repair_sum_s cn56xxp1;
struct cvmx_mio_fus_spr_repair_sum_s cn58xx;
struct cvmx_mio_fus_spr_repair_sum_s cn58xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cn61xx;
struct cvmx_mio_fus_spr_repair_sum_s cn63xx;
struct cvmx_mio_fus_spr_repair_sum_s cn63xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cn66xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn68xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn68xxp1;
+};
+
+union cvmx_mio_fus_tgg {
+ uint64_t u64;
+ struct cvmx_mio_fus_tgg_s {
+ uint64_t val:1;
+ uint64_t dat:63;
+ } s;
+ struct cvmx_mio_fus_tgg_s cn61xx;
+ struct cvmx_mio_fus_tgg_s cn66xx;
};
union cvmx_mio_fus_unlock {
@@ -1141,11 +1603,15 @@ union cvmx_mio_fus_wadr {
struct cvmx_mio_fus_wadr_cn52xx cn56xxp1;
struct cvmx_mio_fus_wadr_cn50xx cn58xx;
struct cvmx_mio_fus_wadr_cn50xx cn58xxp1;
- struct cvmx_mio_fus_wadr_cn63xx {
+ struct cvmx_mio_fus_wadr_cn61xx {
uint64_t reserved_4_63:60;
uint64_t addr:4;
- } cn63xx;
- struct cvmx_mio_fus_wadr_cn63xx cn63xxp1;
+ } cn61xx;
+ struct cvmx_mio_fus_wadr_cn61xx cn63xx;
+ struct cvmx_mio_fus_wadr_cn61xx cn63xxp1;
+ struct cvmx_mio_fus_wadr_cn61xx cn66xx;
+ struct cvmx_mio_fus_wadr_cn61xx cn68xx;
+ struct cvmx_mio_fus_wadr_cn61xx cn68xxp1;
};
union cvmx_mio_gpio_comp {
@@ -1155,8 +1621,12 @@ union cvmx_mio_gpio_comp {
uint64_t pctl:6;
uint64_t nctl:6;
} s;
+ struct cvmx_mio_gpio_comp_s cn61xx;
struct cvmx_mio_gpio_comp_s cn63xx;
struct cvmx_mio_gpio_comp_s cn63xxp1;
+ struct cvmx_mio_gpio_comp_s cn66xx;
+ struct cvmx_mio_gpio_comp_s cn68xx;
+ struct cvmx_mio_gpio_comp_s cn68xxp1;
};
union cvmx_mio_ndf_dma_cfg {
@@ -1174,8 +1644,12 @@ union cvmx_mio_ndf_dma_cfg {
uint64_t adr:36;
} s;
struct cvmx_mio_ndf_dma_cfg_s cn52xx;
+ struct cvmx_mio_ndf_dma_cfg_s cn61xx;
struct cvmx_mio_ndf_dma_cfg_s cn63xx;
struct cvmx_mio_ndf_dma_cfg_s cn63xxp1;
+ struct cvmx_mio_ndf_dma_cfg_s cn66xx;
+ struct cvmx_mio_ndf_dma_cfg_s cn68xx;
+ struct cvmx_mio_ndf_dma_cfg_s cn68xxp1;
};
union cvmx_mio_ndf_dma_int {
@@ -1185,8 +1659,12 @@ union cvmx_mio_ndf_dma_int {
uint64_t done:1;
} s;
struct cvmx_mio_ndf_dma_int_s cn52xx;
+ struct cvmx_mio_ndf_dma_int_s cn61xx;
struct cvmx_mio_ndf_dma_int_s cn63xx;
struct cvmx_mio_ndf_dma_int_s cn63xxp1;
+ struct cvmx_mio_ndf_dma_int_s cn66xx;
+ struct cvmx_mio_ndf_dma_int_s cn68xx;
+ struct cvmx_mio_ndf_dma_int_s cn68xxp1;
};
union cvmx_mio_ndf_dma_int_en {
@@ -1196,8 +1674,12 @@ union cvmx_mio_ndf_dma_int_en {
uint64_t done:1;
} s;
struct cvmx_mio_ndf_dma_int_en_s cn52xx;
+ struct cvmx_mio_ndf_dma_int_en_s cn61xx;
struct cvmx_mio_ndf_dma_int_en_s cn63xx;
struct cvmx_mio_ndf_dma_int_en_s cn63xxp1;
+ struct cvmx_mio_ndf_dma_int_en_s cn66xx;
+ struct cvmx_mio_ndf_dma_int_en_s cn68xx;
+ struct cvmx_mio_ndf_dma_int_en_s cn68xxp1;
};
union cvmx_mio_pll_ctl {
@@ -1220,10 +1702,63 @@ union cvmx_mio_pll_setting {
struct cvmx_mio_pll_setting_s cn31xx;
};
+union cvmx_mio_ptp_ckout_hi_incr {
+ uint64_t u64;
+ struct cvmx_mio_ptp_ckout_hi_incr_s {
+ uint64_t nanosec:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_ckout_hi_incr_s cn61xx;
+ struct cvmx_mio_ptp_ckout_hi_incr_s cn66xx;
+ struct cvmx_mio_ptp_ckout_hi_incr_s cn68xx;
+};
+
+union cvmx_mio_ptp_ckout_lo_incr {
+ uint64_t u64;
+ struct cvmx_mio_ptp_ckout_lo_incr_s {
+ uint64_t nanosec:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_ckout_lo_incr_s cn61xx;
+ struct cvmx_mio_ptp_ckout_lo_incr_s cn66xx;
+ struct cvmx_mio_ptp_ckout_lo_incr_s cn68xx;
+};
+
+union cvmx_mio_ptp_ckout_thresh_hi {
+ uint64_t u64;
+ struct cvmx_mio_ptp_ckout_thresh_hi_s {
+ uint64_t nanosec:64;
+ } s;
+ struct cvmx_mio_ptp_ckout_thresh_hi_s cn61xx;
+ struct cvmx_mio_ptp_ckout_thresh_hi_s cn66xx;
+ struct cvmx_mio_ptp_ckout_thresh_hi_s cn68xx;
+};
+
+union cvmx_mio_ptp_ckout_thresh_lo {
+ uint64_t u64;
+ struct cvmx_mio_ptp_ckout_thresh_lo_s {
+ uint64_t reserved_32_63:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_ckout_thresh_lo_s cn61xx;
+ struct cvmx_mio_ptp_ckout_thresh_lo_s cn66xx;
+ struct cvmx_mio_ptp_ckout_thresh_lo_s cn68xx;
+};
+
union cvmx_mio_ptp_clock_cfg {
uint64_t u64;
struct cvmx_mio_ptp_clock_cfg_s {
- uint64_t reserved_24_63:40;
+ uint64_t reserved_42_63:22;
+ uint64_t pps:1;
+ uint64_t ckout:1;
+ uint64_t ext_clk_edge:2;
+ uint64_t ckout_out4:1;
+ uint64_t pps_out:5;
+ uint64_t pps_inv:1;
+ uint64_t pps_en:1;
+ uint64_t ckout_out:4;
+ uint64_t ckout_inv:1;
+ uint64_t ckout_en:1;
uint64_t evcnt_in:6;
uint64_t evcnt_edge:1;
uint64_t evcnt_en:1;
@@ -1234,8 +1769,42 @@ union cvmx_mio_ptp_clock_cfg {
uint64_t ext_clk_en:1;
uint64_t ptp_en:1;
} s;
- struct cvmx_mio_ptp_clock_cfg_s cn63xx;
- struct cvmx_mio_ptp_clock_cfg_s cn63xxp1;
+ struct cvmx_mio_ptp_clock_cfg_s cn61xx;
+ struct cvmx_mio_ptp_clock_cfg_cn63xx {
+ uint64_t reserved_24_63:40;
+ uint64_t evcnt_in:6;
+ uint64_t evcnt_edge:1;
+ uint64_t evcnt_en:1;
+ uint64_t tstmp_in:6;
+ uint64_t tstmp_edge:1;
+ uint64_t tstmp_en:1;
+ uint64_t ext_clk_in:6;
+ uint64_t ext_clk_en:1;
+ uint64_t ptp_en:1;
+ } cn63xx;
+ struct cvmx_mio_ptp_clock_cfg_cn63xx cn63xxp1;
+ struct cvmx_mio_ptp_clock_cfg_cn66xx {
+ uint64_t reserved_40_63:24;
+ uint64_t ext_clk_edge:2;
+ uint64_t ckout_out4:1;
+ uint64_t pps_out:5;
+ uint64_t pps_inv:1;
+ uint64_t pps_en:1;
+ uint64_t ckout_out:4;
+ uint64_t ckout_inv:1;
+ uint64_t ckout_en:1;
+ uint64_t evcnt_in:6;
+ uint64_t evcnt_edge:1;
+ uint64_t evcnt_en:1;
+ uint64_t tstmp_in:6;
+ uint64_t tstmp_edge:1;
+ uint64_t tstmp_en:1;
+ uint64_t ext_clk_in:6;
+ uint64_t ext_clk_en:1;
+ uint64_t ptp_en:1;
+ } cn66xx;
+ struct cvmx_mio_ptp_clock_cfg_s cn68xx;
+ struct cvmx_mio_ptp_clock_cfg_cn63xx cn68xxp1;
};
union cvmx_mio_ptp_clock_comp {
@@ -1244,8 +1813,12 @@ union cvmx_mio_ptp_clock_comp {
uint64_t nanosec:32;
uint64_t frnanosec:32;
} s;
+ struct cvmx_mio_ptp_clock_comp_s cn61xx;
struct cvmx_mio_ptp_clock_comp_s cn63xx;
struct cvmx_mio_ptp_clock_comp_s cn63xxp1;
+ struct cvmx_mio_ptp_clock_comp_s cn66xx;
+ struct cvmx_mio_ptp_clock_comp_s cn68xx;
+ struct cvmx_mio_ptp_clock_comp_s cn68xxp1;
};
union cvmx_mio_ptp_clock_hi {
@@ -1253,8 +1826,12 @@ union cvmx_mio_ptp_clock_hi {
struct cvmx_mio_ptp_clock_hi_s {
uint64_t nanosec:64;
} s;
+ struct cvmx_mio_ptp_clock_hi_s cn61xx;
struct cvmx_mio_ptp_clock_hi_s cn63xx;
struct cvmx_mio_ptp_clock_hi_s cn63xxp1;
+ struct cvmx_mio_ptp_clock_hi_s cn66xx;
+ struct cvmx_mio_ptp_clock_hi_s cn68xx;
+ struct cvmx_mio_ptp_clock_hi_s cn68xxp1;
};
union cvmx_mio_ptp_clock_lo {
@@ -1263,8 +1840,12 @@ union cvmx_mio_ptp_clock_lo {
uint64_t reserved_32_63:32;
uint64_t frnanosec:32;
} s;
+ struct cvmx_mio_ptp_clock_lo_s cn61xx;
struct cvmx_mio_ptp_clock_lo_s cn63xx;
struct cvmx_mio_ptp_clock_lo_s cn63xxp1;
+ struct cvmx_mio_ptp_clock_lo_s cn66xx;
+ struct cvmx_mio_ptp_clock_lo_s cn68xx;
+ struct cvmx_mio_ptp_clock_lo_s cn68xxp1;
};
union cvmx_mio_ptp_evt_cnt {
@@ -1272,8 +1853,55 @@ union cvmx_mio_ptp_evt_cnt {
struct cvmx_mio_ptp_evt_cnt_s {
uint64_t cntr:64;
} s;
+ struct cvmx_mio_ptp_evt_cnt_s cn61xx;
struct cvmx_mio_ptp_evt_cnt_s cn63xx;
struct cvmx_mio_ptp_evt_cnt_s cn63xxp1;
+ struct cvmx_mio_ptp_evt_cnt_s cn66xx;
+ struct cvmx_mio_ptp_evt_cnt_s cn68xx;
+ struct cvmx_mio_ptp_evt_cnt_s cn68xxp1;
+};
+
+union cvmx_mio_ptp_pps_hi_incr {
+ uint64_t u64;
+ struct cvmx_mio_ptp_pps_hi_incr_s {
+ uint64_t nanosec:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_pps_hi_incr_s cn61xx;
+ struct cvmx_mio_ptp_pps_hi_incr_s cn66xx;
+ struct cvmx_mio_ptp_pps_hi_incr_s cn68xx;
+};
+
+union cvmx_mio_ptp_pps_lo_incr {
+ uint64_t u64;
+ struct cvmx_mio_ptp_pps_lo_incr_s {
+ uint64_t nanosec:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_pps_lo_incr_s cn61xx;
+ struct cvmx_mio_ptp_pps_lo_incr_s cn66xx;
+ struct cvmx_mio_ptp_pps_lo_incr_s cn68xx;
+};
+
+union cvmx_mio_ptp_pps_thresh_hi {
+ uint64_t u64;
+ struct cvmx_mio_ptp_pps_thresh_hi_s {
+ uint64_t nanosec:64;
+ } s;
+ struct cvmx_mio_ptp_pps_thresh_hi_s cn61xx;
+ struct cvmx_mio_ptp_pps_thresh_hi_s cn66xx;
+ struct cvmx_mio_ptp_pps_thresh_hi_s cn68xx;
+};
+
+union cvmx_mio_ptp_pps_thresh_lo {
+ uint64_t u64;
+ struct cvmx_mio_ptp_pps_thresh_lo_s {
+ uint64_t reserved_32_63:32;
+ uint64_t frnanosec:32;
+ } s;
+ struct cvmx_mio_ptp_pps_thresh_lo_s cn61xx;
+ struct cvmx_mio_ptp_pps_thresh_lo_s cn66xx;
+ struct cvmx_mio_ptp_pps_thresh_lo_s cn68xx;
};
union cvmx_mio_ptp_timestamp {
@@ -1281,14 +1909,52 @@ union cvmx_mio_ptp_timestamp {
struct cvmx_mio_ptp_timestamp_s {
uint64_t nanosec:64;
} s;
+ struct cvmx_mio_ptp_timestamp_s cn61xx;
struct cvmx_mio_ptp_timestamp_s cn63xx;
struct cvmx_mio_ptp_timestamp_s cn63xxp1;
+ struct cvmx_mio_ptp_timestamp_s cn66xx;
+ struct cvmx_mio_ptp_timestamp_s cn68xx;
+ struct cvmx_mio_ptp_timestamp_s cn68xxp1;
+};
+
+union cvmx_mio_qlmx_cfg {
+ uint64_t u64;
+ struct cvmx_mio_qlmx_cfg_s {
+ uint64_t reserved_12_63:52;
+ uint64_t qlm_spd:4;
+ uint64_t reserved_4_7:4;
+ uint64_t qlm_cfg:4;
+ } s;
+ struct cvmx_mio_qlmx_cfg_cn61xx {
+ uint64_t reserved_12_63:52;
+ uint64_t qlm_spd:4;
+ uint64_t reserved_2_7:6;
+ uint64_t qlm_cfg:2;
+ } cn61xx;
+ struct cvmx_mio_qlmx_cfg_s cn66xx;
+ struct cvmx_mio_qlmx_cfg_cn68xx {
+ uint64_t reserved_12_63:52;
+ uint64_t qlm_spd:4;
+ uint64_t reserved_3_7:5;
+ uint64_t qlm_cfg:3;
+ } cn68xx;
+ struct cvmx_mio_qlmx_cfg_cn68xx cn68xxp1;
};
union cvmx_mio_rst_boot {
uint64_t u64;
struct cvmx_mio_rst_boot_s {
- uint64_t reserved_36_63:28;
+ uint64_t chipkill:1;
+ uint64_t jtcsrdis:1;
+ uint64_t ejtagdis:1;
+ uint64_t romen:1;
+ uint64_t ckill_ppdis:1;
+ uint64_t jt_tstmode:1;
+ uint64_t reserved_50_57:8;
+ uint64_t lboot_ext:2;
+ uint64_t reserved_44_47:4;
+ uint64_t qlm4_spd:4;
+ uint64_t qlm3_spd:4;
uint64_t c_mul:6;
uint64_t pnr_mul:6;
uint64_t qlm2_spd:4;
@@ -1298,32 +1964,168 @@ union cvmx_mio_rst_boot {
uint64_t rboot:1;
uint64_t rboot_pin:1;
} s;
- struct cvmx_mio_rst_boot_s cn63xx;
- struct cvmx_mio_rst_boot_s cn63xxp1;
+ struct cvmx_mio_rst_boot_cn61xx {
+ uint64_t chipkill:1;
+ uint64_t jtcsrdis:1;
+ uint64_t ejtagdis:1;
+ uint64_t romen:1;
+ uint64_t ckill_ppdis:1;
+ uint64_t jt_tstmode:1;
+ uint64_t reserved_50_57:8;
+ uint64_t lboot_ext:2;
+ uint64_t reserved_36_47:12;
+ uint64_t c_mul:6;
+ uint64_t pnr_mul:6;
+ uint64_t qlm2_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm0_spd:4;
+ uint64_t lboot:10;
+ uint64_t rboot:1;
+ uint64_t rboot_pin:1;
+ } cn61xx;
+ struct cvmx_mio_rst_boot_cn63xx {
+ uint64_t reserved_36_63:28;
+ uint64_t c_mul:6;
+ uint64_t pnr_mul:6;
+ uint64_t qlm2_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm0_spd:4;
+ uint64_t lboot:10;
+ uint64_t rboot:1;
+ uint64_t rboot_pin:1;
+ } cn63xx;
+ struct cvmx_mio_rst_boot_cn63xx cn63xxp1;
+ struct cvmx_mio_rst_boot_cn66xx {
+ uint64_t chipkill:1;
+ uint64_t jtcsrdis:1;
+ uint64_t ejtagdis:1;
+ uint64_t romen:1;
+ uint64_t ckill_ppdis:1;
+ uint64_t reserved_50_58:9;
+ uint64_t lboot_ext:2;
+ uint64_t reserved_36_47:12;
+ uint64_t c_mul:6;
+ uint64_t pnr_mul:6;
+ uint64_t qlm2_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm0_spd:4;
+ uint64_t lboot:10;
+ uint64_t rboot:1;
+ uint64_t rboot_pin:1;
+ } cn66xx;
+ struct cvmx_mio_rst_boot_cn68xx {
+ uint64_t reserved_59_63:5;
+ uint64_t jt_tstmode:1;
+ uint64_t reserved_44_57:14;
+ uint64_t qlm4_spd:4;
+ uint64_t qlm3_spd:4;
+ uint64_t c_mul:6;
+ uint64_t pnr_mul:6;
+ uint64_t qlm2_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm0_spd:4;
+ uint64_t lboot:10;
+ uint64_t rboot:1;
+ uint64_t rboot_pin:1;
+ } cn68xx;
+ struct cvmx_mio_rst_boot_cn68xxp1 {
+ uint64_t reserved_44_63:20;
+ uint64_t qlm4_spd:4;
+ uint64_t qlm3_spd:4;
+ uint64_t c_mul:6;
+ uint64_t pnr_mul:6;
+ uint64_t qlm2_spd:4;
+ uint64_t qlm1_spd:4;
+ uint64_t qlm0_spd:4;
+ uint64_t lboot:10;
+ uint64_t rboot:1;
+ uint64_t rboot_pin:1;
+ } cn68xxp1;
};
union cvmx_mio_rst_cfg {
uint64_t u64;
struct cvmx_mio_rst_cfg_s {
+ uint64_t reserved_3_63:61;
+ uint64_t cntl_clr_bist:1;
+ uint64_t warm_clr_bist:1;
+ uint64_t soft_clr_bist:1;
+ } s;
+ struct cvmx_mio_rst_cfg_cn61xx {
uint64_t bist_delay:58;
uint64_t reserved_3_5:3;
uint64_t cntl_clr_bist:1;
uint64_t warm_clr_bist:1;
uint64_t soft_clr_bist:1;
- } s;
- struct cvmx_mio_rst_cfg_s cn63xx;
+ } cn61xx;
+ struct cvmx_mio_rst_cfg_cn61xx cn63xx;
struct cvmx_mio_rst_cfg_cn63xxp1 {
uint64_t bist_delay:58;
uint64_t reserved_2_5:4;
uint64_t warm_clr_bist:1;
uint64_t soft_clr_bist:1;
} cn63xxp1;
+ struct cvmx_mio_rst_cfg_cn61xx cn66xx;
+ struct cvmx_mio_rst_cfg_cn68xx {
+ uint64_t bist_delay:56;
+ uint64_t reserved_3_7:5;
+ uint64_t cntl_clr_bist:1;
+ uint64_t warm_clr_bist:1;
+ uint64_t soft_clr_bist:1;
+ } cn68xx;
+ struct cvmx_mio_rst_cfg_cn68xx cn68xxp1;
+};
+
+union cvmx_mio_rst_ckill {
+ uint64_t u64;
+ struct cvmx_mio_rst_ckill_s {
+ uint64_t reserved_47_63:17;
+ uint64_t timer:47;
+ } s;
+ struct cvmx_mio_rst_ckill_s cn61xx;
+ struct cvmx_mio_rst_ckill_s cn66xx;
+};
+
+union cvmx_mio_rst_cntlx {
+ uint64_t u64;
+ struct cvmx_mio_rst_cntlx_s {
+ uint64_t reserved_13_63:51;
+ uint64_t in_rev_ln:1;
+ uint64_t rev_lanes:1;
+ uint64_t gen1_only:1;
+ uint64_t prst_link:1;
+ uint64_t rst_done:1;
+ uint64_t rst_link:1;
+ uint64_t host_mode:1;
+ uint64_t prtmode:2;
+ uint64_t rst_drv:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_val:1;
+ } s;
+ struct cvmx_mio_rst_cntlx_s cn61xx;
+ struct cvmx_mio_rst_cntlx_cn66xx {
+ uint64_t reserved_10_63:54;
+ uint64_t prst_link:1;
+ uint64_t rst_done:1;
+ uint64_t rst_link:1;
+ uint64_t host_mode:1;
+ uint64_t prtmode:2;
+ uint64_t rst_drv:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_val:1;
+ } cn66xx;
+ struct cvmx_mio_rst_cntlx_cn66xx cn68xx;
};
union cvmx_mio_rst_ctlx {
uint64_t u64;
struct cvmx_mio_rst_ctlx_s {
- uint64_t reserved_10_63:54;
+ uint64_t reserved_13_63:51;
+ uint64_t in_rev_ln:1;
+ uint64_t rev_lanes:1;
+ uint64_t gen1_only:1;
uint64_t prst_link:1;
uint64_t rst_done:1;
uint64_t rst_link:1;
@@ -1334,7 +2136,19 @@ union cvmx_mio_rst_ctlx {
uint64_t rst_chip:1;
uint64_t rst_val:1;
} s;
- struct cvmx_mio_rst_ctlx_s cn63xx;
+ struct cvmx_mio_rst_ctlx_s cn61xx;
+ struct cvmx_mio_rst_ctlx_cn63xx {
+ uint64_t reserved_10_63:54;
+ uint64_t prst_link:1;
+ uint64_t rst_done:1;
+ uint64_t rst_link:1;
+ uint64_t host_mode:1;
+ uint64_t prtmode:2;
+ uint64_t rst_drv:1;
+ uint64_t rst_rcv:1;
+ uint64_t rst_chip:1;
+ uint64_t rst_val:1;
+ } cn63xx;
struct cvmx_mio_rst_ctlx_cn63xxp1 {
uint64_t reserved_9_63:55;
uint64_t rst_done:1;
@@ -1346,17 +2160,24 @@ union cvmx_mio_rst_ctlx {
uint64_t rst_chip:1;
uint64_t rst_val:1;
} cn63xxp1;
+ struct cvmx_mio_rst_ctlx_cn63xx cn66xx;
+ struct cvmx_mio_rst_ctlx_cn63xx cn68xx;
+ struct cvmx_mio_rst_ctlx_cn63xx cn68xxp1;
};
union cvmx_mio_rst_delay {
uint64_t u64;
struct cvmx_mio_rst_delay_s {
uint64_t reserved_32_63:32;
- uint64_t soft_rst_dly:16;
uint64_t warm_rst_dly:16;
+ uint64_t soft_rst_dly:16;
} s;
+ struct cvmx_mio_rst_delay_s cn61xx;
struct cvmx_mio_rst_delay_s cn63xx;
struct cvmx_mio_rst_delay_s cn63xxp1;
+ struct cvmx_mio_rst_delay_s cn66xx;
+ struct cvmx_mio_rst_delay_s cn68xx;
+ struct cvmx_mio_rst_delay_s cn68xxp1;
};
union cvmx_mio_rst_int {
@@ -1365,12 +2186,25 @@ union cvmx_mio_rst_int {
uint64_t reserved_10_63:54;
uint64_t perst1:1;
uint64_t perst0:1;
- uint64_t reserved_2_7:6;
+ uint64_t reserved_4_7:4;
+ uint64_t rst_link3:1;
+ uint64_t rst_link2:1;
uint64_t rst_link1:1;
uint64_t rst_link0:1;
} s;
- struct cvmx_mio_rst_int_s cn63xx;
- struct cvmx_mio_rst_int_s cn63xxp1;
+ struct cvmx_mio_rst_int_cn61xx {
+ uint64_t reserved_10_63:54;
+ uint64_t perst1:1;
+ uint64_t perst0:1;
+ uint64_t reserved_2_7:6;
+ uint64_t rst_link1:1;
+ uint64_t rst_link0:1;
+ } cn61xx;
+ struct cvmx_mio_rst_int_cn61xx cn63xx;
+ struct cvmx_mio_rst_int_cn61xx cn63xxp1;
+ struct cvmx_mio_rst_int_s cn66xx;
+ struct cvmx_mio_rst_int_cn61xx cn68xx;
+ struct cvmx_mio_rst_int_cn61xx cn68xxp1;
};
union cvmx_mio_rst_int_en {
@@ -1379,12 +2213,25 @@ union cvmx_mio_rst_int_en {
uint64_t reserved_10_63:54;
uint64_t perst1:1;
uint64_t perst0:1;
- uint64_t reserved_2_7:6;
+ uint64_t reserved_4_7:4;
+ uint64_t rst_link3:1;
+ uint64_t rst_link2:1;
uint64_t rst_link1:1;
uint64_t rst_link0:1;
} s;
- struct cvmx_mio_rst_int_en_s cn63xx;
- struct cvmx_mio_rst_int_en_s cn63xxp1;
+ struct cvmx_mio_rst_int_en_cn61xx {
+ uint64_t reserved_10_63:54;
+ uint64_t perst1:1;
+ uint64_t perst0:1;
+ uint64_t reserved_2_7:6;
+ uint64_t rst_link1:1;
+ uint64_t rst_link0:1;
+ } cn61xx;
+ struct cvmx_mio_rst_int_en_cn61xx cn63xx;
+ struct cvmx_mio_rst_int_en_cn61xx cn63xxp1;
+ struct cvmx_mio_rst_int_en_s cn66xx;
+ struct cvmx_mio_rst_int_en_cn61xx cn68xx;
+ struct cvmx_mio_rst_int_en_cn61xx cn68xxp1;
};
union cvmx_mio_twsx_int {
@@ -1424,8 +2271,12 @@ union cvmx_mio_twsx_int {
struct cvmx_mio_twsx_int_s cn56xxp1;
struct cvmx_mio_twsx_int_s cn58xx;
struct cvmx_mio_twsx_int_s cn58xxp1;
+ struct cvmx_mio_twsx_int_s cn61xx;
struct cvmx_mio_twsx_int_s cn63xx;
struct cvmx_mio_twsx_int_s cn63xxp1;
+ struct cvmx_mio_twsx_int_s cn66xx;
+ struct cvmx_mio_twsx_int_s cn68xx;
+ struct cvmx_mio_twsx_int_s cn68xxp1;
};
union cvmx_mio_twsx_sw_twsi {
@@ -1455,8 +2306,12 @@ union cvmx_mio_twsx_sw_twsi {
struct cvmx_mio_twsx_sw_twsi_s cn56xxp1;
struct cvmx_mio_twsx_sw_twsi_s cn58xx;
struct cvmx_mio_twsx_sw_twsi_s cn58xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cn61xx;
struct cvmx_mio_twsx_sw_twsi_s cn63xx;
struct cvmx_mio_twsx_sw_twsi_s cn63xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cn66xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn68xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn68xxp1;
};
union cvmx_mio_twsx_sw_twsi_ext {
@@ -1477,8 +2332,12 @@ union cvmx_mio_twsx_sw_twsi_ext {
struct cvmx_mio_twsx_sw_twsi_ext_s cn56xxp1;
struct cvmx_mio_twsx_sw_twsi_ext_s cn58xx;
struct cvmx_mio_twsx_sw_twsi_ext_s cn58xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn61xx;
struct cvmx_mio_twsx_sw_twsi_ext_s cn63xx;
struct cvmx_mio_twsx_sw_twsi_ext_s cn63xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn66xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn68xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn68xxp1;
};
union cvmx_mio_twsx_twsi_sw {
@@ -1499,8 +2358,12 @@ union cvmx_mio_twsx_twsi_sw {
struct cvmx_mio_twsx_twsi_sw_s cn56xxp1;
struct cvmx_mio_twsx_twsi_sw_s cn58xx;
struct cvmx_mio_twsx_twsi_sw_s cn58xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cn61xx;
struct cvmx_mio_twsx_twsi_sw_s cn63xx;
struct cvmx_mio_twsx_twsi_sw_s cn63xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cn66xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn68xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn68xxp1;
};
union cvmx_mio_uartx_dlh {
@@ -1520,8 +2383,12 @@ union cvmx_mio_uartx_dlh {
struct cvmx_mio_uartx_dlh_s cn56xxp1;
struct cvmx_mio_uartx_dlh_s cn58xx;
struct cvmx_mio_uartx_dlh_s cn58xxp1;
+ struct cvmx_mio_uartx_dlh_s cn61xx;
struct cvmx_mio_uartx_dlh_s cn63xx;
struct cvmx_mio_uartx_dlh_s cn63xxp1;
+ struct cvmx_mio_uartx_dlh_s cn66xx;
+ struct cvmx_mio_uartx_dlh_s cn68xx;
+ struct cvmx_mio_uartx_dlh_s cn68xxp1;
};
union cvmx_mio_uartx_dll {
@@ -1541,8 +2408,12 @@ union cvmx_mio_uartx_dll {
struct cvmx_mio_uartx_dll_s cn56xxp1;
struct cvmx_mio_uartx_dll_s cn58xx;
struct cvmx_mio_uartx_dll_s cn58xxp1;
+ struct cvmx_mio_uartx_dll_s cn61xx;
struct cvmx_mio_uartx_dll_s cn63xx;
struct cvmx_mio_uartx_dll_s cn63xxp1;
+ struct cvmx_mio_uartx_dll_s cn66xx;
+ struct cvmx_mio_uartx_dll_s cn68xx;
+ struct cvmx_mio_uartx_dll_s cn68xxp1;
};
union cvmx_mio_uartx_far {
@@ -1562,8 +2433,12 @@ union cvmx_mio_uartx_far {
struct cvmx_mio_uartx_far_s cn56xxp1;
struct cvmx_mio_uartx_far_s cn58xx;
struct cvmx_mio_uartx_far_s cn58xxp1;
+ struct cvmx_mio_uartx_far_s cn61xx;
struct cvmx_mio_uartx_far_s cn63xx;
struct cvmx_mio_uartx_far_s cn63xxp1;
+ struct cvmx_mio_uartx_far_s cn66xx;
+ struct cvmx_mio_uartx_far_s cn68xx;
+ struct cvmx_mio_uartx_far_s cn68xxp1;
};
union cvmx_mio_uartx_fcr {
@@ -1588,8 +2463,12 @@ union cvmx_mio_uartx_fcr {
struct cvmx_mio_uartx_fcr_s cn56xxp1;
struct cvmx_mio_uartx_fcr_s cn58xx;
struct cvmx_mio_uartx_fcr_s cn58xxp1;
+ struct cvmx_mio_uartx_fcr_s cn61xx;
struct cvmx_mio_uartx_fcr_s cn63xx;
struct cvmx_mio_uartx_fcr_s cn63xxp1;
+ struct cvmx_mio_uartx_fcr_s cn66xx;
+ struct cvmx_mio_uartx_fcr_s cn68xx;
+ struct cvmx_mio_uartx_fcr_s cn68xxp1;
};
union cvmx_mio_uartx_htx {
@@ -1609,8 +2488,12 @@ union cvmx_mio_uartx_htx {
struct cvmx_mio_uartx_htx_s cn56xxp1;
struct cvmx_mio_uartx_htx_s cn58xx;
struct cvmx_mio_uartx_htx_s cn58xxp1;
+ struct cvmx_mio_uartx_htx_s cn61xx;
struct cvmx_mio_uartx_htx_s cn63xx;
struct cvmx_mio_uartx_htx_s cn63xxp1;
+ struct cvmx_mio_uartx_htx_s cn66xx;
+ struct cvmx_mio_uartx_htx_s cn68xx;
+ struct cvmx_mio_uartx_htx_s cn68xxp1;
};
union cvmx_mio_uartx_ier {
@@ -1635,8 +2518,12 @@ union cvmx_mio_uartx_ier {
struct cvmx_mio_uartx_ier_s cn56xxp1;
struct cvmx_mio_uartx_ier_s cn58xx;
struct cvmx_mio_uartx_ier_s cn58xxp1;
+ struct cvmx_mio_uartx_ier_s cn61xx;
struct cvmx_mio_uartx_ier_s cn63xx;
struct cvmx_mio_uartx_ier_s cn63xxp1;
+ struct cvmx_mio_uartx_ier_s cn66xx;
+ struct cvmx_mio_uartx_ier_s cn68xx;
+ struct cvmx_mio_uartx_ier_s cn68xxp1;
};
union cvmx_mio_uartx_iir {
@@ -1658,8 +2545,12 @@ union cvmx_mio_uartx_iir {
struct cvmx_mio_uartx_iir_s cn56xxp1;
struct cvmx_mio_uartx_iir_s cn58xx;
struct cvmx_mio_uartx_iir_s cn58xxp1;
+ struct cvmx_mio_uartx_iir_s cn61xx;
struct cvmx_mio_uartx_iir_s cn63xx;
struct cvmx_mio_uartx_iir_s cn63xxp1;
+ struct cvmx_mio_uartx_iir_s cn66xx;
+ struct cvmx_mio_uartx_iir_s cn68xx;
+ struct cvmx_mio_uartx_iir_s cn68xxp1;
};
union cvmx_mio_uartx_lcr {
@@ -1685,8 +2576,12 @@ union cvmx_mio_uartx_lcr {
struct cvmx_mio_uartx_lcr_s cn56xxp1;
struct cvmx_mio_uartx_lcr_s cn58xx;
struct cvmx_mio_uartx_lcr_s cn58xxp1;
+ struct cvmx_mio_uartx_lcr_s cn61xx;
struct cvmx_mio_uartx_lcr_s cn63xx;
struct cvmx_mio_uartx_lcr_s cn63xxp1;
+ struct cvmx_mio_uartx_lcr_s cn66xx;
+ struct cvmx_mio_uartx_lcr_s cn68xx;
+ struct cvmx_mio_uartx_lcr_s cn68xxp1;
};
union cvmx_mio_uartx_lsr {
@@ -1713,8 +2608,12 @@ union cvmx_mio_uartx_lsr {
struct cvmx_mio_uartx_lsr_s cn56xxp1;
struct cvmx_mio_uartx_lsr_s cn58xx;
struct cvmx_mio_uartx_lsr_s cn58xxp1;
+ struct cvmx_mio_uartx_lsr_s cn61xx;
struct cvmx_mio_uartx_lsr_s cn63xx;
struct cvmx_mio_uartx_lsr_s cn63xxp1;
+ struct cvmx_mio_uartx_lsr_s cn66xx;
+ struct cvmx_mio_uartx_lsr_s cn68xx;
+ struct cvmx_mio_uartx_lsr_s cn68xxp1;
};
union cvmx_mio_uartx_mcr {
@@ -1739,8 +2638,12 @@ union cvmx_mio_uartx_mcr {
struct cvmx_mio_uartx_mcr_s cn56xxp1;
struct cvmx_mio_uartx_mcr_s cn58xx;
struct cvmx_mio_uartx_mcr_s cn58xxp1;
+ struct cvmx_mio_uartx_mcr_s cn61xx;
struct cvmx_mio_uartx_mcr_s cn63xx;
struct cvmx_mio_uartx_mcr_s cn63xxp1;
+ struct cvmx_mio_uartx_mcr_s cn66xx;
+ struct cvmx_mio_uartx_mcr_s cn68xx;
+ struct cvmx_mio_uartx_mcr_s cn68xxp1;
};
union cvmx_mio_uartx_msr {
@@ -1767,8 +2670,12 @@ union cvmx_mio_uartx_msr {
struct cvmx_mio_uartx_msr_s cn56xxp1;
struct cvmx_mio_uartx_msr_s cn58xx;
struct cvmx_mio_uartx_msr_s cn58xxp1;
+ struct cvmx_mio_uartx_msr_s cn61xx;
struct cvmx_mio_uartx_msr_s cn63xx;
struct cvmx_mio_uartx_msr_s cn63xxp1;
+ struct cvmx_mio_uartx_msr_s cn66xx;
+ struct cvmx_mio_uartx_msr_s cn68xx;
+ struct cvmx_mio_uartx_msr_s cn68xxp1;
};
union cvmx_mio_uartx_rbr {
@@ -1788,8 +2695,12 @@ union cvmx_mio_uartx_rbr {
struct cvmx_mio_uartx_rbr_s cn56xxp1;
struct cvmx_mio_uartx_rbr_s cn58xx;
struct cvmx_mio_uartx_rbr_s cn58xxp1;
+ struct cvmx_mio_uartx_rbr_s cn61xx;
struct cvmx_mio_uartx_rbr_s cn63xx;
struct cvmx_mio_uartx_rbr_s cn63xxp1;
+ struct cvmx_mio_uartx_rbr_s cn66xx;
+ struct cvmx_mio_uartx_rbr_s cn68xx;
+ struct cvmx_mio_uartx_rbr_s cn68xxp1;
};
union cvmx_mio_uartx_rfl {
@@ -1809,8 +2720,12 @@ union cvmx_mio_uartx_rfl {
struct cvmx_mio_uartx_rfl_s cn56xxp1;
struct cvmx_mio_uartx_rfl_s cn58xx;
struct cvmx_mio_uartx_rfl_s cn58xxp1;
+ struct cvmx_mio_uartx_rfl_s cn61xx;
struct cvmx_mio_uartx_rfl_s cn63xx;
struct cvmx_mio_uartx_rfl_s cn63xxp1;
+ struct cvmx_mio_uartx_rfl_s cn66xx;
+ struct cvmx_mio_uartx_rfl_s cn68xx;
+ struct cvmx_mio_uartx_rfl_s cn68xxp1;
};
union cvmx_mio_uartx_rfw {
@@ -1832,8 +2747,12 @@ union cvmx_mio_uartx_rfw {
struct cvmx_mio_uartx_rfw_s cn56xxp1;
struct cvmx_mio_uartx_rfw_s cn58xx;
struct cvmx_mio_uartx_rfw_s cn58xxp1;
+ struct cvmx_mio_uartx_rfw_s cn61xx;
struct cvmx_mio_uartx_rfw_s cn63xx;
struct cvmx_mio_uartx_rfw_s cn63xxp1;
+ struct cvmx_mio_uartx_rfw_s cn66xx;
+ struct cvmx_mio_uartx_rfw_s cn68xx;
+ struct cvmx_mio_uartx_rfw_s cn68xxp1;
};
union cvmx_mio_uartx_sbcr {
@@ -1853,8 +2772,12 @@ union cvmx_mio_uartx_sbcr {
struct cvmx_mio_uartx_sbcr_s cn56xxp1;
struct cvmx_mio_uartx_sbcr_s cn58xx;
struct cvmx_mio_uartx_sbcr_s cn58xxp1;
+ struct cvmx_mio_uartx_sbcr_s cn61xx;
struct cvmx_mio_uartx_sbcr_s cn63xx;
struct cvmx_mio_uartx_sbcr_s cn63xxp1;
+ struct cvmx_mio_uartx_sbcr_s cn66xx;
+ struct cvmx_mio_uartx_sbcr_s cn68xx;
+ struct cvmx_mio_uartx_sbcr_s cn68xxp1;
};
union cvmx_mio_uartx_scr {
@@ -1874,8 +2797,12 @@ union cvmx_mio_uartx_scr {
struct cvmx_mio_uartx_scr_s cn56xxp1;
struct cvmx_mio_uartx_scr_s cn58xx;
struct cvmx_mio_uartx_scr_s cn58xxp1;
+ struct cvmx_mio_uartx_scr_s cn61xx;
struct cvmx_mio_uartx_scr_s cn63xx;
struct cvmx_mio_uartx_scr_s cn63xxp1;
+ struct cvmx_mio_uartx_scr_s cn66xx;
+ struct cvmx_mio_uartx_scr_s cn68xx;
+ struct cvmx_mio_uartx_scr_s cn68xxp1;
};
union cvmx_mio_uartx_sfe {
@@ -1895,8 +2822,12 @@ union cvmx_mio_uartx_sfe {
struct cvmx_mio_uartx_sfe_s cn56xxp1;
struct cvmx_mio_uartx_sfe_s cn58xx;
struct cvmx_mio_uartx_sfe_s cn58xxp1;
+ struct cvmx_mio_uartx_sfe_s cn61xx;
struct cvmx_mio_uartx_sfe_s cn63xx;
struct cvmx_mio_uartx_sfe_s cn63xxp1;
+ struct cvmx_mio_uartx_sfe_s cn66xx;
+ struct cvmx_mio_uartx_sfe_s cn68xx;
+ struct cvmx_mio_uartx_sfe_s cn68xxp1;
};
union cvmx_mio_uartx_srr {
@@ -1918,8 +2849,12 @@ union cvmx_mio_uartx_srr {
struct cvmx_mio_uartx_srr_s cn56xxp1;
struct cvmx_mio_uartx_srr_s cn58xx;
struct cvmx_mio_uartx_srr_s cn58xxp1;
+ struct cvmx_mio_uartx_srr_s cn61xx;
struct cvmx_mio_uartx_srr_s cn63xx;
struct cvmx_mio_uartx_srr_s cn63xxp1;
+ struct cvmx_mio_uartx_srr_s cn66xx;
+ struct cvmx_mio_uartx_srr_s cn68xx;
+ struct cvmx_mio_uartx_srr_s cn68xxp1;
};
union cvmx_mio_uartx_srt {
@@ -1939,8 +2874,12 @@ union cvmx_mio_uartx_srt {
struct cvmx_mio_uartx_srt_s cn56xxp1;
struct cvmx_mio_uartx_srt_s cn58xx;
struct cvmx_mio_uartx_srt_s cn58xxp1;
+ struct cvmx_mio_uartx_srt_s cn61xx;
struct cvmx_mio_uartx_srt_s cn63xx;
struct cvmx_mio_uartx_srt_s cn63xxp1;
+ struct cvmx_mio_uartx_srt_s cn66xx;
+ struct cvmx_mio_uartx_srt_s cn68xx;
+ struct cvmx_mio_uartx_srt_s cn68xxp1;
};
union cvmx_mio_uartx_srts {
@@ -1960,8 +2899,12 @@ union cvmx_mio_uartx_srts {
struct cvmx_mio_uartx_srts_s cn56xxp1;
struct cvmx_mio_uartx_srts_s cn58xx;
struct cvmx_mio_uartx_srts_s cn58xxp1;
+ struct cvmx_mio_uartx_srts_s cn61xx;
struct cvmx_mio_uartx_srts_s cn63xx;
struct cvmx_mio_uartx_srts_s cn63xxp1;
+ struct cvmx_mio_uartx_srts_s cn66xx;
+ struct cvmx_mio_uartx_srts_s cn68xx;
+ struct cvmx_mio_uartx_srts_s cn68xxp1;
};
union cvmx_mio_uartx_stt {
@@ -1981,8 +2924,12 @@ union cvmx_mio_uartx_stt {
struct cvmx_mio_uartx_stt_s cn56xxp1;
struct cvmx_mio_uartx_stt_s cn58xx;
struct cvmx_mio_uartx_stt_s cn58xxp1;
+ struct cvmx_mio_uartx_stt_s cn61xx;
struct cvmx_mio_uartx_stt_s cn63xx;
struct cvmx_mio_uartx_stt_s cn63xxp1;
+ struct cvmx_mio_uartx_stt_s cn66xx;
+ struct cvmx_mio_uartx_stt_s cn68xx;
+ struct cvmx_mio_uartx_stt_s cn68xxp1;
};
union cvmx_mio_uartx_tfl {
@@ -2002,8 +2949,12 @@ union cvmx_mio_uartx_tfl {
struct cvmx_mio_uartx_tfl_s cn56xxp1;
struct cvmx_mio_uartx_tfl_s cn58xx;
struct cvmx_mio_uartx_tfl_s cn58xxp1;
+ struct cvmx_mio_uartx_tfl_s cn61xx;
struct cvmx_mio_uartx_tfl_s cn63xx;
struct cvmx_mio_uartx_tfl_s cn63xxp1;
+ struct cvmx_mio_uartx_tfl_s cn66xx;
+ struct cvmx_mio_uartx_tfl_s cn68xx;
+ struct cvmx_mio_uartx_tfl_s cn68xxp1;
};
union cvmx_mio_uartx_tfr {
@@ -2023,8 +2974,12 @@ union cvmx_mio_uartx_tfr {
struct cvmx_mio_uartx_tfr_s cn56xxp1;
struct cvmx_mio_uartx_tfr_s cn58xx;
struct cvmx_mio_uartx_tfr_s cn58xxp1;
+ struct cvmx_mio_uartx_tfr_s cn61xx;
struct cvmx_mio_uartx_tfr_s cn63xx;
struct cvmx_mio_uartx_tfr_s cn63xxp1;
+ struct cvmx_mio_uartx_tfr_s cn66xx;
+ struct cvmx_mio_uartx_tfr_s cn68xx;
+ struct cvmx_mio_uartx_tfr_s cn68xxp1;
};
union cvmx_mio_uartx_thr {
@@ -2044,8 +2999,12 @@ union cvmx_mio_uartx_thr {
struct cvmx_mio_uartx_thr_s cn56xxp1;
struct cvmx_mio_uartx_thr_s cn58xx;
struct cvmx_mio_uartx_thr_s cn58xxp1;
+ struct cvmx_mio_uartx_thr_s cn61xx;
struct cvmx_mio_uartx_thr_s cn63xx;
struct cvmx_mio_uartx_thr_s cn63xxp1;
+ struct cvmx_mio_uartx_thr_s cn66xx;
+ struct cvmx_mio_uartx_thr_s cn68xx;
+ struct cvmx_mio_uartx_thr_s cn68xxp1;
};
union cvmx_mio_uartx_usr {
@@ -2069,8 +3028,12 @@ union cvmx_mio_uartx_usr {
struct cvmx_mio_uartx_usr_s cn56xxp1;
struct cvmx_mio_uartx_usr_s cn58xx;
struct cvmx_mio_uartx_usr_s cn58xxp1;
+ struct cvmx_mio_uartx_usr_s cn61xx;
struct cvmx_mio_uartx_usr_s cn63xx;
struct cvmx_mio_uartx_usr_s cn63xxp1;
+ struct cvmx_mio_uartx_usr_s cn66xx;
+ struct cvmx_mio_uartx_usr_s cn68xx;
+ struct cvmx_mio_uartx_usr_s cn68xxp1;
};
union cvmx_mio_uart2_dlh {
diff --git a/arch/mips/include/asm/octeon/cvmx-npei-defs.h b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
index 9899a9d2ba72..a3075f733ca5 100644
--- a/arch/mips/include/asm/octeon/cvmx-npei-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-npei-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2011 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
@@ -65,7 +65,7 @@
#define CVMX_NPEI_LAST_WIN_RDATA0 (0x0000000000000600ull)
#define CVMX_NPEI_LAST_WIN_RDATA1 (0x0000000000000610ull)
#define CVMX_NPEI_MEM_ACCESS_CTL (0x00000000000004F0ull)
-#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) (0x0000000000000340ull + ((offset) & 31) * 16 - 16*12)
+#define CVMX_NPEI_MEM_ACCESS_SUBIDX(offset) (0x0000000000000280ull + ((offset) & 31) * 16 - 16*12)
#define CVMX_NPEI_MSI_ENB0 (0x0000000000003C50ull)
#define CVMX_NPEI_MSI_ENB1 (0x0000000000003C60ull)
#define CVMX_NPEI_MSI_ENB2 (0x0000000000003C70ull)
diff --git a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
index f8cb88902efb..7b1dc8b74e5b 100644
--- a/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pciercx-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2011 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
@@ -116,8 +116,12 @@ union cvmx_pciercx_cfg000 {
struct cvmx_pciercx_cfg000_s cn52xxp1;
struct cvmx_pciercx_cfg000_s cn56xx;
struct cvmx_pciercx_cfg000_s cn56xxp1;
+ struct cvmx_pciercx_cfg000_s cn61xx;
struct cvmx_pciercx_cfg000_s cn63xx;
struct cvmx_pciercx_cfg000_s cn63xxp1;
+ struct cvmx_pciercx_cfg000_s cn66xx;
+ struct cvmx_pciercx_cfg000_s cn68xx;
+ struct cvmx_pciercx_cfg000_s cn68xxp1;
};
union cvmx_pciercx_cfg001 {
@@ -152,8 +156,12 @@ union cvmx_pciercx_cfg001 {
struct cvmx_pciercx_cfg001_s cn52xxp1;
struct cvmx_pciercx_cfg001_s cn56xx;
struct cvmx_pciercx_cfg001_s cn56xxp1;
+ struct cvmx_pciercx_cfg001_s cn61xx;
struct cvmx_pciercx_cfg001_s cn63xx;
struct cvmx_pciercx_cfg001_s cn63xxp1;
+ struct cvmx_pciercx_cfg001_s cn66xx;
+ struct cvmx_pciercx_cfg001_s cn68xx;
+ struct cvmx_pciercx_cfg001_s cn68xxp1;
};
union cvmx_pciercx_cfg002 {
@@ -168,8 +176,12 @@ union cvmx_pciercx_cfg002 {
struct cvmx_pciercx_cfg002_s cn52xxp1;
struct cvmx_pciercx_cfg002_s cn56xx;
struct cvmx_pciercx_cfg002_s cn56xxp1;
+ struct cvmx_pciercx_cfg002_s cn61xx;
struct cvmx_pciercx_cfg002_s cn63xx;
struct cvmx_pciercx_cfg002_s cn63xxp1;
+ struct cvmx_pciercx_cfg002_s cn66xx;
+ struct cvmx_pciercx_cfg002_s cn68xx;
+ struct cvmx_pciercx_cfg002_s cn68xxp1;
};
union cvmx_pciercx_cfg003 {
@@ -185,8 +197,12 @@ union cvmx_pciercx_cfg003 {
struct cvmx_pciercx_cfg003_s cn52xxp1;
struct cvmx_pciercx_cfg003_s cn56xx;
struct cvmx_pciercx_cfg003_s cn56xxp1;
+ struct cvmx_pciercx_cfg003_s cn61xx;
struct cvmx_pciercx_cfg003_s cn63xx;
struct cvmx_pciercx_cfg003_s cn63xxp1;
+ struct cvmx_pciercx_cfg003_s cn66xx;
+ struct cvmx_pciercx_cfg003_s cn68xx;
+ struct cvmx_pciercx_cfg003_s cn68xxp1;
};
union cvmx_pciercx_cfg004 {
@@ -198,8 +214,12 @@ union cvmx_pciercx_cfg004 {
struct cvmx_pciercx_cfg004_s cn52xxp1;
struct cvmx_pciercx_cfg004_s cn56xx;
struct cvmx_pciercx_cfg004_s cn56xxp1;
+ struct cvmx_pciercx_cfg004_s cn61xx;
struct cvmx_pciercx_cfg004_s cn63xx;
struct cvmx_pciercx_cfg004_s cn63xxp1;
+ struct cvmx_pciercx_cfg004_s cn66xx;
+ struct cvmx_pciercx_cfg004_s cn68xx;
+ struct cvmx_pciercx_cfg004_s cn68xxp1;
};
union cvmx_pciercx_cfg005 {
@@ -211,8 +231,12 @@ union cvmx_pciercx_cfg005 {
struct cvmx_pciercx_cfg005_s cn52xxp1;
struct cvmx_pciercx_cfg005_s cn56xx;
struct cvmx_pciercx_cfg005_s cn56xxp1;
+ struct cvmx_pciercx_cfg005_s cn61xx;
struct cvmx_pciercx_cfg005_s cn63xx;
struct cvmx_pciercx_cfg005_s cn63xxp1;
+ struct cvmx_pciercx_cfg005_s cn66xx;
+ struct cvmx_pciercx_cfg005_s cn68xx;
+ struct cvmx_pciercx_cfg005_s cn68xxp1;
};
union cvmx_pciercx_cfg006 {
@@ -227,8 +251,12 @@ union cvmx_pciercx_cfg006 {
struct cvmx_pciercx_cfg006_s cn52xxp1;
struct cvmx_pciercx_cfg006_s cn56xx;
struct cvmx_pciercx_cfg006_s cn56xxp1;
+ struct cvmx_pciercx_cfg006_s cn61xx;
struct cvmx_pciercx_cfg006_s cn63xx;
struct cvmx_pciercx_cfg006_s cn63xxp1;
+ struct cvmx_pciercx_cfg006_s cn66xx;
+ struct cvmx_pciercx_cfg006_s cn68xx;
+ struct cvmx_pciercx_cfg006_s cn68xxp1;
};
union cvmx_pciercx_cfg007 {
@@ -256,8 +284,12 @@ union cvmx_pciercx_cfg007 {
struct cvmx_pciercx_cfg007_s cn52xxp1;
struct cvmx_pciercx_cfg007_s cn56xx;
struct cvmx_pciercx_cfg007_s cn56xxp1;
+ struct cvmx_pciercx_cfg007_s cn61xx;
struct cvmx_pciercx_cfg007_s cn63xx;
struct cvmx_pciercx_cfg007_s cn63xxp1;
+ struct cvmx_pciercx_cfg007_s cn66xx;
+ struct cvmx_pciercx_cfg007_s cn68xx;
+ struct cvmx_pciercx_cfg007_s cn68xxp1;
};
union cvmx_pciercx_cfg008 {
@@ -272,8 +304,12 @@ union cvmx_pciercx_cfg008 {
struct cvmx_pciercx_cfg008_s cn52xxp1;
struct cvmx_pciercx_cfg008_s cn56xx;
struct cvmx_pciercx_cfg008_s cn56xxp1;
+ struct cvmx_pciercx_cfg008_s cn61xx;
struct cvmx_pciercx_cfg008_s cn63xx;
struct cvmx_pciercx_cfg008_s cn63xxp1;
+ struct cvmx_pciercx_cfg008_s cn66xx;
+ struct cvmx_pciercx_cfg008_s cn68xx;
+ struct cvmx_pciercx_cfg008_s cn68xxp1;
};
union cvmx_pciercx_cfg009 {
@@ -290,8 +326,12 @@ union cvmx_pciercx_cfg009 {
struct cvmx_pciercx_cfg009_s cn52xxp1;
struct cvmx_pciercx_cfg009_s cn56xx;
struct cvmx_pciercx_cfg009_s cn56xxp1;
+ struct cvmx_pciercx_cfg009_s cn61xx;
struct cvmx_pciercx_cfg009_s cn63xx;
struct cvmx_pciercx_cfg009_s cn63xxp1;
+ struct cvmx_pciercx_cfg009_s cn66xx;
+ struct cvmx_pciercx_cfg009_s cn68xx;
+ struct cvmx_pciercx_cfg009_s cn68xxp1;
};
union cvmx_pciercx_cfg010 {
@@ -303,8 +343,12 @@ union cvmx_pciercx_cfg010 {
struct cvmx_pciercx_cfg010_s cn52xxp1;
struct cvmx_pciercx_cfg010_s cn56xx;
struct cvmx_pciercx_cfg010_s cn56xxp1;
+ struct cvmx_pciercx_cfg010_s cn61xx;
struct cvmx_pciercx_cfg010_s cn63xx;
struct cvmx_pciercx_cfg010_s cn63xxp1;
+ struct cvmx_pciercx_cfg010_s cn66xx;
+ struct cvmx_pciercx_cfg010_s cn68xx;
+ struct cvmx_pciercx_cfg010_s cn68xxp1;
};
union cvmx_pciercx_cfg011 {
@@ -316,8 +360,12 @@ union cvmx_pciercx_cfg011 {
struct cvmx_pciercx_cfg011_s cn52xxp1;
struct cvmx_pciercx_cfg011_s cn56xx;
struct cvmx_pciercx_cfg011_s cn56xxp1;
+ struct cvmx_pciercx_cfg011_s cn61xx;
struct cvmx_pciercx_cfg011_s cn63xx;
struct cvmx_pciercx_cfg011_s cn63xxp1;
+ struct cvmx_pciercx_cfg011_s cn66xx;
+ struct cvmx_pciercx_cfg011_s cn68xx;
+ struct cvmx_pciercx_cfg011_s cn68xxp1;
};
union cvmx_pciercx_cfg012 {
@@ -330,8 +378,12 @@ union cvmx_pciercx_cfg012 {
struct cvmx_pciercx_cfg012_s cn52xxp1;
struct cvmx_pciercx_cfg012_s cn56xx;
struct cvmx_pciercx_cfg012_s cn56xxp1;
+ struct cvmx_pciercx_cfg012_s cn61xx;
struct cvmx_pciercx_cfg012_s cn63xx;
struct cvmx_pciercx_cfg012_s cn63xxp1;
+ struct cvmx_pciercx_cfg012_s cn66xx;
+ struct cvmx_pciercx_cfg012_s cn68xx;
+ struct cvmx_pciercx_cfg012_s cn68xxp1;
};
union cvmx_pciercx_cfg013 {
@@ -344,8 +396,12 @@ union cvmx_pciercx_cfg013 {
struct cvmx_pciercx_cfg013_s cn52xxp1;
struct cvmx_pciercx_cfg013_s cn56xx;
struct cvmx_pciercx_cfg013_s cn56xxp1;
+ struct cvmx_pciercx_cfg013_s cn61xx;
struct cvmx_pciercx_cfg013_s cn63xx;
struct cvmx_pciercx_cfg013_s cn63xxp1;
+ struct cvmx_pciercx_cfg013_s cn66xx;
+ struct cvmx_pciercx_cfg013_s cn68xx;
+ struct cvmx_pciercx_cfg013_s cn68xxp1;
};
union cvmx_pciercx_cfg014 {
@@ -357,8 +413,12 @@ union cvmx_pciercx_cfg014 {
struct cvmx_pciercx_cfg014_s cn52xxp1;
struct cvmx_pciercx_cfg014_s cn56xx;
struct cvmx_pciercx_cfg014_s cn56xxp1;
+ struct cvmx_pciercx_cfg014_s cn61xx;
struct cvmx_pciercx_cfg014_s cn63xx;
struct cvmx_pciercx_cfg014_s cn63xxp1;
+ struct cvmx_pciercx_cfg014_s cn66xx;
+ struct cvmx_pciercx_cfg014_s cn68xx;
+ struct cvmx_pciercx_cfg014_s cn68xxp1;
};
union cvmx_pciercx_cfg015 {
@@ -384,8 +444,12 @@ union cvmx_pciercx_cfg015 {
struct cvmx_pciercx_cfg015_s cn52xxp1;
struct cvmx_pciercx_cfg015_s cn56xx;
struct cvmx_pciercx_cfg015_s cn56xxp1;
+ struct cvmx_pciercx_cfg015_s cn61xx;
struct cvmx_pciercx_cfg015_s cn63xx;
struct cvmx_pciercx_cfg015_s cn63xxp1;
+ struct cvmx_pciercx_cfg015_s cn66xx;
+ struct cvmx_pciercx_cfg015_s cn68xx;
+ struct cvmx_pciercx_cfg015_s cn68xxp1;
};
union cvmx_pciercx_cfg016 {
@@ -406,8 +470,12 @@ union cvmx_pciercx_cfg016 {
struct cvmx_pciercx_cfg016_s cn52xxp1;
struct cvmx_pciercx_cfg016_s cn56xx;
struct cvmx_pciercx_cfg016_s cn56xxp1;
+ struct cvmx_pciercx_cfg016_s cn61xx;
struct cvmx_pciercx_cfg016_s cn63xx;
struct cvmx_pciercx_cfg016_s cn63xxp1;
+ struct cvmx_pciercx_cfg016_s cn66xx;
+ struct cvmx_pciercx_cfg016_s cn68xx;
+ struct cvmx_pciercx_cfg016_s cn68xxp1;
};
union cvmx_pciercx_cfg017 {
@@ -430,14 +498,19 @@ union cvmx_pciercx_cfg017 {
struct cvmx_pciercx_cfg017_s cn52xxp1;
struct cvmx_pciercx_cfg017_s cn56xx;
struct cvmx_pciercx_cfg017_s cn56xxp1;
+ struct cvmx_pciercx_cfg017_s cn61xx;
struct cvmx_pciercx_cfg017_s cn63xx;
struct cvmx_pciercx_cfg017_s cn63xxp1;
+ struct cvmx_pciercx_cfg017_s cn66xx;
+ struct cvmx_pciercx_cfg017_s cn68xx;
+ struct cvmx_pciercx_cfg017_s cn68xxp1;
};
union cvmx_pciercx_cfg020 {
uint32_t u32;
struct cvmx_pciercx_cfg020_s {
- uint32_t reserved_24_31:8;
+ uint32_t reserved_25_31:7;
+ uint32_t pvm:1;
uint32_t m64:1;
uint32_t mme:3;
uint32_t mmc:3;
@@ -445,12 +518,24 @@ union cvmx_pciercx_cfg020 {
uint32_t ncp:8;
uint32_t msicid:8;
} s;
- struct cvmx_pciercx_cfg020_s cn52xx;
- struct cvmx_pciercx_cfg020_s cn52xxp1;
- struct cvmx_pciercx_cfg020_s cn56xx;
- struct cvmx_pciercx_cfg020_s cn56xxp1;
- struct cvmx_pciercx_cfg020_s cn63xx;
- struct cvmx_pciercx_cfg020_s cn63xxp1;
+ struct cvmx_pciercx_cfg020_cn52xx {
+ uint32_t reserved_24_31:8;
+ uint32_t m64:1;
+ uint32_t mme:3;
+ uint32_t mmc:3;
+ uint32_t msien:1;
+ uint32_t ncp:8;
+ uint32_t msicid:8;
+ } cn52xx;
+ struct cvmx_pciercx_cfg020_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg020_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg020_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg020_s cn61xx;
+ struct cvmx_pciercx_cfg020_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg020_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg020_cn52xx cn66xx;
+ struct cvmx_pciercx_cfg020_cn52xx cn68xx;
+ struct cvmx_pciercx_cfg020_cn52xx cn68xxp1;
};
union cvmx_pciercx_cfg021 {
@@ -463,8 +548,12 @@ union cvmx_pciercx_cfg021 {
struct cvmx_pciercx_cfg021_s cn52xxp1;
struct cvmx_pciercx_cfg021_s cn56xx;
struct cvmx_pciercx_cfg021_s cn56xxp1;
+ struct cvmx_pciercx_cfg021_s cn61xx;
struct cvmx_pciercx_cfg021_s cn63xx;
struct cvmx_pciercx_cfg021_s cn63xxp1;
+ struct cvmx_pciercx_cfg021_s cn66xx;
+ struct cvmx_pciercx_cfg021_s cn68xx;
+ struct cvmx_pciercx_cfg021_s cn68xxp1;
};
union cvmx_pciercx_cfg022 {
@@ -476,8 +565,12 @@ union cvmx_pciercx_cfg022 {
struct cvmx_pciercx_cfg022_s cn52xxp1;
struct cvmx_pciercx_cfg022_s cn56xx;
struct cvmx_pciercx_cfg022_s cn56xxp1;
+ struct cvmx_pciercx_cfg022_s cn61xx;
struct cvmx_pciercx_cfg022_s cn63xx;
struct cvmx_pciercx_cfg022_s cn63xxp1;
+ struct cvmx_pciercx_cfg022_s cn66xx;
+ struct cvmx_pciercx_cfg022_s cn68xx;
+ struct cvmx_pciercx_cfg022_s cn68xxp1;
};
union cvmx_pciercx_cfg023 {
@@ -490,8 +583,12 @@ union cvmx_pciercx_cfg023 {
struct cvmx_pciercx_cfg023_s cn52xxp1;
struct cvmx_pciercx_cfg023_s cn56xx;
struct cvmx_pciercx_cfg023_s cn56xxp1;
+ struct cvmx_pciercx_cfg023_s cn61xx;
struct cvmx_pciercx_cfg023_s cn63xx;
struct cvmx_pciercx_cfg023_s cn63xxp1;
+ struct cvmx_pciercx_cfg023_s cn66xx;
+ struct cvmx_pciercx_cfg023_s cn68xx;
+ struct cvmx_pciercx_cfg023_s cn68xxp1;
};
union cvmx_pciercx_cfg028 {
@@ -509,8 +606,12 @@ union cvmx_pciercx_cfg028 {
struct cvmx_pciercx_cfg028_s cn52xxp1;
struct cvmx_pciercx_cfg028_s cn56xx;
struct cvmx_pciercx_cfg028_s cn56xxp1;
+ struct cvmx_pciercx_cfg028_s cn61xx;
struct cvmx_pciercx_cfg028_s cn63xx;
struct cvmx_pciercx_cfg028_s cn63xxp1;
+ struct cvmx_pciercx_cfg028_s cn66xx;
+ struct cvmx_pciercx_cfg028_s cn68xx;
+ struct cvmx_pciercx_cfg028_s cn68xxp1;
};
union cvmx_pciercx_cfg029 {
@@ -532,8 +633,12 @@ union cvmx_pciercx_cfg029 {
struct cvmx_pciercx_cfg029_s cn52xxp1;
struct cvmx_pciercx_cfg029_s cn56xx;
struct cvmx_pciercx_cfg029_s cn56xxp1;
+ struct cvmx_pciercx_cfg029_s cn61xx;
struct cvmx_pciercx_cfg029_s cn63xx;
struct cvmx_pciercx_cfg029_s cn63xxp1;
+ struct cvmx_pciercx_cfg029_s cn66xx;
+ struct cvmx_pciercx_cfg029_s cn68xx;
+ struct cvmx_pciercx_cfg029_s cn68xxp1;
};
union cvmx_pciercx_cfg030 {
@@ -563,15 +668,20 @@ union cvmx_pciercx_cfg030 {
struct cvmx_pciercx_cfg030_s cn52xxp1;
struct cvmx_pciercx_cfg030_s cn56xx;
struct cvmx_pciercx_cfg030_s cn56xxp1;
+ struct cvmx_pciercx_cfg030_s cn61xx;
struct cvmx_pciercx_cfg030_s cn63xx;
struct cvmx_pciercx_cfg030_s cn63xxp1;
+ struct cvmx_pciercx_cfg030_s cn66xx;
+ struct cvmx_pciercx_cfg030_s cn68xx;
+ struct cvmx_pciercx_cfg030_s cn68xxp1;
};
union cvmx_pciercx_cfg031 {
uint32_t u32;
struct cvmx_pciercx_cfg031_s {
uint32_t pnum:8;
- uint32_t reserved_22_23:2;
+ uint32_t reserved_23_23:1;
+ uint32_t aspm:1;
uint32_t lbnc:1;
uint32_t dllarc:1;
uint32_t sderc:1;
@@ -582,12 +692,28 @@ union cvmx_pciercx_cfg031 {
uint32_t mlw:6;
uint32_t mls:4;
} s;
- struct cvmx_pciercx_cfg031_s cn52xx;
- struct cvmx_pciercx_cfg031_s cn52xxp1;
- struct cvmx_pciercx_cfg031_s cn56xx;
- struct cvmx_pciercx_cfg031_s cn56xxp1;
- struct cvmx_pciercx_cfg031_s cn63xx;
- struct cvmx_pciercx_cfg031_s cn63xxp1;
+ struct cvmx_pciercx_cfg031_cn52xx {
+ uint32_t pnum:8;
+ uint32_t reserved_22_23:2;
+ uint32_t lbnc:1;
+ uint32_t dllarc:1;
+ uint32_t sderc:1;
+ uint32_t cpm:1;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t aslpms:2;
+ uint32_t mlw:6;
+ uint32_t mls:4;
+ } cn52xx;
+ struct cvmx_pciercx_cfg031_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg031_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg031_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg031_s cn61xx;
+ struct cvmx_pciercx_cfg031_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg031_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg031_s cn66xx;
+ struct cvmx_pciercx_cfg031_s cn68xx;
+ struct cvmx_pciercx_cfg031_cn52xx cn68xxp1;
};
union cvmx_pciercx_cfg032 {
@@ -618,8 +744,12 @@ union cvmx_pciercx_cfg032 {
struct cvmx_pciercx_cfg032_s cn52xxp1;
struct cvmx_pciercx_cfg032_s cn56xx;
struct cvmx_pciercx_cfg032_s cn56xxp1;
+ struct cvmx_pciercx_cfg032_s cn61xx;
struct cvmx_pciercx_cfg032_s cn63xx;
struct cvmx_pciercx_cfg032_s cn63xxp1;
+ struct cvmx_pciercx_cfg032_s cn66xx;
+ struct cvmx_pciercx_cfg032_s cn68xx;
+ struct cvmx_pciercx_cfg032_s cn68xxp1;
};
union cvmx_pciercx_cfg033 {
@@ -642,8 +772,12 @@ union cvmx_pciercx_cfg033 {
struct cvmx_pciercx_cfg033_s cn52xxp1;
struct cvmx_pciercx_cfg033_s cn56xx;
struct cvmx_pciercx_cfg033_s cn56xxp1;
+ struct cvmx_pciercx_cfg033_s cn61xx;
struct cvmx_pciercx_cfg033_s cn63xx;
struct cvmx_pciercx_cfg033_s cn63xxp1;
+ struct cvmx_pciercx_cfg033_s cn66xx;
+ struct cvmx_pciercx_cfg033_s cn68xx;
+ struct cvmx_pciercx_cfg033_s cn68xxp1;
};
union cvmx_pciercx_cfg034 {
@@ -676,8 +810,12 @@ union cvmx_pciercx_cfg034 {
struct cvmx_pciercx_cfg034_s cn52xxp1;
struct cvmx_pciercx_cfg034_s cn56xx;
struct cvmx_pciercx_cfg034_s cn56xxp1;
+ struct cvmx_pciercx_cfg034_s cn61xx;
struct cvmx_pciercx_cfg034_s cn63xx;
struct cvmx_pciercx_cfg034_s cn63xxp1;
+ struct cvmx_pciercx_cfg034_s cn66xx;
+ struct cvmx_pciercx_cfg034_s cn68xx;
+ struct cvmx_pciercx_cfg034_s cn68xxp1;
};
union cvmx_pciercx_cfg035 {
@@ -696,8 +834,12 @@ union cvmx_pciercx_cfg035 {
struct cvmx_pciercx_cfg035_s cn52xxp1;
struct cvmx_pciercx_cfg035_s cn56xx;
struct cvmx_pciercx_cfg035_s cn56xxp1;
+ struct cvmx_pciercx_cfg035_s cn61xx;
struct cvmx_pciercx_cfg035_s cn63xx;
struct cvmx_pciercx_cfg035_s cn63xxp1;
+ struct cvmx_pciercx_cfg035_s cn66xx;
+ struct cvmx_pciercx_cfg035_s cn68xx;
+ struct cvmx_pciercx_cfg035_s cn68xxp1;
};
union cvmx_pciercx_cfg036 {
@@ -712,38 +854,95 @@ union cvmx_pciercx_cfg036 {
struct cvmx_pciercx_cfg036_s cn52xxp1;
struct cvmx_pciercx_cfg036_s cn56xx;
struct cvmx_pciercx_cfg036_s cn56xxp1;
+ struct cvmx_pciercx_cfg036_s cn61xx;
struct cvmx_pciercx_cfg036_s cn63xx;
struct cvmx_pciercx_cfg036_s cn63xxp1;
+ struct cvmx_pciercx_cfg036_s cn66xx;
+ struct cvmx_pciercx_cfg036_s cn68xx;
+ struct cvmx_pciercx_cfg036_s cn68xxp1;
};
union cvmx_pciercx_cfg037 {
uint32_t u32;
struct cvmx_pciercx_cfg037_s {
- uint32_t reserved_5_31:27;
+ uint32_t reserved_14_31:18;
+ uint32_t tph:2;
+ uint32_t reserved_11_11:1;
+ uint32_t noroprpr:1;
+ uint32_t atom128s:1;
+ uint32_t atom64s:1;
+ uint32_t atom32s:1;
+ uint32_t atom_ops:1;
+ uint32_t reserved_5_5:1;
uint32_t ctds:1;
uint32_t ctrs:4;
} s;
- struct cvmx_pciercx_cfg037_s cn52xx;
- struct cvmx_pciercx_cfg037_s cn52xxp1;
- struct cvmx_pciercx_cfg037_s cn56xx;
- struct cvmx_pciercx_cfg037_s cn56xxp1;
- struct cvmx_pciercx_cfg037_s cn63xx;
- struct cvmx_pciercx_cfg037_s cn63xxp1;
+ struct cvmx_pciercx_cfg037_cn52xx {
+ uint32_t reserved_5_31:27;
+ uint32_t ctds:1;
+ uint32_t ctrs:4;
+ } cn52xx;
+ struct cvmx_pciercx_cfg037_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg037_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg037_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg037_cn61xx {
+ uint32_t reserved_14_31:18;
+ uint32_t tph:2;
+ uint32_t reserved_11_11:1;
+ uint32_t noroprpr:1;
+ uint32_t atom128s:1;
+ uint32_t atom64s:1;
+ uint32_t atom32s:1;
+ uint32_t atom_ops:1;
+ uint32_t ari_fw:1;
+ uint32_t ctds:1;
+ uint32_t ctrs:4;
+ } cn61xx;
+ struct cvmx_pciercx_cfg037_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg037_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg037_cn66xx {
+ uint32_t reserved_14_31:18;
+ uint32_t tph:2;
+ uint32_t reserved_11_11:1;
+ uint32_t noroprpr:1;
+ uint32_t atom128s:1;
+ uint32_t atom64s:1;
+ uint32_t atom32s:1;
+ uint32_t atom_ops:1;
+ uint32_t ari:1;
+ uint32_t ctds:1;
+ uint32_t ctrs:4;
+ } cn66xx;
+ struct cvmx_pciercx_cfg037_cn66xx cn68xx;
+ struct cvmx_pciercx_cfg037_cn66xx cn68xxp1;
};
union cvmx_pciercx_cfg038 {
uint32_t u32;
struct cvmx_pciercx_cfg038_s {
- uint32_t reserved_5_31:27;
+ uint32_t reserved_10_31:22;
+ uint32_t id0_cp:1;
+ uint32_t id0_rq:1;
+ uint32_t atom_op_eb:1;
+ uint32_t atom_op:1;
+ uint32_t ari:1;
uint32_t ctd:1;
uint32_t ctv:4;
} s;
- struct cvmx_pciercx_cfg038_s cn52xx;
- struct cvmx_pciercx_cfg038_s cn52xxp1;
- struct cvmx_pciercx_cfg038_s cn56xx;
- struct cvmx_pciercx_cfg038_s cn56xxp1;
- struct cvmx_pciercx_cfg038_s cn63xx;
- struct cvmx_pciercx_cfg038_s cn63xxp1;
+ struct cvmx_pciercx_cfg038_cn52xx {
+ uint32_t reserved_5_31:27;
+ uint32_t ctd:1;
+ uint32_t ctv:4;
+ } cn52xx;
+ struct cvmx_pciercx_cfg038_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg038_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg038_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg038_s cn61xx;
+ struct cvmx_pciercx_cfg038_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg038_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg038_s cn66xx;
+ struct cvmx_pciercx_cfg038_s cn68xx;
+ struct cvmx_pciercx_cfg038_s cn68xxp1;
};
union cvmx_pciercx_cfg039 {
@@ -760,8 +959,12 @@ union cvmx_pciercx_cfg039 {
struct cvmx_pciercx_cfg039_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg039_cn52xx cn56xx;
struct cvmx_pciercx_cfg039_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg039_s cn61xx;
struct cvmx_pciercx_cfg039_s cn63xx;
struct cvmx_pciercx_cfg039_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg039_s cn66xx;
+ struct cvmx_pciercx_cfg039_s cn68xx;
+ struct cvmx_pciercx_cfg039_s cn68xxp1;
};
union cvmx_pciercx_cfg040 {
@@ -785,8 +988,12 @@ union cvmx_pciercx_cfg040 {
struct cvmx_pciercx_cfg040_cn52xx cn52xxp1;
struct cvmx_pciercx_cfg040_cn52xx cn56xx;
struct cvmx_pciercx_cfg040_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg040_s cn61xx;
struct cvmx_pciercx_cfg040_s cn63xx;
struct cvmx_pciercx_cfg040_s cn63xxp1;
+ struct cvmx_pciercx_cfg040_s cn66xx;
+ struct cvmx_pciercx_cfg040_s cn68xx;
+ struct cvmx_pciercx_cfg040_s cn68xxp1;
};
union cvmx_pciercx_cfg041 {
@@ -798,8 +1005,12 @@ union cvmx_pciercx_cfg041 {
struct cvmx_pciercx_cfg041_s cn52xxp1;
struct cvmx_pciercx_cfg041_s cn56xx;
struct cvmx_pciercx_cfg041_s cn56xxp1;
+ struct cvmx_pciercx_cfg041_s cn61xx;
struct cvmx_pciercx_cfg041_s cn63xx;
struct cvmx_pciercx_cfg041_s cn63xxp1;
+ struct cvmx_pciercx_cfg041_s cn66xx;
+ struct cvmx_pciercx_cfg041_s cn68xx;
+ struct cvmx_pciercx_cfg041_s cn68xxp1;
};
union cvmx_pciercx_cfg042 {
@@ -811,8 +1022,12 @@ union cvmx_pciercx_cfg042 {
struct cvmx_pciercx_cfg042_s cn52xxp1;
struct cvmx_pciercx_cfg042_s cn56xx;
struct cvmx_pciercx_cfg042_s cn56xxp1;
+ struct cvmx_pciercx_cfg042_s cn61xx;
struct cvmx_pciercx_cfg042_s cn63xx;
struct cvmx_pciercx_cfg042_s cn63xxp1;
+ struct cvmx_pciercx_cfg042_s cn66xx;
+ struct cvmx_pciercx_cfg042_s cn68xx;
+ struct cvmx_pciercx_cfg042_s cn68xxp1;
};
union cvmx_pciercx_cfg064 {
@@ -826,14 +1041,20 @@ union cvmx_pciercx_cfg064 {
struct cvmx_pciercx_cfg064_s cn52xxp1;
struct cvmx_pciercx_cfg064_s cn56xx;
struct cvmx_pciercx_cfg064_s cn56xxp1;
+ struct cvmx_pciercx_cfg064_s cn61xx;
struct cvmx_pciercx_cfg064_s cn63xx;
struct cvmx_pciercx_cfg064_s cn63xxp1;
+ struct cvmx_pciercx_cfg064_s cn66xx;
+ struct cvmx_pciercx_cfg064_s cn68xx;
+ struct cvmx_pciercx_cfg064_s cn68xxp1;
};
union cvmx_pciercx_cfg065 {
uint32_t u32;
struct cvmx_pciercx_cfg065_s {
- uint32_t reserved_21_31:11;
+ uint32_t reserved_25_31:7;
+ uint32_t uatombs:1;
+ uint32_t reserved_21_23:3;
uint32_t ures:1;
uint32_t ecrces:1;
uint32_t mtlps:1;
@@ -848,18 +1069,39 @@ union cvmx_pciercx_cfg065 {
uint32_t dlpes:1;
uint32_t reserved_0_3:4;
} s;
- struct cvmx_pciercx_cfg065_s cn52xx;
- struct cvmx_pciercx_cfg065_s cn52xxp1;
- struct cvmx_pciercx_cfg065_s cn56xx;
- struct cvmx_pciercx_cfg065_s cn56xxp1;
- struct cvmx_pciercx_cfg065_s cn63xx;
- struct cvmx_pciercx_cfg065_s cn63xxp1;
+ struct cvmx_pciercx_cfg065_cn52xx {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } cn52xx;
+ struct cvmx_pciercx_cfg065_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg065_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg065_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg065_s cn61xx;
+ struct cvmx_pciercx_cfg065_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg065_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg065_s cn66xx;
+ struct cvmx_pciercx_cfg065_s cn68xx;
+ struct cvmx_pciercx_cfg065_cn52xx cn68xxp1;
};
union cvmx_pciercx_cfg066 {
uint32_t u32;
struct cvmx_pciercx_cfg066_s {
- uint32_t reserved_21_31:11;
+ uint32_t reserved_25_31:7;
+ uint32_t uatombm:1;
+ uint32_t reserved_21_23:3;
uint32_t urem:1;
uint32_t ecrcem:1;
uint32_t mtlpm:1;
@@ -874,18 +1116,39 @@ union cvmx_pciercx_cfg066 {
uint32_t dlpem:1;
uint32_t reserved_0_3:4;
} s;
- struct cvmx_pciercx_cfg066_s cn52xx;
- struct cvmx_pciercx_cfg066_s cn52xxp1;
- struct cvmx_pciercx_cfg066_s cn56xx;
- struct cvmx_pciercx_cfg066_s cn56xxp1;
- struct cvmx_pciercx_cfg066_s cn63xx;
- struct cvmx_pciercx_cfg066_s cn63xxp1;
+ struct cvmx_pciercx_cfg066_cn52xx {
+ uint32_t reserved_21_31:11;
+ uint32_t urem:1;
+ uint32_t ecrcem:1;
+ uint32_t mtlpm:1;
+ uint32_t rom:1;
+ uint32_t ucm:1;
+ uint32_t cam:1;
+ uint32_t ctm:1;
+ uint32_t fcpem:1;
+ uint32_t ptlpm:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdem:1;
+ uint32_t dlpem:1;
+ uint32_t reserved_0_3:4;
+ } cn52xx;
+ struct cvmx_pciercx_cfg066_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg066_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg066_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg066_s cn61xx;
+ struct cvmx_pciercx_cfg066_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg066_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg066_s cn66xx;
+ struct cvmx_pciercx_cfg066_s cn68xx;
+ struct cvmx_pciercx_cfg066_cn52xx cn68xxp1;
};
union cvmx_pciercx_cfg067 {
uint32_t u32;
struct cvmx_pciercx_cfg067_s {
- uint32_t reserved_21_31:11;
+ uint32_t reserved_25_31:7;
+ uint32_t uatombs:1;
+ uint32_t reserved_21_23:3;
uint32_t ures:1;
uint32_t ecrces:1;
uint32_t mtlps:1;
@@ -900,12 +1163,31 @@ union cvmx_pciercx_cfg067 {
uint32_t dlpes:1;
uint32_t reserved_0_3:4;
} s;
- struct cvmx_pciercx_cfg067_s cn52xx;
- struct cvmx_pciercx_cfg067_s cn52xxp1;
- struct cvmx_pciercx_cfg067_s cn56xx;
- struct cvmx_pciercx_cfg067_s cn56xxp1;
- struct cvmx_pciercx_cfg067_s cn63xx;
- struct cvmx_pciercx_cfg067_s cn63xxp1;
+ struct cvmx_pciercx_cfg067_cn52xx {
+ uint32_t reserved_21_31:11;
+ uint32_t ures:1;
+ uint32_t ecrces:1;
+ uint32_t mtlps:1;
+ uint32_t ros:1;
+ uint32_t ucs:1;
+ uint32_t cas:1;
+ uint32_t cts:1;
+ uint32_t fcpes:1;
+ uint32_t ptlps:1;
+ uint32_t reserved_6_11:6;
+ uint32_t sdes:1;
+ uint32_t dlpes:1;
+ uint32_t reserved_0_3:4;
+ } cn52xx;
+ struct cvmx_pciercx_cfg067_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg067_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg067_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg067_s cn61xx;
+ struct cvmx_pciercx_cfg067_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg067_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg067_s cn66xx;
+ struct cvmx_pciercx_cfg067_s cn68xx;
+ struct cvmx_pciercx_cfg067_cn52xx cn68xxp1;
};
union cvmx_pciercx_cfg068 {
@@ -925,8 +1207,12 @@ union cvmx_pciercx_cfg068 {
struct cvmx_pciercx_cfg068_s cn52xxp1;
struct cvmx_pciercx_cfg068_s cn56xx;
struct cvmx_pciercx_cfg068_s cn56xxp1;
+ struct cvmx_pciercx_cfg068_s cn61xx;
struct cvmx_pciercx_cfg068_s cn63xx;
struct cvmx_pciercx_cfg068_s cn63xxp1;
+ struct cvmx_pciercx_cfg068_s cn66xx;
+ struct cvmx_pciercx_cfg068_s cn68xx;
+ struct cvmx_pciercx_cfg068_s cn68xxp1;
};
union cvmx_pciercx_cfg069 {
@@ -946,8 +1232,12 @@ union cvmx_pciercx_cfg069 {
struct cvmx_pciercx_cfg069_s cn52xxp1;
struct cvmx_pciercx_cfg069_s cn56xx;
struct cvmx_pciercx_cfg069_s cn56xxp1;
+ struct cvmx_pciercx_cfg069_s cn61xx;
struct cvmx_pciercx_cfg069_s cn63xx;
struct cvmx_pciercx_cfg069_s cn63xxp1;
+ struct cvmx_pciercx_cfg069_s cn66xx;
+ struct cvmx_pciercx_cfg069_s cn68xx;
+ struct cvmx_pciercx_cfg069_s cn68xxp1;
};
union cvmx_pciercx_cfg070 {
@@ -964,8 +1254,12 @@ union cvmx_pciercx_cfg070 {
struct cvmx_pciercx_cfg070_s cn52xxp1;
struct cvmx_pciercx_cfg070_s cn56xx;
struct cvmx_pciercx_cfg070_s cn56xxp1;
+ struct cvmx_pciercx_cfg070_s cn61xx;
struct cvmx_pciercx_cfg070_s cn63xx;
struct cvmx_pciercx_cfg070_s cn63xxp1;
+ struct cvmx_pciercx_cfg070_s cn66xx;
+ struct cvmx_pciercx_cfg070_s cn68xx;
+ struct cvmx_pciercx_cfg070_s cn68xxp1;
};
union cvmx_pciercx_cfg071 {
@@ -977,8 +1271,12 @@ union cvmx_pciercx_cfg071 {
struct cvmx_pciercx_cfg071_s cn52xxp1;
struct cvmx_pciercx_cfg071_s cn56xx;
struct cvmx_pciercx_cfg071_s cn56xxp1;
+ struct cvmx_pciercx_cfg071_s cn61xx;
struct cvmx_pciercx_cfg071_s cn63xx;
struct cvmx_pciercx_cfg071_s cn63xxp1;
+ struct cvmx_pciercx_cfg071_s cn66xx;
+ struct cvmx_pciercx_cfg071_s cn68xx;
+ struct cvmx_pciercx_cfg071_s cn68xxp1;
};
union cvmx_pciercx_cfg072 {
@@ -990,8 +1288,12 @@ union cvmx_pciercx_cfg072 {
struct cvmx_pciercx_cfg072_s cn52xxp1;
struct cvmx_pciercx_cfg072_s cn56xx;
struct cvmx_pciercx_cfg072_s cn56xxp1;
+ struct cvmx_pciercx_cfg072_s cn61xx;
struct cvmx_pciercx_cfg072_s cn63xx;
struct cvmx_pciercx_cfg072_s cn63xxp1;
+ struct cvmx_pciercx_cfg072_s cn66xx;
+ struct cvmx_pciercx_cfg072_s cn68xx;
+ struct cvmx_pciercx_cfg072_s cn68xxp1;
};
union cvmx_pciercx_cfg073 {
@@ -1003,8 +1305,12 @@ union cvmx_pciercx_cfg073 {
struct cvmx_pciercx_cfg073_s cn52xxp1;
struct cvmx_pciercx_cfg073_s cn56xx;
struct cvmx_pciercx_cfg073_s cn56xxp1;
+ struct cvmx_pciercx_cfg073_s cn61xx;
struct cvmx_pciercx_cfg073_s cn63xx;
struct cvmx_pciercx_cfg073_s cn63xxp1;
+ struct cvmx_pciercx_cfg073_s cn66xx;
+ struct cvmx_pciercx_cfg073_s cn68xx;
+ struct cvmx_pciercx_cfg073_s cn68xxp1;
};
union cvmx_pciercx_cfg074 {
@@ -1016,8 +1322,12 @@ union cvmx_pciercx_cfg074 {
struct cvmx_pciercx_cfg074_s cn52xxp1;
struct cvmx_pciercx_cfg074_s cn56xx;
struct cvmx_pciercx_cfg074_s cn56xxp1;
+ struct cvmx_pciercx_cfg074_s cn61xx;
struct cvmx_pciercx_cfg074_s cn63xx;
struct cvmx_pciercx_cfg074_s cn63xxp1;
+ struct cvmx_pciercx_cfg074_s cn66xx;
+ struct cvmx_pciercx_cfg074_s cn68xx;
+ struct cvmx_pciercx_cfg074_s cn68xxp1;
};
union cvmx_pciercx_cfg075 {
@@ -1032,8 +1342,12 @@ union cvmx_pciercx_cfg075 {
struct cvmx_pciercx_cfg075_s cn52xxp1;
struct cvmx_pciercx_cfg075_s cn56xx;
struct cvmx_pciercx_cfg075_s cn56xxp1;
+ struct cvmx_pciercx_cfg075_s cn61xx;
struct cvmx_pciercx_cfg075_s cn63xx;
struct cvmx_pciercx_cfg075_s cn63xxp1;
+ struct cvmx_pciercx_cfg075_s cn66xx;
+ struct cvmx_pciercx_cfg075_s cn68xx;
+ struct cvmx_pciercx_cfg075_s cn68xxp1;
};
union cvmx_pciercx_cfg076 {
@@ -1053,8 +1367,12 @@ union cvmx_pciercx_cfg076 {
struct cvmx_pciercx_cfg076_s cn52xxp1;
struct cvmx_pciercx_cfg076_s cn56xx;
struct cvmx_pciercx_cfg076_s cn56xxp1;
+ struct cvmx_pciercx_cfg076_s cn61xx;
struct cvmx_pciercx_cfg076_s cn63xx;
struct cvmx_pciercx_cfg076_s cn63xxp1;
+ struct cvmx_pciercx_cfg076_s cn66xx;
+ struct cvmx_pciercx_cfg076_s cn68xx;
+ struct cvmx_pciercx_cfg076_s cn68xxp1;
};
union cvmx_pciercx_cfg077 {
@@ -1067,8 +1385,12 @@ union cvmx_pciercx_cfg077 {
struct cvmx_pciercx_cfg077_s cn52xxp1;
struct cvmx_pciercx_cfg077_s cn56xx;
struct cvmx_pciercx_cfg077_s cn56xxp1;
+ struct cvmx_pciercx_cfg077_s cn61xx;
struct cvmx_pciercx_cfg077_s cn63xx;
struct cvmx_pciercx_cfg077_s cn63xxp1;
+ struct cvmx_pciercx_cfg077_s cn66xx;
+ struct cvmx_pciercx_cfg077_s cn68xx;
+ struct cvmx_pciercx_cfg077_s cn68xxp1;
};
union cvmx_pciercx_cfg448 {
@@ -1081,8 +1403,12 @@ union cvmx_pciercx_cfg448 {
struct cvmx_pciercx_cfg448_s cn52xxp1;
struct cvmx_pciercx_cfg448_s cn56xx;
struct cvmx_pciercx_cfg448_s cn56xxp1;
+ struct cvmx_pciercx_cfg448_s cn61xx;
struct cvmx_pciercx_cfg448_s cn63xx;
struct cvmx_pciercx_cfg448_s cn63xxp1;
+ struct cvmx_pciercx_cfg448_s cn66xx;
+ struct cvmx_pciercx_cfg448_s cn68xx;
+ struct cvmx_pciercx_cfg448_s cn68xxp1;
};
union cvmx_pciercx_cfg449 {
@@ -1094,8 +1420,12 @@ union cvmx_pciercx_cfg449 {
struct cvmx_pciercx_cfg449_s cn52xxp1;
struct cvmx_pciercx_cfg449_s cn56xx;
struct cvmx_pciercx_cfg449_s cn56xxp1;
+ struct cvmx_pciercx_cfg449_s cn61xx;
struct cvmx_pciercx_cfg449_s cn63xx;
struct cvmx_pciercx_cfg449_s cn63xxp1;
+ struct cvmx_pciercx_cfg449_s cn66xx;
+ struct cvmx_pciercx_cfg449_s cn68xx;
+ struct cvmx_pciercx_cfg449_s cn68xxp1;
};
union cvmx_pciercx_cfg450 {
@@ -1112,26 +1442,42 @@ union cvmx_pciercx_cfg450 {
struct cvmx_pciercx_cfg450_s cn52xxp1;
struct cvmx_pciercx_cfg450_s cn56xx;
struct cvmx_pciercx_cfg450_s cn56xxp1;
+ struct cvmx_pciercx_cfg450_s cn61xx;
struct cvmx_pciercx_cfg450_s cn63xx;
struct cvmx_pciercx_cfg450_s cn63xxp1;
+ struct cvmx_pciercx_cfg450_s cn66xx;
+ struct cvmx_pciercx_cfg450_s cn68xx;
+ struct cvmx_pciercx_cfg450_s cn68xxp1;
};
union cvmx_pciercx_cfg451 {
uint32_t u32;
struct cvmx_pciercx_cfg451_s {
- uint32_t reserved_30_31:2;
+ uint32_t reserved_31_31:1;
+ uint32_t easpml1:1;
uint32_t l1el:3;
uint32_t l0el:3;
uint32_t n_fts_cc:8;
uint32_t n_fts:8;
uint32_t ack_freq:8;
} s;
- struct cvmx_pciercx_cfg451_s cn52xx;
- struct cvmx_pciercx_cfg451_s cn52xxp1;
- struct cvmx_pciercx_cfg451_s cn56xx;
- struct cvmx_pciercx_cfg451_s cn56xxp1;
- struct cvmx_pciercx_cfg451_s cn63xx;
- struct cvmx_pciercx_cfg451_s cn63xxp1;
+ struct cvmx_pciercx_cfg451_cn52xx {
+ uint32_t reserved_30_31:2;
+ uint32_t l1el:3;
+ uint32_t l0el:3;
+ uint32_t n_fts_cc:8;
+ uint32_t n_fts:8;
+ uint32_t ack_freq:8;
+ } cn52xx;
+ struct cvmx_pciercx_cfg451_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg451_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg451_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg451_s cn61xx;
+ struct cvmx_pciercx_cfg451_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg451_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg451_s cn66xx;
+ struct cvmx_pciercx_cfg451_s cn68xx;
+ struct cvmx_pciercx_cfg451_s cn68xxp1;
};
union cvmx_pciercx_cfg452 {
@@ -1155,8 +1501,24 @@ union cvmx_pciercx_cfg452 {
struct cvmx_pciercx_cfg452_s cn52xxp1;
struct cvmx_pciercx_cfg452_s cn56xx;
struct cvmx_pciercx_cfg452_s cn56xxp1;
+ struct cvmx_pciercx_cfg452_cn61xx {
+ uint32_t reserved_22_31:10;
+ uint32_t lme:6;
+ uint32_t reserved_8_15:8;
+ uint32_t flm:1;
+ uint32_t reserved_6_6:1;
+ uint32_t dllle:1;
+ uint32_t reserved_4_4:1;
+ uint32_t ra:1;
+ uint32_t le:1;
+ uint32_t sd:1;
+ uint32_t omr:1;
+ } cn61xx;
struct cvmx_pciercx_cfg452_s cn63xx;
struct cvmx_pciercx_cfg452_s cn63xxp1;
+ struct cvmx_pciercx_cfg452_cn61xx cn66xx;
+ struct cvmx_pciercx_cfg452_cn61xx cn68xx;
+ struct cvmx_pciercx_cfg452_cn61xx cn68xxp1;
};
union cvmx_pciercx_cfg453 {
@@ -1172,13 +1534,26 @@ union cvmx_pciercx_cfg453 {
struct cvmx_pciercx_cfg453_s cn52xxp1;
struct cvmx_pciercx_cfg453_s cn56xx;
struct cvmx_pciercx_cfg453_s cn56xxp1;
+ struct cvmx_pciercx_cfg453_s cn61xx;
struct cvmx_pciercx_cfg453_s cn63xx;
struct cvmx_pciercx_cfg453_s cn63xxp1;
+ struct cvmx_pciercx_cfg453_s cn66xx;
+ struct cvmx_pciercx_cfg453_s cn68xx;
+ struct cvmx_pciercx_cfg453_s cn68xxp1;
};
union cvmx_pciercx_cfg454 {
uint32_t u32;
struct cvmx_pciercx_cfg454_s {
+ uint32_t cx_nfunc:3;
+ uint32_t tmfcwt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmrt:5;
+ uint32_t reserved_11_13:3;
+ uint32_t nskps:3;
+ uint32_t reserved_0_7:8;
+ } s;
+ struct cvmx_pciercx_cfg454_cn52xx {
uint32_t reserved_29_31:3;
uint32_t tmfcwt:5;
uint32_t tmanlt:5;
@@ -1187,13 +1562,23 @@ union cvmx_pciercx_cfg454 {
uint32_t nskps:3;
uint32_t reserved_4_7:4;
uint32_t ntss:4;
- } s;
- struct cvmx_pciercx_cfg454_s cn52xx;
- struct cvmx_pciercx_cfg454_s cn52xxp1;
- struct cvmx_pciercx_cfg454_s cn56xx;
- struct cvmx_pciercx_cfg454_s cn56xxp1;
- struct cvmx_pciercx_cfg454_s cn63xx;
- struct cvmx_pciercx_cfg454_s cn63xxp1;
+ } cn52xx;
+ struct cvmx_pciercx_cfg454_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg454_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg454_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg454_cn61xx {
+ uint32_t cx_nfunc:3;
+ uint32_t tmfcwt:5;
+ uint32_t tmanlt:5;
+ uint32_t tmrt:5;
+ uint32_t reserved_8_13:6;
+ uint32_t mfuncn:8;
+ } cn61xx;
+ struct cvmx_pciercx_cfg454_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg454_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg454_cn61xx cn66xx;
+ struct cvmx_pciercx_cfg454_cn61xx cn68xx;
+ struct cvmx_pciercx_cfg454_cn52xx cn68xxp1;
};
union cvmx_pciercx_cfg455 {
@@ -1223,23 +1608,37 @@ union cvmx_pciercx_cfg455 {
struct cvmx_pciercx_cfg455_s cn52xxp1;
struct cvmx_pciercx_cfg455_s cn56xx;
struct cvmx_pciercx_cfg455_s cn56xxp1;
+ struct cvmx_pciercx_cfg455_s cn61xx;
struct cvmx_pciercx_cfg455_s cn63xx;
struct cvmx_pciercx_cfg455_s cn63xxp1;
+ struct cvmx_pciercx_cfg455_s cn66xx;
+ struct cvmx_pciercx_cfg455_s cn68xx;
+ struct cvmx_pciercx_cfg455_s cn68xxp1;
};
union cvmx_pciercx_cfg456 {
uint32_t u32;
struct cvmx_pciercx_cfg456_s {
- uint32_t reserved_2_31:30;
+ uint32_t reserved_4_31:28;
+ uint32_t m_handle_flush:1;
+ uint32_t m_dabort_4ucpl:1;
uint32_t m_vend1_drp:1;
uint32_t m_vend0_drp:1;
} s;
- struct cvmx_pciercx_cfg456_s cn52xx;
- struct cvmx_pciercx_cfg456_s cn52xxp1;
- struct cvmx_pciercx_cfg456_s cn56xx;
- struct cvmx_pciercx_cfg456_s cn56xxp1;
- struct cvmx_pciercx_cfg456_s cn63xx;
- struct cvmx_pciercx_cfg456_s cn63xxp1;
+ struct cvmx_pciercx_cfg456_cn52xx {
+ uint32_t reserved_2_31:30;
+ uint32_t m_vend1_drp:1;
+ uint32_t m_vend0_drp:1;
+ } cn52xx;
+ struct cvmx_pciercx_cfg456_cn52xx cn52xxp1;
+ struct cvmx_pciercx_cfg456_cn52xx cn56xx;
+ struct cvmx_pciercx_cfg456_cn52xx cn56xxp1;
+ struct cvmx_pciercx_cfg456_s cn61xx;
+ struct cvmx_pciercx_cfg456_cn52xx cn63xx;
+ struct cvmx_pciercx_cfg456_cn52xx cn63xxp1;
+ struct cvmx_pciercx_cfg456_s cn66xx;
+ struct cvmx_pciercx_cfg456_s cn68xx;
+ struct cvmx_pciercx_cfg456_cn52xx cn68xxp1;
};
union cvmx_pciercx_cfg458 {
@@ -1251,8 +1650,12 @@ union cvmx_pciercx_cfg458 {
struct cvmx_pciercx_cfg458_s cn52xxp1;
struct cvmx_pciercx_cfg458_s cn56xx;
struct cvmx_pciercx_cfg458_s cn56xxp1;
+ struct cvmx_pciercx_cfg458_s cn61xx;
struct cvmx_pciercx_cfg458_s cn63xx;
struct cvmx_pciercx_cfg458_s cn63xxp1;
+ struct cvmx_pciercx_cfg458_s cn66xx;
+ struct cvmx_pciercx_cfg458_s cn68xx;
+ struct cvmx_pciercx_cfg458_s cn68xxp1;
};
union cvmx_pciercx_cfg459 {
@@ -1264,8 +1667,12 @@ union cvmx_pciercx_cfg459 {
struct cvmx_pciercx_cfg459_s cn52xxp1;
struct cvmx_pciercx_cfg459_s cn56xx;
struct cvmx_pciercx_cfg459_s cn56xxp1;
+ struct cvmx_pciercx_cfg459_s cn61xx;
struct cvmx_pciercx_cfg459_s cn63xx;
struct cvmx_pciercx_cfg459_s cn63xxp1;
+ struct cvmx_pciercx_cfg459_s cn66xx;
+ struct cvmx_pciercx_cfg459_s cn68xx;
+ struct cvmx_pciercx_cfg459_s cn68xxp1;
};
union cvmx_pciercx_cfg460 {
@@ -1279,8 +1686,12 @@ union cvmx_pciercx_cfg460 {
struct cvmx_pciercx_cfg460_s cn52xxp1;
struct cvmx_pciercx_cfg460_s cn56xx;
struct cvmx_pciercx_cfg460_s cn56xxp1;
+ struct cvmx_pciercx_cfg460_s cn61xx;
struct cvmx_pciercx_cfg460_s cn63xx;
struct cvmx_pciercx_cfg460_s cn63xxp1;
+ struct cvmx_pciercx_cfg460_s cn66xx;
+ struct cvmx_pciercx_cfg460_s cn68xx;
+ struct cvmx_pciercx_cfg460_s cn68xxp1;
};
union cvmx_pciercx_cfg461 {
@@ -1294,8 +1705,12 @@ union cvmx_pciercx_cfg461 {
struct cvmx_pciercx_cfg461_s cn52xxp1;
struct cvmx_pciercx_cfg461_s cn56xx;
struct cvmx_pciercx_cfg461_s cn56xxp1;
+ struct cvmx_pciercx_cfg461_s cn61xx;
struct cvmx_pciercx_cfg461_s cn63xx;
struct cvmx_pciercx_cfg461_s cn63xxp1;
+ struct cvmx_pciercx_cfg461_s cn66xx;
+ struct cvmx_pciercx_cfg461_s cn68xx;
+ struct cvmx_pciercx_cfg461_s cn68xxp1;
};
union cvmx_pciercx_cfg462 {
@@ -1309,8 +1724,12 @@ union cvmx_pciercx_cfg462 {
struct cvmx_pciercx_cfg462_s cn52xxp1;
struct cvmx_pciercx_cfg462_s cn56xx;
struct cvmx_pciercx_cfg462_s cn56xxp1;
+ struct cvmx_pciercx_cfg462_s cn61xx;
struct cvmx_pciercx_cfg462_s cn63xx;
struct cvmx_pciercx_cfg462_s cn63xxp1;
+ struct cvmx_pciercx_cfg462_s cn66xx;
+ struct cvmx_pciercx_cfg462_s cn68xx;
+ struct cvmx_pciercx_cfg462_s cn68xxp1;
};
union cvmx_pciercx_cfg463 {
@@ -1325,8 +1744,12 @@ union cvmx_pciercx_cfg463 {
struct cvmx_pciercx_cfg463_s cn52xxp1;
struct cvmx_pciercx_cfg463_s cn56xx;
struct cvmx_pciercx_cfg463_s cn56xxp1;
+ struct cvmx_pciercx_cfg463_s cn61xx;
struct cvmx_pciercx_cfg463_s cn63xx;
struct cvmx_pciercx_cfg463_s cn63xxp1;
+ struct cvmx_pciercx_cfg463_s cn66xx;
+ struct cvmx_pciercx_cfg463_s cn68xx;
+ struct cvmx_pciercx_cfg463_s cn68xxp1;
};
union cvmx_pciercx_cfg464 {
@@ -1341,8 +1764,12 @@ union cvmx_pciercx_cfg464 {
struct cvmx_pciercx_cfg464_s cn52xxp1;
struct cvmx_pciercx_cfg464_s cn56xx;
struct cvmx_pciercx_cfg464_s cn56xxp1;
+ struct cvmx_pciercx_cfg464_s cn61xx;
struct cvmx_pciercx_cfg464_s cn63xx;
struct cvmx_pciercx_cfg464_s cn63xxp1;
+ struct cvmx_pciercx_cfg464_s cn66xx;
+ struct cvmx_pciercx_cfg464_s cn68xx;
+ struct cvmx_pciercx_cfg464_s cn68xxp1;
};
union cvmx_pciercx_cfg465 {
@@ -1357,8 +1784,12 @@ union cvmx_pciercx_cfg465 {
struct cvmx_pciercx_cfg465_s cn52xxp1;
struct cvmx_pciercx_cfg465_s cn56xx;
struct cvmx_pciercx_cfg465_s cn56xxp1;
+ struct cvmx_pciercx_cfg465_s cn61xx;
struct cvmx_pciercx_cfg465_s cn63xx;
struct cvmx_pciercx_cfg465_s cn63xxp1;
+ struct cvmx_pciercx_cfg465_s cn66xx;
+ struct cvmx_pciercx_cfg465_s cn68xx;
+ struct cvmx_pciercx_cfg465_s cn68xxp1;
};
union cvmx_pciercx_cfg466 {
@@ -1376,8 +1807,12 @@ union cvmx_pciercx_cfg466 {
struct cvmx_pciercx_cfg466_s cn52xxp1;
struct cvmx_pciercx_cfg466_s cn56xx;
struct cvmx_pciercx_cfg466_s cn56xxp1;
+ struct cvmx_pciercx_cfg466_s cn61xx;
struct cvmx_pciercx_cfg466_s cn63xx;
struct cvmx_pciercx_cfg466_s cn63xxp1;
+ struct cvmx_pciercx_cfg466_s cn66xx;
+ struct cvmx_pciercx_cfg466_s cn68xx;
+ struct cvmx_pciercx_cfg466_s cn68xxp1;
};
union cvmx_pciercx_cfg467 {
@@ -1393,8 +1828,12 @@ union cvmx_pciercx_cfg467 {
struct cvmx_pciercx_cfg467_s cn52xxp1;
struct cvmx_pciercx_cfg467_s cn56xx;
struct cvmx_pciercx_cfg467_s cn56xxp1;
+ struct cvmx_pciercx_cfg467_s cn61xx;
struct cvmx_pciercx_cfg467_s cn63xx;
struct cvmx_pciercx_cfg467_s cn63xxp1;
+ struct cvmx_pciercx_cfg467_s cn66xx;
+ struct cvmx_pciercx_cfg467_s cn68xx;
+ struct cvmx_pciercx_cfg467_s cn68xxp1;
};
union cvmx_pciercx_cfg468 {
@@ -1410,8 +1849,12 @@ union cvmx_pciercx_cfg468 {
struct cvmx_pciercx_cfg468_s cn52xxp1;
struct cvmx_pciercx_cfg468_s cn56xx;
struct cvmx_pciercx_cfg468_s cn56xxp1;
+ struct cvmx_pciercx_cfg468_s cn61xx;
struct cvmx_pciercx_cfg468_s cn63xx;
struct cvmx_pciercx_cfg468_s cn63xxp1;
+ struct cvmx_pciercx_cfg468_s cn66xx;
+ struct cvmx_pciercx_cfg468_s cn68xx;
+ struct cvmx_pciercx_cfg468_s cn68xxp1;
};
union cvmx_pciercx_cfg490 {
@@ -1426,8 +1869,12 @@ union cvmx_pciercx_cfg490 {
struct cvmx_pciercx_cfg490_s cn52xxp1;
struct cvmx_pciercx_cfg490_s cn56xx;
struct cvmx_pciercx_cfg490_s cn56xxp1;
+ struct cvmx_pciercx_cfg490_s cn61xx;
struct cvmx_pciercx_cfg490_s cn63xx;
struct cvmx_pciercx_cfg490_s cn63xxp1;
+ struct cvmx_pciercx_cfg490_s cn66xx;
+ struct cvmx_pciercx_cfg490_s cn68xx;
+ struct cvmx_pciercx_cfg490_s cn68xxp1;
};
union cvmx_pciercx_cfg491 {
@@ -1442,8 +1889,12 @@ union cvmx_pciercx_cfg491 {
struct cvmx_pciercx_cfg491_s cn52xxp1;
struct cvmx_pciercx_cfg491_s cn56xx;
struct cvmx_pciercx_cfg491_s cn56xxp1;
+ struct cvmx_pciercx_cfg491_s cn61xx;
struct cvmx_pciercx_cfg491_s cn63xx;
struct cvmx_pciercx_cfg491_s cn63xxp1;
+ struct cvmx_pciercx_cfg491_s cn66xx;
+ struct cvmx_pciercx_cfg491_s cn68xx;
+ struct cvmx_pciercx_cfg491_s cn68xxp1;
};
union cvmx_pciercx_cfg492 {
@@ -1458,8 +1909,12 @@ union cvmx_pciercx_cfg492 {
struct cvmx_pciercx_cfg492_s cn52xxp1;
struct cvmx_pciercx_cfg492_s cn56xx;
struct cvmx_pciercx_cfg492_s cn56xxp1;
+ struct cvmx_pciercx_cfg492_s cn61xx;
struct cvmx_pciercx_cfg492_s cn63xx;
struct cvmx_pciercx_cfg492_s cn63xxp1;
+ struct cvmx_pciercx_cfg492_s cn66xx;
+ struct cvmx_pciercx_cfg492_s cn68xx;
+ struct cvmx_pciercx_cfg492_s cn68xxp1;
};
union cvmx_pciercx_cfg515 {
@@ -1473,8 +1928,12 @@ union cvmx_pciercx_cfg515 {
uint32_t le:9;
uint32_t n_fts:8;
} s;
+ struct cvmx_pciercx_cfg515_s cn61xx;
struct cvmx_pciercx_cfg515_s cn63xx;
struct cvmx_pciercx_cfg515_s cn63xxp1;
+ struct cvmx_pciercx_cfg515_s cn66xx;
+ struct cvmx_pciercx_cfg515_s cn68xx;
+ struct cvmx_pciercx_cfg515_s cn68xxp1;
};
union cvmx_pciercx_cfg516 {
@@ -1486,8 +1945,12 @@ union cvmx_pciercx_cfg516 {
struct cvmx_pciercx_cfg516_s cn52xxp1;
struct cvmx_pciercx_cfg516_s cn56xx;
struct cvmx_pciercx_cfg516_s cn56xxp1;
+ struct cvmx_pciercx_cfg516_s cn61xx;
struct cvmx_pciercx_cfg516_s cn63xx;
struct cvmx_pciercx_cfg516_s cn63xxp1;
+ struct cvmx_pciercx_cfg516_s cn66xx;
+ struct cvmx_pciercx_cfg516_s cn68xx;
+ struct cvmx_pciercx_cfg516_s cn68xxp1;
};
union cvmx_pciercx_cfg517 {
@@ -1499,8 +1962,12 @@ union cvmx_pciercx_cfg517 {
struct cvmx_pciercx_cfg517_s cn52xxp1;
struct cvmx_pciercx_cfg517_s cn56xx;
struct cvmx_pciercx_cfg517_s cn56xxp1;
+ struct cvmx_pciercx_cfg517_s cn61xx;
struct cvmx_pciercx_cfg517_s cn63xx;
struct cvmx_pciercx_cfg517_s cn63xxp1;
+ struct cvmx_pciercx_cfg517_s cn66xx;
+ struct cvmx_pciercx_cfg517_s cn68xx;
+ struct cvmx_pciercx_cfg517_s cn68xxp1;
};
#endif
diff --git a/drivers/staging/octeon/cvmx-pcsx-defs.h b/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h
index d45952df5f5b..d45952df5f5b 100644
--- a/drivers/staging/octeon/cvmx-pcsx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pcsx-defs.h
diff --git a/drivers/staging/octeon/cvmx-pcsxx-defs.h b/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h
index 55d120fe8aed..55d120fe8aed 100644
--- a/drivers/staging/octeon/cvmx-pcsxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pcsxx-defs.h
diff --git a/arch/mips/include/asm/octeon/cvmx-pemx-defs.h b/arch/mips/include/asm/octeon/cvmx-pemx-defs.h
new file mode 100644
index 000000000000..be189a2585e0
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pemx-defs.h
@@ -0,0 +1,509 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2011 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.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_PEMX_DEFS_H__
+#define __CVMX_PEMX_DEFS_H__
+
+#define CVMX_PEMX_BAR1_INDEXX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C00000A8ull) + (((offset) & 15) + ((block_id) & 1) * 0x200000ull) * 8)
+#define CVMX_PEMX_BAR2_MASK(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000130ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_BAR_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000128ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000018ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_BIST_STATUS2(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000420ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_CFG_RD(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000030ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_CFG_WR(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000028ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_CPL_LUT_VALID(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000098ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_CTL_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000000ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_DBG_INFO(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000008ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_DBG_INFO_EN(block_id) (CVMX_ADD_IO_SEG(0x00011800C00000A0ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_DIAG_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000020ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_INB_READ_CREDITS(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000138ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_INT_ENB(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000410ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_INT_ENB_INT(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000418ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_INT_SUM(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000408ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_P2N_BAR0_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000080ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_P2N_BAR1_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000088ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_P2N_BAR2_START(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000090ull) + ((block_id) & 1) * 0x1000000ull)
+#define CVMX_PEMX_P2P_BARX_END(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C0000048ull) + (((offset) & 3) + ((block_id) & 1) * 0x100000ull) * 16)
+#define CVMX_PEMX_P2P_BARX_START(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C0000040ull) + (((offset) & 3) + ((block_id) & 1) * 0x100000ull) * 16)
+#define CVMX_PEMX_TLP_CREDITS(block_id) (CVMX_ADD_IO_SEG(0x00011800C0000038ull) + ((block_id) & 1) * 0x1000000ull)
+
+union cvmx_pemx_bar1_indexx {
+ uint64_t u64;
+ struct cvmx_pemx_bar1_indexx_s {
+ uint64_t reserved_20_63:44;
+ uint64_t addr_idx:16;
+ uint64_t ca:1;
+ uint64_t end_swp:2;
+ uint64_t addr_v:1;
+ } s;
+ struct cvmx_pemx_bar1_indexx_s cn61xx;
+ struct cvmx_pemx_bar1_indexx_s cn63xx;
+ struct cvmx_pemx_bar1_indexx_s cn63xxp1;
+ struct cvmx_pemx_bar1_indexx_s cn66xx;
+ struct cvmx_pemx_bar1_indexx_s cn68xx;
+ struct cvmx_pemx_bar1_indexx_s cn68xxp1;
+};
+
+union cvmx_pemx_bar2_mask {
+ uint64_t u64;
+ struct cvmx_pemx_bar2_mask_s {
+ uint64_t reserved_38_63:26;
+ uint64_t mask:35;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_pemx_bar2_mask_s cn61xx;
+ struct cvmx_pemx_bar2_mask_s cn66xx;
+ struct cvmx_pemx_bar2_mask_s cn68xx;
+ struct cvmx_pemx_bar2_mask_s cn68xxp1;
+};
+
+union cvmx_pemx_bar_ctl {
+ uint64_t u64;
+ struct cvmx_pemx_bar_ctl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t bar1_siz:3;
+ uint64_t bar2_enb:1;
+ uint64_t bar2_esx:2;
+ uint64_t bar2_cax:1;
+ } s;
+ struct cvmx_pemx_bar_ctl_s cn61xx;
+ struct cvmx_pemx_bar_ctl_s cn63xx;
+ struct cvmx_pemx_bar_ctl_s cn63xxp1;
+ struct cvmx_pemx_bar_ctl_s cn66xx;
+ struct cvmx_pemx_bar_ctl_s cn68xx;
+ struct cvmx_pemx_bar_ctl_s cn68xxp1;
+};
+
+union cvmx_pemx_bist_status {
+ uint64_t u64;
+ struct cvmx_pemx_bist_status_s {
+ uint64_t reserved_8_63:56;
+ uint64_t retry:1;
+ uint64_t rqdata0:1;
+ uint64_t rqdata1:1;
+ uint64_t rqdata2:1;
+ uint64_t rqdata3:1;
+ uint64_t rqhdr1:1;
+ uint64_t rqhdr0:1;
+ uint64_t sot:1;
+ } s;
+ struct cvmx_pemx_bist_status_s cn61xx;
+ struct cvmx_pemx_bist_status_s cn63xx;
+ struct cvmx_pemx_bist_status_s cn63xxp1;
+ struct cvmx_pemx_bist_status_s cn66xx;
+ struct cvmx_pemx_bist_status_s cn68xx;
+ struct cvmx_pemx_bist_status_s cn68xxp1;
+};
+
+union cvmx_pemx_bist_status2 {
+ uint64_t u64;
+ struct cvmx_pemx_bist_status2_s {
+ uint64_t reserved_10_63:54;
+ uint64_t e2p_cpl:1;
+ uint64_t e2p_n:1;
+ uint64_t e2p_p:1;
+ uint64_t peai_p2e:1;
+ uint64_t pef_tpf1:1;
+ uint64_t pef_tpf0:1;
+ uint64_t pef_tnf:1;
+ uint64_t pef_tcf1:1;
+ uint64_t pef_tc0:1;
+ uint64_t ppf:1;
+ } s;
+ struct cvmx_pemx_bist_status2_s cn61xx;
+ struct cvmx_pemx_bist_status2_s cn63xx;
+ struct cvmx_pemx_bist_status2_s cn63xxp1;
+ struct cvmx_pemx_bist_status2_s cn66xx;
+ struct cvmx_pemx_bist_status2_s cn68xx;
+ struct cvmx_pemx_bist_status2_s cn68xxp1;
+};
+
+union cvmx_pemx_cfg_rd {
+ uint64_t u64;
+ struct cvmx_pemx_cfg_rd_s {
+ uint64_t data:32;
+ uint64_t addr:32;
+ } s;
+ struct cvmx_pemx_cfg_rd_s cn61xx;
+ struct cvmx_pemx_cfg_rd_s cn63xx;
+ struct cvmx_pemx_cfg_rd_s cn63xxp1;
+ struct cvmx_pemx_cfg_rd_s cn66xx;
+ struct cvmx_pemx_cfg_rd_s cn68xx;
+ struct cvmx_pemx_cfg_rd_s cn68xxp1;
+};
+
+union cvmx_pemx_cfg_wr {
+ uint64_t u64;
+ struct cvmx_pemx_cfg_wr_s {
+ uint64_t data:32;
+ uint64_t addr:32;
+ } s;
+ struct cvmx_pemx_cfg_wr_s cn61xx;
+ struct cvmx_pemx_cfg_wr_s cn63xx;
+ struct cvmx_pemx_cfg_wr_s cn63xxp1;
+ struct cvmx_pemx_cfg_wr_s cn66xx;
+ struct cvmx_pemx_cfg_wr_s cn68xx;
+ struct cvmx_pemx_cfg_wr_s cn68xxp1;
+};
+
+union cvmx_pemx_cpl_lut_valid {
+ uint64_t u64;
+ struct cvmx_pemx_cpl_lut_valid_s {
+ uint64_t reserved_32_63:32;
+ uint64_t tag:32;
+ } s;
+ struct cvmx_pemx_cpl_lut_valid_s cn61xx;
+ struct cvmx_pemx_cpl_lut_valid_s cn63xx;
+ struct cvmx_pemx_cpl_lut_valid_s cn63xxp1;
+ struct cvmx_pemx_cpl_lut_valid_s cn66xx;
+ struct cvmx_pemx_cpl_lut_valid_s cn68xx;
+ struct cvmx_pemx_cpl_lut_valid_s cn68xxp1;
+};
+
+union cvmx_pemx_ctl_status {
+ uint64_t u64;
+ struct cvmx_pemx_ctl_status_s {
+ uint64_t reserved_48_63:16;
+ uint64_t auto_sd:1;
+ uint64_t dnum:5;
+ uint64_t pbus:8;
+ uint64_t reserved_32_33:2;
+ uint64_t cfg_rtry:16;
+ uint64_t reserved_12_15:4;
+ uint64_t pm_xtoff:1;
+ uint64_t pm_xpme:1;
+ uint64_t ob_p_cmd:1;
+ uint64_t reserved_7_8:2;
+ uint64_t nf_ecrc:1;
+ uint64_t dly_one:1;
+ uint64_t lnk_enb:1;
+ uint64_t ro_ctlp:1;
+ uint64_t fast_lm:1;
+ uint64_t inv_ecrc:1;
+ uint64_t inv_lcrc:1;
+ } s;
+ struct cvmx_pemx_ctl_status_s cn61xx;
+ struct cvmx_pemx_ctl_status_s cn63xx;
+ struct cvmx_pemx_ctl_status_s cn63xxp1;
+ struct cvmx_pemx_ctl_status_s cn66xx;
+ struct cvmx_pemx_ctl_status_s cn68xx;
+ struct cvmx_pemx_ctl_status_s cn68xxp1;
+};
+
+union cvmx_pemx_dbg_info {
+ uint64_t u64;
+ struct cvmx_pemx_dbg_info_s {
+ uint64_t reserved_31_63:33;
+ uint64_t ecrc_e:1;
+ uint64_t rawwpp:1;
+ uint64_t racpp:1;
+ uint64_t ramtlp:1;
+ uint64_t rarwdns:1;
+ uint64_t caar:1;
+ uint64_t racca:1;
+ uint64_t racur:1;
+ uint64_t rauc:1;
+ uint64_t rqo:1;
+ uint64_t fcuv:1;
+ uint64_t rpe:1;
+ uint64_t fcpvwt:1;
+ uint64_t dpeoosd:1;
+ uint64_t rtwdle:1;
+ uint64_t rdwdle:1;
+ uint64_t mre:1;
+ uint64_t rte:1;
+ uint64_t acto:1;
+ uint64_t rvdm:1;
+ uint64_t rumep:1;
+ uint64_t rptamrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rfemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rcemrc:1;
+ uint64_t rpoison:1;
+ uint64_t recrce:1;
+ uint64_t rtlplle:1;
+ uint64_t rtlpmal:1;
+ uint64_t spoison:1;
+ } s;
+ struct cvmx_pemx_dbg_info_s cn61xx;
+ struct cvmx_pemx_dbg_info_s cn63xx;
+ struct cvmx_pemx_dbg_info_s cn63xxp1;
+ struct cvmx_pemx_dbg_info_s cn66xx;
+ struct cvmx_pemx_dbg_info_s cn68xx;
+ struct cvmx_pemx_dbg_info_s cn68xxp1;
+};
+
+union cvmx_pemx_dbg_info_en {
+ uint64_t u64;
+ struct cvmx_pemx_dbg_info_en_s {
+ uint64_t reserved_31_63:33;
+ uint64_t ecrc_e:1;
+ uint64_t rawwpp:1;
+ uint64_t racpp:1;
+ uint64_t ramtlp:1;
+ uint64_t rarwdns:1;
+ uint64_t caar:1;
+ uint64_t racca:1;
+ uint64_t racur:1;
+ uint64_t rauc:1;
+ uint64_t rqo:1;
+ uint64_t fcuv:1;
+ uint64_t rpe:1;
+ uint64_t fcpvwt:1;
+ uint64_t dpeoosd:1;
+ uint64_t rtwdle:1;
+ uint64_t rdwdle:1;
+ uint64_t mre:1;
+ uint64_t rte:1;
+ uint64_t acto:1;
+ uint64_t rvdm:1;
+ uint64_t rumep:1;
+ uint64_t rptamrc:1;
+ uint64_t rpmerc:1;
+ uint64_t rfemrc:1;
+ uint64_t rnfemrc:1;
+ uint64_t rcemrc:1;
+ uint64_t rpoison:1;
+ uint64_t recrce:1;
+ uint64_t rtlplle:1;
+ uint64_t rtlpmal:1;
+ uint64_t spoison:1;
+ } s;
+ struct cvmx_pemx_dbg_info_en_s cn61xx;
+ struct cvmx_pemx_dbg_info_en_s cn63xx;
+ struct cvmx_pemx_dbg_info_en_s cn63xxp1;
+ struct cvmx_pemx_dbg_info_en_s cn66xx;
+ struct cvmx_pemx_dbg_info_en_s cn68xx;
+ struct cvmx_pemx_dbg_info_en_s cn68xxp1;
+};
+
+union cvmx_pemx_diag_status {
+ uint64_t u64;
+ struct cvmx_pemx_diag_status_s {
+ uint64_t reserved_4_63:60;
+ uint64_t pm_dst:1;
+ uint64_t pm_stat:1;
+ uint64_t pm_en:1;
+ uint64_t aux_en:1;
+ } s;
+ struct cvmx_pemx_diag_status_s cn61xx;
+ struct cvmx_pemx_diag_status_s cn63xx;
+ struct cvmx_pemx_diag_status_s cn63xxp1;
+ struct cvmx_pemx_diag_status_s cn66xx;
+ struct cvmx_pemx_diag_status_s cn68xx;
+ struct cvmx_pemx_diag_status_s cn68xxp1;
+};
+
+union cvmx_pemx_inb_read_credits {
+ uint64_t u64;
+ struct cvmx_pemx_inb_read_credits_s {
+ uint64_t reserved_6_63:58;
+ uint64_t num:6;
+ } s;
+ struct cvmx_pemx_inb_read_credits_s cn61xx;
+ struct cvmx_pemx_inb_read_credits_s cn66xx;
+ struct cvmx_pemx_inb_read_credits_s cn68xx;
+};
+
+union cvmx_pemx_int_enb {
+ uint64_t u64;
+ struct cvmx_pemx_int_enb_s {
+ uint64_t reserved_14_63:50;
+ uint64_t crs_dr:1;
+ uint64_t crs_er:1;
+ uint64_t rdlk:1;
+ uint64_t exc:1;
+ uint64_t un_bx:1;
+ uint64_t un_b2:1;
+ uint64_t un_b1:1;
+ uint64_t up_bx:1;
+ uint64_t up_b2:1;
+ uint64_t up_b1:1;
+ uint64_t pmem:1;
+ uint64_t pmei:1;
+ uint64_t se:1;
+ uint64_t aeri:1;
+ } s;
+ struct cvmx_pemx_int_enb_s cn61xx;
+ struct cvmx_pemx_int_enb_s cn63xx;
+ struct cvmx_pemx_int_enb_s cn63xxp1;
+ struct cvmx_pemx_int_enb_s cn66xx;
+ struct cvmx_pemx_int_enb_s cn68xx;
+ struct cvmx_pemx_int_enb_s cn68xxp1;
+};
+
+union cvmx_pemx_int_enb_int {
+ uint64_t u64;
+ struct cvmx_pemx_int_enb_int_s {
+ uint64_t reserved_14_63:50;
+ uint64_t crs_dr:1;
+ uint64_t crs_er:1;
+ uint64_t rdlk:1;
+ uint64_t exc:1;
+ uint64_t un_bx:1;
+ uint64_t un_b2:1;
+ uint64_t un_b1:1;
+ uint64_t up_bx:1;
+ uint64_t up_b2:1;
+ uint64_t up_b1:1;
+ uint64_t pmem:1;
+ uint64_t pmei:1;
+ uint64_t se:1;
+ uint64_t aeri:1;
+ } s;
+ struct cvmx_pemx_int_enb_int_s cn61xx;
+ struct cvmx_pemx_int_enb_int_s cn63xx;
+ struct cvmx_pemx_int_enb_int_s cn63xxp1;
+ struct cvmx_pemx_int_enb_int_s cn66xx;
+ struct cvmx_pemx_int_enb_int_s cn68xx;
+ struct cvmx_pemx_int_enb_int_s cn68xxp1;
+};
+
+union cvmx_pemx_int_sum {
+ uint64_t u64;
+ struct cvmx_pemx_int_sum_s {
+ uint64_t reserved_14_63:50;
+ uint64_t crs_dr:1;
+ uint64_t crs_er:1;
+ uint64_t rdlk:1;
+ uint64_t exc:1;
+ uint64_t un_bx:1;
+ uint64_t un_b2:1;
+ uint64_t un_b1:1;
+ uint64_t up_bx:1;
+ uint64_t up_b2:1;
+ uint64_t up_b1:1;
+ uint64_t pmem:1;
+ uint64_t pmei:1;
+ uint64_t se:1;
+ uint64_t aeri:1;
+ } s;
+ struct cvmx_pemx_int_sum_s cn61xx;
+ struct cvmx_pemx_int_sum_s cn63xx;
+ struct cvmx_pemx_int_sum_s cn63xxp1;
+ struct cvmx_pemx_int_sum_s cn66xx;
+ struct cvmx_pemx_int_sum_s cn68xx;
+ struct cvmx_pemx_int_sum_s cn68xxp1;
+};
+
+union cvmx_pemx_p2n_bar0_start {
+ uint64_t u64;
+ struct cvmx_pemx_p2n_bar0_start_s {
+ uint64_t addr:50;
+ uint64_t reserved_0_13:14;
+ } s;
+ struct cvmx_pemx_p2n_bar0_start_s cn61xx;
+ struct cvmx_pemx_p2n_bar0_start_s cn63xx;
+ struct cvmx_pemx_p2n_bar0_start_s cn63xxp1;
+ struct cvmx_pemx_p2n_bar0_start_s cn66xx;
+ struct cvmx_pemx_p2n_bar0_start_s cn68xx;
+ struct cvmx_pemx_p2n_bar0_start_s cn68xxp1;
+};
+
+union cvmx_pemx_p2n_bar1_start {
+ uint64_t u64;
+ struct cvmx_pemx_p2n_bar1_start_s {
+ uint64_t addr:38;
+ uint64_t reserved_0_25:26;
+ } s;
+ struct cvmx_pemx_p2n_bar1_start_s cn61xx;
+ struct cvmx_pemx_p2n_bar1_start_s cn63xx;
+ struct cvmx_pemx_p2n_bar1_start_s cn63xxp1;
+ struct cvmx_pemx_p2n_bar1_start_s cn66xx;
+ struct cvmx_pemx_p2n_bar1_start_s cn68xx;
+ struct cvmx_pemx_p2n_bar1_start_s cn68xxp1;
+};
+
+union cvmx_pemx_p2n_bar2_start {
+ uint64_t u64;
+ struct cvmx_pemx_p2n_bar2_start_s {
+ uint64_t addr:23;
+ uint64_t reserved_0_40:41;
+ } s;
+ struct cvmx_pemx_p2n_bar2_start_s cn61xx;
+ struct cvmx_pemx_p2n_bar2_start_s cn63xx;
+ struct cvmx_pemx_p2n_bar2_start_s cn63xxp1;
+ struct cvmx_pemx_p2n_bar2_start_s cn66xx;
+ struct cvmx_pemx_p2n_bar2_start_s cn68xx;
+ struct cvmx_pemx_p2n_bar2_start_s cn68xxp1;
+};
+
+union cvmx_pemx_p2p_barx_end {
+ uint64_t u64;
+ struct cvmx_pemx_p2p_barx_end_s {
+ uint64_t addr:52;
+ uint64_t reserved_0_11:12;
+ } s;
+ struct cvmx_pemx_p2p_barx_end_s cn63xx;
+ struct cvmx_pemx_p2p_barx_end_s cn63xxp1;
+ struct cvmx_pemx_p2p_barx_end_s cn66xx;
+ struct cvmx_pemx_p2p_barx_end_s cn68xx;
+ struct cvmx_pemx_p2p_barx_end_s cn68xxp1;
+};
+
+union cvmx_pemx_p2p_barx_start {
+ uint64_t u64;
+ struct cvmx_pemx_p2p_barx_start_s {
+ uint64_t addr:52;
+ uint64_t reserved_0_11:12;
+ } s;
+ struct cvmx_pemx_p2p_barx_start_s cn63xx;
+ struct cvmx_pemx_p2p_barx_start_s cn63xxp1;
+ struct cvmx_pemx_p2p_barx_start_s cn66xx;
+ struct cvmx_pemx_p2p_barx_start_s cn68xx;
+ struct cvmx_pemx_p2p_barx_start_s cn68xxp1;
+};
+
+union cvmx_pemx_tlp_credits {
+ uint64_t u64;
+ struct cvmx_pemx_tlp_credits_s {
+ uint64_t reserved_56_63:8;
+ uint64_t peai_ppf:8;
+ uint64_t pem_cpl:8;
+ uint64_t pem_np:8;
+ uint64_t pem_p:8;
+ uint64_t sli_cpl:8;
+ uint64_t sli_np:8;
+ uint64_t sli_p:8;
+ } s;
+ struct cvmx_pemx_tlp_credits_cn61xx {
+ uint64_t reserved_56_63:8;
+ uint64_t peai_ppf:8;
+ uint64_t reserved_24_47:24;
+ uint64_t sli_cpl:8;
+ uint64_t sli_np:8;
+ uint64_t sli_p:8;
+ } cn61xx;
+ struct cvmx_pemx_tlp_credits_s cn63xx;
+ struct cvmx_pemx_tlp_credits_s cn63xxp1;
+ struct cvmx_pemx_tlp_credits_s cn66xx;
+ struct cvmx_pemx_tlp_credits_s cn68xx;
+ struct cvmx_pemx_tlp_credits_s cn68xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
index 5ab8679d89af..4438d211988b 100644
--- a/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pexp-defs.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2010 Cavium Networks
+ * Copyright (c) 2003-2011 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
@@ -25,13 +25,6 @@
* Contact Cavium Networks for more information
***********************license end**************************************/
-/**
- * cvmx-pexp-defs.h
- *
- * Configuration and status register (CSR) definitions for
- * OCTEON PEXP.
- *
- */
#ifndef __CVMX_PEXP_DEFS_H__
#define __CVMX_PEXP_DEFS_H__
@@ -139,7 +132,7 @@
#define CVMX_PEXP_NPEI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000008640ull))
#define CVMX_PEXP_NPEI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F0000008380ull))
#define CVMX_PEXP_SLI_BIST_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010580ull))
-#define CVMX_PEXP_SLI_CTL_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010050ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_CTL_PORTX(offset) (CVMX_ADD_IO_SEG(0x00011F0000010050ull) + ((offset) & 3) * 16)
#define CVMX_PEXP_SLI_CTL_STATUS (CVMX_ADD_IO_SEG(0x00011F0000010570ull))
#define CVMX_PEXP_SLI_DATA_OUT_CNT (CVMX_ADD_IO_SEG(0x00011F00000105F0ull))
#define CVMX_PEXP_SLI_DBG_DATA (CVMX_ADD_IO_SEG(0x00011F0000010310ull))
@@ -152,7 +145,10 @@
#define CVMX_PEXP_SLI_INT_SUM (CVMX_ADD_IO_SEG(0x00011F0000010330ull))
#define CVMX_PEXP_SLI_LAST_WIN_RDATA0 (CVMX_ADD_IO_SEG(0x00011F0000010600ull))
#define CVMX_PEXP_SLI_LAST_WIN_RDATA1 (CVMX_ADD_IO_SEG(0x00011F0000010610ull))
+#define CVMX_PEXP_SLI_LAST_WIN_RDATA2 (CVMX_ADD_IO_SEG(0x00011F00000106C0ull))
+#define CVMX_PEXP_SLI_LAST_WIN_RDATA3 (CVMX_ADD_IO_SEG(0x00011F00000106D0ull))
#define CVMX_PEXP_SLI_MAC_CREDIT_CNT (CVMX_ADD_IO_SEG(0x00011F0000013D70ull))
+#define CVMX_PEXP_SLI_MAC_CREDIT_CNT2 (CVMX_ADD_IO_SEG(0x00011F0000013E10ull))
#define CVMX_PEXP_SLI_MEM_ACCESS_CTL (CVMX_ADD_IO_SEG(0x00011F00000102F0ull))
#define CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(offset) (CVMX_ADD_IO_SEG(0x00011F00000100E0ull) + ((offset) & 31) * 16 - 16*12)
#define CVMX_PEXP_SLI_MSI_ENB0 (CVMX_ADD_IO_SEG(0x00011F0000013C50ull))
@@ -206,6 +202,7 @@
#define CVMX_PEXP_SLI_PKT_IPTR (CVMX_ADD_IO_SEG(0x00011F0000011070ull))
#define CVMX_PEXP_SLI_PKT_OUTPUT_WMARK (CVMX_ADD_IO_SEG(0x00011F0000011180ull))
#define CVMX_PEXP_SLI_PKT_OUT_BMODE (CVMX_ADD_IO_SEG(0x00011F00000110D0ull))
+#define CVMX_PEXP_SLI_PKT_OUT_BP_EN (CVMX_ADD_IO_SEG(0x00011F0000011240ull))
#define CVMX_PEXP_SLI_PKT_OUT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011010ull))
#define CVMX_PEXP_SLI_PKT_PCIE_PORT (CVMX_ADD_IO_SEG(0x00011F00000110E0ull))
#define CVMX_PEXP_SLI_PKT_PORT_IN_RST (CVMX_ADD_IO_SEG(0x00011F00000111F0ull))
@@ -214,12 +211,14 @@
#define CVMX_PEXP_SLI_PKT_SLIST_ROR (CVMX_ADD_IO_SEG(0x00011F0000011030ull))
#define CVMX_PEXP_SLI_PKT_TIME_INT (CVMX_ADD_IO_SEG(0x00011F0000011140ull))
#define CVMX_PEXP_SLI_PKT_TIME_INT_ENB (CVMX_ADD_IO_SEG(0x00011F0000011160ull))
-#define CVMX_PEXP_SLI_S2M_PORTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011F0000013D80ull) + ((offset) & 1) * 16)
+#define CVMX_PEXP_SLI_PORTX_PKIND(offset) (CVMX_ADD_IO_SEG(0x00011F0000010800ull) + ((offset) & 31) * 16)
+#define CVMX_PEXP_SLI_S2M_PORTX_CTL(offset) (CVMX_ADD_IO_SEG(0x00011F0000013D80ull) + ((offset) & 3) * 16)
#define CVMX_PEXP_SLI_SCRATCH_1 (CVMX_ADD_IO_SEG(0x00011F00000103C0ull))
#define CVMX_PEXP_SLI_SCRATCH_2 (CVMX_ADD_IO_SEG(0x00011F00000103D0ull))
#define CVMX_PEXP_SLI_STATE1 (CVMX_ADD_IO_SEG(0x00011F0000010620ull))
#define CVMX_PEXP_SLI_STATE2 (CVMX_ADD_IO_SEG(0x00011F0000010630ull))
#define CVMX_PEXP_SLI_STATE3 (CVMX_ADD_IO_SEG(0x00011F0000010640ull))
+#define CVMX_PEXP_SLI_TX_PIPE (CVMX_ADD_IO_SEG(0x00011F0000011230ull))
#define CVMX_PEXP_SLI_WINDOW_CTL (CVMX_ADD_IO_SEG(0x00011F00000102E0ull))
#endif
diff --git a/drivers/staging/octeon/cvmx-pip-defs.h b/arch/mips/include/asm/octeon/cvmx-pip-defs.h
index 5a369100ca68..5a369100ca68 100644
--- a/drivers/staging/octeon/cvmx-pip-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pip-defs.h
diff --git a/drivers/staging/octeon/cvmx-pip.h b/arch/mips/include/asm/octeon/cvmx-pip.h
index 78dbce8f2c5e..78dbce8f2c5e 100644
--- a/drivers/staging/octeon/cvmx-pip.h
+++ b/arch/mips/include/asm/octeon/cvmx-pip.h
diff --git a/drivers/staging/octeon/cvmx-pko-defs.h b/arch/mips/include/asm/octeon/cvmx-pko-defs.h
index 50e779cf1ad8..50e779cf1ad8 100644
--- a/drivers/staging/octeon/cvmx-pko-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-pko-defs.h
diff --git a/drivers/staging/octeon/cvmx-pko.h b/arch/mips/include/asm/octeon/cvmx-pko.h
index de3412aada5d..de3412aada5d 100644
--- a/drivers/staging/octeon/cvmx-pko.h
+++ b/arch/mips/include/asm/octeon/cvmx-pko.h
diff --git a/drivers/staging/octeon/cvmx-pow.h b/arch/mips/include/asm/octeon/cvmx-pow.h
index 999aefe3274c..999aefe3274c 100644
--- a/drivers/staging/octeon/cvmx-pow.h
+++ b/arch/mips/include/asm/octeon/cvmx-pow.h
diff --git a/drivers/staging/octeon/cvmx-scratch.h b/arch/mips/include/asm/octeon/cvmx-scratch.h
index 96b70cfd6245..96b70cfd6245 100644
--- a/drivers/staging/octeon/cvmx-scratch.h
+++ b/arch/mips/include/asm/octeon/cvmx-scratch.h
diff --git a/arch/mips/include/asm/octeon/cvmx-sli-defs.h b/arch/mips/include/asm/octeon/cvmx-sli-defs.h
new file mode 100644
index 000000000000..7c6c901d3d28
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-sli-defs.h
@@ -0,0 +1,2172 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2011 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.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_SLI_DEFS_H__
+#define __CVMX_SLI_DEFS_H__
+
+#define CVMX_SLI_BIST_STATUS (0x0000000000000580ull)
+#define CVMX_SLI_CTL_PORTX(offset) (0x0000000000000050ull + ((offset) & 3) * 16)
+#define CVMX_SLI_CTL_STATUS (0x0000000000000570ull)
+#define CVMX_SLI_DATA_OUT_CNT (0x00000000000005F0ull)
+#define CVMX_SLI_DBG_DATA (0x0000000000000310ull)
+#define CVMX_SLI_DBG_SELECT (0x0000000000000300ull)
+#define CVMX_SLI_DMAX_CNT(offset) (0x0000000000000400ull + ((offset) & 1) * 16)
+#define CVMX_SLI_DMAX_INT_LEVEL(offset) (0x00000000000003E0ull + ((offset) & 1) * 16)
+#define CVMX_SLI_DMAX_TIM(offset) (0x0000000000000420ull + ((offset) & 1) * 16)
+#define CVMX_SLI_INT_ENB_CIU (0x0000000000003CD0ull)
+#define CVMX_SLI_INT_ENB_PORTX(offset) (0x0000000000000340ull + ((offset) & 1) * 16)
+#define CVMX_SLI_INT_SUM (0x0000000000000330ull)
+#define CVMX_SLI_LAST_WIN_RDATA0 (0x0000000000000600ull)
+#define CVMX_SLI_LAST_WIN_RDATA1 (0x0000000000000610ull)
+#define CVMX_SLI_LAST_WIN_RDATA2 (0x00000000000006C0ull)
+#define CVMX_SLI_LAST_WIN_RDATA3 (0x00000000000006D0ull)
+#define CVMX_SLI_MAC_CREDIT_CNT (0x0000000000003D70ull)
+#define CVMX_SLI_MAC_CREDIT_CNT2 (0x0000000000003E10ull)
+#define CVMX_SLI_MAC_NUMBER (0x0000000000003E00ull)
+#define CVMX_SLI_MEM_ACCESS_CTL (0x00000000000002F0ull)
+#define CVMX_SLI_MEM_ACCESS_SUBIDX(offset) (0x00000000000000E0ull + ((offset) & 31) * 16 - 16*12)
+#define CVMX_SLI_MSI_ENB0 (0x0000000000003C50ull)
+#define CVMX_SLI_MSI_ENB1 (0x0000000000003C60ull)
+#define CVMX_SLI_MSI_ENB2 (0x0000000000003C70ull)
+#define CVMX_SLI_MSI_ENB3 (0x0000000000003C80ull)
+#define CVMX_SLI_MSI_RCV0 (0x0000000000003C10ull)
+#define CVMX_SLI_MSI_RCV1 (0x0000000000003C20ull)
+#define CVMX_SLI_MSI_RCV2 (0x0000000000003C30ull)
+#define CVMX_SLI_MSI_RCV3 (0x0000000000003C40ull)
+#define CVMX_SLI_MSI_RD_MAP (0x0000000000003CA0ull)
+#define CVMX_SLI_MSI_W1C_ENB0 (0x0000000000003CF0ull)
+#define CVMX_SLI_MSI_W1C_ENB1 (0x0000000000003D00ull)
+#define CVMX_SLI_MSI_W1C_ENB2 (0x0000000000003D10ull)
+#define CVMX_SLI_MSI_W1C_ENB3 (0x0000000000003D20ull)
+#define CVMX_SLI_MSI_W1S_ENB0 (0x0000000000003D30ull)
+#define CVMX_SLI_MSI_W1S_ENB1 (0x0000000000003D40ull)
+#define CVMX_SLI_MSI_W1S_ENB2 (0x0000000000003D50ull)
+#define CVMX_SLI_MSI_W1S_ENB3 (0x0000000000003D60ull)
+#define CVMX_SLI_MSI_WR_MAP (0x0000000000003C90ull)
+#define CVMX_SLI_PCIE_MSI_RCV (0x0000000000003CB0ull)
+#define CVMX_SLI_PCIE_MSI_RCV_B1 (0x0000000000000650ull)
+#define CVMX_SLI_PCIE_MSI_RCV_B2 (0x0000000000000660ull)
+#define CVMX_SLI_PCIE_MSI_RCV_B3 (0x0000000000000670ull)
+#define CVMX_SLI_PKTX_CNTS(offset) (0x0000000000002400ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_INSTR_BADDR(offset) (0x0000000000002800ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_INSTR_BAOFF_DBELL(offset) (0x0000000000002C00ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_INSTR_FIFO_RSIZE(offset) (0x0000000000003000ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_INSTR_HEADER(offset) (0x0000000000003400ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_IN_BP(offset) (0x0000000000003800ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_OUT_SIZE(offset) (0x0000000000000C00ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_SLIST_BADDR(offset) (0x0000000000001400ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_SLIST_BAOFF_DBELL(offset) (0x0000000000001800ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKTX_SLIST_FIFO_RSIZE(offset) (0x0000000000001C00ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKT_CNT_INT (0x0000000000001130ull)
+#define CVMX_SLI_PKT_CNT_INT_ENB (0x0000000000001150ull)
+#define CVMX_SLI_PKT_CTL (0x0000000000001220ull)
+#define CVMX_SLI_PKT_DATA_OUT_ES (0x00000000000010B0ull)
+#define CVMX_SLI_PKT_DATA_OUT_NS (0x00000000000010A0ull)
+#define CVMX_SLI_PKT_DATA_OUT_ROR (0x0000000000001090ull)
+#define CVMX_SLI_PKT_DPADDR (0x0000000000001080ull)
+#define CVMX_SLI_PKT_INPUT_CONTROL (0x0000000000001170ull)
+#define CVMX_SLI_PKT_INSTR_ENB (0x0000000000001000ull)
+#define CVMX_SLI_PKT_INSTR_RD_SIZE (0x00000000000011A0ull)
+#define CVMX_SLI_PKT_INSTR_SIZE (0x0000000000001020ull)
+#define CVMX_SLI_PKT_INT_LEVELS (0x0000000000001120ull)
+#define CVMX_SLI_PKT_IN_BP (0x0000000000001210ull)
+#define CVMX_SLI_PKT_IN_DONEX_CNTS(offset) (0x0000000000002000ull + ((offset) & 31) * 16)
+#define CVMX_SLI_PKT_IN_INSTR_COUNTS (0x0000000000001200ull)
+#define CVMX_SLI_PKT_IN_PCIE_PORT (0x00000000000011B0ull)
+#define CVMX_SLI_PKT_IPTR (0x0000000000001070ull)
+#define CVMX_SLI_PKT_OUTPUT_WMARK (0x0000000000001180ull)
+#define CVMX_SLI_PKT_OUT_BMODE (0x00000000000010D0ull)
+#define CVMX_SLI_PKT_OUT_BP_EN (0x0000000000001240ull)
+#define CVMX_SLI_PKT_OUT_ENB (0x0000000000001010ull)
+#define CVMX_SLI_PKT_PCIE_PORT (0x00000000000010E0ull)
+#define CVMX_SLI_PKT_PORT_IN_RST (0x00000000000011F0ull)
+#define CVMX_SLI_PKT_SLIST_ES (0x0000000000001050ull)
+#define CVMX_SLI_PKT_SLIST_NS (0x0000000000001040ull)
+#define CVMX_SLI_PKT_SLIST_ROR (0x0000000000001030ull)
+#define CVMX_SLI_PKT_TIME_INT (0x0000000000001140ull)
+#define CVMX_SLI_PKT_TIME_INT_ENB (0x0000000000001160ull)
+#define CVMX_SLI_PORTX_PKIND(offset) (0x0000000000000800ull + ((offset) & 31) * 16)
+#define CVMX_SLI_S2M_PORTX_CTL(offset) (0x0000000000003D80ull + ((offset) & 3) * 16)
+#define CVMX_SLI_SCRATCH_1 (0x00000000000003C0ull)
+#define CVMX_SLI_SCRATCH_2 (0x00000000000003D0ull)
+#define CVMX_SLI_STATE1 (0x0000000000000620ull)
+#define CVMX_SLI_STATE2 (0x0000000000000630ull)
+#define CVMX_SLI_STATE3 (0x0000000000000640ull)
+#define CVMX_SLI_TX_PIPE (0x0000000000001230ull)
+#define CVMX_SLI_WINDOW_CTL (0x00000000000002E0ull)
+#define CVMX_SLI_WIN_RD_ADDR (0x0000000000000010ull)
+#define CVMX_SLI_WIN_RD_DATA (0x0000000000000040ull)
+#define CVMX_SLI_WIN_WR_ADDR (0x0000000000000000ull)
+#define CVMX_SLI_WIN_WR_DATA (0x0000000000000020ull)
+#define CVMX_SLI_WIN_WR_MASK (0x0000000000000030ull)
+
+union cvmx_sli_bist_status {
+ uint64_t u64;
+ struct cvmx_sli_bist_status_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ncb_req:1;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t reserved_19_24:6;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t reserved_6_8:3;
+ uint64_t dsi1_1:1;
+ uint64_t dsi1_0:1;
+ uint64_t dsi0_1:1;
+ uint64_t dsi0_0:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } s;
+ struct cvmx_sli_bist_status_cn61xx {
+ uint64_t reserved_31_63:33;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t reserved_27_28:2;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t reserved_19_24:6;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t reserved_6_8:3;
+ uint64_t dsi1_1:1;
+ uint64_t dsi1_0:1;
+ uint64_t dsi0_1:1;
+ uint64_t dsi0_0:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn61xx;
+ struct cvmx_sli_bist_status_cn63xx {
+ uint64_t reserved_31_63:33;
+ uint64_t n2p0_c:1;
+ uint64_t n2p0_o:1;
+ uint64_t n2p1_c:1;
+ uint64_t n2p1_o:1;
+ uint64_t cpl_p0:1;
+ uint64_t cpl_p1:1;
+ uint64_t reserved_19_24:6;
+ uint64_t p2n0_c0:1;
+ uint64_t p2n0_c1:1;
+ uint64_t p2n0_n:1;
+ uint64_t p2n0_p0:1;
+ uint64_t p2n0_p1:1;
+ uint64_t p2n1_c0:1;
+ uint64_t p2n1_c1:1;
+ uint64_t p2n1_n:1;
+ uint64_t p2n1_p0:1;
+ uint64_t p2n1_p1:1;
+ uint64_t reserved_6_8:3;
+ uint64_t dsi1_1:1;
+ uint64_t dsi1_0:1;
+ uint64_t dsi0_1:1;
+ uint64_t dsi0_0:1;
+ uint64_t msi:1;
+ uint64_t ncb_cmd:1;
+ } cn63xx;
+ struct cvmx_sli_bist_status_cn63xx cn63xxp1;
+ struct cvmx_sli_bist_status_cn61xx cn66xx;
+ struct cvmx_sli_bist_status_s cn68xx;
+ struct cvmx_sli_bist_status_s cn68xxp1;
+};
+
+union cvmx_sli_ctl_portx {
+ uint64_t u64;
+ struct cvmx_sli_ctl_portx_s {
+ uint64_t reserved_22_63:42;
+ uint64_t intd:1;
+ uint64_t intc:1;
+ uint64_t intb:1;
+ uint64_t inta:1;
+ uint64_t dis_port:1;
+ uint64_t waitl_com:1;
+ uint64_t intd_map:2;
+ uint64_t intc_map:2;
+ uint64_t intb_map:2;
+ uint64_t inta_map:2;
+ uint64_t ctlp_ro:1;
+ uint64_t reserved_6_6:1;
+ uint64_t ptlp_ro:1;
+ uint64_t reserved_1_4:4;
+ uint64_t wait_com:1;
+ } s;
+ struct cvmx_sli_ctl_portx_s cn61xx;
+ struct cvmx_sli_ctl_portx_s cn63xx;
+ struct cvmx_sli_ctl_portx_s cn63xxp1;
+ struct cvmx_sli_ctl_portx_s cn66xx;
+ struct cvmx_sli_ctl_portx_s cn68xx;
+ struct cvmx_sli_ctl_portx_s cn68xxp1;
+};
+
+union cvmx_sli_ctl_status {
+ uint64_t u64;
+ struct cvmx_sli_ctl_status_s {
+ uint64_t reserved_20_63:44;
+ uint64_t p1_ntags:6;
+ uint64_t p0_ntags:6;
+ uint64_t chip_rev:8;
+ } s;
+ struct cvmx_sli_ctl_status_cn61xx {
+ uint64_t reserved_14_63:50;
+ uint64_t p0_ntags:6;
+ uint64_t chip_rev:8;
+ } cn61xx;
+ struct cvmx_sli_ctl_status_s cn63xx;
+ struct cvmx_sli_ctl_status_s cn63xxp1;
+ struct cvmx_sli_ctl_status_cn61xx cn66xx;
+ struct cvmx_sli_ctl_status_s cn68xx;
+ struct cvmx_sli_ctl_status_s cn68xxp1;
+};
+
+union cvmx_sli_data_out_cnt {
+ uint64_t u64;
+ struct cvmx_sli_data_out_cnt_s {
+ uint64_t reserved_44_63:20;
+ uint64_t p1_ucnt:16;
+ uint64_t p1_fcnt:6;
+ uint64_t p0_ucnt:16;
+ uint64_t p0_fcnt:6;
+ } s;
+ struct cvmx_sli_data_out_cnt_s cn61xx;
+ struct cvmx_sli_data_out_cnt_s cn63xx;
+ struct cvmx_sli_data_out_cnt_s cn63xxp1;
+ struct cvmx_sli_data_out_cnt_s cn66xx;
+ struct cvmx_sli_data_out_cnt_s cn68xx;
+ struct cvmx_sli_data_out_cnt_s cn68xxp1;
+};
+
+union cvmx_sli_dbg_data {
+ uint64_t u64;
+ struct cvmx_sli_dbg_data_s {
+ uint64_t reserved_18_63:46;
+ uint64_t dsel_ext:1;
+ uint64_t data:17;
+ } s;
+ struct cvmx_sli_dbg_data_s cn61xx;
+ struct cvmx_sli_dbg_data_s cn63xx;
+ struct cvmx_sli_dbg_data_s cn63xxp1;
+ struct cvmx_sli_dbg_data_s cn66xx;
+ struct cvmx_sli_dbg_data_s cn68xx;
+ struct cvmx_sli_dbg_data_s cn68xxp1;
+};
+
+union cvmx_sli_dbg_select {
+ uint64_t u64;
+ struct cvmx_sli_dbg_select_s {
+ uint64_t reserved_33_63:31;
+ uint64_t adbg_sel:1;
+ uint64_t dbg_sel:32;
+ } s;
+ struct cvmx_sli_dbg_select_s cn61xx;
+ struct cvmx_sli_dbg_select_s cn63xx;
+ struct cvmx_sli_dbg_select_s cn63xxp1;
+ struct cvmx_sli_dbg_select_s cn66xx;
+ struct cvmx_sli_dbg_select_s cn68xx;
+ struct cvmx_sli_dbg_select_s cn68xxp1;
+};
+
+union cvmx_sli_dmax_cnt {
+ uint64_t u64;
+ struct cvmx_sli_dmax_cnt_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_sli_dmax_cnt_s cn61xx;
+ struct cvmx_sli_dmax_cnt_s cn63xx;
+ struct cvmx_sli_dmax_cnt_s cn63xxp1;
+ struct cvmx_sli_dmax_cnt_s cn66xx;
+ struct cvmx_sli_dmax_cnt_s cn68xx;
+ struct cvmx_sli_dmax_cnt_s cn68xxp1;
+};
+
+union cvmx_sli_dmax_int_level {
+ uint64_t u64;
+ struct cvmx_sli_dmax_int_level_s {
+ uint64_t time:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_sli_dmax_int_level_s cn61xx;
+ struct cvmx_sli_dmax_int_level_s cn63xx;
+ struct cvmx_sli_dmax_int_level_s cn63xxp1;
+ struct cvmx_sli_dmax_int_level_s cn66xx;
+ struct cvmx_sli_dmax_int_level_s cn68xx;
+ struct cvmx_sli_dmax_int_level_s cn68xxp1;
+};
+
+union cvmx_sli_dmax_tim {
+ uint64_t u64;
+ struct cvmx_sli_dmax_tim_s {
+ uint64_t reserved_32_63:32;
+ uint64_t tim:32;
+ } s;
+ struct cvmx_sli_dmax_tim_s cn61xx;
+ struct cvmx_sli_dmax_tim_s cn63xx;
+ struct cvmx_sli_dmax_tim_s cn63xxp1;
+ struct cvmx_sli_dmax_tim_s cn66xx;
+ struct cvmx_sli_dmax_tim_s cn68xx;
+ struct cvmx_sli_dmax_tim_s cn68xxp1;
+};
+
+union cvmx_sli_int_enb_ciu {
+ uint64_t u64;
+ struct cvmx_sli_int_enb_ciu_s {
+ uint64_t reserved_62_63:2;
+ uint64_t pipe_err:1;
+ uint64_t ill_pad:1;
+ uint64_t sprt3_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_28_31:4;
+ uint64_t m3_un_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_up_b0:1;
+ uint64_t reserved_18_19:2;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } s;
+ struct cvmx_sli_int_enb_ciu_cn61xx {
+ uint64_t reserved_61_63:3;
+ uint64_t ill_pad:1;
+ uint64_t sprt3_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_28_31:4;
+ uint64_t m3_un_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_up_b0:1;
+ uint64_t reserved_18_19:2;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn61xx;
+ struct cvmx_sli_int_enb_ciu_cn63xx {
+ uint64_t reserved_61_63:3;
+ uint64_t ill_pad:1;
+ uint64_t reserved_58_59:2;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_18_31:14;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn63xx;
+ struct cvmx_sli_int_enb_ciu_cn63xx cn63xxp1;
+ struct cvmx_sli_int_enb_ciu_cn61xx cn66xx;
+ struct cvmx_sli_int_enb_ciu_cn68xx {
+ uint64_t reserved_62_63:2;
+ uint64_t pipe_err:1;
+ uint64_t ill_pad:1;
+ uint64_t reserved_58_59:2;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t reserved_51_51:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_18_31:14;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn68xx;
+ struct cvmx_sli_int_enb_ciu_cn68xx cn68xxp1;
+};
+
+union cvmx_sli_int_enb_portx {
+ uint64_t u64;
+ struct cvmx_sli_int_enb_portx_s {
+ uint64_t reserved_62_63:2;
+ uint64_t pipe_err:1;
+ uint64_t ill_pad:1;
+ uint64_t sprt3_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_28_31:4;
+ uint64_t m3_un_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_up_b0:1;
+ uint64_t mac1_int:1;
+ uint64_t mac0_int:1;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } s;
+ struct cvmx_sli_int_enb_portx_cn61xx {
+ uint64_t reserved_61_63:3;
+ uint64_t ill_pad:1;
+ uint64_t sprt3_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_28_31:4;
+ uint64_t m3_un_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_up_b0:1;
+ uint64_t mac1_int:1;
+ uint64_t mac0_int:1;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn61xx;
+ struct cvmx_sli_int_enb_portx_cn63xx {
+ uint64_t reserved_61_63:3;
+ uint64_t ill_pad:1;
+ uint64_t reserved_58_59:2;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_20_31:12;
+ uint64_t mac1_int:1;
+ uint64_t mac0_int:1;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn63xx;
+ struct cvmx_sli_int_enb_portx_cn63xx cn63xxp1;
+ struct cvmx_sli_int_enb_portx_cn61xx cn66xx;
+ struct cvmx_sli_int_enb_portx_cn68xx {
+ uint64_t reserved_62_63:2;
+ uint64_t pipe_err:1;
+ uint64_t ill_pad:1;
+ uint64_t reserved_58_59:2;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t reserved_51_51:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_20_31:12;
+ uint64_t mac1_int:1;
+ uint64_t mac0_int:1;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn68xx;
+ struct cvmx_sli_int_enb_portx_cn68xx cn68xxp1;
+};
+
+union cvmx_sli_int_sum {
+ uint64_t u64;
+ struct cvmx_sli_int_sum_s {
+ uint64_t reserved_62_63:2;
+ uint64_t pipe_err:1;
+ uint64_t ill_pad:1;
+ uint64_t sprt3_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_28_31:4;
+ uint64_t m3_un_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_up_b0:1;
+ uint64_t mac1_int:1;
+ uint64_t mac0_int:1;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } s;
+ struct cvmx_sli_int_sum_cn61xx {
+ uint64_t reserved_61_63:3;
+ uint64_t ill_pad:1;
+ uint64_t sprt3_err:1;
+ uint64_t sprt2_err:1;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_28_31:4;
+ uint64_t m3_un_wi:1;
+ uint64_t m3_un_b0:1;
+ uint64_t m3_up_wi:1;
+ uint64_t m3_up_b0:1;
+ uint64_t m2_un_wi:1;
+ uint64_t m2_un_b0:1;
+ uint64_t m2_up_wi:1;
+ uint64_t m2_up_b0:1;
+ uint64_t mac1_int:1;
+ uint64_t mac0_int:1;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn61xx;
+ struct cvmx_sli_int_sum_cn63xx {
+ uint64_t reserved_61_63:3;
+ uint64_t ill_pad:1;
+ uint64_t reserved_58_59:2;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t pin_bp:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_20_31:12;
+ uint64_t mac1_int:1;
+ uint64_t mac0_int:1;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn63xx;
+ struct cvmx_sli_int_sum_cn63xx cn63xxp1;
+ struct cvmx_sli_int_sum_cn61xx cn66xx;
+ struct cvmx_sli_int_sum_cn68xx {
+ uint64_t reserved_62_63:2;
+ uint64_t pipe_err:1;
+ uint64_t ill_pad:1;
+ uint64_t reserved_58_59:2;
+ uint64_t sprt1_err:1;
+ uint64_t sprt0_err:1;
+ uint64_t pins_err:1;
+ uint64_t pop_err:1;
+ uint64_t pdi_err:1;
+ uint64_t pgl_err:1;
+ uint64_t reserved_51_51:1;
+ uint64_t pout_err:1;
+ uint64_t psldbof:1;
+ uint64_t pidbof:1;
+ uint64_t reserved_38_47:10;
+ uint64_t dtime:2;
+ uint64_t dcnt:2;
+ uint64_t dmafi:2;
+ uint64_t reserved_20_31:12;
+ uint64_t mac1_int:1;
+ uint64_t mac0_int:1;
+ uint64_t mio_int1:1;
+ uint64_t mio_int0:1;
+ uint64_t m1_un_wi:1;
+ uint64_t m1_un_b0:1;
+ uint64_t m1_up_wi:1;
+ uint64_t m1_up_b0:1;
+ uint64_t m0_un_wi:1;
+ uint64_t m0_un_b0:1;
+ uint64_t m0_up_wi:1;
+ uint64_t m0_up_b0:1;
+ uint64_t reserved_6_7:2;
+ uint64_t ptime:1;
+ uint64_t pcnt:1;
+ uint64_t iob2big:1;
+ uint64_t bar0_to:1;
+ uint64_t reserved_1_1:1;
+ uint64_t rml_to:1;
+ } cn68xx;
+ struct cvmx_sli_int_sum_cn68xx cn68xxp1;
+};
+
+union cvmx_sli_last_win_rdata0 {
+ uint64_t u64;
+ struct cvmx_sli_last_win_rdata0_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_sli_last_win_rdata0_s cn61xx;
+ struct cvmx_sli_last_win_rdata0_s cn63xx;
+ struct cvmx_sli_last_win_rdata0_s cn63xxp1;
+ struct cvmx_sli_last_win_rdata0_s cn66xx;
+ struct cvmx_sli_last_win_rdata0_s cn68xx;
+ struct cvmx_sli_last_win_rdata0_s cn68xxp1;
+};
+
+union cvmx_sli_last_win_rdata1 {
+ uint64_t u64;
+ struct cvmx_sli_last_win_rdata1_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_sli_last_win_rdata1_s cn61xx;
+ struct cvmx_sli_last_win_rdata1_s cn63xx;
+ struct cvmx_sli_last_win_rdata1_s cn63xxp1;
+ struct cvmx_sli_last_win_rdata1_s cn66xx;
+ struct cvmx_sli_last_win_rdata1_s cn68xx;
+ struct cvmx_sli_last_win_rdata1_s cn68xxp1;
+};
+
+union cvmx_sli_last_win_rdata2 {
+ uint64_t u64;
+ struct cvmx_sli_last_win_rdata2_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_sli_last_win_rdata2_s cn61xx;
+ struct cvmx_sli_last_win_rdata2_s cn66xx;
+};
+
+union cvmx_sli_last_win_rdata3 {
+ uint64_t u64;
+ struct cvmx_sli_last_win_rdata3_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_sli_last_win_rdata3_s cn61xx;
+ struct cvmx_sli_last_win_rdata3_s cn66xx;
+};
+
+union cvmx_sli_mac_credit_cnt {
+ uint64_t u64;
+ struct cvmx_sli_mac_credit_cnt_s {
+ uint64_t reserved_54_63:10;
+ uint64_t p1_c_d:1;
+ uint64_t p1_n_d:1;
+ uint64_t p1_p_d:1;
+ uint64_t p0_c_d:1;
+ uint64_t p0_n_d:1;
+ uint64_t p0_p_d:1;
+ uint64_t p1_ccnt:8;
+ uint64_t p1_ncnt:8;
+ uint64_t p1_pcnt:8;
+ uint64_t p0_ccnt:8;
+ uint64_t p0_ncnt:8;
+ uint64_t p0_pcnt:8;
+ } s;
+ struct cvmx_sli_mac_credit_cnt_s cn61xx;
+ struct cvmx_sli_mac_credit_cnt_s cn63xx;
+ struct cvmx_sli_mac_credit_cnt_cn63xxp1 {
+ uint64_t reserved_48_63:16;
+ uint64_t p1_ccnt:8;
+ uint64_t p1_ncnt:8;
+ uint64_t p1_pcnt:8;
+ uint64_t p0_ccnt:8;
+ uint64_t p0_ncnt:8;
+ uint64_t p0_pcnt:8;
+ } cn63xxp1;
+ struct cvmx_sli_mac_credit_cnt_s cn66xx;
+ struct cvmx_sli_mac_credit_cnt_s cn68xx;
+ struct cvmx_sli_mac_credit_cnt_s cn68xxp1;
+};
+
+union cvmx_sli_mac_credit_cnt2 {
+ uint64_t u64;
+ struct cvmx_sli_mac_credit_cnt2_s {
+ uint64_t reserved_54_63:10;
+ uint64_t p3_c_d:1;
+ uint64_t p3_n_d:1;
+ uint64_t p3_p_d:1;
+ uint64_t p2_c_d:1;
+ uint64_t p2_n_d:1;
+ uint64_t p2_p_d:1;
+ uint64_t p3_ccnt:8;
+ uint64_t p3_ncnt:8;
+ uint64_t p3_pcnt:8;
+ uint64_t p2_ccnt:8;
+ uint64_t p2_ncnt:8;
+ uint64_t p2_pcnt:8;
+ } s;
+ struct cvmx_sli_mac_credit_cnt2_s cn61xx;
+ struct cvmx_sli_mac_credit_cnt2_s cn66xx;
+};
+
+union cvmx_sli_mac_number {
+ uint64_t u64;
+ struct cvmx_sli_mac_number_s {
+ uint64_t reserved_9_63:55;
+ uint64_t a_mode:1;
+ uint64_t num:8;
+ } s;
+ struct cvmx_sli_mac_number_s cn61xx;
+ struct cvmx_sli_mac_number_cn63xx {
+ uint64_t reserved_8_63:56;
+ uint64_t num:8;
+ } cn63xx;
+ struct cvmx_sli_mac_number_s cn66xx;
+ struct cvmx_sli_mac_number_cn63xx cn68xx;
+ struct cvmx_sli_mac_number_cn63xx cn68xxp1;
+};
+
+union cvmx_sli_mem_access_ctl {
+ uint64_t u64;
+ struct cvmx_sli_mem_access_ctl_s {
+ uint64_t reserved_14_63:50;
+ uint64_t max_word:4;
+ uint64_t timer:10;
+ } s;
+ struct cvmx_sli_mem_access_ctl_s cn61xx;
+ struct cvmx_sli_mem_access_ctl_s cn63xx;
+ struct cvmx_sli_mem_access_ctl_s cn63xxp1;
+ struct cvmx_sli_mem_access_ctl_s cn66xx;
+ struct cvmx_sli_mem_access_ctl_s cn68xx;
+ struct cvmx_sli_mem_access_ctl_s cn68xxp1;
+};
+
+union cvmx_sli_mem_access_subidx {
+ uint64_t u64;
+ struct cvmx_sli_mem_access_subidx_s {
+ uint64_t reserved_43_63:21;
+ uint64_t zero:1;
+ uint64_t port:3;
+ uint64_t nmerge:1;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t wtype:2;
+ uint64_t rtype:2;
+ uint64_t reserved_0_29:30;
+ } s;
+ struct cvmx_sli_mem_access_subidx_cn61xx {
+ uint64_t reserved_43_63:21;
+ uint64_t zero:1;
+ uint64_t port:3;
+ uint64_t nmerge:1;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t wtype:2;
+ uint64_t rtype:2;
+ uint64_t ba:30;
+ } cn61xx;
+ struct cvmx_sli_mem_access_subidx_cn61xx cn63xx;
+ struct cvmx_sli_mem_access_subidx_cn61xx cn63xxp1;
+ struct cvmx_sli_mem_access_subidx_cn61xx cn66xx;
+ struct cvmx_sli_mem_access_subidx_cn68xx {
+ uint64_t reserved_43_63:21;
+ uint64_t zero:1;
+ uint64_t port:3;
+ uint64_t nmerge:1;
+ uint64_t esr:2;
+ uint64_t esw:2;
+ uint64_t wtype:2;
+ uint64_t rtype:2;
+ uint64_t ba:28;
+ uint64_t reserved_0_1:2;
+ } cn68xx;
+ struct cvmx_sli_mem_access_subidx_cn68xx cn68xxp1;
+};
+
+union cvmx_sli_msi_enb0 {
+ uint64_t u64;
+ struct cvmx_sli_msi_enb0_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_sli_msi_enb0_s cn61xx;
+ struct cvmx_sli_msi_enb0_s cn63xx;
+ struct cvmx_sli_msi_enb0_s cn63xxp1;
+ struct cvmx_sli_msi_enb0_s cn66xx;
+ struct cvmx_sli_msi_enb0_s cn68xx;
+ struct cvmx_sli_msi_enb0_s cn68xxp1;
+};
+
+union cvmx_sli_msi_enb1 {
+ uint64_t u64;
+ struct cvmx_sli_msi_enb1_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_sli_msi_enb1_s cn61xx;
+ struct cvmx_sli_msi_enb1_s cn63xx;
+ struct cvmx_sli_msi_enb1_s cn63xxp1;
+ struct cvmx_sli_msi_enb1_s cn66xx;
+ struct cvmx_sli_msi_enb1_s cn68xx;
+ struct cvmx_sli_msi_enb1_s cn68xxp1;
+};
+
+union cvmx_sli_msi_enb2 {
+ uint64_t u64;
+ struct cvmx_sli_msi_enb2_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_sli_msi_enb2_s cn61xx;
+ struct cvmx_sli_msi_enb2_s cn63xx;
+ struct cvmx_sli_msi_enb2_s cn63xxp1;
+ struct cvmx_sli_msi_enb2_s cn66xx;
+ struct cvmx_sli_msi_enb2_s cn68xx;
+ struct cvmx_sli_msi_enb2_s cn68xxp1;
+};
+
+union cvmx_sli_msi_enb3 {
+ uint64_t u64;
+ struct cvmx_sli_msi_enb3_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_sli_msi_enb3_s cn61xx;
+ struct cvmx_sli_msi_enb3_s cn63xx;
+ struct cvmx_sli_msi_enb3_s cn63xxp1;
+ struct cvmx_sli_msi_enb3_s cn66xx;
+ struct cvmx_sli_msi_enb3_s cn68xx;
+ struct cvmx_sli_msi_enb3_s cn68xxp1;
+};
+
+union cvmx_sli_msi_rcv0 {
+ uint64_t u64;
+ struct cvmx_sli_msi_rcv0_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_sli_msi_rcv0_s cn61xx;
+ struct cvmx_sli_msi_rcv0_s cn63xx;
+ struct cvmx_sli_msi_rcv0_s cn63xxp1;
+ struct cvmx_sli_msi_rcv0_s cn66xx;
+ struct cvmx_sli_msi_rcv0_s cn68xx;
+ struct cvmx_sli_msi_rcv0_s cn68xxp1;
+};
+
+union cvmx_sli_msi_rcv1 {
+ uint64_t u64;
+ struct cvmx_sli_msi_rcv1_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_sli_msi_rcv1_s cn61xx;
+ struct cvmx_sli_msi_rcv1_s cn63xx;
+ struct cvmx_sli_msi_rcv1_s cn63xxp1;
+ struct cvmx_sli_msi_rcv1_s cn66xx;
+ struct cvmx_sli_msi_rcv1_s cn68xx;
+ struct cvmx_sli_msi_rcv1_s cn68xxp1;
+};
+
+union cvmx_sli_msi_rcv2 {
+ uint64_t u64;
+ struct cvmx_sli_msi_rcv2_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_sli_msi_rcv2_s cn61xx;
+ struct cvmx_sli_msi_rcv2_s cn63xx;
+ struct cvmx_sli_msi_rcv2_s cn63xxp1;
+ struct cvmx_sli_msi_rcv2_s cn66xx;
+ struct cvmx_sli_msi_rcv2_s cn68xx;
+ struct cvmx_sli_msi_rcv2_s cn68xxp1;
+};
+
+union cvmx_sli_msi_rcv3 {
+ uint64_t u64;
+ struct cvmx_sli_msi_rcv3_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_sli_msi_rcv3_s cn61xx;
+ struct cvmx_sli_msi_rcv3_s cn63xx;
+ struct cvmx_sli_msi_rcv3_s cn63xxp1;
+ struct cvmx_sli_msi_rcv3_s cn66xx;
+ struct cvmx_sli_msi_rcv3_s cn68xx;
+ struct cvmx_sli_msi_rcv3_s cn68xxp1;
+};
+
+union cvmx_sli_msi_rd_map {
+ uint64_t u64;
+ struct cvmx_sli_msi_rd_map_s {
+ uint64_t reserved_16_63:48;
+ uint64_t rd_int:8;
+ uint64_t msi_int:8;
+ } s;
+ struct cvmx_sli_msi_rd_map_s cn61xx;
+ struct cvmx_sli_msi_rd_map_s cn63xx;
+ struct cvmx_sli_msi_rd_map_s cn63xxp1;
+ struct cvmx_sli_msi_rd_map_s cn66xx;
+ struct cvmx_sli_msi_rd_map_s cn68xx;
+ struct cvmx_sli_msi_rd_map_s cn68xxp1;
+};
+
+union cvmx_sli_msi_w1c_enb0 {
+ uint64_t u64;
+ struct cvmx_sli_msi_w1c_enb0_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_sli_msi_w1c_enb0_s cn61xx;
+ struct cvmx_sli_msi_w1c_enb0_s cn63xx;
+ struct cvmx_sli_msi_w1c_enb0_s cn63xxp1;
+ struct cvmx_sli_msi_w1c_enb0_s cn66xx;
+ struct cvmx_sli_msi_w1c_enb0_s cn68xx;
+ struct cvmx_sli_msi_w1c_enb0_s cn68xxp1;
+};
+
+union cvmx_sli_msi_w1c_enb1 {
+ uint64_t u64;
+ struct cvmx_sli_msi_w1c_enb1_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_sli_msi_w1c_enb1_s cn61xx;
+ struct cvmx_sli_msi_w1c_enb1_s cn63xx;
+ struct cvmx_sli_msi_w1c_enb1_s cn63xxp1;
+ struct cvmx_sli_msi_w1c_enb1_s cn66xx;
+ struct cvmx_sli_msi_w1c_enb1_s cn68xx;
+ struct cvmx_sli_msi_w1c_enb1_s cn68xxp1;
+};
+
+union cvmx_sli_msi_w1c_enb2 {
+ uint64_t u64;
+ struct cvmx_sli_msi_w1c_enb2_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_sli_msi_w1c_enb2_s cn61xx;
+ struct cvmx_sli_msi_w1c_enb2_s cn63xx;
+ struct cvmx_sli_msi_w1c_enb2_s cn63xxp1;
+ struct cvmx_sli_msi_w1c_enb2_s cn66xx;
+ struct cvmx_sli_msi_w1c_enb2_s cn68xx;
+ struct cvmx_sli_msi_w1c_enb2_s cn68xxp1;
+};
+
+union cvmx_sli_msi_w1c_enb3 {
+ uint64_t u64;
+ struct cvmx_sli_msi_w1c_enb3_s {
+ uint64_t clr:64;
+ } s;
+ struct cvmx_sli_msi_w1c_enb3_s cn61xx;
+ struct cvmx_sli_msi_w1c_enb3_s cn63xx;
+ struct cvmx_sli_msi_w1c_enb3_s cn63xxp1;
+ struct cvmx_sli_msi_w1c_enb3_s cn66xx;
+ struct cvmx_sli_msi_w1c_enb3_s cn68xx;
+ struct cvmx_sli_msi_w1c_enb3_s cn68xxp1;
+};
+
+union cvmx_sli_msi_w1s_enb0 {
+ uint64_t u64;
+ struct cvmx_sli_msi_w1s_enb0_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_sli_msi_w1s_enb0_s cn61xx;
+ struct cvmx_sli_msi_w1s_enb0_s cn63xx;
+ struct cvmx_sli_msi_w1s_enb0_s cn63xxp1;
+ struct cvmx_sli_msi_w1s_enb0_s cn66xx;
+ struct cvmx_sli_msi_w1s_enb0_s cn68xx;
+ struct cvmx_sli_msi_w1s_enb0_s cn68xxp1;
+};
+
+union cvmx_sli_msi_w1s_enb1 {
+ uint64_t u64;
+ struct cvmx_sli_msi_w1s_enb1_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_sli_msi_w1s_enb1_s cn61xx;
+ struct cvmx_sli_msi_w1s_enb1_s cn63xx;
+ struct cvmx_sli_msi_w1s_enb1_s cn63xxp1;
+ struct cvmx_sli_msi_w1s_enb1_s cn66xx;
+ struct cvmx_sli_msi_w1s_enb1_s cn68xx;
+ struct cvmx_sli_msi_w1s_enb1_s cn68xxp1;
+};
+
+union cvmx_sli_msi_w1s_enb2 {
+ uint64_t u64;
+ struct cvmx_sli_msi_w1s_enb2_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_sli_msi_w1s_enb2_s cn61xx;
+ struct cvmx_sli_msi_w1s_enb2_s cn63xx;
+ struct cvmx_sli_msi_w1s_enb2_s cn63xxp1;
+ struct cvmx_sli_msi_w1s_enb2_s cn66xx;
+ struct cvmx_sli_msi_w1s_enb2_s cn68xx;
+ struct cvmx_sli_msi_w1s_enb2_s cn68xxp1;
+};
+
+union cvmx_sli_msi_w1s_enb3 {
+ uint64_t u64;
+ struct cvmx_sli_msi_w1s_enb3_s {
+ uint64_t set:64;
+ } s;
+ struct cvmx_sli_msi_w1s_enb3_s cn61xx;
+ struct cvmx_sli_msi_w1s_enb3_s cn63xx;
+ struct cvmx_sli_msi_w1s_enb3_s cn63xxp1;
+ struct cvmx_sli_msi_w1s_enb3_s cn66xx;
+ struct cvmx_sli_msi_w1s_enb3_s cn68xx;
+ struct cvmx_sli_msi_w1s_enb3_s cn68xxp1;
+};
+
+union cvmx_sli_msi_wr_map {
+ uint64_t u64;
+ struct cvmx_sli_msi_wr_map_s {
+ uint64_t reserved_16_63:48;
+ uint64_t ciu_int:8;
+ uint64_t msi_int:8;
+ } s;
+ struct cvmx_sli_msi_wr_map_s cn61xx;
+ struct cvmx_sli_msi_wr_map_s cn63xx;
+ struct cvmx_sli_msi_wr_map_s cn63xxp1;
+ struct cvmx_sli_msi_wr_map_s cn66xx;
+ struct cvmx_sli_msi_wr_map_s cn68xx;
+ struct cvmx_sli_msi_wr_map_s cn68xxp1;
+};
+
+union cvmx_sli_pcie_msi_rcv {
+ uint64_t u64;
+ struct cvmx_sli_pcie_msi_rcv_s {
+ uint64_t reserved_8_63:56;
+ uint64_t intr:8;
+ } s;
+ struct cvmx_sli_pcie_msi_rcv_s cn61xx;
+ struct cvmx_sli_pcie_msi_rcv_s cn63xx;
+ struct cvmx_sli_pcie_msi_rcv_s cn63xxp1;
+ struct cvmx_sli_pcie_msi_rcv_s cn66xx;
+ struct cvmx_sli_pcie_msi_rcv_s cn68xx;
+ struct cvmx_sli_pcie_msi_rcv_s cn68xxp1;
+};
+
+union cvmx_sli_pcie_msi_rcv_b1 {
+ uint64_t u64;
+ struct cvmx_sli_pcie_msi_rcv_b1_s {
+ uint64_t reserved_16_63:48;
+ uint64_t intr:8;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_sli_pcie_msi_rcv_b1_s cn61xx;
+ struct cvmx_sli_pcie_msi_rcv_b1_s cn63xx;
+ struct cvmx_sli_pcie_msi_rcv_b1_s cn63xxp1;
+ struct cvmx_sli_pcie_msi_rcv_b1_s cn66xx;
+ struct cvmx_sli_pcie_msi_rcv_b1_s cn68xx;
+ struct cvmx_sli_pcie_msi_rcv_b1_s cn68xxp1;
+};
+
+union cvmx_sli_pcie_msi_rcv_b2 {
+ uint64_t u64;
+ struct cvmx_sli_pcie_msi_rcv_b2_s {
+ uint64_t reserved_24_63:40;
+ uint64_t intr:8;
+ uint64_t reserved_0_15:16;
+ } s;
+ struct cvmx_sli_pcie_msi_rcv_b2_s cn61xx;
+ struct cvmx_sli_pcie_msi_rcv_b2_s cn63xx;
+ struct cvmx_sli_pcie_msi_rcv_b2_s cn63xxp1;
+ struct cvmx_sli_pcie_msi_rcv_b2_s cn66xx;
+ struct cvmx_sli_pcie_msi_rcv_b2_s cn68xx;
+ struct cvmx_sli_pcie_msi_rcv_b2_s cn68xxp1;
+};
+
+union cvmx_sli_pcie_msi_rcv_b3 {
+ uint64_t u64;
+ struct cvmx_sli_pcie_msi_rcv_b3_s {
+ uint64_t reserved_32_63:32;
+ uint64_t intr:8;
+ uint64_t reserved_0_23:24;
+ } s;
+ struct cvmx_sli_pcie_msi_rcv_b3_s cn61xx;
+ struct cvmx_sli_pcie_msi_rcv_b3_s cn63xx;
+ struct cvmx_sli_pcie_msi_rcv_b3_s cn63xxp1;
+ struct cvmx_sli_pcie_msi_rcv_b3_s cn66xx;
+ struct cvmx_sli_pcie_msi_rcv_b3_s cn68xx;
+ struct cvmx_sli_pcie_msi_rcv_b3_s cn68xxp1;
+};
+
+union cvmx_sli_pktx_cnts {
+ uint64_t u64;
+ struct cvmx_sli_pktx_cnts_s {
+ uint64_t reserved_54_63:10;
+ uint64_t timer:22;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_sli_pktx_cnts_s cn61xx;
+ struct cvmx_sli_pktx_cnts_s cn63xx;
+ struct cvmx_sli_pktx_cnts_s cn63xxp1;
+ struct cvmx_sli_pktx_cnts_s cn66xx;
+ struct cvmx_sli_pktx_cnts_s cn68xx;
+ struct cvmx_sli_pktx_cnts_s cn68xxp1;
+};
+
+union cvmx_sli_pktx_in_bp {
+ uint64_t u64;
+ struct cvmx_sli_pktx_in_bp_s {
+ uint64_t wmark:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_sli_pktx_in_bp_s cn61xx;
+ struct cvmx_sli_pktx_in_bp_s cn63xx;
+ struct cvmx_sli_pktx_in_bp_s cn63xxp1;
+ struct cvmx_sli_pktx_in_bp_s cn66xx;
+};
+
+union cvmx_sli_pktx_instr_baddr {
+ uint64_t u64;
+ struct cvmx_sli_pktx_instr_baddr_s {
+ uint64_t addr:61;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_sli_pktx_instr_baddr_s cn61xx;
+ struct cvmx_sli_pktx_instr_baddr_s cn63xx;
+ struct cvmx_sli_pktx_instr_baddr_s cn63xxp1;
+ struct cvmx_sli_pktx_instr_baddr_s cn66xx;
+ struct cvmx_sli_pktx_instr_baddr_s cn68xx;
+ struct cvmx_sli_pktx_instr_baddr_s cn68xxp1;
+};
+
+union cvmx_sli_pktx_instr_baoff_dbell {
+ uint64_t u64;
+ struct cvmx_sli_pktx_instr_baoff_dbell_s {
+ uint64_t aoff:32;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_sli_pktx_instr_baoff_dbell_s cn61xx;
+ struct cvmx_sli_pktx_instr_baoff_dbell_s cn63xx;
+ struct cvmx_sli_pktx_instr_baoff_dbell_s cn63xxp1;
+ struct cvmx_sli_pktx_instr_baoff_dbell_s cn66xx;
+ struct cvmx_sli_pktx_instr_baoff_dbell_s cn68xx;
+ struct cvmx_sli_pktx_instr_baoff_dbell_s cn68xxp1;
+};
+
+union cvmx_sli_pktx_instr_fifo_rsize {
+ uint64_t u64;
+ struct cvmx_sli_pktx_instr_fifo_rsize_s {
+ uint64_t max:9;
+ uint64_t rrp:9;
+ uint64_t wrp:9;
+ uint64_t fcnt:5;
+ uint64_t rsize:32;
+ } s;
+ struct cvmx_sli_pktx_instr_fifo_rsize_s cn61xx;
+ struct cvmx_sli_pktx_instr_fifo_rsize_s cn63xx;
+ struct cvmx_sli_pktx_instr_fifo_rsize_s cn63xxp1;
+ struct cvmx_sli_pktx_instr_fifo_rsize_s cn66xx;
+ struct cvmx_sli_pktx_instr_fifo_rsize_s cn68xx;
+ struct cvmx_sli_pktx_instr_fifo_rsize_s cn68xxp1;
+};
+
+union cvmx_sli_pktx_instr_header {
+ uint64_t u64;
+ struct cvmx_sli_pktx_instr_header_s {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t reserved_38_42:5;
+ uint64_t rparmode:2;
+ uint64_t reserved_35_35:1;
+ uint64_t rskp_len:7;
+ uint64_t rngrpext:2;
+ uint64_t rnqos:1;
+ uint64_t rngrp:1;
+ uint64_t rntt:1;
+ uint64_t rntag:1;
+ uint64_t use_ihdr:1;
+ uint64_t reserved_16_20:5;
+ uint64_t par_mode:2;
+ uint64_t reserved_13_13:1;
+ uint64_t skp_len:7;
+ uint64_t ngrpext:2;
+ uint64_t nqos:1;
+ uint64_t ngrp:1;
+ uint64_t ntt:1;
+ uint64_t ntag:1;
+ } s;
+ struct cvmx_sli_pktx_instr_header_cn61xx {
+ uint64_t reserved_44_63:20;
+ uint64_t pbp:1;
+ uint64_t reserved_38_42:5;
+ uint64_t rparmode:2;
+ uint64_t reserved_35_35:1;
+ uint64_t rskp_len:7;
+ uint64_t reserved_26_27:2;
+ uint64_t rnqos:1;
+ uint64_t rngrp:1;
+ uint64_t rntt:1;
+ uint64_t rntag:1;
+ uint64_t use_ihdr:1;
+ uint64_t reserved_16_20:5;
+ uint64_t par_mode:2;
+ uint64_t reserved_13_13:1;
+ uint64_t skp_len:7;
+ uint64_t reserved_4_5:2;
+ uint64_t nqos:1;
+ uint64_t ngrp:1;
+ uint64_t ntt:1;
+ uint64_t ntag:1;
+ } cn61xx;
+ struct cvmx_sli_pktx_instr_header_cn61xx cn63xx;
+ struct cvmx_sli_pktx_instr_header_cn61xx cn63xxp1;
+ struct cvmx_sli_pktx_instr_header_cn61xx cn66xx;
+ struct cvmx_sli_pktx_instr_header_s cn68xx;
+ struct cvmx_sli_pktx_instr_header_cn61xx cn68xxp1;
+};
+
+union cvmx_sli_pktx_out_size {
+ uint64_t u64;
+ struct cvmx_sli_pktx_out_size_s {
+ uint64_t reserved_23_63:41;
+ uint64_t isize:7;
+ uint64_t bsize:16;
+ } s;
+ struct cvmx_sli_pktx_out_size_s cn61xx;
+ struct cvmx_sli_pktx_out_size_s cn63xx;
+ struct cvmx_sli_pktx_out_size_s cn63xxp1;
+ struct cvmx_sli_pktx_out_size_s cn66xx;
+ struct cvmx_sli_pktx_out_size_s cn68xx;
+ struct cvmx_sli_pktx_out_size_s cn68xxp1;
+};
+
+union cvmx_sli_pktx_slist_baddr {
+ uint64_t u64;
+ struct cvmx_sli_pktx_slist_baddr_s {
+ uint64_t addr:60;
+ uint64_t reserved_0_3:4;
+ } s;
+ struct cvmx_sli_pktx_slist_baddr_s cn61xx;
+ struct cvmx_sli_pktx_slist_baddr_s cn63xx;
+ struct cvmx_sli_pktx_slist_baddr_s cn63xxp1;
+ struct cvmx_sli_pktx_slist_baddr_s cn66xx;
+ struct cvmx_sli_pktx_slist_baddr_s cn68xx;
+ struct cvmx_sli_pktx_slist_baddr_s cn68xxp1;
+};
+
+union cvmx_sli_pktx_slist_baoff_dbell {
+ uint64_t u64;
+ struct cvmx_sli_pktx_slist_baoff_dbell_s {
+ uint64_t aoff:32;
+ uint64_t dbell:32;
+ } s;
+ struct cvmx_sli_pktx_slist_baoff_dbell_s cn61xx;
+ struct cvmx_sli_pktx_slist_baoff_dbell_s cn63xx;
+ struct cvmx_sli_pktx_slist_baoff_dbell_s cn63xxp1;
+ struct cvmx_sli_pktx_slist_baoff_dbell_s cn66xx;
+ struct cvmx_sli_pktx_slist_baoff_dbell_s cn68xx;
+ struct cvmx_sli_pktx_slist_baoff_dbell_s cn68xxp1;
+};
+
+union cvmx_sli_pktx_slist_fifo_rsize {
+ uint64_t u64;
+ struct cvmx_sli_pktx_slist_fifo_rsize_s {
+ uint64_t reserved_32_63:32;
+ uint64_t rsize:32;
+ } s;
+ struct cvmx_sli_pktx_slist_fifo_rsize_s cn61xx;
+ struct cvmx_sli_pktx_slist_fifo_rsize_s cn63xx;
+ struct cvmx_sli_pktx_slist_fifo_rsize_s cn63xxp1;
+ struct cvmx_sli_pktx_slist_fifo_rsize_s cn66xx;
+ struct cvmx_sli_pktx_slist_fifo_rsize_s cn68xx;
+ struct cvmx_sli_pktx_slist_fifo_rsize_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_cnt_int {
+ uint64_t u64;
+ struct cvmx_sli_pkt_cnt_int_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_sli_pkt_cnt_int_s cn61xx;
+ struct cvmx_sli_pkt_cnt_int_s cn63xx;
+ struct cvmx_sli_pkt_cnt_int_s cn63xxp1;
+ struct cvmx_sli_pkt_cnt_int_s cn66xx;
+ struct cvmx_sli_pkt_cnt_int_s cn68xx;
+ struct cvmx_sli_pkt_cnt_int_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_cnt_int_enb {
+ uint64_t u64;
+ struct cvmx_sli_pkt_cnt_int_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_sli_pkt_cnt_int_enb_s cn61xx;
+ struct cvmx_sli_pkt_cnt_int_enb_s cn63xx;
+ struct cvmx_sli_pkt_cnt_int_enb_s cn63xxp1;
+ struct cvmx_sli_pkt_cnt_int_enb_s cn66xx;
+ struct cvmx_sli_pkt_cnt_int_enb_s cn68xx;
+ struct cvmx_sli_pkt_cnt_int_enb_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_ctl {
+ uint64_t u64;
+ struct cvmx_sli_pkt_ctl_s {
+ uint64_t reserved_5_63:59;
+ uint64_t ring_en:1;
+ uint64_t pkt_bp:4;
+ } s;
+ struct cvmx_sli_pkt_ctl_s cn61xx;
+ struct cvmx_sli_pkt_ctl_s cn63xx;
+ struct cvmx_sli_pkt_ctl_s cn63xxp1;
+ struct cvmx_sli_pkt_ctl_s cn66xx;
+ struct cvmx_sli_pkt_ctl_s cn68xx;
+ struct cvmx_sli_pkt_ctl_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_data_out_es {
+ uint64_t u64;
+ struct cvmx_sli_pkt_data_out_es_s {
+ uint64_t es:64;
+ } s;
+ struct cvmx_sli_pkt_data_out_es_s cn61xx;
+ struct cvmx_sli_pkt_data_out_es_s cn63xx;
+ struct cvmx_sli_pkt_data_out_es_s cn63xxp1;
+ struct cvmx_sli_pkt_data_out_es_s cn66xx;
+ struct cvmx_sli_pkt_data_out_es_s cn68xx;
+ struct cvmx_sli_pkt_data_out_es_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_data_out_ns {
+ uint64_t u64;
+ struct cvmx_sli_pkt_data_out_ns_s {
+ uint64_t reserved_32_63:32;
+ uint64_t nsr:32;
+ } s;
+ struct cvmx_sli_pkt_data_out_ns_s cn61xx;
+ struct cvmx_sli_pkt_data_out_ns_s cn63xx;
+ struct cvmx_sli_pkt_data_out_ns_s cn63xxp1;
+ struct cvmx_sli_pkt_data_out_ns_s cn66xx;
+ struct cvmx_sli_pkt_data_out_ns_s cn68xx;
+ struct cvmx_sli_pkt_data_out_ns_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_data_out_ror {
+ uint64_t u64;
+ struct cvmx_sli_pkt_data_out_ror_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ror:32;
+ } s;
+ struct cvmx_sli_pkt_data_out_ror_s cn61xx;
+ struct cvmx_sli_pkt_data_out_ror_s cn63xx;
+ struct cvmx_sli_pkt_data_out_ror_s cn63xxp1;
+ struct cvmx_sli_pkt_data_out_ror_s cn66xx;
+ struct cvmx_sli_pkt_data_out_ror_s cn68xx;
+ struct cvmx_sli_pkt_data_out_ror_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_dpaddr {
+ uint64_t u64;
+ struct cvmx_sli_pkt_dpaddr_s {
+ uint64_t reserved_32_63:32;
+ uint64_t dptr:32;
+ } s;
+ struct cvmx_sli_pkt_dpaddr_s cn61xx;
+ struct cvmx_sli_pkt_dpaddr_s cn63xx;
+ struct cvmx_sli_pkt_dpaddr_s cn63xxp1;
+ struct cvmx_sli_pkt_dpaddr_s cn66xx;
+ struct cvmx_sli_pkt_dpaddr_s cn68xx;
+ struct cvmx_sli_pkt_dpaddr_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_in_bp {
+ uint64_t u64;
+ struct cvmx_sli_pkt_in_bp_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bp:32;
+ } s;
+ struct cvmx_sli_pkt_in_bp_s cn61xx;
+ struct cvmx_sli_pkt_in_bp_s cn63xx;
+ struct cvmx_sli_pkt_in_bp_s cn63xxp1;
+ struct cvmx_sli_pkt_in_bp_s cn66xx;
+};
+
+union cvmx_sli_pkt_in_donex_cnts {
+ uint64_t u64;
+ struct cvmx_sli_pkt_in_donex_cnts_s {
+ uint64_t reserved_32_63:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_sli_pkt_in_donex_cnts_s cn61xx;
+ struct cvmx_sli_pkt_in_donex_cnts_s cn63xx;
+ struct cvmx_sli_pkt_in_donex_cnts_s cn63xxp1;
+ struct cvmx_sli_pkt_in_donex_cnts_s cn66xx;
+ struct cvmx_sli_pkt_in_donex_cnts_s cn68xx;
+ struct cvmx_sli_pkt_in_donex_cnts_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_in_instr_counts {
+ uint64_t u64;
+ struct cvmx_sli_pkt_in_instr_counts_s {
+ uint64_t wr_cnt:32;
+ uint64_t rd_cnt:32;
+ } s;
+ struct cvmx_sli_pkt_in_instr_counts_s cn61xx;
+ struct cvmx_sli_pkt_in_instr_counts_s cn63xx;
+ struct cvmx_sli_pkt_in_instr_counts_s cn63xxp1;
+ struct cvmx_sli_pkt_in_instr_counts_s cn66xx;
+ struct cvmx_sli_pkt_in_instr_counts_s cn68xx;
+ struct cvmx_sli_pkt_in_instr_counts_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_in_pcie_port {
+ uint64_t u64;
+ struct cvmx_sli_pkt_in_pcie_port_s {
+ uint64_t pp:64;
+ } s;
+ struct cvmx_sli_pkt_in_pcie_port_s cn61xx;
+ struct cvmx_sli_pkt_in_pcie_port_s cn63xx;
+ struct cvmx_sli_pkt_in_pcie_port_s cn63xxp1;
+ struct cvmx_sli_pkt_in_pcie_port_s cn66xx;
+ struct cvmx_sli_pkt_in_pcie_port_s cn68xx;
+ struct cvmx_sli_pkt_in_pcie_port_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_input_control {
+ uint64_t u64;
+ struct cvmx_sli_pkt_input_control_s {
+ uint64_t prd_erst:1;
+ uint64_t prd_rds:7;
+ uint64_t gii_erst:1;
+ uint64_t gii_rds:7;
+ uint64_t reserved_41_47:7;
+ uint64_t prc_idle:1;
+ uint64_t reserved_24_39:16;
+ uint64_t pin_rst:1;
+ uint64_t pkt_rr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t d_nsr:1;
+ uint64_t d_esr:2;
+ uint64_t d_ror:1;
+ uint64_t use_csr:1;
+ uint64_t nsr:1;
+ uint64_t esr:2;
+ uint64_t ror:1;
+ } s;
+ struct cvmx_sli_pkt_input_control_s cn61xx;
+ struct cvmx_sli_pkt_input_control_cn63xx {
+ uint64_t reserved_23_63:41;
+ uint64_t pkt_rr:1;
+ uint64_t pbp_dhi:13;
+ uint64_t d_nsr:1;
+ uint64_t d_esr:2;
+ uint64_t d_ror:1;
+ uint64_t use_csr:1;
+ uint64_t nsr:1;
+ uint64_t esr:2;
+ uint64_t ror:1;
+ } cn63xx;
+ struct cvmx_sli_pkt_input_control_cn63xx cn63xxp1;
+ struct cvmx_sli_pkt_input_control_s cn66xx;
+ struct cvmx_sli_pkt_input_control_s cn68xx;
+ struct cvmx_sli_pkt_input_control_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_instr_enb {
+ uint64_t u64;
+ struct cvmx_sli_pkt_instr_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enb:32;
+ } s;
+ struct cvmx_sli_pkt_instr_enb_s cn61xx;
+ struct cvmx_sli_pkt_instr_enb_s cn63xx;
+ struct cvmx_sli_pkt_instr_enb_s cn63xxp1;
+ struct cvmx_sli_pkt_instr_enb_s cn66xx;
+ struct cvmx_sli_pkt_instr_enb_s cn68xx;
+ struct cvmx_sli_pkt_instr_enb_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_instr_rd_size {
+ uint64_t u64;
+ struct cvmx_sli_pkt_instr_rd_size_s {
+ uint64_t rdsize:64;
+ } s;
+ struct cvmx_sli_pkt_instr_rd_size_s cn61xx;
+ struct cvmx_sli_pkt_instr_rd_size_s cn63xx;
+ struct cvmx_sli_pkt_instr_rd_size_s cn63xxp1;
+ struct cvmx_sli_pkt_instr_rd_size_s cn66xx;
+ struct cvmx_sli_pkt_instr_rd_size_s cn68xx;
+ struct cvmx_sli_pkt_instr_rd_size_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_instr_size {
+ uint64_t u64;
+ struct cvmx_sli_pkt_instr_size_s {
+ uint64_t reserved_32_63:32;
+ uint64_t is_64b:32;
+ } s;
+ struct cvmx_sli_pkt_instr_size_s cn61xx;
+ struct cvmx_sli_pkt_instr_size_s cn63xx;
+ struct cvmx_sli_pkt_instr_size_s cn63xxp1;
+ struct cvmx_sli_pkt_instr_size_s cn66xx;
+ struct cvmx_sli_pkt_instr_size_s cn68xx;
+ struct cvmx_sli_pkt_instr_size_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_int_levels {
+ uint64_t u64;
+ struct cvmx_sli_pkt_int_levels_s {
+ uint64_t reserved_54_63:10;
+ uint64_t time:22;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_sli_pkt_int_levels_s cn61xx;
+ struct cvmx_sli_pkt_int_levels_s cn63xx;
+ struct cvmx_sli_pkt_int_levels_s cn63xxp1;
+ struct cvmx_sli_pkt_int_levels_s cn66xx;
+ struct cvmx_sli_pkt_int_levels_s cn68xx;
+ struct cvmx_sli_pkt_int_levels_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_iptr {
+ uint64_t u64;
+ struct cvmx_sli_pkt_iptr_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iptr:32;
+ } s;
+ struct cvmx_sli_pkt_iptr_s cn61xx;
+ struct cvmx_sli_pkt_iptr_s cn63xx;
+ struct cvmx_sli_pkt_iptr_s cn63xxp1;
+ struct cvmx_sli_pkt_iptr_s cn66xx;
+ struct cvmx_sli_pkt_iptr_s cn68xx;
+ struct cvmx_sli_pkt_iptr_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_out_bmode {
+ uint64_t u64;
+ struct cvmx_sli_pkt_out_bmode_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bmode:32;
+ } s;
+ struct cvmx_sli_pkt_out_bmode_s cn61xx;
+ struct cvmx_sli_pkt_out_bmode_s cn63xx;
+ struct cvmx_sli_pkt_out_bmode_s cn63xxp1;
+ struct cvmx_sli_pkt_out_bmode_s cn66xx;
+ struct cvmx_sli_pkt_out_bmode_s cn68xx;
+ struct cvmx_sli_pkt_out_bmode_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_out_bp_en {
+ uint64_t u64;
+ struct cvmx_sli_pkt_out_bp_en_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bp_en:32;
+ } s;
+ struct cvmx_sli_pkt_out_bp_en_s cn68xx;
+ struct cvmx_sli_pkt_out_bp_en_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_out_enb {
+ uint64_t u64;
+ struct cvmx_sli_pkt_out_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enb:32;
+ } s;
+ struct cvmx_sli_pkt_out_enb_s cn61xx;
+ struct cvmx_sli_pkt_out_enb_s cn63xx;
+ struct cvmx_sli_pkt_out_enb_s cn63xxp1;
+ struct cvmx_sli_pkt_out_enb_s cn66xx;
+ struct cvmx_sli_pkt_out_enb_s cn68xx;
+ struct cvmx_sli_pkt_out_enb_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_output_wmark {
+ uint64_t u64;
+ struct cvmx_sli_pkt_output_wmark_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wmark:32;
+ } s;
+ struct cvmx_sli_pkt_output_wmark_s cn61xx;
+ struct cvmx_sli_pkt_output_wmark_s cn63xx;
+ struct cvmx_sli_pkt_output_wmark_s cn63xxp1;
+ struct cvmx_sli_pkt_output_wmark_s cn66xx;
+ struct cvmx_sli_pkt_output_wmark_s cn68xx;
+ struct cvmx_sli_pkt_output_wmark_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_pcie_port {
+ uint64_t u64;
+ struct cvmx_sli_pkt_pcie_port_s {
+ uint64_t pp:64;
+ } s;
+ struct cvmx_sli_pkt_pcie_port_s cn61xx;
+ struct cvmx_sli_pkt_pcie_port_s cn63xx;
+ struct cvmx_sli_pkt_pcie_port_s cn63xxp1;
+ struct cvmx_sli_pkt_pcie_port_s cn66xx;
+ struct cvmx_sli_pkt_pcie_port_s cn68xx;
+ struct cvmx_sli_pkt_pcie_port_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_port_in_rst {
+ uint64_t u64;
+ struct cvmx_sli_pkt_port_in_rst_s {
+ uint64_t in_rst:32;
+ uint64_t out_rst:32;
+ } s;
+ struct cvmx_sli_pkt_port_in_rst_s cn61xx;
+ struct cvmx_sli_pkt_port_in_rst_s cn63xx;
+ struct cvmx_sli_pkt_port_in_rst_s cn63xxp1;
+ struct cvmx_sli_pkt_port_in_rst_s cn66xx;
+ struct cvmx_sli_pkt_port_in_rst_s cn68xx;
+ struct cvmx_sli_pkt_port_in_rst_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_slist_es {
+ uint64_t u64;
+ struct cvmx_sli_pkt_slist_es_s {
+ uint64_t es:64;
+ } s;
+ struct cvmx_sli_pkt_slist_es_s cn61xx;
+ struct cvmx_sli_pkt_slist_es_s cn63xx;
+ struct cvmx_sli_pkt_slist_es_s cn63xxp1;
+ struct cvmx_sli_pkt_slist_es_s cn66xx;
+ struct cvmx_sli_pkt_slist_es_s cn68xx;
+ struct cvmx_sli_pkt_slist_es_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_slist_ns {
+ uint64_t u64;
+ struct cvmx_sli_pkt_slist_ns_s {
+ uint64_t reserved_32_63:32;
+ uint64_t nsr:32;
+ } s;
+ struct cvmx_sli_pkt_slist_ns_s cn61xx;
+ struct cvmx_sli_pkt_slist_ns_s cn63xx;
+ struct cvmx_sli_pkt_slist_ns_s cn63xxp1;
+ struct cvmx_sli_pkt_slist_ns_s cn66xx;
+ struct cvmx_sli_pkt_slist_ns_s cn68xx;
+ struct cvmx_sli_pkt_slist_ns_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_slist_ror {
+ uint64_t u64;
+ struct cvmx_sli_pkt_slist_ror_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ror:32;
+ } s;
+ struct cvmx_sli_pkt_slist_ror_s cn61xx;
+ struct cvmx_sli_pkt_slist_ror_s cn63xx;
+ struct cvmx_sli_pkt_slist_ror_s cn63xxp1;
+ struct cvmx_sli_pkt_slist_ror_s cn66xx;
+ struct cvmx_sli_pkt_slist_ror_s cn68xx;
+ struct cvmx_sli_pkt_slist_ror_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_time_int {
+ uint64_t u64;
+ struct cvmx_sli_pkt_time_int_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_sli_pkt_time_int_s cn61xx;
+ struct cvmx_sli_pkt_time_int_s cn63xx;
+ struct cvmx_sli_pkt_time_int_s cn63xxp1;
+ struct cvmx_sli_pkt_time_int_s cn66xx;
+ struct cvmx_sli_pkt_time_int_s cn68xx;
+ struct cvmx_sli_pkt_time_int_s cn68xxp1;
+};
+
+union cvmx_sli_pkt_time_int_enb {
+ uint64_t u64;
+ struct cvmx_sli_pkt_time_int_enb_s {
+ uint64_t reserved_32_63:32;
+ uint64_t port:32;
+ } s;
+ struct cvmx_sli_pkt_time_int_enb_s cn61xx;
+ struct cvmx_sli_pkt_time_int_enb_s cn63xx;
+ struct cvmx_sli_pkt_time_int_enb_s cn63xxp1;
+ struct cvmx_sli_pkt_time_int_enb_s cn66xx;
+ struct cvmx_sli_pkt_time_int_enb_s cn68xx;
+ struct cvmx_sli_pkt_time_int_enb_s cn68xxp1;
+};
+
+union cvmx_sli_portx_pkind {
+ uint64_t u64;
+ struct cvmx_sli_portx_pkind_s {
+ uint64_t reserved_25_63:39;
+ uint64_t rpk_enb:1;
+ uint64_t reserved_22_23:2;
+ uint64_t pkindr:6;
+ uint64_t reserved_14_15:2;
+ uint64_t bpkind:6;
+ uint64_t reserved_6_7:2;
+ uint64_t pkind:6;
+ } s;
+ struct cvmx_sli_portx_pkind_s cn68xx;
+ struct cvmx_sli_portx_pkind_cn68xxp1 {
+ uint64_t reserved_14_63:50;
+ uint64_t bpkind:6;
+ uint64_t reserved_6_7:2;
+ uint64_t pkind:6;
+ } cn68xxp1;
+};
+
+union cvmx_sli_s2m_portx_ctl {
+ uint64_t u64;
+ struct cvmx_sli_s2m_portx_ctl_s {
+ uint64_t reserved_5_63:59;
+ uint64_t wind_d:1;
+ uint64_t bar0_d:1;
+ uint64_t mrrs:3;
+ } s;
+ struct cvmx_sli_s2m_portx_ctl_s cn61xx;
+ struct cvmx_sli_s2m_portx_ctl_s cn63xx;
+ struct cvmx_sli_s2m_portx_ctl_s cn63xxp1;
+ struct cvmx_sli_s2m_portx_ctl_s cn66xx;
+ struct cvmx_sli_s2m_portx_ctl_s cn68xx;
+ struct cvmx_sli_s2m_portx_ctl_s cn68xxp1;
+};
+
+union cvmx_sli_scratch_1 {
+ uint64_t u64;
+ struct cvmx_sli_scratch_1_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_sli_scratch_1_s cn61xx;
+ struct cvmx_sli_scratch_1_s cn63xx;
+ struct cvmx_sli_scratch_1_s cn63xxp1;
+ struct cvmx_sli_scratch_1_s cn66xx;
+ struct cvmx_sli_scratch_1_s cn68xx;
+ struct cvmx_sli_scratch_1_s cn68xxp1;
+};
+
+union cvmx_sli_scratch_2 {
+ uint64_t u64;
+ struct cvmx_sli_scratch_2_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_sli_scratch_2_s cn61xx;
+ struct cvmx_sli_scratch_2_s cn63xx;
+ struct cvmx_sli_scratch_2_s cn63xxp1;
+ struct cvmx_sli_scratch_2_s cn66xx;
+ struct cvmx_sli_scratch_2_s cn68xx;
+ struct cvmx_sli_scratch_2_s cn68xxp1;
+};
+
+union cvmx_sli_state1 {
+ uint64_t u64;
+ struct cvmx_sli_state1_s {
+ uint64_t cpl1:12;
+ uint64_t cpl0:12;
+ uint64_t arb:1;
+ uint64_t csr:39;
+ } s;
+ struct cvmx_sli_state1_s cn61xx;
+ struct cvmx_sli_state1_s cn63xx;
+ struct cvmx_sli_state1_s cn63xxp1;
+ struct cvmx_sli_state1_s cn66xx;
+ struct cvmx_sli_state1_s cn68xx;
+ struct cvmx_sli_state1_s cn68xxp1;
+};
+
+union cvmx_sli_state2 {
+ uint64_t u64;
+ struct cvmx_sli_state2_s {
+ uint64_t reserved_56_63:8;
+ uint64_t nnp1:8;
+ uint64_t reserved_47_47:1;
+ uint64_t rac:1;
+ uint64_t csm1:15;
+ uint64_t csm0:15;
+ uint64_t nnp0:8;
+ uint64_t nnd:8;
+ } s;
+ struct cvmx_sli_state2_s cn61xx;
+ struct cvmx_sli_state2_s cn63xx;
+ struct cvmx_sli_state2_s cn63xxp1;
+ struct cvmx_sli_state2_s cn66xx;
+ struct cvmx_sli_state2_s cn68xx;
+ struct cvmx_sli_state2_s cn68xxp1;
+};
+
+union cvmx_sli_state3 {
+ uint64_t u64;
+ struct cvmx_sli_state3_s {
+ uint64_t reserved_56_63:8;
+ uint64_t psm1:15;
+ uint64_t psm0:15;
+ uint64_t nsm1:13;
+ uint64_t nsm0:13;
+ } s;
+ struct cvmx_sli_state3_s cn61xx;
+ struct cvmx_sli_state3_s cn63xx;
+ struct cvmx_sli_state3_s cn63xxp1;
+ struct cvmx_sli_state3_s cn66xx;
+ struct cvmx_sli_state3_s cn68xx;
+ struct cvmx_sli_state3_s cn68xxp1;
+};
+
+union cvmx_sli_tx_pipe {
+ uint64_t u64;
+ struct cvmx_sli_tx_pipe_s {
+ uint64_t reserved_24_63:40;
+ uint64_t nump:8;
+ uint64_t reserved_7_15:9;
+ uint64_t base:7;
+ } s;
+ struct cvmx_sli_tx_pipe_s cn68xx;
+ struct cvmx_sli_tx_pipe_s cn68xxp1;
+};
+
+union cvmx_sli_win_rd_addr {
+ uint64_t u64;
+ struct cvmx_sli_win_rd_addr_s {
+ uint64_t reserved_51_63:13;
+ uint64_t ld_cmd:2;
+ uint64_t iobit:1;
+ uint64_t rd_addr:48;
+ } s;
+ struct cvmx_sli_win_rd_addr_s cn61xx;
+ struct cvmx_sli_win_rd_addr_s cn63xx;
+ struct cvmx_sli_win_rd_addr_s cn63xxp1;
+ struct cvmx_sli_win_rd_addr_s cn66xx;
+ struct cvmx_sli_win_rd_addr_s cn68xx;
+ struct cvmx_sli_win_rd_addr_s cn68xxp1;
+};
+
+union cvmx_sli_win_rd_data {
+ uint64_t u64;
+ struct cvmx_sli_win_rd_data_s {
+ uint64_t rd_data:64;
+ } s;
+ struct cvmx_sli_win_rd_data_s cn61xx;
+ struct cvmx_sli_win_rd_data_s cn63xx;
+ struct cvmx_sli_win_rd_data_s cn63xxp1;
+ struct cvmx_sli_win_rd_data_s cn66xx;
+ struct cvmx_sli_win_rd_data_s cn68xx;
+ struct cvmx_sli_win_rd_data_s cn68xxp1;
+};
+
+union cvmx_sli_win_wr_addr {
+ uint64_t u64;
+ struct cvmx_sli_win_wr_addr_s {
+ uint64_t reserved_49_63:15;
+ uint64_t iobit:1;
+ uint64_t wr_addr:45;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_sli_win_wr_addr_s cn61xx;
+ struct cvmx_sli_win_wr_addr_s cn63xx;
+ struct cvmx_sli_win_wr_addr_s cn63xxp1;
+ struct cvmx_sli_win_wr_addr_s cn66xx;
+ struct cvmx_sli_win_wr_addr_s cn68xx;
+ struct cvmx_sli_win_wr_addr_s cn68xxp1;
+};
+
+union cvmx_sli_win_wr_data {
+ uint64_t u64;
+ struct cvmx_sli_win_wr_data_s {
+ uint64_t wr_data:64;
+ } s;
+ struct cvmx_sli_win_wr_data_s cn61xx;
+ struct cvmx_sli_win_wr_data_s cn63xx;
+ struct cvmx_sli_win_wr_data_s cn63xxp1;
+ struct cvmx_sli_win_wr_data_s cn66xx;
+ struct cvmx_sli_win_wr_data_s cn68xx;
+ struct cvmx_sli_win_wr_data_s cn68xxp1;
+};
+
+union cvmx_sli_win_wr_mask {
+ uint64_t u64;
+ struct cvmx_sli_win_wr_mask_s {
+ uint64_t reserved_8_63:56;
+ uint64_t wr_mask:8;
+ } s;
+ struct cvmx_sli_win_wr_mask_s cn61xx;
+ struct cvmx_sli_win_wr_mask_s cn63xx;
+ struct cvmx_sli_win_wr_mask_s cn63xxp1;
+ struct cvmx_sli_win_wr_mask_s cn66xx;
+ struct cvmx_sli_win_wr_mask_s cn68xx;
+ struct cvmx_sli_win_wr_mask_s cn68xxp1;
+};
+
+union cvmx_sli_window_ctl {
+ uint64_t u64;
+ struct cvmx_sli_window_ctl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t time:32;
+ } s;
+ struct cvmx_sli_window_ctl_s cn61xx;
+ struct cvmx_sli_window_ctl_s cn63xx;
+ struct cvmx_sli_window_ctl_s cn63xxp1;
+ struct cvmx_sli_window_ctl_s cn66xx;
+ struct cvmx_sli_window_ctl_s cn68xx;
+ struct cvmx_sli_window_ctl_s cn68xxp1;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-spi.h b/arch/mips/include/asm/octeon/cvmx-spi.h
index e814648953a5..e814648953a5 100644
--- a/drivers/staging/octeon/cvmx-spi.h
+++ b/arch/mips/include/asm/octeon/cvmx-spi.h
diff --git a/drivers/staging/octeon/cvmx-spxx-defs.h b/arch/mips/include/asm/octeon/cvmx-spxx-defs.h
index b16940e32c83..b16940e32c83 100644
--- a/drivers/staging/octeon/cvmx-spxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-spxx-defs.h
diff --git a/arch/mips/include/asm/octeon/cvmx-sriox-defs.h b/arch/mips/include/asm/octeon/cvmx-sriox-defs.h
new file mode 100644
index 000000000000..7be7e9ed7465
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-sriox-defs.h
@@ -0,0 +1,1036 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2011 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.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_SRIOX_DEFS_H__
+#define __CVMX_SRIOX_DEFS_H__
+
+#define CVMX_SRIOX_ACC_CTRL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000148ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_ASMBLY_ID(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000200ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_ASMBLY_INFO(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000208ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_BELL_RESP_CTRL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000310ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_BIST_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000108ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_IMSG_CTRL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000508ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_IMSG_INST_HDRX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000510ull) + (((offset) & 1) + ((block_id) & 3) * 0x200000ull) * 8)
+#define CVMX_SRIOX_IMSG_QOS_GRPX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000600ull) + (((offset) & 31) + ((block_id) & 3) * 0x200000ull) * 8)
+#define CVMX_SRIOX_IMSG_STATUSX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000700ull) + (((offset) & 31) + ((block_id) & 3) * 0x200000ull) * 8)
+#define CVMX_SRIOX_IMSG_VPORT_THR(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000500ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_IMSG_VPORT_THR2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000528ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_INT2_ENABLE(block_id) (CVMX_ADD_IO_SEG(0x00011800C80003E0ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_INT2_REG(block_id) (CVMX_ADD_IO_SEG(0x00011800C80003E8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_INT_ENABLE(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000110ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_INT_INFO0(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000120ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_INT_INFO1(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000128ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_INT_INFO2(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000130ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_INT_INFO3(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000138ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_INT_REG(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000118ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_IP_FEATURE(block_id) (CVMX_ADD_IO_SEG(0x00011800C80003F8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_MAC_BUFFERS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000390ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_MAINT_OP(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000158ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_MAINT_RD_DATA(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000160ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_MCE_TX_CTL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000240ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_MEM_OP_CTRL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000168ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_OMSG_CTRLX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000488ull) + (((offset) & 1) + ((block_id) & 3) * 0x40000ull) * 64)
+#define CVMX_SRIOX_OMSG_DONE_COUNTSX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C80004B0ull) + (((offset) & 1) + ((block_id) & 3) * 0x40000ull) * 64)
+#define CVMX_SRIOX_OMSG_FMP_MRX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000498ull) + (((offset) & 1) + ((block_id) & 3) * 0x40000ull) * 64)
+#define CVMX_SRIOX_OMSG_NMP_MRX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C80004A0ull) + (((offset) & 1) + ((block_id) & 3) * 0x40000ull) * 64)
+#define CVMX_SRIOX_OMSG_PORTX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000480ull) + (((offset) & 1) + ((block_id) & 3) * 0x40000ull) * 64)
+#define CVMX_SRIOX_OMSG_SILO_THR(block_id) (CVMX_ADD_IO_SEG(0x00011800C80004F8ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_OMSG_SP_MRX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000490ull) + (((offset) & 1) + ((block_id) & 3) * 0x40000ull) * 64)
+#define CVMX_SRIOX_PRIOX_IN_USE(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C80003C0ull) + (((offset) & 3) + ((block_id) & 3) * 0x200000ull) * 8)
+#define CVMX_SRIOX_RX_BELL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000308ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_RX_BELL_SEQ(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000300ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_RX_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000380ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_S2M_TYPEX(offset, block_id) (CVMX_ADD_IO_SEG(0x00011800C8000180ull) + (((offset) & 15) + ((block_id) & 3) * 0x200000ull) * 8)
+#define CVMX_SRIOX_SEQ(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000278ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_STATUS_REG(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000100ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_TAG_CTRL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000178ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_TLP_CREDITS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000150ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_TX_BELL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000280ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_TX_BELL_INFO(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000288ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_TX_CTRL(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000170ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_TX_EMPHASIS(block_id) (CVMX_ADD_IO_SEG(0x00011800C80003F0ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_TX_STATUS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000388ull) + ((block_id) & 3) * 0x1000000ull)
+#define CVMX_SRIOX_WR_DONE_COUNTS(block_id) (CVMX_ADD_IO_SEG(0x00011800C8000340ull) + ((block_id) & 3) * 0x1000000ull)
+
+union cvmx_sriox_acc_ctrl {
+ uint64_t u64;
+ struct cvmx_sriox_acc_ctrl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t deny_adr2:1;
+ uint64_t deny_adr1:1;
+ uint64_t deny_adr0:1;
+ uint64_t reserved_3_3:1;
+ uint64_t deny_bar2:1;
+ uint64_t deny_bar1:1;
+ uint64_t deny_bar0:1;
+ } s;
+ struct cvmx_sriox_acc_ctrl_cn63xx {
+ uint64_t reserved_3_63:61;
+ uint64_t deny_bar2:1;
+ uint64_t deny_bar1:1;
+ uint64_t deny_bar0:1;
+ } cn63xx;
+ struct cvmx_sriox_acc_ctrl_cn63xx cn63xxp1;
+ struct cvmx_sriox_acc_ctrl_s cn66xx;
+};
+
+union cvmx_sriox_asmbly_id {
+ uint64_t u64;
+ struct cvmx_sriox_asmbly_id_s {
+ uint64_t reserved_32_63:32;
+ uint64_t assy_id:16;
+ uint64_t assy_ven:16;
+ } s;
+ struct cvmx_sriox_asmbly_id_s cn63xx;
+ struct cvmx_sriox_asmbly_id_s cn63xxp1;
+ struct cvmx_sriox_asmbly_id_s cn66xx;
+};
+
+union cvmx_sriox_asmbly_info {
+ uint64_t u64;
+ struct cvmx_sriox_asmbly_info_s {
+ uint64_t reserved_32_63:32;
+ uint64_t assy_rev:16;
+ uint64_t reserved_0_15:16;
+ } s;
+ struct cvmx_sriox_asmbly_info_s cn63xx;
+ struct cvmx_sriox_asmbly_info_s cn63xxp1;
+ struct cvmx_sriox_asmbly_info_s cn66xx;
+};
+
+union cvmx_sriox_bell_resp_ctrl {
+ uint64_t u64;
+ struct cvmx_sriox_bell_resp_ctrl_s {
+ uint64_t reserved_6_63:58;
+ uint64_t rp1_sid:1;
+ uint64_t rp0_sid:2;
+ uint64_t rp1_pid:1;
+ uint64_t rp0_pid:2;
+ } s;
+ struct cvmx_sriox_bell_resp_ctrl_s cn63xx;
+ struct cvmx_sriox_bell_resp_ctrl_s cn63xxp1;
+ struct cvmx_sriox_bell_resp_ctrl_s cn66xx;
+};
+
+union cvmx_sriox_bist_status {
+ uint64_t u64;
+ struct cvmx_sriox_bist_status_s {
+ uint64_t reserved_45_63:19;
+ uint64_t lram:1;
+ uint64_t mram:2;
+ uint64_t cram:2;
+ uint64_t bell:2;
+ uint64_t otag:2;
+ uint64_t itag:1;
+ uint64_t ofree:1;
+ uint64_t rtn:2;
+ uint64_t obulk:4;
+ uint64_t optrs:4;
+ uint64_t oarb2:2;
+ uint64_t rxbuf2:2;
+ uint64_t oarb:2;
+ uint64_t ispf:1;
+ uint64_t ospf:1;
+ uint64_t txbuf:2;
+ uint64_t rxbuf:2;
+ uint64_t imsg:5;
+ uint64_t omsg:7;
+ } s;
+ struct cvmx_sriox_bist_status_cn63xx {
+ uint64_t reserved_44_63:20;
+ uint64_t mram:2;
+ uint64_t cram:2;
+ uint64_t bell:2;
+ uint64_t otag:2;
+ uint64_t itag:1;
+ uint64_t ofree:1;
+ uint64_t rtn:2;
+ uint64_t obulk:4;
+ uint64_t optrs:4;
+ uint64_t oarb2:2;
+ uint64_t rxbuf2:2;
+ uint64_t oarb:2;
+ uint64_t ispf:1;
+ uint64_t ospf:1;
+ uint64_t txbuf:2;
+ uint64_t rxbuf:2;
+ uint64_t imsg:5;
+ uint64_t omsg:7;
+ } cn63xx;
+ struct cvmx_sriox_bist_status_cn63xxp1 {
+ uint64_t reserved_44_63:20;
+ uint64_t mram:2;
+ uint64_t cram:2;
+ uint64_t bell:2;
+ uint64_t otag:2;
+ uint64_t itag:1;
+ uint64_t ofree:1;
+ uint64_t rtn:2;
+ uint64_t obulk:4;
+ uint64_t optrs:4;
+ uint64_t reserved_20_23:4;
+ uint64_t oarb:2;
+ uint64_t ispf:1;
+ uint64_t ospf:1;
+ uint64_t txbuf:2;
+ uint64_t rxbuf:2;
+ uint64_t imsg:5;
+ uint64_t omsg:7;
+ } cn63xxp1;
+ struct cvmx_sriox_bist_status_s cn66xx;
+};
+
+union cvmx_sriox_imsg_ctrl {
+ uint64_t u64;
+ struct cvmx_sriox_imsg_ctrl_s {
+ uint64_t reserved_32_63:32;
+ uint64_t to_mode:1;
+ uint64_t reserved_30_30:1;
+ uint64_t rsp_thr:6;
+ uint64_t reserved_22_23:2;
+ uint64_t rp1_sid:1;
+ uint64_t rp0_sid:2;
+ uint64_t rp1_pid:1;
+ uint64_t rp0_pid:2;
+ uint64_t reserved_15_15:1;
+ uint64_t prt_sel:3;
+ uint64_t lttr:4;
+ uint64_t prio:4;
+ uint64_t mbox:4;
+ } s;
+ struct cvmx_sriox_imsg_ctrl_s cn63xx;
+ struct cvmx_sriox_imsg_ctrl_s cn63xxp1;
+ struct cvmx_sriox_imsg_ctrl_s cn66xx;
+};
+
+union cvmx_sriox_imsg_inst_hdrx {
+ uint64_t u64;
+ struct cvmx_sriox_imsg_inst_hdrx_s {
+ uint64_t r:1;
+ uint64_t reserved_58_62:5;
+ uint64_t pm:2;
+ uint64_t reserved_55_55:1;
+ uint64_t sl:7;
+ uint64_t reserved_46_47:2;
+ uint64_t nqos:1;
+ uint64_t ngrp:1;
+ uint64_t ntt:1;
+ uint64_t ntag:1;
+ uint64_t reserved_35_41:7;
+ uint64_t rs:1;
+ uint64_t tt:2;
+ uint64_t tag:32;
+ } s;
+ struct cvmx_sriox_imsg_inst_hdrx_s cn63xx;
+ struct cvmx_sriox_imsg_inst_hdrx_s cn63xxp1;
+ struct cvmx_sriox_imsg_inst_hdrx_s cn66xx;
+};
+
+union cvmx_sriox_imsg_qos_grpx {
+ uint64_t u64;
+ struct cvmx_sriox_imsg_qos_grpx_s {
+ uint64_t reserved_63_63:1;
+ uint64_t qos7:3;
+ uint64_t grp7:4;
+ uint64_t reserved_55_55:1;
+ uint64_t qos6:3;
+ uint64_t grp6:4;
+ uint64_t reserved_47_47:1;
+ uint64_t qos5:3;
+ uint64_t grp5:4;
+ uint64_t reserved_39_39:1;
+ uint64_t qos4:3;
+ uint64_t grp4:4;
+ uint64_t reserved_31_31:1;
+ uint64_t qos3:3;
+ uint64_t grp3:4;
+ uint64_t reserved_23_23:1;
+ uint64_t qos2:3;
+ uint64_t grp2:4;
+ uint64_t reserved_15_15:1;
+ uint64_t qos1:3;
+ uint64_t grp1:4;
+ uint64_t reserved_7_7:1;
+ uint64_t qos0:3;
+ uint64_t grp0:4;
+ } s;
+ struct cvmx_sriox_imsg_qos_grpx_s cn63xx;
+ struct cvmx_sriox_imsg_qos_grpx_s cn63xxp1;
+ struct cvmx_sriox_imsg_qos_grpx_s cn66xx;
+};
+
+union cvmx_sriox_imsg_statusx {
+ uint64_t u64;
+ struct cvmx_sriox_imsg_statusx_s {
+ uint64_t val1:1;
+ uint64_t err1:1;
+ uint64_t toe1:1;
+ uint64_t toc1:1;
+ uint64_t prt1:1;
+ uint64_t reserved_58_58:1;
+ uint64_t tt1:1;
+ uint64_t dis1:1;
+ uint64_t seg1:4;
+ uint64_t mbox1:2;
+ uint64_t lttr1:2;
+ uint64_t sid1:16;
+ uint64_t val0:1;
+ uint64_t err0:1;
+ uint64_t toe0:1;
+ uint64_t toc0:1;
+ uint64_t prt0:1;
+ uint64_t reserved_26_26:1;
+ uint64_t tt0:1;
+ uint64_t dis0:1;
+ uint64_t seg0:4;
+ uint64_t mbox0:2;
+ uint64_t lttr0:2;
+ uint64_t sid0:16;
+ } s;
+ struct cvmx_sriox_imsg_statusx_s cn63xx;
+ struct cvmx_sriox_imsg_statusx_s cn63xxp1;
+ struct cvmx_sriox_imsg_statusx_s cn66xx;
+};
+
+union cvmx_sriox_imsg_vport_thr {
+ uint64_t u64;
+ struct cvmx_sriox_imsg_vport_thr_s {
+ uint64_t reserved_54_63:10;
+ uint64_t max_tot:6;
+ uint64_t reserved_46_47:2;
+ uint64_t max_s1:6;
+ uint64_t reserved_38_39:2;
+ uint64_t max_s0:6;
+ uint64_t sp_vport:1;
+ uint64_t reserved_20_30:11;
+ uint64_t buf_thr:4;
+ uint64_t reserved_14_15:2;
+ uint64_t max_p1:6;
+ uint64_t reserved_6_7:2;
+ uint64_t max_p0:6;
+ } s;
+ struct cvmx_sriox_imsg_vport_thr_s cn63xx;
+ struct cvmx_sriox_imsg_vport_thr_s cn63xxp1;
+ struct cvmx_sriox_imsg_vport_thr_s cn66xx;
+};
+
+union cvmx_sriox_imsg_vport_thr2 {
+ uint64_t u64;
+ struct cvmx_sriox_imsg_vport_thr2_s {
+ uint64_t reserved_46_63:18;
+ uint64_t max_s3:6;
+ uint64_t reserved_38_39:2;
+ uint64_t max_s2:6;
+ uint64_t reserved_0_31:32;
+ } s;
+ struct cvmx_sriox_imsg_vport_thr2_s cn66xx;
+};
+
+union cvmx_sriox_int2_enable {
+ uint64_t u64;
+ struct cvmx_sriox_int2_enable_s {
+ uint64_t reserved_1_63:63;
+ uint64_t pko_rst:1;
+ } s;
+ struct cvmx_sriox_int2_enable_s cn63xx;
+ struct cvmx_sriox_int2_enable_s cn66xx;
+};
+
+union cvmx_sriox_int2_reg {
+ uint64_t u64;
+ struct cvmx_sriox_int2_reg_s {
+ uint64_t reserved_32_63:32;
+ uint64_t int_sum:1;
+ uint64_t reserved_1_30:30;
+ uint64_t pko_rst:1;
+ } s;
+ struct cvmx_sriox_int2_reg_s cn63xx;
+ struct cvmx_sriox_int2_reg_s cn66xx;
+};
+
+union cvmx_sriox_int_enable {
+ uint64_t u64;
+ struct cvmx_sriox_int_enable_s {
+ uint64_t reserved_27_63:37;
+ uint64_t zero_pkt:1;
+ uint64_t ttl_tout:1;
+ uint64_t fail:1;
+ uint64_t degrade:1;
+ uint64_t mac_buf:1;
+ uint64_t f_error:1;
+ uint64_t rtry_err:1;
+ uint64_t pko_err:1;
+ uint64_t omsg_err:1;
+ uint64_t omsg1:1;
+ uint64_t omsg0:1;
+ uint64_t link_up:1;
+ uint64_t link_dwn:1;
+ uint64_t phy_erb:1;
+ uint64_t log_erb:1;
+ uint64_t soft_rx:1;
+ uint64_t soft_tx:1;
+ uint64_t mce_rx:1;
+ uint64_t mce_tx:1;
+ uint64_t wr_done:1;
+ uint64_t sli_err:1;
+ uint64_t deny_wr:1;
+ uint64_t bar_err:1;
+ uint64_t maint_op:1;
+ uint64_t rxbell:1;
+ uint64_t bell_err:1;
+ uint64_t txbell:1;
+ } s;
+ struct cvmx_sriox_int_enable_s cn63xx;
+ struct cvmx_sriox_int_enable_cn63xxp1 {
+ uint64_t reserved_22_63:42;
+ uint64_t f_error:1;
+ uint64_t rtry_err:1;
+ uint64_t pko_err:1;
+ uint64_t omsg_err:1;
+ uint64_t omsg1:1;
+ uint64_t omsg0:1;
+ uint64_t link_up:1;
+ uint64_t link_dwn:1;
+ uint64_t phy_erb:1;
+ uint64_t log_erb:1;
+ uint64_t soft_rx:1;
+ uint64_t soft_tx:1;
+ uint64_t mce_rx:1;
+ uint64_t mce_tx:1;
+ uint64_t wr_done:1;
+ uint64_t sli_err:1;
+ uint64_t deny_wr:1;
+ uint64_t bar_err:1;
+ uint64_t maint_op:1;
+ uint64_t rxbell:1;
+ uint64_t bell_err:1;
+ uint64_t txbell:1;
+ } cn63xxp1;
+ struct cvmx_sriox_int_enable_s cn66xx;
+};
+
+union cvmx_sriox_int_info0 {
+ uint64_t u64;
+ struct cvmx_sriox_int_info0_s {
+ uint64_t cmd:4;
+ uint64_t type:4;
+ uint64_t tag:8;
+ uint64_t reserved_42_47:6;
+ uint64_t length:10;
+ uint64_t status:3;
+ uint64_t reserved_16_28:13;
+ uint64_t be0:8;
+ uint64_t be1:8;
+ } s;
+ struct cvmx_sriox_int_info0_s cn63xx;
+ struct cvmx_sriox_int_info0_s cn63xxp1;
+ struct cvmx_sriox_int_info0_s cn66xx;
+};
+
+union cvmx_sriox_int_info1 {
+ uint64_t u64;
+ struct cvmx_sriox_int_info1_s {
+ uint64_t info1:64;
+ } s;
+ struct cvmx_sriox_int_info1_s cn63xx;
+ struct cvmx_sriox_int_info1_s cn63xxp1;
+ struct cvmx_sriox_int_info1_s cn66xx;
+};
+
+union cvmx_sriox_int_info2 {
+ uint64_t u64;
+ struct cvmx_sriox_int_info2_s {
+ uint64_t prio:2;
+ uint64_t tt:1;
+ uint64_t sis:1;
+ uint64_t ssize:4;
+ uint64_t did:16;
+ uint64_t xmbox:4;
+ uint64_t mbox:2;
+ uint64_t letter:2;
+ uint64_t rsrvd:30;
+ uint64_t lns:1;
+ uint64_t intr:1;
+ } s;
+ struct cvmx_sriox_int_info2_s cn63xx;
+ struct cvmx_sriox_int_info2_s cn63xxp1;
+ struct cvmx_sriox_int_info2_s cn66xx;
+};
+
+union cvmx_sriox_int_info3 {
+ uint64_t u64;
+ struct cvmx_sriox_int_info3_s {
+ uint64_t prio:2;
+ uint64_t tt:2;
+ uint64_t type:4;
+ uint64_t other:48;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_sriox_int_info3_s cn63xx;
+ struct cvmx_sriox_int_info3_s cn63xxp1;
+ struct cvmx_sriox_int_info3_s cn66xx;
+};
+
+union cvmx_sriox_int_reg {
+ uint64_t u64;
+ struct cvmx_sriox_int_reg_s {
+ uint64_t reserved_32_63:32;
+ uint64_t int2_sum:1;
+ uint64_t reserved_27_30:4;
+ uint64_t zero_pkt:1;
+ uint64_t ttl_tout:1;
+ uint64_t fail:1;
+ uint64_t degrad:1;
+ uint64_t mac_buf:1;
+ uint64_t f_error:1;
+ uint64_t rtry_err:1;
+ uint64_t pko_err:1;
+ uint64_t omsg_err:1;
+ uint64_t omsg1:1;
+ uint64_t omsg0:1;
+ uint64_t link_up:1;
+ uint64_t link_dwn:1;
+ uint64_t phy_erb:1;
+ uint64_t log_erb:1;
+ uint64_t soft_rx:1;
+ uint64_t soft_tx:1;
+ uint64_t mce_rx:1;
+ uint64_t mce_tx:1;
+ uint64_t wr_done:1;
+ uint64_t sli_err:1;
+ uint64_t deny_wr:1;
+ uint64_t bar_err:1;
+ uint64_t maint_op:1;
+ uint64_t rxbell:1;
+ uint64_t bell_err:1;
+ uint64_t txbell:1;
+ } s;
+ struct cvmx_sriox_int_reg_s cn63xx;
+ struct cvmx_sriox_int_reg_cn63xxp1 {
+ uint64_t reserved_22_63:42;
+ uint64_t f_error:1;
+ uint64_t rtry_err:1;
+ uint64_t pko_err:1;
+ uint64_t omsg_err:1;
+ uint64_t omsg1:1;
+ uint64_t omsg0:1;
+ uint64_t link_up:1;
+ uint64_t link_dwn:1;
+ uint64_t phy_erb:1;
+ uint64_t log_erb:1;
+ uint64_t soft_rx:1;
+ uint64_t soft_tx:1;
+ uint64_t mce_rx:1;
+ uint64_t mce_tx:1;
+ uint64_t wr_done:1;
+ uint64_t sli_err:1;
+ uint64_t deny_wr:1;
+ uint64_t bar_err:1;
+ uint64_t maint_op:1;
+ uint64_t rxbell:1;
+ uint64_t bell_err:1;
+ uint64_t txbell:1;
+ } cn63xxp1;
+ struct cvmx_sriox_int_reg_s cn66xx;
+};
+
+union cvmx_sriox_ip_feature {
+ uint64_t u64;
+ struct cvmx_sriox_ip_feature_s {
+ uint64_t ops:32;
+ uint64_t reserved_15_31:17;
+ uint64_t no_vmin:1;
+ uint64_t a66:1;
+ uint64_t a50:1;
+ uint64_t reserved_11_11:1;
+ uint64_t tx_flow:1;
+ uint64_t pt_width:2;
+ uint64_t tx_pol:4;
+ uint64_t rx_pol:4;
+ } s;
+ struct cvmx_sriox_ip_feature_cn63xx {
+ uint64_t ops:32;
+ uint64_t reserved_14_31:18;
+ uint64_t a66:1;
+ uint64_t a50:1;
+ uint64_t reserved_11_11:1;
+ uint64_t tx_flow:1;
+ uint64_t pt_width:2;
+ uint64_t tx_pol:4;
+ uint64_t rx_pol:4;
+ } cn63xx;
+ struct cvmx_sriox_ip_feature_cn63xx cn63xxp1;
+ struct cvmx_sriox_ip_feature_s cn66xx;
+};
+
+union cvmx_sriox_mac_buffers {
+ uint64_t u64;
+ struct cvmx_sriox_mac_buffers_s {
+ uint64_t reserved_56_63:8;
+ uint64_t tx_enb:8;
+ uint64_t reserved_44_47:4;
+ uint64_t tx_inuse:4;
+ uint64_t tx_stat:8;
+ uint64_t reserved_24_31:8;
+ uint64_t rx_enb:8;
+ uint64_t reserved_12_15:4;
+ uint64_t rx_inuse:4;
+ uint64_t rx_stat:8;
+ } s;
+ struct cvmx_sriox_mac_buffers_s cn63xx;
+ struct cvmx_sriox_mac_buffers_s cn66xx;
+};
+
+union cvmx_sriox_maint_op {
+ uint64_t u64;
+ struct cvmx_sriox_maint_op_s {
+ uint64_t wr_data:32;
+ uint64_t reserved_27_31:5;
+ uint64_t fail:1;
+ uint64_t pending:1;
+ uint64_t op:1;
+ uint64_t addr:24;
+ } s;
+ struct cvmx_sriox_maint_op_s cn63xx;
+ struct cvmx_sriox_maint_op_s cn63xxp1;
+ struct cvmx_sriox_maint_op_s cn66xx;
+};
+
+union cvmx_sriox_maint_rd_data {
+ uint64_t u64;
+ struct cvmx_sriox_maint_rd_data_s {
+ uint64_t reserved_33_63:31;
+ uint64_t valid:1;
+ uint64_t rd_data:32;
+ } s;
+ struct cvmx_sriox_maint_rd_data_s cn63xx;
+ struct cvmx_sriox_maint_rd_data_s cn63xxp1;
+ struct cvmx_sriox_maint_rd_data_s cn66xx;
+};
+
+union cvmx_sriox_mce_tx_ctl {
+ uint64_t u64;
+ struct cvmx_sriox_mce_tx_ctl_s {
+ uint64_t reserved_1_63:63;
+ uint64_t mce:1;
+ } s;
+ struct cvmx_sriox_mce_tx_ctl_s cn63xx;
+ struct cvmx_sriox_mce_tx_ctl_s cn63xxp1;
+ struct cvmx_sriox_mce_tx_ctl_s cn66xx;
+};
+
+union cvmx_sriox_mem_op_ctrl {
+ uint64_t u64;
+ struct cvmx_sriox_mem_op_ctrl_s {
+ uint64_t reserved_10_63:54;
+ uint64_t rr_ro:1;
+ uint64_t w_ro:1;
+ uint64_t reserved_6_7:2;
+ uint64_t rp1_sid:1;
+ uint64_t rp0_sid:2;
+ uint64_t rp1_pid:1;
+ uint64_t rp0_pid:2;
+ } s;
+ struct cvmx_sriox_mem_op_ctrl_s cn63xx;
+ struct cvmx_sriox_mem_op_ctrl_s cn63xxp1;
+ struct cvmx_sriox_mem_op_ctrl_s cn66xx;
+};
+
+union cvmx_sriox_omsg_ctrlx {
+ uint64_t u64;
+ struct cvmx_sriox_omsg_ctrlx_s {
+ uint64_t testmode:1;
+ uint64_t reserved_37_62:26;
+ uint64_t silo_max:5;
+ uint64_t rtry_thr:16;
+ uint64_t rtry_en:1;
+ uint64_t reserved_11_14:4;
+ uint64_t idm_tt:1;
+ uint64_t idm_sis:1;
+ uint64_t idm_did:1;
+ uint64_t lttr_sp:4;
+ uint64_t lttr_mp:4;
+ } s;
+ struct cvmx_sriox_omsg_ctrlx_s cn63xx;
+ struct cvmx_sriox_omsg_ctrlx_cn63xxp1 {
+ uint64_t testmode:1;
+ uint64_t reserved_32_62:31;
+ uint64_t rtry_thr:16;
+ uint64_t rtry_en:1;
+ uint64_t reserved_11_14:4;
+ uint64_t idm_tt:1;
+ uint64_t idm_sis:1;
+ uint64_t idm_did:1;
+ uint64_t lttr_sp:4;
+ uint64_t lttr_mp:4;
+ } cn63xxp1;
+ struct cvmx_sriox_omsg_ctrlx_s cn66xx;
+};
+
+union cvmx_sriox_omsg_done_countsx {
+ uint64_t u64;
+ struct cvmx_sriox_omsg_done_countsx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bad:16;
+ uint64_t good:16;
+ } s;
+ struct cvmx_sriox_omsg_done_countsx_s cn63xx;
+ struct cvmx_sriox_omsg_done_countsx_s cn66xx;
+};
+
+union cvmx_sriox_omsg_fmp_mrx {
+ uint64_t u64;
+ struct cvmx_sriox_omsg_fmp_mrx_s {
+ uint64_t reserved_15_63:49;
+ uint64_t ctlr_sp:1;
+ uint64_t ctlr_fmp:1;
+ uint64_t ctlr_nmp:1;
+ uint64_t id_sp:1;
+ uint64_t id_fmp:1;
+ uint64_t id_nmp:1;
+ uint64_t id_psd:1;
+ uint64_t mbox_sp:1;
+ uint64_t mbox_fmp:1;
+ uint64_t mbox_nmp:1;
+ uint64_t mbox_psd:1;
+ uint64_t all_sp:1;
+ uint64_t all_fmp:1;
+ uint64_t all_nmp:1;
+ uint64_t all_psd:1;
+ } s;
+ struct cvmx_sriox_omsg_fmp_mrx_s cn63xx;
+ struct cvmx_sriox_omsg_fmp_mrx_s cn63xxp1;
+ struct cvmx_sriox_omsg_fmp_mrx_s cn66xx;
+};
+
+union cvmx_sriox_omsg_nmp_mrx {
+ uint64_t u64;
+ struct cvmx_sriox_omsg_nmp_mrx_s {
+ uint64_t reserved_15_63:49;
+ uint64_t ctlr_sp:1;
+ uint64_t ctlr_fmp:1;
+ uint64_t ctlr_nmp:1;
+ uint64_t id_sp:1;
+ uint64_t id_fmp:1;
+ uint64_t id_nmp:1;
+ uint64_t reserved_8_8:1;
+ uint64_t mbox_sp:1;
+ uint64_t mbox_fmp:1;
+ uint64_t mbox_nmp:1;
+ uint64_t reserved_4_4:1;
+ uint64_t all_sp:1;
+ uint64_t all_fmp:1;
+ uint64_t all_nmp:1;
+ uint64_t reserved_0_0:1;
+ } s;
+ struct cvmx_sriox_omsg_nmp_mrx_s cn63xx;
+ struct cvmx_sriox_omsg_nmp_mrx_s cn63xxp1;
+ struct cvmx_sriox_omsg_nmp_mrx_s cn66xx;
+};
+
+union cvmx_sriox_omsg_portx {
+ uint64_t u64;
+ struct cvmx_sriox_omsg_portx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t enable:1;
+ uint64_t reserved_3_30:28;
+ uint64_t port:3;
+ } s;
+ struct cvmx_sriox_omsg_portx_cn63xx {
+ uint64_t reserved_32_63:32;
+ uint64_t enable:1;
+ uint64_t reserved_2_30:29;
+ uint64_t port:2;
+ } cn63xx;
+ struct cvmx_sriox_omsg_portx_cn63xx cn63xxp1;
+ struct cvmx_sriox_omsg_portx_s cn66xx;
+};
+
+union cvmx_sriox_omsg_silo_thr {
+ uint64_t u64;
+ struct cvmx_sriox_omsg_silo_thr_s {
+ uint64_t reserved_5_63:59;
+ uint64_t tot_silo:5;
+ } s;
+ struct cvmx_sriox_omsg_silo_thr_s cn63xx;
+ struct cvmx_sriox_omsg_silo_thr_s cn66xx;
+};
+
+union cvmx_sriox_omsg_sp_mrx {
+ uint64_t u64;
+ struct cvmx_sriox_omsg_sp_mrx_s {
+ uint64_t reserved_16_63:48;
+ uint64_t xmbox_sp:1;
+ uint64_t ctlr_sp:1;
+ uint64_t ctlr_fmp:1;
+ uint64_t ctlr_nmp:1;
+ uint64_t id_sp:1;
+ uint64_t id_fmp:1;
+ uint64_t id_nmp:1;
+ uint64_t id_psd:1;
+ uint64_t mbox_sp:1;
+ uint64_t mbox_fmp:1;
+ uint64_t mbox_nmp:1;
+ uint64_t mbox_psd:1;
+ uint64_t all_sp:1;
+ uint64_t all_fmp:1;
+ uint64_t all_nmp:1;
+ uint64_t all_psd:1;
+ } s;
+ struct cvmx_sriox_omsg_sp_mrx_s cn63xx;
+ struct cvmx_sriox_omsg_sp_mrx_s cn63xxp1;
+ struct cvmx_sriox_omsg_sp_mrx_s cn66xx;
+};
+
+union cvmx_sriox_priox_in_use {
+ uint64_t u64;
+ struct cvmx_sriox_priox_in_use_s {
+ uint64_t reserved_32_63:32;
+ uint64_t end_cnt:16;
+ uint64_t start_cnt:16;
+ } s;
+ struct cvmx_sriox_priox_in_use_s cn63xx;
+ struct cvmx_sriox_priox_in_use_s cn66xx;
+};
+
+union cvmx_sriox_rx_bell {
+ uint64_t u64;
+ struct cvmx_sriox_rx_bell_s {
+ uint64_t reserved_48_63:16;
+ uint64_t data:16;
+ uint64_t src_id:16;
+ uint64_t count:8;
+ uint64_t reserved_5_7:3;
+ uint64_t dest_id:1;
+ uint64_t id16:1;
+ uint64_t reserved_2_2:1;
+ uint64_t priority:2;
+ } s;
+ struct cvmx_sriox_rx_bell_s cn63xx;
+ struct cvmx_sriox_rx_bell_s cn63xxp1;
+ struct cvmx_sriox_rx_bell_s cn66xx;
+};
+
+union cvmx_sriox_rx_bell_seq {
+ uint64_t u64;
+ struct cvmx_sriox_rx_bell_seq_s {
+ uint64_t reserved_40_63:24;
+ uint64_t count:8;
+ uint64_t seq:32;
+ } s;
+ struct cvmx_sriox_rx_bell_seq_s cn63xx;
+ struct cvmx_sriox_rx_bell_seq_s cn63xxp1;
+ struct cvmx_sriox_rx_bell_seq_s cn66xx;
+};
+
+union cvmx_sriox_rx_status {
+ uint64_t u64;
+ struct cvmx_sriox_rx_status_s {
+ uint64_t rtn_pr3:8;
+ uint64_t rtn_pr2:8;
+ uint64_t rtn_pr1:8;
+ uint64_t reserved_28_39:12;
+ uint64_t mbox:4;
+ uint64_t comp:8;
+ uint64_t reserved_13_15:3;
+ uint64_t n_post:5;
+ uint64_t post:8;
+ } s;
+ struct cvmx_sriox_rx_status_s cn63xx;
+ struct cvmx_sriox_rx_status_s cn63xxp1;
+ struct cvmx_sriox_rx_status_s cn66xx;
+};
+
+union cvmx_sriox_s2m_typex {
+ uint64_t u64;
+ struct cvmx_sriox_s2m_typex_s {
+ uint64_t reserved_19_63:45;
+ uint64_t wr_op:3;
+ uint64_t reserved_15_15:1;
+ uint64_t rd_op:3;
+ uint64_t wr_prior:2;
+ uint64_t rd_prior:2;
+ uint64_t reserved_6_7:2;
+ uint64_t src_id:1;
+ uint64_t id16:1;
+ uint64_t reserved_2_3:2;
+ uint64_t iaow_sel:2;
+ } s;
+ struct cvmx_sriox_s2m_typex_s cn63xx;
+ struct cvmx_sriox_s2m_typex_s cn63xxp1;
+ struct cvmx_sriox_s2m_typex_s cn66xx;
+};
+
+union cvmx_sriox_seq {
+ uint64_t u64;
+ struct cvmx_sriox_seq_s {
+ uint64_t reserved_32_63:32;
+ uint64_t seq:32;
+ } s;
+ struct cvmx_sriox_seq_s cn63xx;
+ struct cvmx_sriox_seq_s cn63xxp1;
+ struct cvmx_sriox_seq_s cn66xx;
+};
+
+union cvmx_sriox_status_reg {
+ uint64_t u64;
+ struct cvmx_sriox_status_reg_s {
+ uint64_t reserved_2_63:62;
+ uint64_t access:1;
+ uint64_t srio:1;
+ } s;
+ struct cvmx_sriox_status_reg_s cn63xx;
+ struct cvmx_sriox_status_reg_s cn63xxp1;
+ struct cvmx_sriox_status_reg_s cn66xx;
+};
+
+union cvmx_sriox_tag_ctrl {
+ uint64_t u64;
+ struct cvmx_sriox_tag_ctrl_s {
+ uint64_t reserved_17_63:47;
+ uint64_t o_clr:1;
+ uint64_t reserved_13_15:3;
+ uint64_t otag:5;
+ uint64_t reserved_5_7:3;
+ uint64_t itag:5;
+ } s;
+ struct cvmx_sriox_tag_ctrl_s cn63xx;
+ struct cvmx_sriox_tag_ctrl_s cn63xxp1;
+ struct cvmx_sriox_tag_ctrl_s cn66xx;
+};
+
+union cvmx_sriox_tlp_credits {
+ uint64_t u64;
+ struct cvmx_sriox_tlp_credits_s {
+ uint64_t reserved_28_63:36;
+ uint64_t mbox:4;
+ uint64_t comp:8;
+ uint64_t reserved_13_15:3;
+ uint64_t n_post:5;
+ uint64_t post:8;
+ } s;
+ struct cvmx_sriox_tlp_credits_s cn63xx;
+ struct cvmx_sriox_tlp_credits_s cn63xxp1;
+ struct cvmx_sriox_tlp_credits_s cn66xx;
+};
+
+union cvmx_sriox_tx_bell {
+ uint64_t u64;
+ struct cvmx_sriox_tx_bell_s {
+ uint64_t reserved_48_63:16;
+ uint64_t data:16;
+ uint64_t dest_id:16;
+ uint64_t reserved_9_15:7;
+ uint64_t pending:1;
+ uint64_t reserved_5_7:3;
+ uint64_t src_id:1;
+ uint64_t id16:1;
+ uint64_t reserved_2_2:1;
+ uint64_t priority:2;
+ } s;
+ struct cvmx_sriox_tx_bell_s cn63xx;
+ struct cvmx_sriox_tx_bell_s cn63xxp1;
+ struct cvmx_sriox_tx_bell_s cn66xx;
+};
+
+union cvmx_sriox_tx_bell_info {
+ uint64_t u64;
+ struct cvmx_sriox_tx_bell_info_s {
+ uint64_t reserved_48_63:16;
+ uint64_t data:16;
+ uint64_t dest_id:16;
+ uint64_t reserved_8_15:8;
+ uint64_t timeout:1;
+ uint64_t error:1;
+ uint64_t retry:1;
+ uint64_t src_id:1;
+ uint64_t id16:1;
+ uint64_t reserved_2_2:1;
+ uint64_t priority:2;
+ } s;
+ struct cvmx_sriox_tx_bell_info_s cn63xx;
+ struct cvmx_sriox_tx_bell_info_s cn63xxp1;
+ struct cvmx_sriox_tx_bell_info_s cn66xx;
+};
+
+union cvmx_sriox_tx_ctrl {
+ uint64_t u64;
+ struct cvmx_sriox_tx_ctrl_s {
+ uint64_t reserved_53_63:11;
+ uint64_t tag_th2:5;
+ uint64_t reserved_45_47:3;
+ uint64_t tag_th1:5;
+ uint64_t reserved_37_39:3;
+ uint64_t tag_th0:5;
+ uint64_t reserved_20_31:12;
+ uint64_t tx_th2:4;
+ uint64_t reserved_12_15:4;
+ uint64_t tx_th1:4;
+ uint64_t reserved_4_7:4;
+ uint64_t tx_th0:4;
+ } s;
+ struct cvmx_sriox_tx_ctrl_s cn63xx;
+ struct cvmx_sriox_tx_ctrl_s cn63xxp1;
+ struct cvmx_sriox_tx_ctrl_s cn66xx;
+};
+
+union cvmx_sriox_tx_emphasis {
+ uint64_t u64;
+ struct cvmx_sriox_tx_emphasis_s {
+ uint64_t reserved_4_63:60;
+ uint64_t emph:4;
+ } s;
+ struct cvmx_sriox_tx_emphasis_s cn63xx;
+ struct cvmx_sriox_tx_emphasis_s cn66xx;
+};
+
+union cvmx_sriox_tx_status {
+ uint64_t u64;
+ struct cvmx_sriox_tx_status_s {
+ uint64_t reserved_32_63:32;
+ uint64_t s2m_pr3:8;
+ uint64_t s2m_pr2:8;
+ uint64_t s2m_pr1:8;
+ uint64_t s2m_pr0:8;
+ } s;
+ struct cvmx_sriox_tx_status_s cn63xx;
+ struct cvmx_sriox_tx_status_s cn63xxp1;
+ struct cvmx_sriox_tx_status_s cn66xx;
+};
+
+union cvmx_sriox_wr_done_counts {
+ uint64_t u64;
+ struct cvmx_sriox_wr_done_counts_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bad:16;
+ uint64_t good:16;
+ } s;
+ struct cvmx_sriox_wr_done_counts_s cn63xx;
+ struct cvmx_sriox_wr_done_counts_s cn66xx;
+};
+
+#endif
diff --git a/drivers/staging/octeon/cvmx-srxx-defs.h b/arch/mips/include/asm/octeon/cvmx-srxx-defs.h
index d82b366c279f..d82b366c279f 100644
--- a/drivers/staging/octeon/cvmx-srxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-srxx-defs.h
diff --git a/drivers/staging/octeon/cvmx-stxx-defs.h b/arch/mips/include/asm/octeon/cvmx-stxx-defs.h
index 4f209b62cae1..4f209b62cae1 100644
--- a/drivers/staging/octeon/cvmx-stxx-defs.h
+++ b/arch/mips/include/asm/octeon/cvmx-stxx-defs.h
diff --git a/drivers/staging/octeon/cvmx-wqe.h b/arch/mips/include/asm/octeon/cvmx-wqe.h
index 653610953d28..653610953d28 100644
--- a/drivers/staging/octeon/cvmx-wqe.h
+++ b/arch/mips/include/asm/octeon/cvmx-wqe.h
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
index 7e1286706d46..740be97a3251 100644
--- a/arch/mips/include/asm/octeon/cvmx.h
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -31,6 +31,27 @@
#include <linux/kernel.h>
#include <linux/string.h>
+enum cvmx_mips_space {
+ CVMX_MIPS_SPACE_XKSEG = 3LL,
+ CVMX_MIPS_SPACE_XKPHYS = 2LL,
+ CVMX_MIPS_SPACE_XSSEG = 1LL,
+ CVMX_MIPS_SPACE_XUSEG = 0LL
+};
+
+/* These macros for use when using 32 bit pointers. */
+#define CVMX_MIPS32_SPACE_KSEG0 1l
+#define CVMX_ADD_SEG32(segment, add) \
+ (((int32_t)segment << 31) | (int32_t)(add))
+
+#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
+
+/* These macros simplify the process of creating common IO addresses */
+#define CVMX_ADD_SEG(segment, add) \
+ ((((uint64_t)segment) << 62) | (add))
+#ifndef CVMX_ADD_IO_SEG
+#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
+#endif
+
#include "cvmx-asm.h"
#include "cvmx-packet.h"
#include "cvmx-sysinfo.h"
@@ -129,27 +150,6 @@ static inline uint64_t cvmx_build_bits(uint64_t high_bit,
return (value & cvmx_build_mask(high_bit - low_bit + 1)) << low_bit;
}
-enum cvmx_mips_space {
- CVMX_MIPS_SPACE_XKSEG = 3LL,
- CVMX_MIPS_SPACE_XKPHYS = 2LL,
- CVMX_MIPS_SPACE_XSSEG = 1LL,
- CVMX_MIPS_SPACE_XUSEG = 0LL
-};
-
-/* These macros for use when using 32 bit pointers. */
-#define CVMX_MIPS32_SPACE_KSEG0 1l
-#define CVMX_ADD_SEG32(segment, add) \
- (((int32_t)segment << 31) | (int32_t)(add))
-
-#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
-
-/* These macros simplify the process of creating common IO addresses */
-#define CVMX_ADD_SEG(segment, add) \
- ((((uint64_t)segment) << 62) | (add))
-#ifndef CVMX_ADD_IO_SEG
-#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
-#endif
-
/**
* Convert a memory pointer (void*) into a hardware compatible
* memory address (uint64_t). Octeon hardware widgets don't
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h
index cba6fbed9f43..8008da2f8779 100644
--- a/arch/mips/include/asm/octeon/octeon-feature.h
+++ b/arch/mips/include/asm/octeon/octeon-feature.h
@@ -31,8 +31,14 @@
#ifndef __OCTEON_FEATURE_H__
#define __OCTEON_FEATURE_H__
+#include <asm/octeon/cvmx-mio-defs.h>
+#include <asm/octeon/cvmx-rnm-defs.h>
enum octeon_feature {
+ /* CN68XX uses port kinds for packet interface */
+ OCTEON_FEATURE_PKND,
+ /* CN68XX has different fields in word0 - word2 */
+ OCTEON_FEATURE_CN68XX_WQE,
/*
* Octeon models in the CN5XXX family and higher support
* atomic add instructions to memory (saa/saad).
@@ -42,8 +48,13 @@ enum octeon_feature {
OCTEON_FEATURE_ZIP,
/* Does this Octeon support crypto acceleration using COP2? */
OCTEON_FEATURE_CRYPTO,
+ OCTEON_FEATURE_DORM_CRYPTO,
/* Does this Octeon support PCI express? */
OCTEON_FEATURE_PCIE,
+ /* Does this Octeon support SRIOs */
+ OCTEON_FEATURE_SRIO,
+ /* Does this Octeon support Interlaken */
+ OCTEON_FEATURE_ILK,
/* Some Octeon models support internal memory for storing
* cryptographic keys */
OCTEON_FEATURE_KEY_MEMORY,
@@ -64,6 +75,15 @@ enum octeon_feature {
/* Octeon MDIO block supports clause 45 transactions for 10
* Gig support */
OCTEON_FEATURE_MDIO_CLAUSE_45,
+ /*
+ * CN52XX and CN56XX used a block named NPEI for PCIe
+ * access. Newer chips replaced this with SLI+DPI.
+ */
+ OCTEON_FEATURE_NPEI,
+ OCTEON_FEATURE_HFA,
+ OCTEON_FEATURE_DFM,
+ OCTEON_FEATURE_CIU2,
+ OCTEON_MAX_FEATURE
};
static inline int cvmx_fuse_read(int fuse);
@@ -96,30 +116,78 @@ static inline int octeon_has_feature(enum octeon_feature feature)
return !cvmx_fuse_read(121);
case OCTEON_FEATURE_CRYPTO:
- return !cvmx_fuse_read(90);
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ union cvmx_mio_fus_dat2 fus_2;
+ fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
+ if (fus_2.s.nocrypto || fus_2.s.nomul) {
+ return 0;
+ } else if (!fus_2.s.dorm_crypto) {
+ return 1;
+ } else {
+ union cvmx_rnm_ctl_status st;
+ st.u64 = cvmx_read_csr(CVMX_RNM_CTL_STATUS);
+ return st.s.eer_val;
+ }
+ } else {
+ return !cvmx_fuse_read(90);
+ }
+
+ case OCTEON_FEATURE_DORM_CRYPTO:
+ if (OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
+ union cvmx_mio_fus_dat2 fus_2;
+ fus_2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
+ return !fus_2.s.nocrypto && !fus_2.s.nomul && fus_2.s.dorm_crypto;
+ } else {
+ return 0;
+ }
case OCTEON_FEATURE_PCIE:
- case OCTEON_FEATURE_MGMT_PORT:
- case OCTEON_FEATURE_RAID:
return OCTEON_IS_MODEL(OCTEON_CN56XX)
- || OCTEON_IS_MODEL(OCTEON_CN52XX);
+ || OCTEON_IS_MODEL(OCTEON_CN52XX)
+ || OCTEON_IS_MODEL(OCTEON_CN6XXX);
+
+ case OCTEON_FEATURE_SRIO:
+ return OCTEON_IS_MODEL(OCTEON_CN63XX)
+ || OCTEON_IS_MODEL(OCTEON_CN66XX);
+
+ case OCTEON_FEATURE_ILK:
+ return (OCTEON_IS_MODEL(OCTEON_CN68XX));
case OCTEON_FEATURE_KEY_MEMORY:
+ return OCTEON_IS_MODEL(OCTEON_CN38XX)
+ || OCTEON_IS_MODEL(OCTEON_CN58XX)
+ || OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN6XXX);
+
case OCTEON_FEATURE_LED_CONTROLLER:
return OCTEON_IS_MODEL(OCTEON_CN38XX)
|| OCTEON_IS_MODEL(OCTEON_CN58XX)
|| OCTEON_IS_MODEL(OCTEON_CN56XX);
+
case OCTEON_FEATURE_TRA:
return !(OCTEON_IS_MODEL(OCTEON_CN30XX)
|| OCTEON_IS_MODEL(OCTEON_CN50XX));
+ case OCTEON_FEATURE_MGMT_PORT:
+ return OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX)
+ || OCTEON_IS_MODEL(OCTEON_CN6XXX);
+
+ case OCTEON_FEATURE_RAID:
+ return OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX)
+ || OCTEON_IS_MODEL(OCTEON_CN6XXX);
+
case OCTEON_FEATURE_USB:
return !(OCTEON_IS_MODEL(OCTEON_CN38XX)
|| OCTEON_IS_MODEL(OCTEON_CN58XX));
+
case OCTEON_FEATURE_NO_WPTR:
return (OCTEON_IS_MODEL(OCTEON_CN56XX)
- || OCTEON_IS_MODEL(OCTEON_CN52XX))
- && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
- && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X);
+ || OCTEON_IS_MODEL(OCTEON_CN52XX)
+ || OCTEON_IS_MODEL(OCTEON_CN6XXX))
+ && !OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
+ && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X);
+
case OCTEON_FEATURE_DFA:
if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
&& !OCTEON_IS_MODEL(OCTEON_CN31XX)
@@ -127,14 +195,42 @@ static inline int octeon_has_feature(enum octeon_feature feature)
return 0;
else if (OCTEON_IS_MODEL(OCTEON_CN3020))
return 0;
- else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
- return 1;
else
return !cvmx_fuse_read(120);
+
+ case OCTEON_FEATURE_HFA:
+ if (!OCTEON_IS_MODEL(OCTEON_CN6XXX))
+ return 0;
+ else
+ return !cvmx_fuse_read(90);
+
+ case OCTEON_FEATURE_DFM:
+ if (!(OCTEON_IS_MODEL(OCTEON_CN63XX)
+ || OCTEON_IS_MODEL(OCTEON_CN66XX)))
+ return 0;
+ else
+ return !cvmx_fuse_read(90);
+
case OCTEON_FEATURE_MDIO_CLAUSE_45:
return !(OCTEON_IS_MODEL(OCTEON_CN3XXX)
|| OCTEON_IS_MODEL(OCTEON_CN58XX)
|| OCTEON_IS_MODEL(OCTEON_CN50XX));
+
+ case OCTEON_FEATURE_NPEI:
+ return OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX);
+
+ case OCTEON_FEATURE_PKND:
+ return OCTEON_IS_MODEL(OCTEON_CN68XX);
+
+ case OCTEON_FEATURE_CN68XX_WQE:
+ return OCTEON_IS_MODEL(OCTEON_CN68XX);
+
+ case OCTEON_FEATURE_CIU2:
+ return OCTEON_IS_MODEL(OCTEON_CN68XX);
+
+ default:
+ break;
}
return 0;
}
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
index 700f88e31cad..4e338a4d9424 100644
--- a/arch/mips/include/asm/octeon/octeon-model.h
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -4,7 +4,7 @@
* Contact: support@caviumnetworks.com
* This file is part of the OCTEON SDK
*
- * Copyright (c) 2003-2008 Cavium Networks
+ * Copyright (c) 2003-2010 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
@@ -24,14 +24,6 @@
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
***********************license end**************************************/
-
-/*
- *
- * File defining different Octeon model IDs and macros to
- * compare them.
- *
- */
-
#ifndef __OCTEON_MODEL_H__
#define __OCTEON_MODEL_H__
@@ -52,6 +44,8 @@
* for internal use only, and may change without notice.
*/
+#define OCTEON_FAMILY_MASK 0x00ffff00
+
/* Flag bits in top byte */
/* Ignores revision in model checks */
#define OM_IGNORE_REVISION 0x01000000
@@ -63,21 +57,48 @@
#define OM_IGNORE_MINOR_REVISION 0x08000000
#define OM_FLAG_MASK 0xff000000
-#define OM_MATCH_5XXX_FAMILY_MODELS 0x20000000 /* Match all cn5XXX Octeon models. */
-#define OM_MATCH_6XXX_FAMILY_MODELS 0x40000000 /* Match all cn6XXX Octeon models. */
+/* Match all cn5XXX Octeon models. */
+#define OM_MATCH_5XXX_FAMILY_MODELS 0x20000000
+/* Match all cn6XXX Octeon models. */
+#define OM_MATCH_6XXX_FAMILY_MODELS 0x40000000
/*
* CN6XXX models with new revision encoding
*/
+#define OCTEON_CN68XX_PASS1_0 0x000d9100
+#define OCTEON_CN68XX_PASS1_1 0x000d9101
+#define OCTEON_CN68XX_PASS1_2 0x000d9102
+#define OCTEON_CN68XX_PASS2_0 0x000d9108
+
+#define OCTEON_CN68XX (OCTEON_CN68XX_PASS2_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN68XX_PASS1_X (OCTEON_CN68XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN68XX_PASS2_X (OCTEON_CN68XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
+
+#define OCTEON_CN68XX_PASS1 OCTEON_CN68XX_PASS1_X
+#define OCTEON_CN68XX_PASS2 OCTEON_CN68XX_PASS2_X
+
+#define OCTEON_CN66XX_PASS1_0 0x000d9200
+#define OCTEON_CN66XX_PASS1_2 0x000d9202
+
+#define OCTEON_CN66XX (OCTEON_CN66XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN66XX_PASS1_X (OCTEON_CN66XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+
#define OCTEON_CN63XX_PASS1_0 0x000d9000
#define OCTEON_CN63XX_PASS1_1 0x000d9001
#define OCTEON_CN63XX_PASS1_2 0x000d9002
#define OCTEON_CN63XX_PASS2_0 0x000d9008
+#define OCTEON_CN63XX_PASS2_1 0x000d9009
+#define OCTEON_CN63XX_PASS2_2 0x000d900a
#define OCTEON_CN63XX (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_REVISION)
#define OCTEON_CN63XX_PASS1_X (OCTEON_CN63XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
#define OCTEON_CN63XX_PASS2_X (OCTEON_CN63XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN61XX_PASS1_0 0x000d9300
+
+#define OCTEON_CN61XX (OCTEON_CN61XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN61XX_PASS1_X (OCTEON_CN61XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+
/*
* CN5XXX models with new revision encoding
*/
@@ -90,10 +111,8 @@
#define OCTEON_CN58XX_PASS2_3 0x000d030b
#define OCTEON_CN58XX (OCTEON_CN58XX_PASS1_0 | OM_IGNORE_REVISION)
-#define OCTEON_CN58XX_PASS1_X (OCTEON_CN58XX_PASS1_0 \
- | OM_IGNORE_MINOR_REVISION)
-#define OCTEON_CN58XX_PASS2_X (OCTEON_CN58XX_PASS2_0 \
- | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN58XX_PASS1_X (OCTEON_CN58XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN58XX_PASS2_X (OCTEON_CN58XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
#define OCTEON_CN58XX_PASS1 OCTEON_CN58XX_PASS1_X
#define OCTEON_CN58XX_PASS2 OCTEON_CN58XX_PASS2_X
@@ -103,10 +122,8 @@
#define OCTEON_CN56XX_PASS2_1 0x000d0409
#define OCTEON_CN56XX (OCTEON_CN56XX_PASS2_0 | OM_IGNORE_REVISION)
-#define OCTEON_CN56XX_PASS1_X (OCTEON_CN56XX_PASS1_0 \
- | OM_IGNORE_MINOR_REVISION)
-#define OCTEON_CN56XX_PASS2_X (OCTEON_CN56XX_PASS2_0 \
- | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN56XX_PASS1_X (OCTEON_CN56XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN56XX_PASS2_X (OCTEON_CN56XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
#define OCTEON_CN56XX_PASS1 OCTEON_CN56XX_PASS1_X
#define OCTEON_CN56XX_PASS2 OCTEON_CN56XX_PASS2_X
@@ -125,8 +142,7 @@
#define OCTEON_CN50XX_PASS1_0 0x000d0600
#define OCTEON_CN50XX (OCTEON_CN50XX_PASS1_0 | OM_IGNORE_REVISION)
-#define OCTEON_CN50XX_PASS1_X (OCTEON_CN50XX_PASS1_0 \
- | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN50XX_PASS1_X (OCTEON_CN50XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
#define OCTEON_CN50XX_PASS1 OCTEON_CN50XX_PASS1_X
/*
@@ -138,10 +154,8 @@
#define OCTEON_CN52XX_PASS2_0 0x000d0708
#define OCTEON_CN52XX (OCTEON_CN52XX_PASS2_0 | OM_IGNORE_REVISION)
-#define OCTEON_CN52XX_PASS1_X (OCTEON_CN52XX_PASS1_0 \
- | OM_IGNORE_MINOR_REVISION)
-#define OCTEON_CN52XX_PASS2_X (OCTEON_CN52XX_PASS2_0 \
- | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN52XX_PASS1_X (OCTEON_CN52XX_PASS1_0 | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN52XX_PASS2_X (OCTEON_CN52XX_PASS2_0 | OM_IGNORE_MINOR_REVISION)
#define OCTEON_CN52XX_PASS1 OCTEON_CN52XX_PASS1_X
#define OCTEON_CN52XX_PASS2 OCTEON_CN52XX_PASS2_X
@@ -174,28 +188,23 @@
#define OCTEON_CN3005_PASS1 (0x000d0210 | OM_CHECK_SUBMODEL)
#define OCTEON_CN3005_PASS1_0 (0x000d0210 | OM_CHECK_SUBMODEL)
#define OCTEON_CN3005_PASS1_1 (0x000d0212 | OM_CHECK_SUBMODEL)
-#define OCTEON_CN3005 (OCTEON_CN3005_PASS1 | OM_IGNORE_REVISION \
- | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3005 (OCTEON_CN3005_PASS1 | OM_IGNORE_REVISION | OM_CHECK_SUBMODEL)
#define OCTEON_CN3010_PASS1 (0x000d0200 | OM_CHECK_SUBMODEL)
#define OCTEON_CN3010_PASS1_0 (0x000d0200 | OM_CHECK_SUBMODEL)
#define OCTEON_CN3010_PASS1_1 (0x000d0202 | OM_CHECK_SUBMODEL)
-#define OCTEON_CN3010 (OCTEON_CN3010_PASS1 | OM_IGNORE_REVISION \
- | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3010 (OCTEON_CN3010_PASS1 | OM_IGNORE_REVISION | OM_CHECK_SUBMODEL)
#define OCTEON_CN3020_PASS1 (0x000d0110 | OM_CHECK_SUBMODEL)
#define OCTEON_CN3020_PASS1_0 (0x000d0110 | OM_CHECK_SUBMODEL)
#define OCTEON_CN3020_PASS1_1 (0x000d0112 | OM_CHECK_SUBMODEL)
-#define OCTEON_CN3020 (OCTEON_CN3020_PASS1 | OM_IGNORE_REVISION \
- | OM_CHECK_SUBMODEL)
-
-
-
-/* This matches the complete family of CN3xxx CPUs, and not subsequent models */
-#define OCTEON_CN3XXX (OCTEON_CN58XX_PASS1_0 \
- | OM_MATCH_PREVIOUS_MODELS \
- | OM_IGNORE_REVISION)
+#define OCTEON_CN3020 (OCTEON_CN3020_PASS1 | OM_IGNORE_REVISION | OM_CHECK_SUBMODEL)
+/*
+ * This matches the complete family of CN3xxx CPUs, and not subsequent
+ * models
+ */
+#define OCTEON_CN3XXX (OCTEON_CN58XX_PASS1_0 | OM_MATCH_PREVIOUS_MODELS | OM_IGNORE_REVISION)
#define OCTEON_CN5XXX (OCTEON_CN58XX_PASS1_0 | OM_MATCH_5XXX_FAMILY_MODELS)
#define OCTEON_CN6XXX (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS)
@@ -221,90 +230,55 @@
#define OCTEON_38XX_FAMILY_MASK 0x00ffff00
#define OCTEON_38XX_FAMILY_REV_MASK 0x00ffff0f
#define OCTEON_38XX_MODEL_MASK 0x00ffff10
-#define OCTEON_38XX_MODEL_REV_MASK (OCTEON_38XX_FAMILY_REV_MASK \
- | OCTEON_38XX_MODEL_MASK)
+#define OCTEON_38XX_MODEL_REV_MASK (OCTEON_38XX_FAMILY_REV_MASK | OCTEON_38XX_MODEL_MASK)
/* CN5XXX and later use different layout of bits in the revision ID field */
#define OCTEON_58XX_FAMILY_MASK OCTEON_38XX_FAMILY_MASK
#define OCTEON_58XX_FAMILY_REV_MASK 0x00ffff3f
#define OCTEON_58XX_MODEL_MASK 0x00ffffc0
-#define OCTEON_58XX_MODEL_REV_MASK (OCTEON_58XX_FAMILY_REV_MASK \
- | OCTEON_58XX_MODEL_MASK)
-#define OCTEON_58XX_MODEL_MINOR_REV_MASK (OCTEON_58XX_MODEL_REV_MASK \
- & 0x00fffff8)
+#define OCTEON_58XX_MODEL_REV_MASK (OCTEON_58XX_FAMILY_REV_MASK | OCTEON_58XX_MODEL_MASK)
+#define OCTEON_58XX_MODEL_MINOR_REV_MASK (OCTEON_58XX_MODEL_REV_MASK & 0x00fffff8)
#define OCTEON_5XXX_MODEL_MASK 0x00ff0fc0
-#define __OCTEON_MATCH_MASK__(x, y, z) (((x) & (z)) == ((y) & (z)))
-
-/* NOTE: This is for internal (to this file) use only. */
-static inline int __OCTEON_IS_MODEL_COMPILE__(uint32_t arg_model,
- uint32_t chip_model)
-{
- uint32_t rev_and_sub = OM_IGNORE_REVISION | OM_CHECK_SUBMODEL;
-
- if ((arg_model & OCTEON_38XX_FAMILY_MASK) < OCTEON_CN58XX_PASS1_0) {
- if (((arg_model & OM_FLAG_MASK) == rev_and_sub) &&
- __OCTEON_MATCH_MASK__(chip_model, arg_model,
- OCTEON_38XX_MODEL_MASK))
- return 1;
- if (((arg_model & OM_FLAG_MASK) == 0) &&
- __OCTEON_MATCH_MASK__(chip_model, arg_model,
- OCTEON_38XX_FAMILY_REV_MASK))
- return 1;
- if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_REVISION) &&
- __OCTEON_MATCH_MASK__(chip_model, arg_model,
- OCTEON_38XX_FAMILY_MASK))
- return 1;
- if (((arg_model & OM_FLAG_MASK) == OM_CHECK_SUBMODEL) &&
- __OCTEON_MATCH_MASK__((chip_model), (arg_model),
- OCTEON_38XX_MODEL_REV_MASK))
- return 1;
- if ((arg_model & OM_MATCH_PREVIOUS_MODELS) &&
- ((chip_model & OCTEON_38XX_MODEL_MASK) <
- (arg_model & OCTEON_38XX_MODEL_MASK)))
- return 1;
- } else {
- if (((arg_model & OM_FLAG_MASK) == rev_and_sub) &&
- __OCTEON_MATCH_MASK__((chip_model), (arg_model),
- OCTEON_58XX_MODEL_MASK))
- return 1;
- if (((arg_model & OM_FLAG_MASK) == 0) &&
- __OCTEON_MATCH_MASK__((chip_model), (arg_model),
- OCTEON_58XX_FAMILY_REV_MASK))
- return 1;
- if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_MINOR_REVISION) &&
- __OCTEON_MATCH_MASK__((chip_model), (arg_model),
- OCTEON_58XX_MODEL_MINOR_REV_MASK))
- return 1;
- if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_REVISION) &&
- __OCTEON_MATCH_MASK__((chip_model), (arg_model),
- OCTEON_58XX_FAMILY_MASK))
- return 1;
- if (((arg_model & OM_FLAG_MASK) == OM_CHECK_SUBMODEL) &&
- __OCTEON_MATCH_MASK__((chip_model), (arg_model),
- OCTEON_58XX_MODEL_REV_MASK))
- return 1;
-
- if (((arg_model & OM_MATCH_5XXX_FAMILY_MODELS) == OM_MATCH_5XXX_FAMILY_MODELS) &&
- ((chip_model) >= OCTEON_CN58XX_PASS1_0) && ((chip_model) < OCTEON_CN63XX_PASS1_0))
- return 1;
-
- if (((arg_model & OM_MATCH_6XXX_FAMILY_MODELS) == OM_MATCH_6XXX_FAMILY_MODELS) &&
- ((chip_model) >= OCTEON_CN63XX_PASS1_0))
- return 1;
-
- if ((arg_model & OM_MATCH_PREVIOUS_MODELS) &&
- ((chip_model & OCTEON_58XX_MODEL_MASK) <
- (arg_model & OCTEON_58XX_MODEL_MASK)))
- return 1;
- }
- return 0;
-}
-
/* forward declarations */
static inline uint32_t cvmx_get_proc_id(void) __attribute__ ((pure));
static inline uint64_t cvmx_read_csr(uint64_t csr_addr);
+#define __OCTEON_MATCH_MASK__(x, y, z) (((x) & (z)) == ((y) & (z)))
+
+/* NOTE: This for internal use only! */
+#define __OCTEON_IS_MODEL_COMPILE__(arg_model, chip_model) \
+((((arg_model & OCTEON_38XX_FAMILY_MASK) < OCTEON_CN58XX_PASS1_0) && ( \
+ ((((arg_model) & (OM_FLAG_MASK)) == (OM_IGNORE_REVISION | OM_CHECK_SUBMODEL)) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_38XX_MODEL_MASK)) || \
+ ((((arg_model) & (OM_FLAG_MASK)) == 0) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_38XX_FAMILY_REV_MASK)) || \
+ ((((arg_model) & (OM_FLAG_MASK)) == OM_IGNORE_REVISION) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_38XX_FAMILY_MASK)) || \
+ ((((arg_model) & (OM_FLAG_MASK)) == OM_CHECK_SUBMODEL) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_38XX_MODEL_REV_MASK)) || \
+ ((((arg_model) & (OM_MATCH_PREVIOUS_MODELS)) == OM_MATCH_PREVIOUS_MODELS) \
+ && (((chip_model) & OCTEON_38XX_MODEL_MASK) < ((arg_model) & OCTEON_38XX_MODEL_MASK))) \
+ )) || \
+ (((arg_model & OCTEON_38XX_FAMILY_MASK) >= OCTEON_CN58XX_PASS1_0) && ( \
+ ((((arg_model) & (OM_FLAG_MASK)) == (OM_IGNORE_REVISION | OM_CHECK_SUBMODEL)) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_58XX_MODEL_MASK)) || \
+ ((((arg_model) & (OM_FLAG_MASK)) == 0) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_58XX_FAMILY_REV_MASK)) || \
+ ((((arg_model) & (OM_FLAG_MASK)) == OM_IGNORE_MINOR_REVISION) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_58XX_MODEL_MINOR_REV_MASK)) || \
+ ((((arg_model) & (OM_FLAG_MASK)) == OM_IGNORE_REVISION) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_58XX_FAMILY_MASK)) || \
+ ((((arg_model) & (OM_FLAG_MASK)) == OM_CHECK_SUBMODEL) \
+ && __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_58XX_MODEL_REV_MASK)) || \
+ ((((arg_model) & (OM_MATCH_5XXX_FAMILY_MODELS)) == OM_MATCH_5XXX_FAMILY_MODELS) \
+ && ((chip_model) >= OCTEON_CN58XX_PASS1_0) && ((chip_model) < OCTEON_CN63XX_PASS1_0)) || \
+ ((((arg_model) & (OM_MATCH_6XXX_FAMILY_MODELS)) == OM_MATCH_6XXX_FAMILY_MODELS) \
+ && ((chip_model) >= OCTEON_CN63XX_PASS1_0)) || \
+ ((((arg_model) & (OM_MATCH_PREVIOUS_MODELS)) == OM_MATCH_PREVIOUS_MODELS) \
+ && (((chip_model) & OCTEON_58XX_MODEL_MASK) < ((arg_model) & OCTEON_58XX_MODEL_MASK))) \
+ )))
+
/* NOTE: This for internal use only!!!!! */
static inline int __octeon_is_model_runtime__(uint32_t model)
{
@@ -312,22 +286,25 @@ static inline int __octeon_is_model_runtime__(uint32_t model)
/*
* Check for special case of mismarked 3005 samples. We only
- * need to check if the sub model isn't being ignored.
+ * need to check if the sub model isn't being ignored
*/
if ((model & OM_CHECK_SUBMODEL) == OM_CHECK_SUBMODEL) {
- if (cpuid == OCTEON_CN3010_PASS1 \
- && (cvmx_read_csr(0x80011800800007B8ull) & (1ull << 34)))
+ if (cpuid == OCTEON_CN3010_PASS1 && (cvmx_read_csr(0x80011800800007B8ull) & (1ull << 34)))
cpuid |= 0x10;
}
return __OCTEON_IS_MODEL_COMPILE__(model, cpuid);
}
/*
- * The OCTEON_IS_MODEL macro should be used for all Octeon model
- * checking done in a program. This should be kept runtime if at all
- * possible. Any compile time (#if OCTEON_IS_MODEL) usage must be
- * condtionalized with OCTEON_IS_COMMON_BINARY() if runtime checking
- * support is required.
+ * The OCTEON_IS_MODEL macro should be used for all Octeon model checking done
+ * in a program.
+ * This should be kept runtime if at all possible and must be conditionalized
+ * with OCTEON_IS_COMMON_BINARY() if runtime checking support is required.
+ *
+ * Use of the macro in preprocessor directives ( #if OCTEON_IS_MODEL(...) )
+ * is NOT SUPPORTED, and should be replaced with CVMX_COMPILED_FOR()
+ * I.e.:
+ * #if OCTEON_IS_MODEL(OCTEON_CN56XX) -> #if CVMX_COMPILED_FOR(OCTEON_CN56XX)
*/
#define OCTEON_IS_MODEL(x) __octeon_is_model_runtime__(x)
#define OCTEON_IS_COMMON_BINARY() 1
diff --git a/arch/mips/include/asm/octeon/pci-octeon.h b/arch/mips/include/asm/octeon/pci-octeon.h
index fba2ba200f58..c66734bd3382 100644
--- a/arch/mips/include/asm/octeon/pci-octeon.h
+++ b/arch/mips/include/asm/octeon/pci-octeon.h
@@ -56,7 +56,8 @@ enum octeon_dma_bar_type {
OCTEON_DMA_BAR_TYPE_INVALID,
OCTEON_DMA_BAR_TYPE_SMALL,
OCTEON_DMA_BAR_TYPE_BIG,
- OCTEON_DMA_BAR_TYPE_PCIE
+ OCTEON_DMA_BAR_TYPE_PCIE,
+ OCTEON_DMA_BAR_TYPE_PCIE2
};
/*
diff --git a/arch/mips/include/asm/page.h b/arch/mips/include/asm/page.h
index e59cd1ac09c2..d41790928c64 100644
--- a/arch/mips/include/asm/page.h
+++ b/arch/mips/include/asm/page.h
@@ -38,6 +38,14 @@
#define HPAGE_SIZE (_AC(1,UL) << HPAGE_SHIFT)
#define HPAGE_MASK (~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT)
+#else /* !CONFIG_HUGETLB_PAGE */
+# ifndef BUILD_BUG
+# define BUILD_BUG() do { extern void __build_bug(void); __build_bug(); } while (0)
+# endif
+#define HPAGE_SHIFT ({BUILD_BUG(); 0; })
+#define HPAGE_SIZE ({BUILD_BUG(); 0; })
+#define HPAGE_MASK ({BUILD_BUG(); 0; })
+#define HUGETLB_PAGE_ORDER ({BUILD_BUG(); 0; })
#endif /* CONFIG_HUGETLB_PAGE */
#ifndef __ASSEMBLY__
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h
index 8a153d2fa62a..5d56bb230345 100644
--- a/arch/mips/include/asm/pgtable-32.h
+++ b/arch/mips/include/asm/pgtable-32.h
@@ -19,23 +19,7 @@
#include <asm-generic/pgtable-nopmd.h>
/*
- * - add_wired_entry() add a fixed TLB entry, and move wired register
- */
-extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
- unsigned long entryhi, unsigned long pagemask);
-
-/*
- * - add_temporary_entry() add a temporary TLB entry. We use TLB entries
- * starting at the top and working down. This is for populating the
- * TLB before trap_init() puts the TLB miss handler in place. It
- * should be used only for entries matching the actual page tables,
- * to prevent inconsistencies.
- */
-extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
- unsigned long entryhi, unsigned long pagemask);
-
-
-/* Basically we have the same two-level (which is the logical three level
+ * Basically we have the same two-level (which is the logical three level
* Linux page table layout folded) page tables as the i386. Some day
* when we have proper page coloring support we can have a 1% quicker
* tlb refill handling mechanism, but for now it is a bit slower but
diff --git a/arch/mips/include/asm/tlbmisc.h b/arch/mips/include/asm/tlbmisc.h
new file mode 100644
index 000000000000..3a452282cba0
--- /dev/null
+++ b/arch/mips/include/asm/tlbmisc.h
@@ -0,0 +1,10 @@
+#ifndef __ASM_TLBMISC_H
+#define __ASM_TLBMISC_H
+
+/*
+ * - add_wired_entry() add a fixed TLB entry, and move wired register
+ */
+extern void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
+ unsigned long entryhi, unsigned long pagemask);
+
+#endif /* __ASM_TLBMISC_H */
diff --git a/arch/mips/include/asm/traps.h b/arch/mips/include/asm/traps.h
index 90ff2f497c50..ff74aec3561a 100644
--- a/arch/mips/include/asm/traps.h
+++ b/arch/mips/include/asm/traps.h
@@ -24,5 +24,18 @@ extern int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
extern void (*board_nmi_handler_setup)(void);
extern void (*board_ejtag_handler_setup)(void);
extern void (*board_bind_eic_interrupt)(int irq, int regset);
+extern void (*board_ebase_setup)(void);
+
+extern int register_nmi_notifier(struct notifier_block *nb);
+
+#define nmi_notifier(fn, pri) \
+({ \
+ static struct notifier_block fn##_nb = { \
+ .notifier_call = fn, \
+ .priority = pri \
+ }; \
+ \
+ register_nmi_notifier(&fn##_nb); \
+})
#endif /* _ASM_TRAPS_H */
diff --git a/arch/mips/include/asm/types.h b/arch/mips/include/asm/types.h
index 43bf70ebd3a2..1228b25b290a 100644
--- a/arch/mips/include/asm/types.h
+++ b/arch/mips/include/asm/types.h
@@ -15,10 +15,14 @@
* We don't use int-l64.h for the kernel anymore but still use it for
* userspace to avoid code changes.
*/
-#if (_MIPS_SZLONG == 64) && !defined(__KERNEL__)
-# include <asm-generic/int-l64.h>
-#else
+#ifdef __KERNEL__
# include <asm-generic/int-ll64.h>
+#else
+# if _MIPS_SZLONG == 64
+# include <asm-generic/int-l64.h>
+# else
+# include <asm-generic/int-ll64.h>
+# endif
#endif
/*
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c
index ca9bd2069142..f21868b28b24 100644
--- a/arch/mips/jazz/irq.c
+++ b/arch/mips/jazz/irq.c
@@ -20,6 +20,7 @@
#include <asm/io.h>
#include <asm/jazz.h>
#include <asm/pgtable.h>
+#include <asm/tlbmisc.h>
static DEFINE_RAW_SPINLOCK(r4030_lock);
@@ -133,7 +134,7 @@ static irqreturn_t r4030_timer_interrupt(int irq, void *dev_id)
static struct irqaction r4030_timer_irqaction = {
.handler = r4030_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_TIMER,
.name = "R4030 timer",
};
diff --git a/arch/mips/jazz/setup.c b/arch/mips/jazz/setup.c
index 0d0f054a02f4..820e926dacbc 100644
--- a/arch/mips/jazz/setup.c
+++ b/arch/mips/jazz/setup.c
@@ -21,6 +21,7 @@
#include <asm/jazzdma.h>
#include <asm/reboot.h>
#include <asm/pgtable.h>
+#include <asm/tlbmisc.h>
extern asmlinkage void jazz_handle_int(void);
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index c3b04be3fb2b..639e3ce6c264 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -488,7 +488,7 @@ static int __init qi_lb60_board_setup(void)
board_gpio_setup();
if (qi_lb60_init_platform_devices())
- panic("Failed to initialize platform devices\n");
+ panic("Failed to initialize platform devices");
return 0;
}
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index 1a966183e353..0c6877ea9004 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -55,9 +55,11 @@ obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o
obj-$(CONFIG_CPU_XLR) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_XLP) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SMP_UP) += smp-up.o
+obj-$(CONFIG_CPU_BMIPS) += smp-bmips.o bmips_vec.o
obj-$(CONFIG_MIPS_MT) += mips-mt.o
obj-$(CONFIG_MIPS_MT_FPAFF) += mips-mt-fpaff.o
diff --git a/arch/mips/kernel/bmips_vec.S b/arch/mips/kernel/bmips_vec.S
new file mode 100644
index 000000000000..e908e81330b1
--- /dev/null
+++ b/arch/mips/kernel/bmips_vec.S
@@ -0,0 +1,255 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2011 by Kevin Cernekee (cernekee@gmail.com)
+ *
+ * Reset/NMI/re-entry vectors for BMIPS processors
+ */
+
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/asmmacro.h>
+#include <asm/cacheops.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/addrspace.h>
+#include <asm/hazards.h>
+#include <asm/bmips.h>
+
+ .macro BARRIER
+ .set mips32
+ _ssnop
+ _ssnop
+ _ssnop
+ .set mips0
+ .endm
+
+ __CPUINIT
+
+/***********************************************************************
+ * Alternate CPU1 startup vector for BMIPS4350
+ *
+ * On some systems the bootloader has already started CPU1 and configured
+ * it to resume execution at 0x8000_0200 (!BEV IV vector) when it is
+ * triggered by the SW1 interrupt. If that is the case we try to move
+ * it to a more convenient place: BMIPS_WARM_RESTART_VEC @ 0x8000_0380.
+ ***********************************************************************/
+
+LEAF(bmips_smp_movevec)
+ la k0, 1f
+ li k1, CKSEG1
+ or k0, k1
+ jr k0
+
+1:
+ /* clear IV, pending IPIs */
+ mtc0 zero, CP0_CAUSE
+
+ /* re-enable IRQs to wait for SW1 */
+ li k0, ST0_IE | ST0_BEV | STATUSF_IP1
+ mtc0 k0, CP0_STATUS
+
+ /* set up CPU1 CBR; move BASE to 0xa000_0000 */
+ li k0, 0xff400000
+ mtc0 k0, $22, 6
+ li k1, CKSEG1 | BMIPS_RELO_VECTOR_CONTROL_1
+ or k0, k1
+ li k1, 0xa0080000
+ sw k1, 0(k0)
+
+ /* wait here for SW1 interrupt from bmips_boot_secondary() */
+ wait
+
+ la k0, bmips_reset_nmi_vec
+ li k1, CKSEG1
+ or k0, k1
+ jr k0
+END(bmips_smp_movevec)
+
+/***********************************************************************
+ * Reset/NMI vector
+ * For BMIPS processors that can relocate their exception vectors, this
+ * entire function gets copied to 0x8000_0000.
+ ***********************************************************************/
+
+NESTED(bmips_reset_nmi_vec, PT_SIZE, sp)
+ .set push
+ .set noat
+ .align 4
+
+#ifdef CONFIG_SMP
+ /* if the NMI bit is clear, assume this is a CPU1 reset instead */
+ li k1, (1 << 19)
+ mfc0 k0, CP0_STATUS
+ and k0, k1
+ beqz k0, bmips_smp_entry
+
+#if defined(CONFIG_CPU_BMIPS5000)
+ /* if we're not on core 0, this must be the SMP boot signal */
+ li k1, (3 << 25)
+ mfc0 k0, $22
+ and k0, k1
+ bnez k0, bmips_smp_entry
+#endif
+#endif /* CONFIG_SMP */
+
+ /* nope, it's just a regular NMI */
+ SAVE_ALL
+ move a0, sp
+
+ /* clear EXL, ERL, BEV so that TLB refills still work */
+ mfc0 k0, CP0_STATUS
+ li k1, ST0_ERL | ST0_EXL | ST0_BEV | ST0_IE
+ or k0, k1
+ xor k0, k1
+ mtc0 k0, CP0_STATUS
+ BARRIER
+
+ /* jump to the NMI handler function */
+ la k0, nmi_handler
+ jr k0
+
+ RESTORE_ALL
+ .set mips3
+ eret
+
+/***********************************************************************
+ * CPU1 reset vector (used for the initial boot only)
+ * This is still part of bmips_reset_nmi_vec().
+ ***********************************************************************/
+
+#ifdef CONFIG_SMP
+
+bmips_smp_entry:
+
+ /* set up CP0 STATUS; enable FPU */
+ li k0, 0x30000000
+ mtc0 k0, CP0_STATUS
+ BARRIER
+
+ /* set local CP0 CONFIG to make kseg0 cacheable, write-back */
+ mfc0 k0, CP0_CONFIG
+ ori k0, 0x07
+ xori k0, 0x04
+ mtc0 k0, CP0_CONFIG
+
+#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
+ /* initialize CPU1's local I-cache */
+ li k0, 0x80000000
+ li k1, 0x80010000
+ mtc0 zero, $28
+ mtc0 zero, $28, 1
+ BARRIER
+
+1: cache Index_Store_Tag_I, 0(k0)
+ addiu k0, 16
+ bne k0, k1, 1b
+#elif defined(CONFIG_CPU_BMIPS5000)
+ /* set exception vector base */
+ la k0, ebase
+ lw k0, 0(k0)
+ mtc0 k0, $15, 1
+ BARRIER
+#endif
+
+ /* jump back to kseg0 in case we need to remap the kseg1 area */
+ la k0, 1f
+ jr k0
+1:
+ la k0, bmips_enable_xks01
+ jalr k0
+
+ /* use temporary stack to set up upper memory TLB */
+ li sp, BMIPS_WARM_RESTART_VEC
+ la k0, plat_wired_tlb_setup
+ jalr k0
+
+ /* switch to permanent stack and continue booting */
+
+ .global bmips_secondary_reentry
+bmips_secondary_reentry:
+ la k0, bmips_smp_boot_sp
+ lw sp, 0(k0)
+ la k0, bmips_smp_boot_gp
+ lw gp, 0(k0)
+ la k0, start_secondary
+ jr k0
+
+#endif /* CONFIG_SMP */
+
+ .align 4
+ .global bmips_reset_nmi_vec_end
+bmips_reset_nmi_vec_end:
+
+END(bmips_reset_nmi_vec)
+
+ .set pop
+ .previous
+
+/***********************************************************************
+ * CPU1 warm restart vector (used for second and subsequent boots).
+ * Also used for S2 standby recovery (PM).
+ * This entire function gets copied to (BMIPS_WARM_RESTART_VEC)
+ ***********************************************************************/
+
+LEAF(bmips_smp_int_vec)
+
+ .align 4
+ mfc0 k0, CP0_STATUS
+ ori k0, 0x01
+ xori k0, 0x01
+ mtc0 k0, CP0_STATUS
+ eret
+
+ .align 4
+ .global bmips_smp_int_vec_end
+bmips_smp_int_vec_end:
+
+END(bmips_smp_int_vec)
+
+/***********************************************************************
+ * XKS01 support
+ * Certain CPUs support extending kseg0 to 1024MB.
+ ***********************************************************************/
+
+ __CPUINIT
+
+LEAF(bmips_enable_xks01)
+
+#if defined(CONFIG_XKS01)
+
+#if defined(CONFIG_CPU_BMIPS4380)
+ mfc0 t0, $22, 3
+ li t1, 0x1ff0
+ li t2, (1 << 12) | (1 << 9)
+ or t0, t1
+ xor t0, t1
+ or t0, t2
+ mtc0 t0, $22, 3
+ BARRIER
+#elif defined(CONFIG_CPU_BMIPS5000)
+ mfc0 t0, $22, 5
+ li t1, 0x01ff
+ li t2, (1 << 8) | (1 << 5)
+ or t0, t1
+ xor t0, t1
+ or t0, t2
+ mtc0 t0, $22, 5
+ BARRIER
+#else
+
+#error Missing XKS01 setup
+
+#endif
+
+#endif /* defined(CONFIG_XKS01) */
+
+ jr ra
+
+END(bmips_enable_xks01)
+
+ .previous
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 32103cc2a257..4d735d0e58f5 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -9,6 +9,7 @@
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/signal.h>
+#include <linux/module.h>
#include <asm/branch.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
@@ -17,28 +18,22 @@
#include <asm/ptrace.h>
#include <asm/uaccess.h>
-/*
- * Compute the return address and do emulate branch simulation, if required.
+/**
+ * __compute_return_epc_for_insn - Computes the return address and do emulate
+ * branch simulation, if required.
+ *
+ * @regs: Pointer to pt_regs
+ * @insn: branch instruction to decode
+ * @returns: -EFAULT on error and forces SIGBUS, and on success
+ * returns 0 or BRANCH_LIKELY_TAKEN as appropriate after
+ * evaluating the branch.
*/
-int __compute_return_epc(struct pt_regs *regs)
+int __compute_return_epc_for_insn(struct pt_regs *regs,
+ union mips_instruction insn)
{
- unsigned int __user *addr;
unsigned int bit, fcr31, dspcontrol;
- long epc;
- union mips_instruction insn;
-
- epc = regs->cp0_epc;
- if (epc & 3)
- goto unaligned;
-
- /*
- * Read the instruction
- */
- addr = (unsigned int __user *) epc;
- if (__get_user(insn.word, addr)) {
- force_sig(SIGSEGV, current);
- return -EFAULT;
- }
+ long epc = regs->cp0_epc;
+ int ret = 0;
switch (insn.i_format.opcode) {
/*
@@ -64,18 +59,22 @@ int __compute_return_epc(struct pt_regs *regs)
switch (insn.i_format.rt) {
case bltz_op:
case bltzl_op:
- if ((long)regs->regs[insn.i_format.rs] < 0)
+ if ((long)regs->regs[insn.i_format.rs] < 0) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == bltzl_op)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
case bgez_op:
case bgezl_op:
- if ((long)regs->regs[insn.i_format.rs] >= 0)
+ if ((long)regs->regs[insn.i_format.rs] >= 0) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == bgezl_op)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
@@ -83,9 +82,11 @@ int __compute_return_epc(struct pt_regs *regs)
case bltzal_op:
case bltzall_op:
regs->regs[31] = epc + 8;
- if ((long)regs->regs[insn.i_format.rs] < 0)
+ if ((long)regs->regs[insn.i_format.rs] < 0) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == bltzall_op)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
@@ -93,12 +94,15 @@ int __compute_return_epc(struct pt_regs *regs)
case bgezal_op:
case bgezall_op:
regs->regs[31] = epc + 8;
- if ((long)regs->regs[insn.i_format.rs] >= 0)
+ if ((long)regs->regs[insn.i_format.rs] >= 0) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == bgezall_op)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
+
case bposge32_op:
if (!cpu_has_dsp)
goto sigill;
@@ -133,9 +137,11 @@ int __compute_return_epc(struct pt_regs *regs)
case beq_op:
case beql_op:
if (regs->regs[insn.i_format.rs] ==
- regs->regs[insn.i_format.rt])
+ regs->regs[insn.i_format.rt]) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == beql_op)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
@@ -143,9 +149,11 @@ int __compute_return_epc(struct pt_regs *regs)
case bne_op:
case bnel_op:
if (regs->regs[insn.i_format.rs] !=
- regs->regs[insn.i_format.rt])
+ regs->regs[insn.i_format.rt]) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == bnel_op)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
@@ -153,9 +161,11 @@ int __compute_return_epc(struct pt_regs *regs)
case blez_op: /* not really i_format */
case blezl_op:
/* rt field assumed to be zero */
- if ((long)regs->regs[insn.i_format.rs] <= 0)
+ if ((long)regs->regs[insn.i_format.rs] <= 0) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == bnel_op)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
@@ -163,9 +173,11 @@ int __compute_return_epc(struct pt_regs *regs)
case bgtz_op:
case bgtzl_op:
/* rt field assumed to be zero */
- if ((long)regs->regs[insn.i_format.rs] > 0)
+ if ((long)regs->regs[insn.i_format.rs] > 0) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == bnel_op)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
@@ -187,18 +199,22 @@ int __compute_return_epc(struct pt_regs *regs)
switch (insn.i_format.rt & 3) {
case 0: /* bc1f */
case 2: /* bc1fl */
- if (~fcr31 & (1 << bit))
+ if (~fcr31 & (1 << bit)) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == 2)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
case 1: /* bc1t */
case 3: /* bc1tl */
- if (fcr31 & (1 << bit))
+ if (fcr31 & (1 << bit)) {
epc = epc + 4 + (insn.i_format.simmediate << 2);
- else
+ if (insn.i_format.rt == 3)
+ ret = BRANCH_LIKELY_TAKEN;
+ } else
epc += 8;
regs->cp0_epc = epc;
break;
@@ -239,15 +255,39 @@ int __compute_return_epc(struct pt_regs *regs)
#endif
}
- return 0;
+ return ret;
-unaligned:
- printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
+sigill:
+ printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
force_sig(SIGBUS, current);
return -EFAULT;
+}
+EXPORT_SYMBOL_GPL(__compute_return_epc_for_insn);
-sigill:
- printk("%s: DSP branch but not DSP ASE - sending SIGBUS.\n", current->comm);
+int __compute_return_epc(struct pt_regs *regs)
+{
+ unsigned int __user *addr;
+ long epc;
+ union mips_instruction insn;
+
+ epc = regs->cp0_epc;
+ if (epc & 3)
+ goto unaligned;
+
+ /*
+ * Read the instruction
+ */
+ addr = (unsigned int __user *) epc;
+ if (__get_user(insn.word, addr)) {
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+ }
+
+ return __compute_return_epc_for_insn(regs, insn);
+
+unaligned:
+ printk("%s: unaligned epc - sending SIGBUS.\n", current->comm);
force_sig(SIGBUS, current);
return -EFAULT;
+
}
diff --git a/arch/mips/kernel/cevt-bcm1480.c b/arch/mips/kernel/cevt-bcm1480.c
index 36c3898b76db..69bbfae183bc 100644
--- a/arch/mips/kernel/cevt-bcm1480.c
+++ b/arch/mips/kernel/cevt-bcm1480.c
@@ -145,7 +145,7 @@ void __cpuinit sb1480_clockevent_init(void)
bcm1480_unmask_irq(cpu, irq);
action->handler = sibyte_counter_handler;
- action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER;
+ action->flags = IRQF_PERCPU | IRQF_TIMER;
action->name = name;
action->dev_id = cd;
diff --git a/arch/mips/kernel/cevt-ds1287.c b/arch/mips/kernel/cevt-ds1287.c
index 939157e397b9..ed648cb5a69f 100644
--- a/arch/mips/kernel/cevt-ds1287.c
+++ b/arch/mips/kernel/cevt-ds1287.c
@@ -108,7 +108,7 @@ static irqreturn_t ds1287_interrupt(int irq, void *dev_id)
static struct irqaction ds1287_irqaction = {
.handler = ds1287_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
.name = "ds1287",
};
diff --git a/arch/mips/kernel/cevt-gt641xx.c b/arch/mips/kernel/cevt-gt641xx.c
index 339f3639b90e..831b47585b7c 100644
--- a/arch/mips/kernel/cevt-gt641xx.c
+++ b/arch/mips/kernel/cevt-gt641xx.c
@@ -114,7 +114,7 @@ static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
static struct irqaction gt641xx_timer0_irqaction = {
.handler = gt641xx_timer0_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
.name = "gt641xx_timer0",
};
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index e2d8e199be32..51095dd9599d 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -84,7 +84,7 @@ out:
struct irqaction c0_compare_irqaction = {
.handler = c0_compare_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
.name = "timer",
};
diff --git a/arch/mips/kernel/cevt-sb1250.c b/arch/mips/kernel/cevt-sb1250.c
index 590c54f28a81..e73439fd6850 100644
--- a/arch/mips/kernel/cevt-sb1250.c
+++ b/arch/mips/kernel/cevt-sb1250.c
@@ -144,7 +144,7 @@ void __cpuinit sb1250_clockevent_init(void)
sb1250_unmask_irq(cpu, irq);
action->handler = sibyte_counter_handler;
- action->flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER;
+ action->flags = IRQF_PERCPU | IRQF_TIMER;
action->name = name;
action->dev_id = cd;
diff --git a/arch/mips/kernel/cevt-txx9.c b/arch/mips/kernel/cevt-txx9.c
index f0ab92a1b057..e5c30b1d0860 100644
--- a/arch/mips/kernel/cevt-txx9.c
+++ b/arch/mips/kernel/cevt-txx9.c
@@ -146,7 +146,7 @@ static irqreturn_t txx9tmr_interrupt(int irq, void *dev_id)
static struct irqaction txx9tmr_irq = {
.handler = txx9tmr_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
.name = "txx9tmr",
.dev_id = &txx9_clock_event_device,
};
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index c7d3cf1ce46e..0bab464b8e33 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -191,6 +191,8 @@ void __init check_wait(void)
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
case CPU_JZRISC:
+ case CPU_XLR:
+ case CPU_XLP:
cpu_wait = r4k_wait;
break;
@@ -1014,6 +1016,13 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
{
decode_configs(c);
+ if ((c->processor_id & 0xff00) == PRID_IMP_NETLOGIC_AU13XX) {
+ c->cputype = CPU_ALCHEMY;
+ __cpu_name[cpu] = "Au1300";
+ /* following stuff is not for Alchemy */
+ return;
+ }
+
c->options = (MIPS_CPU_TLB |
MIPS_CPU_4KEX |
MIPS_CPU_COUNTER |
@@ -1023,6 +1032,12 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
MIPS_CPU_LLSC);
switch (c->processor_id & 0xff00) {
+ case PRID_IMP_NETLOGIC_XLP8XX:
+ case PRID_IMP_NETLOGIC_XLP3XX:
+ c->cputype = CPU_XLP;
+ __cpu_name[cpu] = "Netlogic XLP";
+ break;
+
case PRID_IMP_NETLOGIC_XLR732:
case PRID_IMP_NETLOGIC_XLR716:
case PRID_IMP_NETLOGIC_XLR532:
@@ -1053,14 +1068,21 @@ static inline void cpu_probe_netlogic(struct cpuinfo_mips *c, int cpu)
break;
default:
- printk(KERN_INFO "Unknown Netlogic chip id [%02x]!\n",
+ pr_info("Unknown Netlogic chip id [%02x]!\n",
c->processor_id);
c->cputype = CPU_XLR;
break;
}
- c->isa_level = MIPS_CPU_ISA_M64R1;
- c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
+ if (c->cputype == CPU_XLP) {
+ c->isa_level = MIPS_CPU_ISA_M64R2;
+ c->options |= (MIPS_CPU_FPU | MIPS_CPU_ULRI | MIPS_CPU_MCHECK);
+ /* This will be updated again after all threads are woken up */
+ c->tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
+ } else {
+ c->isa_level = MIPS_CPU_ISA_M64R1;
+ c->tlbsize = ((read_c0_config1() >> 25) & 0x3f) + 1;
+ }
}
#ifdef CONFIG_64BIT
diff --git a/arch/mips/kernel/i8253.c b/arch/mips/kernel/i8253.c
index 7047bff35ea5..c5bc344fc745 100644
--- a/arch/mips/kernel/i8253.c
+++ b/arch/mips/kernel/i8253.c
@@ -19,7 +19,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
static struct irqaction irq0 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
+ .flags = IRQF_NOBALANCING | IRQF_TIMER,
.name = "timer"
};
diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c
index ee28683fc2ac..158467da9bc1 100644
--- a/arch/mips/kernel/kprobes.c
+++ b/arch/mips/kernel/kprobes.c
@@ -25,10 +25,12 @@
#include <linux/kprobes.h>
#include <linux/preempt.h>
+#include <linux/uaccess.h>
#include <linux/kdebug.h>
#include <linux/slab.h>
#include <asm/ptrace.h>
+#include <asm/branch.h>
#include <asm/break.h>
#include <asm/inst.h>
@@ -112,17 +114,49 @@ insn_ok:
return 0;
}
+/*
+ * insn_has_ll_or_sc function checks whether instruction is ll or sc
+ * one; putting breakpoint on top of atomic ll/sc pair is bad idea;
+ * so we need to prevent it and refuse kprobes insertion for such
+ * instructions; cannot do much about breakpoint in the middle of
+ * ll/sc pair; it is upto user to avoid those places
+ */
+static int __kprobes insn_has_ll_or_sc(union mips_instruction insn)
+{
+ int ret = 0;
+
+ switch (insn.i_format.opcode) {
+ case ll_op:
+ case lld_op:
+ case sc_op:
+ case scd_op:
+ ret = 1;
+ break;
+ default:
+ break;
+ }
+ return ret;
+}
+
int __kprobes arch_prepare_kprobe(struct kprobe *p)
{
union mips_instruction insn;
union mips_instruction prev_insn;
int ret = 0;
- prev_insn = p->addr[-1];
insn = p->addr[0];
- if (insn_has_delayslot(insn) || insn_has_delayslot(prev_insn)) {
- pr_notice("Kprobes for branch and jump instructions are not supported\n");
+ if (insn_has_ll_or_sc(insn)) {
+ pr_notice("Kprobes for ll and sc instructions are not"
+ "supported\n");
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if ((probe_kernel_read(&prev_insn, p->addr - 1,
+ sizeof(mips_instruction)) == 0) &&
+ insn_has_delayslot(prev_insn)) {
+ pr_notice("Kprobes for branch delayslot are not supported\n");
ret = -EINVAL;
goto out;
}
@@ -138,9 +172,20 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
* In the kprobe->ainsn.insn[] array we store the original
* instruction at index zero and a break trap instruction at
* index one.
+ *
+ * On MIPS arch if the instruction at probed address is a
+ * branch instruction, we need to execute the instruction at
+ * Branch Delayslot (BD) at the time of probe hit. As MIPS also
+ * doesn't have single stepping support, the BD instruction can
+ * not be executed in-line and it would be executed on SSOL slot
+ * using a normal breakpoint instruction in the next slot.
+ * So, read the instruction and save it for later execution.
*/
+ if (insn_has_delayslot(insn))
+ memcpy(&p->ainsn.insn[0], p->addr + 1, sizeof(kprobe_opcode_t));
+ else
+ memcpy(&p->ainsn.insn[0], p->addr, sizeof(kprobe_opcode_t));
- memcpy(&p->ainsn.insn[0], p->addr, sizeof(kprobe_opcode_t));
p->ainsn.insn[1] = breakpoint2_insn;
p->opcode = *p->addr;
@@ -191,16 +236,96 @@ static void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
kcb->kprobe_saved_epc = regs->cp0_epc;
}
-static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+/**
+ * evaluate_branch_instrucion -
+ *
+ * Evaluate the branch instruction at probed address during probe hit. The
+ * result of evaluation would be the updated epc. The insturction in delayslot
+ * would actually be single stepped using a normal breakpoint) on SSOL slot.
+ *
+ * The result is also saved in the kprobe control block for later use,
+ * in case we need to execute the delayslot instruction. The latter will be
+ * false for NOP instruction in dealyslot and the branch-likely instructions
+ * when the branch is taken. And for those cases we set a flag as
+ * SKIP_DELAYSLOT in the kprobe control block
+ */
+static int evaluate_branch_instruction(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
{
+ union mips_instruction insn = p->opcode;
+ long epc;
+ int ret = 0;
+
+ epc = regs->cp0_epc;
+ if (epc & 3)
+ goto unaligned;
+
+ if (p->ainsn.insn->word == 0)
+ kcb->flags |= SKIP_DELAYSLOT;
+ else
+ kcb->flags &= ~SKIP_DELAYSLOT;
+
+ ret = __compute_return_epc_for_insn(regs, insn);
+ if (ret < 0)
+ return ret;
+
+ if (ret == BRANCH_LIKELY_TAKEN)
+ kcb->flags |= SKIP_DELAYSLOT;
+
+ kcb->target_epc = regs->cp0_epc;
+
+ return 0;
+
+unaligned:
+ pr_notice("%s: unaligned epc - sending SIGBUS.\n", current->comm);
+ force_sig(SIGBUS, current);
+ return -EFAULT;
+
+}
+
+static void prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
+{
+ int ret = 0;
+
regs->cp0_status &= ~ST0_IE;
/* single step inline if the instruction is a break */
if (p->opcode.word == breakpoint_insn.word ||
p->opcode.word == breakpoint2_insn.word)
regs->cp0_epc = (unsigned long)p->addr;
- else
- regs->cp0_epc = (unsigned long)&p->ainsn.insn[0];
+ else if (insn_has_delayslot(p->opcode)) {
+ ret = evaluate_branch_instruction(p, regs, kcb);
+ if (ret < 0) {
+ pr_notice("Kprobes: Error in evaluating branch\n");
+ return;
+ }
+ }
+ regs->cp0_epc = (unsigned long)&p->ainsn.insn[0];
+}
+
+/*
+ * Called after single-stepping. p->addr is the address of the
+ * instruction whose first byte has been replaced by the "break 0"
+ * instruction. To avoid the SMP problems that can occur when we
+ * temporarily put back the original opcode to single-step, we
+ * single-stepped a copy of the instruction. The address of this
+ * copy is p->ainsn.insn.
+ *
+ * This function prepares to return from the post-single-step
+ * breakpoint trap. In case of branch instructions, the target
+ * epc to be restored.
+ */
+static void __kprobes resume_execution(struct kprobe *p,
+ struct pt_regs *regs,
+ struct kprobe_ctlblk *kcb)
+{
+ if (insn_has_delayslot(p->opcode))
+ regs->cp0_epc = kcb->target_epc;
+ else {
+ unsigned long orig_epc = kcb->kprobe_saved_epc;
+ regs->cp0_epc = orig_epc + 4;
+ }
}
static int __kprobes kprobe_handler(struct pt_regs *regs)
@@ -239,8 +364,13 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
save_previous_kprobe(kcb);
set_current_kprobe(p, regs, kcb);
kprobes_inc_nmissed_count(p);
- prepare_singlestep(p, regs);
+ prepare_singlestep(p, regs, kcb);
kcb->kprobe_status = KPROBE_REENTER;
+ if (kcb->flags & SKIP_DELAYSLOT) {
+ resume_execution(p, regs, kcb);
+ restore_previous_kprobe(kcb);
+ preempt_enable_no_resched();
+ }
return 1;
} else {
if (addr->word != breakpoint_insn.word) {
@@ -284,8 +414,16 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
}
ss_probe:
- prepare_singlestep(p, regs);
- kcb->kprobe_status = KPROBE_HIT_SS;
+ prepare_singlestep(p, regs, kcb);
+ if (kcb->flags & SKIP_DELAYSLOT) {
+ kcb->kprobe_status = KPROBE_HIT_SSDONE;
+ if (p->post_handler)
+ p->post_handler(p, regs, 0);
+ resume_execution(p, regs, kcb);
+ preempt_enable_no_resched();
+ } else
+ kcb->kprobe_status = KPROBE_HIT_SS;
+
return 1;
no_kprobe:
@@ -294,25 +432,6 @@ no_kprobe:
}
-/*
- * Called after single-stepping. p->addr is the address of the
- * instruction whose first byte has been replaced by the "break 0"
- * instruction. To avoid the SMP problems that can occur when we
- * temporarily put back the original opcode to single-step, we
- * single-stepped a copy of the instruction. The address of this
- * copy is p->ainsn.insn.
- *
- * This function prepares to return from the post-single-step
- * breakpoint trap.
- */
-static void __kprobes resume_execution(struct kprobe *p,
- struct pt_regs *regs,
- struct kprobe_ctlblk *kcb)
-{
- unsigned long orig_epc = kcb->kprobe_saved_epc;
- regs->cp0_epc = orig_epc + 4;
-}
-
static inline int post_kprobe_handler(struct pt_regs *regs)
{
struct kprobe *cur = kprobe_running();
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index 315fc0b250f8..e3b897acfbc0 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -621,11 +621,6 @@ static int mipspmu_event_init(struct perf_event *event)
return -ENODEV;
if (!atomic_inc_not_zero(&active_events)) {
- if (atomic_read(&active_events) > MIPS_MAX_HWEVENTS) {
- atomic_dec(&active_events);
- return -EINVAL;
- }
-
mutex_lock(&pmu_reserve_mutex);
if (atomic_read(&active_events) == 0)
err = mipspmu_get_irq();
@@ -638,11 +633,7 @@ static int mipspmu_event_init(struct perf_event *event)
if (err)
return err;
- err = __hw_perf_event_init(event);
- if (err)
- hw_perf_event_destroy(event);
-
- return err;
+ return __hw_perf_event_init(event);
}
static struct pmu pmu = {
@@ -712,18 +703,6 @@ static const struct mips_perf_event *mipspmu_map_cache_event(u64 config)
}
-static int validate_event(struct cpu_hw_events *cpuc,
- struct perf_event *event)
-{
- struct hw_perf_event fake_hwc = event->hw;
-
- /* Allow mixed event group. So return 1 to pass validation. */
- if (event->pmu != &pmu || event->state <= PERF_EVENT_STATE_OFF)
- return 1;
-
- return mipsxx_pmu_alloc_counter(cpuc, &fake_hwc) >= 0;
-}
-
static int validate_group(struct perf_event *event)
{
struct perf_event *sibling, *leader = event->group_leader;
@@ -731,15 +710,15 @@ static int validate_group(struct perf_event *event)
memset(&fake_cpuc, 0, sizeof(fake_cpuc));
- if (!validate_event(&fake_cpuc, leader))
+ if (mipsxx_pmu_alloc_counter(&fake_cpuc, &leader->hw) < 0)
return -EINVAL;
list_for_each_entry(sibling, &leader->sibling_list, group_entry) {
- if (!validate_event(&fake_cpuc, sibling))
+ if (mipsxx_pmu_alloc_counter(&fake_cpuc, &sibling->hw) < 0)
return -EINVAL;
}
- if (!validate_event(&fake_cpuc, event))
+ if (mipsxx_pmu_alloc_counter(&fake_cpuc, &event->hw) < 0)
return -EINVAL;
return 0;
@@ -1279,13 +1258,14 @@ static int __hw_perf_event_init(struct perf_event *event)
}
err = 0;
- if (event->group_leader != event) {
+ if (event->group_leader != event)
err = validate_group(event);
- if (err)
- return -EINVAL;
- }
event->destroy = hw_perf_event_destroy;
+
+ if (err)
+ event->destroy(event);
+
return err;
}
@@ -1380,20 +1360,10 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
}
/* 24K */
-#define IS_UNSUPPORTED_24K_EVENT(r, b) \
- ((b) == 12 || (r) == 151 || (r) == 152 || (b) == 26 || \
- (b) == 27 || (r) == 28 || (r) == 158 || (b) == 31 || \
- (b) == 32 || (b) == 34 || (b) == 36 || (r) == 168 || \
- (r) == 172 || (b) == 47 || ((b) >= 56 && (b) <= 63) || \
- ((b) >= 68 && (b) <= 127))
#define IS_BOTH_COUNTERS_24K_EVENT(b) \
((b) == 0 || (b) == 1 || (b) == 11)
/* 34K */
-#define IS_UNSUPPORTED_34K_EVENT(r, b) \
- ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 36 || \
- (b) == 38 || (r) == 175 || ((b) >= 56 && (b) <= 63) || \
- ((b) >= 68 && (b) <= 127))
#define IS_BOTH_COUNTERS_34K_EVENT(b) \
((b) == 0 || (b) == 1 || (b) == 11)
#ifdef CONFIG_MIPS_MT_SMP
@@ -1406,20 +1376,10 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev)
#endif
/* 74K */
-#define IS_UNSUPPORTED_74K_EVENT(r, b) \
- ((r) == 5 || ((r) >= 135 && (r) <= 137) || \
- ((b) >= 10 && (b) <= 12) || (b) == 22 || (b) == 27 || \
- (b) == 33 || (b) == 34 || ((b) >= 47 && (b) <= 49) || \
- (r) == 178 || (b) == 55 || (b) == 57 || (b) == 60 || \
- (b) == 61 || (r) == 62 || (r) == 191 || \
- ((b) >= 64 && (b) <= 127))
#define IS_BOTH_COUNTERS_74K_EVENT(b) \
((b) == 0 || (b) == 1)
/* 1004K */
-#define IS_UNSUPPORTED_1004K_EVENT(r, b) \
- ((b) == 12 || (r) == 27 || (r) == 158 || (b) == 38 || \
- (r) == 175 || (b) == 63 || ((b) >= 68 && (b) <= 127))
#define IS_BOTH_COUNTERS_1004K_EVENT(b) \
((b) == 0 || (b) == 1 || (b) == 11)
#ifdef CONFIG_MIPS_MT_SMP
@@ -1445,11 +1405,10 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
unsigned int raw_id = config & 0xff;
unsigned int base_id = raw_id & 0x7f;
+ raw_event.event_id = base_id;
+
switch (current_cpu_type()) {
case CPU_24K:
- if (IS_UNSUPPORTED_24K_EVENT(raw_id, base_id))
- return ERR_PTR(-EOPNOTSUPP);
- raw_event.event_id = base_id;
if (IS_BOTH_COUNTERS_24K_EVENT(base_id))
raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
else
@@ -1464,9 +1423,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
#endif
break;
case CPU_34K:
- if (IS_UNSUPPORTED_34K_EVENT(raw_id, base_id))
- return ERR_PTR(-EOPNOTSUPP);
- raw_event.event_id = base_id;
if (IS_BOTH_COUNTERS_34K_EVENT(base_id))
raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
else
@@ -1482,9 +1438,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
#endif
break;
case CPU_74K:
- if (IS_UNSUPPORTED_74K_EVENT(raw_id, base_id))
- return ERR_PTR(-EOPNOTSUPP);
- raw_event.event_id = base_id;
if (IS_BOTH_COUNTERS_74K_EVENT(base_id))
raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
else
@@ -1495,9 +1448,6 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config)
#endif
break;
case CPU_1004K:
- if (IS_UNSUPPORTED_1004K_EVENT(raw_id, base_id))
- return ERR_PTR(-EOPNOTSUPP);
- raw_event.event_id = base_id;
if (IS_BOTH_COUNTERS_1004K_EVENT(base_id))
raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD;
else
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index 933166f44a6d..a9d801dec6b0 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -473,7 +473,6 @@ static const struct file_operations rtlx_fops = {
static struct irqaction rtlx_irq = {
.handler = rtlx_interrupt,
- .flags = IRQF_DISABLED,
.name = "RTLX",
};
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index b1cb8f87d7b4..058e964e7303 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -122,6 +122,9 @@ static void __init print_memory_map(void)
case BOOT_MEM_RAM:
printk(KERN_CONT "(usable)\n");
break;
+ case BOOT_MEM_INIT_RAM:
+ printk(KERN_CONT "(usable after init)\n");
+ break;
case BOOT_MEM_ROM_DATA:
printk(KERN_CONT "(ROM data)\n");
break;
@@ -362,15 +365,24 @@ static void __init bootmem_init(void)
for (i = 0; i < boot_mem_map.nr_map; i++) {
unsigned long start, end, size;
+ start = PFN_UP(boot_mem_map.map[i].addr);
+ end = PFN_DOWN(boot_mem_map.map[i].addr
+ + boot_mem_map.map[i].size);
+
/*
* Reserve usable memory.
*/
- if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ break;
+ case BOOT_MEM_INIT_RAM:
+ memory_present(0, start, end);
continue;
+ default:
+ /* Not usable memory */
+ continue;
+ }
- start = PFN_UP(boot_mem_map.map[i].addr);
- end = PFN_DOWN(boot_mem_map.map[i].addr
- + boot_mem_map.map[i].size);
/*
* We are rounding up the start address of usable memory
* and at the end of the usable range downwards.
@@ -456,11 +468,33 @@ early_param("mem", early_parse_mem);
static void __init arch_mem_init(char **cmdline_p)
{
+ phys_t init_mem, init_end, init_size;
+
extern void plat_mem_setup(void);
/* call board setup routine */
plat_mem_setup();
+ init_mem = PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT;
+ init_end = PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT;
+ init_size = init_end - init_mem;
+ if (init_size) {
+ /* Make sure it is in the boot_mem_map */
+ int i, found;
+ found = 0;
+ for (i = 0; i < boot_mem_map.nr_map; i++) {
+ if (init_mem >= boot_mem_map.map[i].addr &&
+ init_mem < (boot_mem_map.map[i].addr +
+ boot_mem_map.map[i].size)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ add_memory_region(init_mem, init_size,
+ BOOT_MEM_INIT_RAM);
+ }
+
pr_info("Determined physical RAM map:\n");
print_memory_map();
@@ -524,6 +558,7 @@ static void __init resource_init(void)
res = alloc_bootmem(sizeof(struct resource));
switch (boot_mem_map.map[i].type) {
case BOOT_MEM_RAM:
+ case BOOT_MEM_INIT_RAM:
case BOOT_MEM_ROM_DATA:
res->name = "System RAM";
break;
diff --git a/arch/mips/kernel/smp-bmips.c b/arch/mips/kernel/smp-bmips.c
new file mode 100644
index 000000000000..58fe71afd879
--- /dev/null
+++ b/arch/mips/kernel/smp-bmips.c
@@ -0,0 +1,458 @@
+/*
+ * 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.
+ *
+ * Copyright (C) 2011 by Kevin Cernekee (cernekee@gmail.com)
+ *
+ * SMP support for BMIPS
+ */
+
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/reboot.h>
+#include <linux/io.h>
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/bug.h>
+#include <linux/kernel.h>
+
+#include <asm/time.h>
+#include <asm/pgtable.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/bootinfo.h>
+#include <asm/pmon.h>
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/mipsregs.h>
+#include <asm/bmips.h>
+#include <asm/traps.h>
+#include <asm/barrier.h>
+
+static int __maybe_unused max_cpus = 1;
+
+/* these may be configured by the platform code */
+int bmips_smp_enabled = 1;
+int bmips_cpu_offset;
+cpumask_t bmips_booted_mask;
+
+#ifdef CONFIG_SMP
+
+/* initial $sp, $gp - used by arch/mips/kernel/bmips_vec.S */
+unsigned long bmips_smp_boot_sp;
+unsigned long bmips_smp_boot_gp;
+
+static void bmips_send_ipi_single(int cpu, unsigned int action);
+static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id);
+
+/* SW interrupts 0,1 are used for interprocessor signaling */
+#define IPI0_IRQ (MIPS_CPU_IRQ_BASE + 0)
+#define IPI1_IRQ (MIPS_CPU_IRQ_BASE + 1)
+
+#define CPUNUM(cpu, shift) (((cpu) + bmips_cpu_offset) << (shift))
+#define ACTION_CLR_IPI(cpu, ipi) (0x2000 | CPUNUM(cpu, 9) | ((ipi) << 8))
+#define ACTION_SET_IPI(cpu, ipi) (0x3000 | CPUNUM(cpu, 9) | ((ipi) << 8))
+#define ACTION_BOOT_THREAD(cpu) (0x08 | CPUNUM(cpu, 0))
+
+static void __init bmips_smp_setup(void)
+{
+ int i;
+
+#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
+ /* arbitration priority */
+ clear_c0_brcm_cmt_ctrl(0x30);
+
+ /* NBK and weak order flags */
+ set_c0_brcm_config_0(0x30000);
+
+ /*
+ * MIPS interrupts 0,1 (SW INT 0,1) cross over to the other thread
+ * MIPS interrupt 2 (HW INT 0) is the CPU0 L1 controller output
+ * MIPS interrupt 3 (HW INT 1) is the CPU1 L1 controller output
+ */
+ change_c0_brcm_cmt_intr(0xf8018000,
+ (0x02 << 27) | (0x03 << 15));
+
+ /* single core, 2 threads (2 pipelines) */
+ max_cpus = 2;
+#elif defined(CONFIG_CPU_BMIPS5000)
+ /* enable raceless SW interrupts */
+ set_c0_brcm_config(0x03 << 22);
+
+ /* route HW interrupt 0 to CPU0, HW interrupt 1 to CPU1 */
+ change_c0_brcm_mode(0x1f << 27, 0x02 << 27);
+
+ /* N cores, 2 threads per core */
+ max_cpus = (((read_c0_brcm_config() >> 6) & 0x03) + 1) << 1;
+
+ /* clear any pending SW interrupts */
+ for (i = 0; i < max_cpus; i++) {
+ write_c0_brcm_action(ACTION_CLR_IPI(i, 0));
+ write_c0_brcm_action(ACTION_CLR_IPI(i, 1));
+ }
+#endif
+
+ if (!bmips_smp_enabled)
+ max_cpus = 1;
+
+ /* this can be overridden by the BSP */
+ if (!board_ebase_setup)
+ board_ebase_setup = &bmips_ebase_setup;
+
+ for (i = 0; i < max_cpus; i++) {
+ __cpu_number_map[i] = 1;
+ __cpu_logical_map[i] = 1;
+ set_cpu_possible(i, 1);
+ set_cpu_present(i, 1);
+ }
+}
+
+/*
+ * IPI IRQ setup - runs on CPU0
+ */
+static void bmips_prepare_cpus(unsigned int max_cpus)
+{
+ if (request_irq(IPI0_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
+ "smp_ipi0", NULL))
+ panic("Can't request IPI0 interrupt\n");
+ if (request_irq(IPI1_IRQ, bmips_ipi_interrupt, IRQF_PERCPU,
+ "smp_ipi1", NULL))
+ panic("Can't request IPI1 interrupt\n");
+}
+
+/*
+ * Tell the hardware to boot CPUx - runs on CPU0
+ */
+static void bmips_boot_secondary(int cpu, struct task_struct *idle)
+{
+ bmips_smp_boot_sp = __KSTK_TOS(idle);
+ bmips_smp_boot_gp = (unsigned long)task_thread_info(idle);
+ mb();
+
+ /*
+ * Initial boot sequence for secondary CPU:
+ * bmips_reset_nmi_vec @ a000_0000 ->
+ * bmips_smp_entry ->
+ * plat_wired_tlb_setup (cached function call; optional) ->
+ * start_secondary (cached jump)
+ *
+ * Warm restart sequence:
+ * play_dead WAIT loop ->
+ * bmips_smp_int_vec @ BMIPS_WARM_RESTART_VEC ->
+ * eret to play_dead ->
+ * bmips_secondary_reentry ->
+ * start_secondary
+ */
+
+ pr_info("SMP: Booting CPU%d...\n", cpu);
+
+ if (cpumask_test_cpu(cpu, &bmips_booted_mask))
+ bmips_send_ipi_single(cpu, 0);
+ else {
+#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
+ set_c0_brcm_cmt_ctrl(0x01);
+#elif defined(CONFIG_CPU_BMIPS5000)
+ if (cpu & 0x01)
+ write_c0_brcm_action(ACTION_BOOT_THREAD(cpu));
+ else {
+ /*
+ * core N thread 0 was already booted; just
+ * pulse the NMI line
+ */
+ bmips_write_zscm_reg(0x210, 0xc0000000);
+ udelay(10);
+ bmips_write_zscm_reg(0x210, 0x00);
+ }
+#endif
+ cpumask_set_cpu(cpu, &bmips_booted_mask);
+ }
+}
+
+/*
+ * Early setup - runs on secondary CPU after cache probe
+ */
+static void bmips_init_secondary(void)
+{
+ /* move NMI vector to kseg0, in case XKS01 is enabled */
+
+#if defined(CONFIG_CPU_BMIPS4350) || defined(CONFIG_CPU_BMIPS4380)
+ void __iomem *cbr = BMIPS_GET_CBR();
+ unsigned long old_vec;
+
+ old_vec = __raw_readl(cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+ __raw_writel(old_vec & ~0x20000000, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+
+ clear_c0_cause(smp_processor_id() ? C_SW1 : C_SW0);
+#elif defined(CONFIG_CPU_BMIPS5000)
+ write_c0_brcm_bootvec(read_c0_brcm_bootvec() &
+ (smp_processor_id() & 0x01 ? ~0x20000000 : ~0x2000));
+
+ write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), 0));
+#endif
+
+ /* make sure there won't be a timer interrupt for a little while */
+ write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
+
+ irq_enable_hazard();
+ set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ1 | IE_IRQ5 | ST0_IE);
+ irq_enable_hazard();
+}
+
+/*
+ * Late setup - runs on secondary CPU before entering the idle loop
+ */
+static void bmips_smp_finish(void)
+{
+ pr_info("SMP: CPU%d is running\n", smp_processor_id());
+}
+
+/*
+ * Runs on CPU0 after all CPUs have been booted
+ */
+static void bmips_cpus_done(void)
+{
+}
+
+#if defined(CONFIG_CPU_BMIPS5000)
+
+/*
+ * BMIPS5000 raceless IPIs
+ *
+ * Each CPU has two inbound SW IRQs which are independent of all other CPUs.
+ * IPI0 is used for SMP_RESCHEDULE_YOURSELF
+ * IPI1 is used for SMP_CALL_FUNCTION
+ */
+
+static void bmips_send_ipi_single(int cpu, unsigned int action)
+{
+ write_c0_brcm_action(ACTION_SET_IPI(cpu, action == SMP_CALL_FUNCTION));
+}
+
+static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
+{
+ int action = irq - IPI0_IRQ;
+
+ write_c0_brcm_action(ACTION_CLR_IPI(smp_processor_id(), action));
+
+ if (action == 0)
+ scheduler_ipi();
+ else
+ smp_call_function_interrupt();
+
+ return IRQ_HANDLED;
+}
+
+#else
+
+/*
+ * BMIPS43xx racey IPIs
+ *
+ * We use one inbound SW IRQ for each CPU.
+ *
+ * A spinlock must be held in order to keep CPUx from accidentally clearing
+ * an incoming IPI when it writes CP0 CAUSE to raise an IPI on CPUy. The
+ * same spinlock is used to protect the action masks.
+ */
+
+static DEFINE_SPINLOCK(ipi_lock);
+static DEFINE_PER_CPU(int, ipi_action_mask);
+
+static void bmips_send_ipi_single(int cpu, unsigned int action)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ipi_lock, flags);
+ set_c0_cause(cpu ? C_SW1 : C_SW0);
+ per_cpu(ipi_action_mask, cpu) |= action;
+ irq_enable_hazard();
+ spin_unlock_irqrestore(&ipi_lock, flags);
+}
+
+static irqreturn_t bmips_ipi_interrupt(int irq, void *dev_id)
+{
+ unsigned long flags;
+ int action, cpu = irq - IPI0_IRQ;
+
+ spin_lock_irqsave(&ipi_lock, flags);
+ action = __get_cpu_var(ipi_action_mask);
+ per_cpu(ipi_action_mask, cpu) = 0;
+ clear_c0_cause(cpu ? C_SW1 : C_SW0);
+ spin_unlock_irqrestore(&ipi_lock, flags);
+
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ scheduler_ipi();
+ if (action & SMP_CALL_FUNCTION)
+ smp_call_function_interrupt();
+
+ return IRQ_HANDLED;
+}
+
+#endif /* BMIPS type */
+
+static void bmips_send_ipi_mask(const struct cpumask *mask,
+ unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu(i, mask)
+ bmips_send_ipi_single(i, action);
+}
+
+#ifdef CONFIG_HOTPLUG_CPU
+
+static int bmips_cpu_disable(void)
+{
+ unsigned int cpu = smp_processor_id();
+
+ if (cpu == 0)
+ return -EBUSY;
+
+ pr_info("SMP: CPU%d is offline\n", cpu);
+
+ cpu_clear(cpu, cpu_online_map);
+ cpu_clear(cpu, cpu_callin_map);
+
+ local_flush_tlb_all();
+ local_flush_icache_range(0, ~0);
+
+ return 0;
+}
+
+static void bmips_cpu_die(unsigned int cpu)
+{
+}
+
+void __ref play_dead(void)
+{
+ idle_task_exit();
+
+ /* flush data cache */
+ _dma_cache_wback_inv(0, ~0);
+
+ /*
+ * Wakeup is on SW0 or SW1; disable everything else
+ * Use BEV !IV (BMIPS_WARM_RESTART_VEC) to avoid the regular Linux
+ * IRQ handlers; this clears ST0_IE and returns immediately.
+ */
+ clear_c0_cause(CAUSEF_IV | C_SW0 | C_SW1);
+ change_c0_status(IE_IRQ5 | IE_IRQ1 | IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV,
+ IE_SW0 | IE_SW1 | ST0_IE | ST0_BEV);
+ irq_disable_hazard();
+
+ /*
+ * wait for SW interrupt from bmips_boot_secondary(), then jump
+ * back to start_secondary()
+ */
+ __asm__ __volatile__(
+ " wait\n"
+ " j bmips_secondary_reentry\n"
+ : : : "memory");
+}
+
+#endif /* CONFIG_HOTPLUG_CPU */
+
+struct plat_smp_ops bmips_smp_ops = {
+ .smp_setup = bmips_smp_setup,
+ .prepare_cpus = bmips_prepare_cpus,
+ .boot_secondary = bmips_boot_secondary,
+ .smp_finish = bmips_smp_finish,
+ .init_secondary = bmips_init_secondary,
+ .cpus_done = bmips_cpus_done,
+ .send_ipi_single = bmips_send_ipi_single,
+ .send_ipi_mask = bmips_send_ipi_mask,
+#ifdef CONFIG_HOTPLUG_CPU
+ .cpu_disable = bmips_cpu_disable,
+ .cpu_die = bmips_cpu_die,
+#endif
+};
+
+#endif /* CONFIG_SMP */
+
+/***********************************************************************
+ * BMIPS vector relocation
+ * This is primarily used for SMP boot, but it is applicable to some
+ * UP BMIPS systems as well.
+ ***********************************************************************/
+
+static void __cpuinit bmips_wr_vec(unsigned long dst, char *start, char *end)
+{
+ memcpy((void *)dst, start, end - start);
+ dma_cache_wback((unsigned long)start, end - start);
+ local_flush_icache_range(dst, dst + (end - start));
+ instruction_hazard();
+}
+
+static inline void __cpuinit bmips_nmi_handler_setup(void)
+{
+ bmips_wr_vec(BMIPS_NMI_RESET_VEC, &bmips_reset_nmi_vec,
+ &bmips_reset_nmi_vec_end);
+ bmips_wr_vec(BMIPS_WARM_RESTART_VEC, &bmips_smp_int_vec,
+ &bmips_smp_int_vec_end);
+}
+
+void __cpuinit bmips_ebase_setup(void)
+{
+ unsigned long new_ebase = ebase;
+ void __iomem __maybe_unused *cbr;
+
+ BUG_ON(ebase != CKSEG0);
+
+#if defined(CONFIG_CPU_BMIPS4350)
+ /*
+ * BMIPS4350 cannot relocate the normal vectors, but it
+ * can relocate the BEV=1 vectors. So CPU1 starts up at
+ * the relocated BEV=1, IV=0 general exception vector @
+ * 0xa000_0380.
+ *
+ * set_uncached_handler() is used here because:
+ * - CPU1 will run this from uncached space
+ * - None of the cacheflush functions are set up yet
+ */
+ set_uncached_handler(BMIPS_WARM_RESTART_VEC - CKSEG0,
+ &bmips_smp_int_vec, 0x80);
+ __sync();
+ return;
+#elif defined(CONFIG_CPU_BMIPS4380)
+ /*
+ * 0x8000_0000: reset/NMI (initially in kseg1)
+ * 0x8000_0400: normal vectors
+ */
+ new_ebase = 0x80000400;
+ cbr = BMIPS_GET_CBR();
+ __raw_writel(0x80080800, cbr + BMIPS_RELO_VECTOR_CONTROL_0);
+ __raw_writel(0xa0080800, cbr + BMIPS_RELO_VECTOR_CONTROL_1);
+#elif defined(CONFIG_CPU_BMIPS5000)
+ /*
+ * 0x8000_0000: reset/NMI (initially in kseg1)
+ * 0x8000_1000: normal vectors
+ */
+ new_ebase = 0x80001000;
+ write_c0_brcm_bootvec(0xa0088008);
+ write_c0_ebase(new_ebase);
+ if (max_cpus > 2)
+ bmips_write_zscm_reg(0xa0, 0xa008a008);
+#else
+ return;
+#endif
+ board_nmi_handler_setup = &bmips_nmi_handler_setup;
+ ebase = new_ebase;
+}
+
+asmlinkage void __weak plat_wired_tlb_setup(void)
+{
+ /*
+ * Called when starting/restarting a secondary CPU.
+ * Kernel stacks and other important data might only be accessible
+ * once the wired entries are present.
+ */
+}
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index f0895e70e283..0a42ff3ff6a1 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -559,7 +559,7 @@ void smtc_prepare_cpus(int cpus)
pipi = kmalloc(nipi *sizeof(struct smtc_ipi), GFP_KERNEL);
if (pipi == NULL)
- panic("kmalloc of IPI message buffers failed\n");
+ panic("kmalloc of IPI message buffers failed");
else
printk("IPI buffer pool of %d buffers\n", nipi);
for (i = 0; i < nipi; i++) {
@@ -813,7 +813,7 @@ void smtc_send_ipi(int cpu, int type, unsigned int action)
if (pipi == NULL) {
bust_spinlocks(1);
mips_mt_regdump(dvpe());
- panic("IPI Msg. Buffers Depleted\n");
+ panic("IPI Msg. Buffers Depleted");
}
pipi->type = type;
pipi->arg = (void *)action;
@@ -1130,7 +1130,7 @@ static void ipi_irq_dispatch(void)
static struct irqaction irq_ipi = {
.handler = ipi_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_PERCPU,
.name = "SMTC_IPI"
};
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index bbddb86c1fa1..cc4a3f120f54 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -91,6 +91,7 @@ int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
void (*board_nmi_handler_setup)(void);
void (*board_ejtag_handler_setup)(void);
void (*board_bind_eic_interrupt)(int irq, int regset);
+void (*board_ebase_setup)(void);
static void show_raw_backtrace(unsigned long reg29)
@@ -400,7 +401,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
panic("Fatal exception in interrupt");
if (panic_on_oops) {
- printk(KERN_EMERG "Fatal exception: panic in 5 seconds\n");
+ printk(KERN_EMERG "Fatal exception: panic in 5 seconds");
ssleep(5);
panic("Fatal exception");
}
@@ -1150,7 +1151,7 @@ asmlinkage void do_mt(struct pt_regs *regs)
asmlinkage void do_dsp(struct pt_regs *regs)
{
if (cpu_has_dsp)
- panic("Unexpected DSP exception\n");
+ panic("Unexpected DSP exception");
force_sig(SIGILL, current);
}
@@ -1339,9 +1340,18 @@ void ejtag_exception_handler(struct pt_regs *regs)
/*
* NMI exception handler.
+ * No lock; only written during early bootup by CPU 0.
*/
+static RAW_NOTIFIER_HEAD(nmi_chain);
+
+int register_nmi_notifier(struct notifier_block *nb)
+{
+ return raw_notifier_chain_register(&nmi_chain, nb);
+}
+
void __noreturn nmi_exception_handler(struct pt_regs *regs)
{
+ raw_notifier_call_chain(&nmi_chain, 0, regs);
bust_spinlocks(1);
printk("NMI taken!!!!\n");
die("NMI", regs);
@@ -1682,6 +1692,8 @@ void __init trap_init(void)
ebase += (read_c0_ebase() & 0x3ffff000);
}
+ if (board_ebase_setup)
+ board_ebase_setup();
per_cpu_trap_init();
/*
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
index 77ed70fc2fe5..412814fdd3ee 100644
--- a/arch/mips/lantiq/clk.c
+++ b/arch/mips/lantiq/clk.c
@@ -134,11 +134,11 @@ void __init plat_time_init(void)
struct clk *clk;
if (insert_resource(&iomem_resource, &ltq_cgu_resource) < 0)
- panic("Failed to insert cgu memory\n");
+ panic("Failed to insert cgu memory");
if (request_mem_region(ltq_cgu_resource.start,
resource_size(&ltq_cgu_resource), "cgu") < 0)
- panic("Failed to request cgu memory\n");
+ panic("Failed to request cgu memory");
ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start,
resource_size(&ltq_cgu_resource));
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c
index f9737bb3c5ab..d673731c538a 100644
--- a/arch/mips/lantiq/irq.c
+++ b/arch/mips/lantiq/irq.c
@@ -240,7 +240,6 @@ out:
static struct irqaction cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED,
.name = "cascade",
};
@@ -249,28 +248,28 @@ void __init arch_init_irq(void)
int i;
if (insert_resource(&iomem_resource, &ltq_icu_resource) < 0)
- panic("Failed to insert icu memory\n");
+ panic("Failed to insert icu memory");
if (request_mem_region(ltq_icu_resource.start,
resource_size(&ltq_icu_resource), "icu") < 0)
- panic("Failed to request icu memory\n");
+ panic("Failed to request icu memory");
ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start,
resource_size(&ltq_icu_resource));
if (!ltq_icu_membase)
- panic("Failed to remap icu memory\n");
+ panic("Failed to remap icu memory");
if (insert_resource(&iomem_resource, &ltq_eiu_resource) < 0)
- panic("Failed to insert eiu memory\n");
+ panic("Failed to insert eiu memory");
if (request_mem_region(ltq_eiu_resource.start,
resource_size(&ltq_eiu_resource), "eiu") < 0)
- panic("Failed to request eiu memory\n");
+ panic("Failed to request eiu memory");
ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start,
resource_size(&ltq_eiu_resource));
if (!ltq_eiu_membase)
- panic("Failed to remap eiu memory\n");
+ panic("Failed to remap eiu memory");
/* make sure all irqs are turned off by default */
for (i = 0; i < 5; i++)
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c
index cbb6ae5747b9..b210e936c7c3 100644
--- a/arch/mips/lantiq/xway/dma.c
+++ b/arch/mips/lantiq/xway/dma.c
@@ -222,17 +222,17 @@ ltq_dma_init(void)
/* insert and request the memory region */
if (insert_resource(&iomem_resource, &ltq_dma_resource) < 0)
- panic("Failed to insert dma memory\n");
+ panic("Failed to insert dma memory");
if (request_mem_region(ltq_dma_resource.start,
resource_size(&ltq_dma_resource), "dma") < 0)
- panic("Failed to request dma memory\n");
+ panic("Failed to request dma memory");
/* remap dma register range */
ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start,
resource_size(&ltq_dma_resource));
if (!ltq_dma_membase)
- panic("Failed to remap dma memory\n");
+ panic("Failed to remap dma memory");
/* power up and reset the dma engine */
ltq_pmu_enable(PMU_DMA);
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c
index 033b3184c7a7..862e3e830680 100644
--- a/arch/mips/lantiq/xway/ebu.c
+++ b/arch/mips/lantiq/xway/ebu.c
@@ -32,17 +32,17 @@ static int __init lantiq_ebu_init(void)
{
/* insert and request the memory region */
if (insert_resource(&iomem_resource, &ltq_ebu_resource) < 0)
- panic("Failed to insert ebu memory\n");
+ panic("Failed to insert ebu memory");
if (request_mem_region(ltq_ebu_resource.start,
resource_size(&ltq_ebu_resource), "ebu") < 0)
- panic("Failed to request ebu memory\n");
+ panic("Failed to request ebu memory");
/* remap ebu register range */
ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start,
resource_size(&ltq_ebu_resource));
if (!ltq_ebu_membase)
- panic("Failed to remap ebu memory\n");
+ panic("Failed to remap ebu memory");
/* make sure to unprotect the memory region where flash is located */
ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0);
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c
index 39f0d2641cbf..fe85361e032e 100644
--- a/arch/mips/lantiq/xway/pmu.c
+++ b/arch/mips/lantiq/xway/pmu.c
@@ -40,7 +40,7 @@ void ltq_pmu_enable(unsigned int module)
do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module));
if (!err)
- panic("activating PMU module failed!\n");
+ panic("activating PMU module failed!");
}
EXPORT_SYMBOL(ltq_pmu_enable);
@@ -53,16 +53,16 @@ EXPORT_SYMBOL(ltq_pmu_disable);
int __init ltq_pmu_init(void)
{
if (insert_resource(&iomem_resource, &ltq_pmu_resource) < 0)
- panic("Failed to insert pmu memory\n");
+ panic("Failed to insert pmu memory");
if (request_mem_region(ltq_pmu_resource.start,
resource_size(&ltq_pmu_resource), "pmu") < 0)
- panic("Failed to request pmu memory\n");
+ panic("Failed to request pmu memory");
ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start,
resource_size(&ltq_pmu_resource));
if (!ltq_pmu_membase)
- panic("Failed to remap pmu memory\n");
+ panic("Failed to remap pmu memory");
return 0;
}
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c
index 3d41f0bb5bf7..8b66bd87f0c1 100644
--- a/arch/mips/lantiq/xway/reset.c
+++ b/arch/mips/lantiq/xway/reset.c
@@ -69,17 +69,17 @@ static int __init mips_reboot_setup(void)
{
/* insert and request the memory region */
if (insert_resource(&iomem_resource, &ltq_rcu_resource) < 0)
- panic("Failed to insert rcu memory\n");
+ panic("Failed to insert rcu memory");
if (request_mem_region(ltq_rcu_resource.start,
resource_size(&ltq_rcu_resource), "rcu") < 0)
- panic("Failed to request rcu memory\n");
+ panic("Failed to request rcu memory");
/* remap rcu register range */
ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start,
resource_size(&ltq_rcu_resource));
if (!ltq_rcu_membase)
- panic("Failed to remap rcu memory\n");
+ panic("Failed to remap rcu memory");
_machine_restart = ltq_machine_restart;
_machine_halt = ltq_machine_halt;
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index b2cad4fd5fc4..2a7c74fc15fc 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o
obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += dump_tlb.o
obj-$(CONFIG_CPU_XLR) += dump_tlb.o
+obj-$(CONFIG_CPU_XLP) += dump_tlb.o
# libgcc-style stuff needed in the kernel
obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
index 0cb1b9760e34..5d1f48fa1a52 100644
--- a/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
+++ b/arch/mips/loongson/common/cs5536/cs5536_mfgpt.c
@@ -111,7 +111,7 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id)
static struct irqaction irq5 = {
.handler = timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_TIMER,
+ .flags = IRQF_NOBALANCING | IRQF_TIMER,
.name = "timer"
};
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
index dbf2f93a5091..a03bf00a1a9c 100644
--- a/arch/mips/math-emu/cp1emu.c
+++ b/arch/mips/math-emu/cp1emu.c
@@ -245,7 +245,7 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx,
*/
emulpc = xcp->cp0_epc + 4; /* Snapshot emulation target */
- if (__compute_return_epc(xcp)) {
+ if (__compute_return_epc(xcp) < 0) {
#ifdef CP1DBG
printk("failed to emulate branch at %p\n",
(void *) (xcp->cp0_epc));
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 4d8c1623eee2..4aa20280613e 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -3,8 +3,8 @@
#
obj-y += cache.o dma-default.o extable.o fault.o \
- init.o mmap.o tlbex.o tlbex-fault.o uasm.o \
- page.o
+ gup.o init.o mmap.o page.o tlbex.o \
+ tlbex-fault.o uasm.o
obj-$(CONFIG_32BIT) += ioremap.o pgtable-32.o
obj-$(CONFIG_64BIT) += pgtable-64.o
@@ -31,6 +31,7 @@ obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o
obj-$(CONFIG_CPU_XLR) += c-r4k.o tlb-r4k.o cex-gen.o
+obj-$(CONFIG_CPU_XLP) += c-r4k.o tlb-r4k.o cex-gen.o
obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c
index daa81f7284ac..cf7895db0739 100644
--- a/arch/mips/mm/c-octeon.c
+++ b/arch/mips/mm/c-octeon.c
@@ -223,7 +223,7 @@ static void __cpuinit probe_octeon(void)
break;
default:
- panic("Unsupported Cavium Networks CPU type\n");
+ panic("Unsupported Cavium Networks CPU type");
break;
}
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index a79fe9aa7721..4f9eb0b23036 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -1235,6 +1235,9 @@ static void __cpuinit setup_scache(void)
loongson2_sc_init();
return;
#endif
+ case CPU_XLP:
+ /* don't need to worry about L2, fully coherent */
+ return;
default:
if (c->isa_level == MIPS_CPU_ISA_M32R1 ||
diff --git a/arch/mips/mm/gup.c b/arch/mips/mm/gup.c
new file mode 100644
index 000000000000..33aadbcf170b
--- /dev/null
+++ b/arch/mips/mm/gup.c
@@ -0,0 +1,315 @@
+/*
+ * Lockless get_user_pages_fast for MIPS
+ *
+ * Copyright (C) 2008 Nick Piggin
+ * Copyright (C) 2008 Novell Inc.
+ * Copyright (C) 2011 Ralf Baechle
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/vmstat.h>
+#include <linux/highmem.h>
+#include <linux/swap.h>
+#include <linux/hugetlb.h>
+
+#include <asm/pgtable.h>
+
+static inline pte_t gup_get_pte(pte_t *ptep)
+{
+#if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32)
+ pte_t pte;
+
+retry:
+ pte.pte_low = ptep->pte_low;
+ smp_rmb();
+ pte.pte_high = ptep->pte_high;
+ smp_rmb();
+ if (unlikely(pte.pte_low != ptep->pte_low))
+ goto retry;
+
+ return pte;
+#else
+ return ACCESS_ONCE(*ptep);
+#endif
+}
+
+static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
+ int write, struct page **pages, int *nr)
+{
+ pte_t *ptep = pte_offset_map(&pmd, addr);
+ do {
+ pte_t pte = gup_get_pte(ptep);
+ struct page *page;
+
+ if (!pte_present(pte) ||
+ pte_special(pte) || (write && !pte_write(pte))) {
+ pte_unmap(ptep);
+ return 0;
+ }
+ VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+ page = pte_page(pte);
+ get_page(page);
+ SetPageReferenced(page);
+ pages[*nr] = page;
+ (*nr)++;
+
+ } while (ptep++, addr += PAGE_SIZE, addr != end);
+
+ pte_unmap(ptep - 1);
+ return 1;
+}
+
+static inline void get_head_page_multiple(struct page *page, int nr)
+{
+ VM_BUG_ON(page != compound_head(page));
+ VM_BUG_ON(page_count(page) == 0);
+ atomic_add(nr, &page->_count);
+ SetPageReferenced(page);
+}
+
+static int gup_huge_pmd(pmd_t pmd, unsigned long addr, unsigned long end,
+ int write, struct page **pages, int *nr)
+{
+ pte_t pte = *(pte_t *)&pmd;
+ struct page *head, *page;
+ int refs;
+
+ if (write && !pte_write(pte))
+ return 0;
+ /* hugepages are never "special" */
+ VM_BUG_ON(pte_special(pte));
+ VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+
+ refs = 0;
+ head = pte_page(pte);
+ page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT);
+ do {
+ VM_BUG_ON(compound_head(page) != head);
+ pages[*nr] = page;
+ if (PageTail(page))
+ get_huge_page_tail(page);
+ (*nr)++;
+ page++;
+ refs++;
+ } while (addr += PAGE_SIZE, addr != end);
+
+ get_head_page_multiple(head, refs);
+ return 1;
+}
+
+static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
+ int write, struct page **pages, int *nr)
+{
+ unsigned long next;
+ pmd_t *pmdp;
+
+ pmdp = pmd_offset(&pud, addr);
+ do {
+ pmd_t pmd = *pmdp;
+
+ next = pmd_addr_end(addr, end);
+ /*
+ * The pmd_trans_splitting() check below explains why
+ * pmdp_splitting_flush has to flush the tlb, to stop
+ * this gup-fast code from running while we set the
+ * splitting bit in the pmd. Returning zero will take
+ * the slow path that will call wait_split_huge_page()
+ * if the pmd is still in splitting state. gup-fast
+ * can't because it has irq disabled and
+ * wait_split_huge_page() would never return as the
+ * tlb flush IPI wouldn't run.
+ */
+ if (pmd_none(pmd) || pmd_trans_splitting(pmd))
+ return 0;
+ if (unlikely(pmd_huge(pmd))) {
+ if (!gup_huge_pmd(pmd, addr, next, write, pages,nr))
+ return 0;
+ } else {
+ if (!gup_pte_range(pmd, addr, next, write, pages,nr))
+ return 0;
+ }
+ } while (pmdp++, addr = next, addr != end);
+
+ return 1;
+}
+
+static int gup_huge_pud(pud_t pud, unsigned long addr, unsigned long end,
+ int write, struct page **pages, int *nr)
+{
+ pte_t pte = *(pte_t *)&pud;
+ struct page *head, *page;
+ int refs;
+
+ if (write && !pte_write(pte))
+ return 0;
+ /* hugepages are never "special" */
+ VM_BUG_ON(pte_special(pte));
+ VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
+
+ refs = 0;
+ head = pte_page(pte);
+ page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
+ do {
+ VM_BUG_ON(compound_head(page) != head);
+ pages[*nr] = page;
+ (*nr)++;
+ page++;
+ refs++;
+ } while (addr += PAGE_SIZE, addr != end);
+
+ get_head_page_multiple(head, refs);
+ return 1;
+}
+
+static int gup_pud_range(pgd_t pgd, unsigned long addr, unsigned long end,
+ int write, struct page **pages, int *nr)
+{
+ unsigned long next;
+ pud_t *pudp;
+
+ pudp = pud_offset(&pgd, addr);
+ do {
+ pud_t pud = *pudp;
+
+ next = pud_addr_end(addr, end);
+ if (pud_none(pud))
+ return 0;
+ if (unlikely(pud_huge(pud))) {
+ if (!gup_huge_pud(pud, addr, next, write, pages,nr))
+ return 0;
+ } else {
+ if (!gup_pmd_range(pud, addr, next, write, pages,nr))
+ return 0;
+ }
+ } while (pudp++, addr = next, addr != end);
+
+ return 1;
+}
+
+/*
+ * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
+ * back to the regular GUP.
+ */
+int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ struct page **pages)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long addr, len, end;
+ unsigned long next;
+ unsigned long flags;
+ pgd_t *pgdp;
+ int nr = 0;
+
+ start &= PAGE_MASK;
+ addr = start;
+ len = (unsigned long) nr_pages << PAGE_SHIFT;
+ end = start + len;
+ if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
+ (void __user *)start, len)))
+ return 0;
+
+ /*
+ * XXX: batch / limit 'nr', to avoid large irq off latency
+ * needs some instrumenting to determine the common sizes used by
+ * important workloads (eg. DB2), and whether limiting the batch
+ * size will decrease performance.
+ *
+ * It seems like we're in the clear for the moment. Direct-IO is
+ * the main guy that batches up lots of get_user_pages, and even
+ * they are limited to 64-at-a-time which is not so many.
+ */
+ /*
+ * This doesn't prevent pagetable teardown, but does prevent
+ * the pagetables and pages from being freed.
+ *
+ * So long as we atomically load page table pointers versus teardown,
+ * we can follow the address down to the page and take a ref on it.
+ */
+ local_irq_save(flags);
+ pgdp = pgd_offset(mm, addr);
+ do {
+ pgd_t pgd = *pgdp;
+
+ next = pgd_addr_end(addr, end);
+ if (pgd_none(pgd))
+ break;
+ if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
+ break;
+ } while (pgdp++, addr = next, addr != end);
+ local_irq_restore(flags);
+
+ return nr;
+}
+
+/**
+ * get_user_pages_fast() - pin user pages in memory
+ * @start: starting user address
+ * @nr_pages: number of pages from start to pin
+ * @write: whether pages will be written to
+ * @pages: array that receives pointers to the pages pinned.
+ * Should be at least nr_pages long.
+ *
+ * Attempt to pin user pages in memory without taking mm->mmap_sem.
+ * If not successful, it will fall back to taking the lock and
+ * calling get_user_pages().
+ *
+ * Returns number of pages pinned. This may be fewer than the number
+ * requested. If nr_pages is 0 or negative, returns 0. If no pages
+ * were pinned, returns -errno.
+ */
+int get_user_pages_fast(unsigned long start, int nr_pages, int write,
+ struct page **pages)
+{
+ struct mm_struct *mm = current->mm;
+ unsigned long addr, len, end;
+ unsigned long next;
+ pgd_t *pgdp;
+ int ret, nr = 0;
+
+ start &= PAGE_MASK;
+ addr = start;
+ len = (unsigned long) nr_pages << PAGE_SHIFT;
+
+ end = start + len;
+ if (end < start)
+ goto slow_irqon;
+
+ /* XXX: batch / limit 'nr' */
+ local_irq_disable();
+ pgdp = pgd_offset(mm, addr);
+ do {
+ pgd_t pgd = *pgdp;
+
+ next = pgd_addr_end(addr, end);
+ if (pgd_none(pgd))
+ goto slow;
+ if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
+ goto slow;
+ } while (pgdp++, addr = next, addr != end);
+ local_irq_enable();
+
+ VM_BUG_ON(nr != (end - start) >> PAGE_SHIFT);
+ return nr;
+slow:
+ local_irq_enable();
+
+slow_irqon:
+ /* Try to get the remaining pages with get_user_pages */
+ start += nr << PAGE_SHIFT;
+ pages += nr;
+
+ down_read(&mm->mmap_sem);
+ ret = get_user_pages(current, mm, start,
+ (end - start) >> PAGE_SHIFT,
+ write, 0, pages, NULL);
+ up_read(&mm->mmap_sem);
+
+ /* Have to be a bit careful with return values */
+ if (nr > 0) {
+ if (ret < 0)
+ ret = nr;
+ else
+ ret += nr;
+ }
+ return ret;
+}
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index b7ebc4fa89bc..3b3ffd439cd7 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -304,9 +304,14 @@ int page_is_ram(unsigned long pagenr)
for (i = 0; i < boot_mem_map.nr_map; i++) {
unsigned long addr, end;
- if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ case BOOT_MEM_INIT_RAM:
+ break;
+ default:
/* not usable memory */
continue;
+ }
addr = PFN_UP(boot_mem_map.map[i].addr);
end = PFN_DOWN(boot_mem_map.map[i].addr +
@@ -379,7 +384,7 @@ void __init mem_init(void)
reservedpages = ram = 0;
for (tmp = 0; tmp < max_low_pfn; tmp++)
- if (page_is_ram(tmp)) {
+ if (page_is_ram(tmp) && pfn_valid(tmp)) {
ram++;
if (PageReserved(pfn_to_page(tmp)))
reservedpages++;
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c
index 87bb85d8d537..ed1fa460f84e 100644
--- a/arch/mips/mm/tlb-r3k.c
+++ b/arch/mips/mm/tlb-r3k.c
@@ -20,6 +20,7 @@
#include <asm/pgtable.h>
#include <asm/mmu_context.h>
#include <asm/system.h>
+#include <asm/tlbmisc.h>
#include <asm/isadep.h>
#include <asm/io.h>
#include <asm/bootinfo.h>
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 0d394e0e8837..2dc625346c40 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -19,6 +19,7 @@
#include <asm/mmu_context.h>
#include <asm/pgtable.h>
#include <asm/system.h>
+#include <asm/tlbmisc.h>
extern void build_tlb_refill_handler(void);
@@ -120,22 +121,30 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
if (cpu_context(cpu, mm) != 0) {
unsigned long size, flags;
+ int huge = is_vm_hugetlb_page(vma);
ENTER_CRITICAL(flags);
- size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
- size = (size + 1) >> 1;
+ if (huge) {
+ start = round_down(start, HPAGE_SIZE);
+ end = round_up(end, HPAGE_SIZE);
+ size = (end - start) >> HPAGE_SHIFT;
+ } else {
+ start = round_down(start, PAGE_SIZE << 1);
+ end = round_up(end, PAGE_SIZE << 1);
+ size = (end - start) >> (PAGE_SHIFT + 1);
+ }
if (size <= current_cpu_data.tlbsize/2) {
int oldpid = read_c0_entryhi();
int newpid = cpu_asid(cpu, mm);
- start &= (PAGE_MASK << 1);
- end += ((PAGE_SIZE << 1) - 1);
- end &= (PAGE_MASK << 1);
while (start < end) {
int idx;
write_c0_entryhi(start | newpid);
- start += (PAGE_SIZE << 1);
+ if (huge)
+ start += HPAGE_SIZE;
+ else
+ start += (PAGE_SIZE << 1);
mtc0_tlbw_hazard();
tlb_probe();
tlb_probe_hazard();
@@ -368,51 +377,6 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1,
EXIT_CRITICAL(flags);
}
-/*
- * Used for loading TLB entries before trap_init() has started, when we
- * don't actually want to add a wired entry which remains throughout the
- * lifetime of the system
- */
-
-static int temp_tlb_entry __cpuinitdata;
-
-__init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1,
- unsigned long entryhi, unsigned long pagemask)
-{
- int ret = 0;
- unsigned long flags;
- unsigned long wired;
- unsigned long old_pagemask;
- unsigned long old_ctx;
-
- ENTER_CRITICAL(flags);
- /* Save old context and create impossible VPN2 value */
- old_ctx = read_c0_entryhi();
- old_pagemask = read_c0_pagemask();
- wired = read_c0_wired();
- if (--temp_tlb_entry < wired) {
- printk(KERN_WARNING
- "No TLB space left for add_temporary_entry\n");
- ret = -ENOSPC;
- goto out;
- }
-
- write_c0_index(temp_tlb_entry);
- write_c0_pagemask(pagemask);
- write_c0_entryhi(entryhi);
- write_c0_entrylo0(entrylo0);
- write_c0_entrylo1(entrylo1);
- mtc0_tlbw_hazard();
- tlb_write_indexed();
- tlbw_use_hazard();
-
- write_c0_entryhi(old_ctx);
- write_c0_pagemask(old_pagemask);
-out:
- EXIT_CRITICAL(flags);
- return ret;
-}
-
static int __cpuinitdata ntlb;
static int __init set_ntlb(char *str)
{
@@ -450,8 +414,6 @@ void __cpuinit tlb_init(void)
write_c0_pagegrain(pg);
}
- temp_tlb_entry = current_cpu_data.tlbsize - 1;
-
/* From this point on the ARC firmware is dead. */
local_flush_tlb_all();
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c
index d53ff91b277c..a588b5cef8d2 100644
--- a/arch/mips/mti-malta/malta-int.c
+++ b/arch/mips/mti-malta/malta-int.c
@@ -322,13 +322,13 @@ static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
static struct irqaction irq_resched = {
.handler = ipi_resched_interrupt,
- .flags = IRQF_DISABLED|IRQF_PERCPU,
+ .flags = IRQF_PERCPU,
.name = "IPI_resched"
};
static struct irqaction irq_call = {
.handler = ipi_call_interrupt,
- .flags = IRQF_DISABLED|IRQF_PERCPU,
+ .flags = IRQF_PERCPU,
.name = "IPI_call"
};
#endif /* CONFIG_MIPS_MT_SMP */
diff --git a/arch/mips/netlogic/Kconfig b/arch/mips/netlogic/Kconfig
index a5ca743613f2..75bec44b5856 100644
--- a/arch/mips/netlogic/Kconfig
+++ b/arch/mips/netlogic/Kconfig
@@ -1,5 +1,2 @@
config NLM_COMMON
bool
-
-config NLM_XLR
- bool
diff --git a/arch/mips/netlogic/Makefile b/arch/mips/netlogic/Makefile
new file mode 100644
index 000000000000..36d169b2ca6d
--- /dev/null
+++ b/arch/mips/netlogic/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_NLM_COMMON) += common/
+obj-$(CONFIG_CPU_XLR) += xlr/
+obj-$(CONFIG_CPU_XLP) += xlp/
diff --git a/arch/mips/netlogic/Platform b/arch/mips/netlogic/Platform
index b648b487fd66..cdfc9abbbb7b 100644
--- a/arch/mips/netlogic/Platform
+++ b/arch/mips/netlogic/Platform
@@ -1,16 +1,17 @@
#
# NETLOGIC includes
#
-cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic
-cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic
+cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/mach-netlogic
+cflags-$(CONFIG_NLM_COMMON) += -I$(srctree)/arch/mips/include/asm/netlogic
#
# use mips64 if xlr is not available
#
-cflags-$(CONFIG_NLM_XLR) += $(call cc-option,-march=xlr,-march=mips64)
+cflags-$(CONFIG_CPU_XLR) += $(call cc-option,-march=xlr,-march=mips64)
+cflags-$(CONFIG_CPU_XLP) += $(call cc-option,-march=xlp,-march=mips64r2)
#
-# NETLOGIC XLR/XLS SoC, Simulator and boards
+# NETLOGIC processor support
#
-core-$(CONFIG_NLM_XLR) += arch/mips/netlogic/xlr/
-load-$(CONFIG_NLM_XLR_BOARD) += 0xffffffff84000000
+platform-$(CONFIG_NLM_COMMON) += netlogic/
+load-$(CONFIG_NLM_COMMON) += 0xffffffff80100000
diff --git a/arch/mips/netlogic/common/Makefile b/arch/mips/netlogic/common/Makefile
new file mode 100644
index 000000000000..291372a086f5
--- /dev/null
+++ b/arch/mips/netlogic/common/Makefile
@@ -0,0 +1,3 @@
+obj-y += irq.o time.o
+obj-$(CONFIG_SMP) += smp.o smpboot.o
+obj-$(CONFIG_EARLY_PRINTK) += earlycons.o
diff --git a/arch/mips/netlogic/common/earlycons.c b/arch/mips/netlogic/common/earlycons.c
new file mode 100644
index 000000000000..f193f7b3bd81
--- /dev/null
+++ b/arch/mips/netlogic/common/earlycons.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <linux/serial_reg.h>
+
+#include <asm/mipsregs.h>
+#include <asm/netlogic/haldefs.h>
+
+#if defined(CONFIG_CPU_XLP)
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/uart.h>
+#elif defined(CONFIG_CPU_XLR)
+#include <asm/netlogic/xlr/iomap.h>
+#endif
+
+void prom_putchar(char c)
+{
+ uint64_t uartbase;
+
+#if defined(CONFIG_CPU_XLP)
+ uartbase = nlm_get_uart_regbase(0, 0);
+#elif defined(CONFIG_CPU_XLR)
+ uartbase = nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
+#endif
+ while (nlm_read_reg(uartbase, UART_LSR) == 0)
+ ;
+ nlm_write_reg(uartbase, UART_TX, c);
+}
diff --git a/arch/mips/netlogic/common/irq.c b/arch/mips/netlogic/common/irq.c
new file mode 100644
index 000000000000..49a4f6cf71e5
--- /dev/null
+++ b/arch/mips/netlogic/common/irq.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/linkage.h>
+#include <linux/interrupt.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/irq.h>
+
+#include <asm/errno.h>
+#include <asm/signal.h>
+#include <asm/system.h>
+#include <asm/ptrace.h>
+#include <asm/mipsregs.h>
+#include <asm/thread_info.h>
+
+#include <asm/netlogic/mips-extns.h>
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
+
+#if defined(CONFIG_CPU_XLP)
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pic.h>
+#elif defined(CONFIG_CPU_XLR)
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
+#else
+#error "Unknown CPU"
+#endif
+/*
+ * These are the routines that handle all the low level interrupt stuff.
+ * Actions handled here are: initialization of the interrupt map, requesting of
+ * interrupt lines by handlers, dispatching if interrupts to handlers, probing
+ * for interrupt lines
+ */
+
+/* Globals */
+static uint64_t nlm_irq_mask;
+static DEFINE_SPINLOCK(nlm_pic_lock);
+
+static void xlp_pic_enable(struct irq_data *d)
+{
+ unsigned long flags;
+ int irt;
+
+ irt = nlm_irq_to_irt(d->irq);
+ if (irt == -1)
+ return;
+ spin_lock_irqsave(&nlm_pic_lock, flags);
+ nlm_pic_enable_irt(nlm_pic_base, irt);
+ spin_unlock_irqrestore(&nlm_pic_lock, flags);
+}
+
+static void xlp_pic_disable(struct irq_data *d)
+{
+ unsigned long flags;
+ int irt;
+
+ irt = nlm_irq_to_irt(d->irq);
+ if (irt == -1)
+ return;
+ spin_lock_irqsave(&nlm_pic_lock, flags);
+ nlm_pic_disable_irt(nlm_pic_base, irt);
+ spin_unlock_irqrestore(&nlm_pic_lock, flags);
+}
+
+static void xlp_pic_mask_ack(struct irq_data *d)
+{
+ uint64_t mask = 1ull << d->irq;
+
+ write_c0_eirr(mask); /* ack by writing EIRR */
+}
+
+static void xlp_pic_unmask(struct irq_data *d)
+{
+ void *hd = irq_data_get_irq_handler_data(d);
+ int irt;
+
+ irt = nlm_irq_to_irt(d->irq);
+ if (irt == -1)
+ return;
+
+ if (hd) {
+ void (*extra_ack)(void *) = hd;
+ extra_ack(d);
+ }
+ /* Ack is a single write, no need to lock */
+ nlm_pic_ack(nlm_pic_base, irt);
+}
+
+static struct irq_chip xlp_pic = {
+ .name = "XLP-PIC",
+ .irq_enable = xlp_pic_enable,
+ .irq_disable = xlp_pic_disable,
+ .irq_mask_ack = xlp_pic_mask_ack,
+ .irq_unmask = xlp_pic_unmask,
+};
+
+static void cpuintr_disable(struct irq_data *d)
+{
+ uint64_t eimr;
+ uint64_t mask = 1ull << d->irq;
+
+ eimr = read_c0_eimr();
+ write_c0_eimr(eimr & ~mask);
+}
+
+static void cpuintr_enable(struct irq_data *d)
+{
+ uint64_t eimr;
+ uint64_t mask = 1ull << d->irq;
+
+ eimr = read_c0_eimr();
+ write_c0_eimr(eimr | mask);
+}
+
+static void cpuintr_ack(struct irq_data *d)
+{
+ uint64_t mask = 1ull << d->irq;
+
+ write_c0_eirr(mask);
+}
+
+static void cpuintr_nop(struct irq_data *d)
+{
+ WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq);
+}
+
+/*
+ * Chip definition for CPU originated interrupts(timer, msg) and
+ * IPIs
+ */
+struct irq_chip nlm_cpu_intr = {
+ .name = "XLP-CPU-INTR",
+ .irq_enable = cpuintr_enable,
+ .irq_disable = cpuintr_disable,
+ .irq_mask = cpuintr_nop,
+ .irq_ack = cpuintr_nop,
+ .irq_eoi = cpuintr_ack,
+};
+
+void __init init_nlm_common_irqs(void)
+{
+ int i, irq, irt;
+
+ for (i = 0; i < PIC_IRT_FIRST_IRQ; i++)
+ irq_set_chip_and_handler(i, &nlm_cpu_intr, handle_percpu_irq);
+
+ for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ ; i++)
+ irq_set_chip_and_handler(i, &xlp_pic, handle_level_irq);
+
+#ifdef CONFIG_SMP
+ irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr,
+ nlm_smp_function_ipi_handler);
+ irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,
+ nlm_smp_resched_ipi_handler);
+ nlm_irq_mask |=
+ ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));
+#endif
+
+ for (irq = PIC_IRT_FIRST_IRQ; irq <= PIC_IRT_LAST_IRQ; irq++) {
+ irt = nlm_irq_to_irt(irq);
+ if (irt == -1)
+ continue;
+ nlm_irq_mask |= (1ULL << irq);
+ nlm_pic_init_irt(nlm_pic_base, irt, irq, 0);
+ }
+
+ nlm_irq_mask |= (1ULL << IRQ_TIMER);
+}
+
+void __init arch_init_irq(void)
+{
+ /* Initialize the irq descriptors */
+ init_nlm_common_irqs();
+
+ write_c0_eimr(nlm_irq_mask);
+}
+
+void __cpuinit nlm_smp_irq_init(void)
+{
+ /* set interrupt mask for non-zero cpus */
+ write_c0_eimr(nlm_irq_mask);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ uint64_t eirr;
+ int i;
+
+ eirr = read_c0_eirr() & read_c0_eimr();
+ if (eirr & (1 << IRQ_TIMER)) {
+ do_IRQ(IRQ_TIMER);
+ return;
+ }
+
+ i = __ilog2_u64(eirr);
+ if (i == -1)
+ return;
+
+ do_IRQ(i);
+}
diff --git a/arch/mips/netlogic/xlr/smp.c b/arch/mips/netlogic/common/smp.c
index 080284ded508..db17f49886c2 100644
--- a/arch/mips/netlogic/xlr/smp.c
+++ b/arch/mips/netlogic/common/smp.c
@@ -42,31 +42,29 @@
#include <asm/netlogic/interrupt.h>
#include <asm/netlogic/mips-extns.h>
-
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
+
+#if defined(CONFIG_CPU_XLP)
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pic.h>
+#elif defined(CONFIG_CPU_XLR)
#include <asm/netlogic/xlr/iomap.h>
#include <asm/netlogic/xlr/pic.h>
#include <asm/netlogic/xlr/xlr.h>
+#else
+#error "Unknown CPU"
+#endif
-void core_send_ipi(int logical_cpu, unsigned int action)
+void nlm_send_ipi_single(int logical_cpu, unsigned int action)
{
int cpu = cpu_logical_map(logical_cpu);
- u32 tid = cpu & 0x3;
- u32 pid = (cpu >> 2) & 0x07;
- u32 ipi = (tid << 16) | (pid << 20);
if (action & SMP_CALL_FUNCTION)
- ipi |= IRQ_IPI_SMP_FUNCTION;
- else if (action & SMP_RESCHEDULE_YOURSELF)
- ipi |= IRQ_IPI_SMP_RESCHEDULE;
- else
- return;
-
- pic_send_ipi(ipi);
-}
-
-void nlm_send_ipi_single(int cpu, unsigned int action)
-{
- core_send_ipi(cpu, action);
+ nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_FUNCTION, 0);
+ if (action & SMP_RESCHEDULE_YOURSELF)
+ nlm_pic_send_ipi(nlm_pic_base, cpu, IRQ_IPI_SMP_RESCHEDULE, 0);
}
void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
@@ -74,29 +72,35 @@ void nlm_send_ipi_mask(const struct cpumask *mask, unsigned int action)
int cpu;
for_each_cpu(cpu, mask) {
- core_send_ipi(cpu, action);
+ nlm_send_ipi_single(cpu, action);
}
}
/* IRQ_IPI_SMP_FUNCTION Handler */
void nlm_smp_function_ipi_handler(unsigned int irq, struct irq_desc *desc)
{
+ write_c0_eirr(1ull << irq);
smp_call_function_interrupt();
}
/* IRQ_IPI_SMP_RESCHEDULE handler */
void nlm_smp_resched_ipi_handler(unsigned int irq, struct irq_desc *desc)
{
+ write_c0_eirr(1ull << irq);
scheduler_ipi();
}
/*
* Called before going into mips code, early cpu init
*/
-void nlm_early_init_secondary(void)
+void nlm_early_init_secondary(int cpu)
{
+ change_c0_config(CONF_CM_CMASK, 0x3);
write_c0_ebase((uint32_t)nlm_common_ebase);
- /* TLB partition here later */
+#ifdef CONFIG_CPU_XLP
+ if (hard_smp_processor_id() % 4 == 0)
+ xlp_mmu_init();
+#endif
}
/*
@@ -104,9 +108,16 @@ void nlm_early_init_secondary(void)
*/
static void __cpuinit nlm_init_secondary(void)
{
+ current_cpu_data.core = hard_smp_processor_id() / 4;
nlm_smp_irq_init();
}
+void nlm_prepare_cpus(unsigned int max_cpus)
+{
+ /* declare we are SMT capable */
+ smp_num_siblings = nlm_threads_per_core;
+}
+
void nlm_smp_finish(void)
{
#ifdef notyet
@@ -123,10 +134,10 @@ void nlm_cpus_done(void)
* Boot all other cpus in the system, initialize them, and bring them into
* the boot function
*/
-int nlm_cpu_unblock[NR_CPUS];
int nlm_cpu_ready[NR_CPUS];
unsigned long nlm_next_gp;
unsigned long nlm_next_sp;
+
cpumask_t phys_cpu_present_map;
void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
@@ -140,7 +151,7 @@ void nlm_boot_secondary(int logical_cpu, struct task_struct *idle)
/* barrier */
__sync();
- nlm_cpu_unblock[cpu] = 1;
+ nlm_pic_send_ipi(nlm_pic_base, cpu, 1, 1);
}
void __init nlm_smp_setup(void)
@@ -159,8 +170,8 @@ void __init nlm_smp_setup(void)
num_cpus = 1;
for (i = 0; i < NR_CPUS; i++) {
/*
- * BSP is not set in nlm_cpu_ready array, it is only for
- * ASPs (goto see smpboot.S)
+ * nlm_cpu_ready array is not set for the boot_cpu,
+ * it is only set for ASPs (see smpboot.S)
*/
if (nlm_cpu_ready[i]) {
cpu_set(i, phys_cpu_present_map);
@@ -176,10 +187,75 @@ void __init nlm_smp_setup(void)
(unsigned long)cpu_possible_map.bits[0]);
pr_info("Detected %i Slave CPU(s)\n", num_cpus);
+ nlm_set_nmi_handler(nlm_boot_secondary_cpus);
}
-void nlm_prepare_cpus(unsigned int max_cpus)
+static int nlm_parse_cpumask(u32 cpu_mask)
+{
+ uint32_t core0_thr_mask, core_thr_mask;
+ int threadmode, i;
+
+ core0_thr_mask = cpu_mask & 0xf;
+ switch (core0_thr_mask) {
+ case 1:
+ nlm_threads_per_core = 1;
+ threadmode = 0;
+ break;
+ case 3:
+ nlm_threads_per_core = 2;
+ threadmode = 2;
+ break;
+ case 0xf:
+ nlm_threads_per_core = 4;
+ threadmode = 3;
+ break;
+ default:
+ goto unsupp;
+ }
+
+ /* Verify other cores CPU masks */
+ nlm_coremask = 1;
+ nlm_cpumask = core0_thr_mask;
+ for (i = 1; i < 8; i++) {
+ core_thr_mask = (cpu_mask >> (i * 4)) & 0xf;
+ if (core_thr_mask) {
+ if (core_thr_mask != core0_thr_mask)
+ goto unsupp;
+ nlm_coremask |= 1 << i;
+ nlm_cpumask |= core0_thr_mask << (4 * i);
+ }
+ }
+ return threadmode;
+
+unsupp:
+ panic("Unsupported CPU mask %x\n", cpu_mask);
+ return 0;
+}
+
+int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
{
+ unsigned long reset_vec;
+ char *reset_data;
+ int threadmode;
+
+ /* Update reset entry point with CPU init code */
+ reset_vec = CKSEG1ADDR(RESET_VEC_PHYS);
+ memcpy((void *)reset_vec, (void *)nlm_reset_entry,
+ (nlm_reset_entry_end - nlm_reset_entry));
+
+ /* verify the mask and setup core config variables */
+ threadmode = nlm_parse_cpumask(wakeup_mask);
+
+ /* Setup CPU init parameters */
+ reset_data = (char *)CKSEG1ADDR(RESET_DATA_PHYS);
+ *(int *)(reset_data + BOOT_THREAD_MODE) = threadmode;
+
+#ifdef CONFIG_CPU_XLP
+ xlp_wakeup_secondary_cpus();
+#else
+ xlr_wakeup_secondary_cpus();
+#endif
+ return 0;
}
struct plat_smp_ops nlm_smp_ops = {
@@ -192,29 +268,3 @@ struct plat_smp_ops nlm_smp_ops = {
.smp_setup = nlm_smp_setup,
.prepare_cpus = nlm_prepare_cpus,
};
-
-unsigned long secondary_entry_point;
-
-int __cpuinit nlm_wakeup_secondary_cpus(u32 wakeup_mask)
-{
- unsigned int tid, pid, ipi, i, boot_cpu;
- void *reset_vec;
-
- secondary_entry_point = (unsigned long)prom_pre_boot_secondary_cpus;
- reset_vec = (void *)CKSEG1ADDR(0x1fc00000);
- memcpy(reset_vec, nlm_boot_smp_nmi, 0x80);
- boot_cpu = hard_smp_processor_id();
-
- for (i = 0; i < NR_CPUS; i++) {
- if (i == boot_cpu)
- continue;
- if (wakeup_mask & (1u << i)) {
- tid = i & 0x3;
- pid = (i >> 2) & 0x7;
- ipi = (tid << 16) | (pid << 20) | (1 << 8);
- pic_send_ipi(ipi);
- }
- }
-
- return 0;
-}
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S
new file mode 100644
index 000000000000..c138b1a6dec3
--- /dev/null
+++ b/arch/mips/netlogic/common/smpboot.S
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/init.h>
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+#include <asm/asmmacro.h>
+#include <asm/addrspace.h>
+
+#include <asm/netlogic/common.h>
+
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/sys.h>
+#include <asm/netlogic/xlp-hal/cpucontrol.h>
+
+#define CP0_EBASE $15
+#define SYS_CPU_COHERENT_BASE(node) CKSEG1ADDR(XLP_DEFAULT_IO_BASE) + \
+ XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
+ SYS_CPU_NONCOHERENT_MODE * 4
+
+.macro __config_lsu
+ li t0, LSU_DEFEATURE
+ mfcr t1, t0
+
+ lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */
+ or t1, t1, t2
+ li t2, ~0xe /* S1RCM */
+ and t1, t1, t2
+ mtcr t1, t0
+
+ li t0, SCHED_DEFEATURE
+ lui t1, 0x0100 /* Experimental: Disable BRU accepting ALU ops */
+ mtcr t1, t0
+.endm
+
+/*
+ * The cores can come start when they are woken up. This is also the NMI
+ * entry, so check that first.
+ *
+ * The data corresponding to reset is stored at RESET_DATA_PHYS location,
+ * this will have the thread mask (used when core is woken up) and the
+ * current NMI handler in case we reached here for an NMI.
+ *
+ * When a core or thread is newly woken up, it loops in a 'wait'. When
+ * the CPU really needs waking up, we send an NMI to it, with the NMI
+ * handler set to prom_boot_secondary_cpus
+ */
+
+ .set noreorder
+ .set noat
+ .set arch=xlr /* for mfcr/mtcr, XLR is sufficient */
+
+FEXPORT(nlm_reset_entry)
+ dmtc0 k0, $22, 6
+ dmtc0 k1, $22, 7
+ mfc0 k0, CP0_STATUS
+ li k1, 0x80000
+ and k1, k0, k1
+ beqz k1, 1f /* go to real reset entry */
+ nop
+ li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
+ ld k0, BOOT_NMI_HANDLER(k1)
+ jr k0
+ nop
+
+1: /* Entry point on core wakeup */
+ mfc0 t0, CP0_EBASE, 1
+ mfc0 t1, CP0_EBASE, 1
+ srl t1, 5
+ andi t1, 0x3 /* t1 <- node */
+ li t2, 0x40000
+ mul t3, t2, t1 /* t3 = node * 0x40000 */
+ srl t0, t0, 2
+ and t0, t0, 0x7 /* t0 <- core */
+ li t1, 0x1
+ sll t0, t1, t0
+ nor t0, t0, zero /* t0 <- ~(1 << core) */
+ li t2, SYS_CPU_COHERENT_BASE(0)
+ add t2, t2, t3 /* t2 <- SYS offset for node */
+ lw t1, 0(t2)
+ and t1, t1, t0
+ sw t1, 0(t2)
+
+ /* read back to ensure complete */
+ lw t1, 0(t2)
+ sync
+
+ /* Configure LSU on Non-0 Cores. */
+ __config_lsu
+
+/*
+ * Wake up sibling threads from the initial thread in
+ * a core.
+ */
+EXPORT(nlm_boot_siblings)
+ li t0, CKSEG1ADDR(RESET_DATA_PHYS)
+ lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
+ li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
+ mfcr t2, t0
+ or t2, t2, t1
+ mtcr t2, t0
+
+ /*
+ * The new hardware thread starts at the next instruction
+ * For all the cases other than core 0 thread 0, we will
+ * jump to the secondary wait function.
+ */
+ mfc0 v0, CP0_EBASE, 1
+ andi v0, 0x7f /* v0 <- node/core */
+
+#if 1
+ /* A0 errata - Write MMU_SETUP after changing thread mode register. */
+ andi v1, v0, 0x3 /* v1 <- thread id */
+ bnez v1, 2f
+ nop
+
+ li t0, MMU_SETUP
+ li t1, 0
+ mtcr t1, t0
+ ehb
+#endif
+
+2: beqz v0, 4f
+ nop
+
+ /* setup status reg */
+ mfc0 t1, CP0_STATUS
+ li t0, ST0_BEV
+ or t1, t0
+ xor t1, t0
+#ifdef CONFIG_64BIT
+ ori t1, ST0_KX
+#endif
+ mtc0 t1, CP0_STATUS
+ /* mark CPU ready */
+ PTR_LA t1, nlm_cpu_ready
+ sll v1, v0, 2
+ PTR_ADDU t1, v1
+ li t2, 1
+ sw t2, 0(t1)
+ /* Wait until NMI hits */
+3: wait
+ j 3b
+ nop
+
+ /*
+ * For the boot CPU, we have to restore registers and
+ * return
+ */
+4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
+ li t1, 0xfadebeef
+ dmtc0 t1, $4, 2 /* restore SP from UserLocal */
+ PTR_SUBU sp, t0, PT_SIZE
+ RESTORE_ALL
+ jr ra
+ nop
+EXPORT(nlm_reset_entry_end)
+
+FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
+ __config_lsu
+ dmtc0 sp, $4, 2 /* SP saved in UserLocal */
+ SAVE_ALL
+ sync
+ /* find the location to which nlm_boot_siblings was relocated */
+ li t0, CKSEG1ADDR(RESET_VEC_PHYS)
+ dla t1, nlm_reset_entry
+ dla t2, nlm_boot_siblings
+ dsubu t2, t1
+ daddu t2, t0
+ /* call it */
+ jr t2
+ nop
+ /* not reached */
+
+ __CPUINIT
+NESTED(nlm_boot_secondary_cpus, 16, sp)
+ PTR_LA t1, nlm_next_sp
+ PTR_L sp, 0(t1)
+ PTR_LA t1, nlm_next_gp
+ PTR_L gp, 0(t1)
+
+ /* a0 has the processor id */
+ PTR_LA t0, nlm_early_init_secondary
+ jalr t0
+ nop
+
+ PTR_LA t0, smp_bootstrap
+ jr t0
+ nop
+END(nlm_boot_secondary_cpus)
+ __FINIT
+
+/*
+ * In case of RMIboot bootloader which is used on XLR boards, the CPUs
+ * be already woken up and waiting in bootloader code.
+ * This will get them out of the bootloader code and into linux. Needed
+ * because the bootloader area will be taken and initialized by linux.
+ */
+ __CPUINIT
+NESTED(nlm_rmiboot_preboot, 16, sp)
+ mfc0 t0, $15, 1 # read ebase
+ andi t0, 0x1f # t0 has the processor_id()
+ andi t2, t0, 0x3 # thread no
+ sll t0, 2 # offset in cpu array
+
+ PTR_LA t1, nlm_cpu_ready # mark CPU ready
+ PTR_ADDU t1, t0
+ li t3, 1
+ sw t3, 0(t1)
+
+ bnez t2, 1f # skip thread programming
+ nop # for non zero hw threads
+
+ /*
+ * MMU setup only for first thread in core
+ */
+ li t0, 0x400
+ mfcr t1, t0
+ li t2, 6 # XLR thread mode mask
+ nor t3, t2, zero
+ and t2, t1, t2 # t2 - current thread mode
+ li v0, CKSEG1ADDR(RESET_DATA_PHYS)
+ lw v1, BOOT_THREAD_MODE(v0) # v1 - new thread mode
+ sll v1, 1
+ beq v1, t2, 1f # same as request value
+ nop # nothing to do */
+
+ and t2, t1, t3 # mask out old thread mode
+ or t1, t2, v1 # put in new value
+ mtcr t1, t0 # update core control
+
+1: wait
+ j 1b
+ nop
+END(nlm_rmiboot_preboot)
+ __FINIT
diff --git a/arch/mips/netlogic/xlr/time.c b/arch/mips/netlogic/common/time.c
index 0d81b262593c..bd3e498157ff 100644
--- a/arch/mips/netlogic/xlr/time.c
+++ b/arch/mips/netlogic/common/time.c
@@ -36,7 +36,7 @@
#include <asm/time.h>
#include <asm/netlogic/interrupt.h>
-#include <asm/netlogic/psb-bootinfo.h>
+#include <asm/netlogic/common.h>
unsigned int __cpuinit get_c0_compare_int(void)
{
@@ -45,7 +45,7 @@ unsigned int __cpuinit get_c0_compare_int(void)
void __init plat_time_init(void)
{
- mips_hpt_frequency = nlm_prom_info.cpu_frequency;
+ mips_hpt_frequency = nlm_get_cpu_frequency();
pr_info("MIPS counter frequency [%ld]\n",
- (unsigned long)mips_hpt_frequency);
+ (unsigned long)mips_hpt_frequency);
}
diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile
new file mode 100644
index 000000000000..b93ed83474ec
--- /dev/null
+++ b/arch/mips/netlogic/xlp/Makefile
@@ -0,0 +1,2 @@
+obj-y += setup.o platform.o nlm_hal.o
+obj-$(CONFIG_SMP) += wakeup.o
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
new file mode 100644
index 000000000000..9428e7125fed
--- /dev/null
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+
+#include <asm/mipsregs.h>
+#include <asm/time.h>
+
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pic.h>
+#include <asm/netlogic/xlp-hal/sys.h>
+
+/* These addresses are computed by the nlm_hal_init() */
+uint64_t nlm_io_base;
+uint64_t nlm_sys_base;
+uint64_t nlm_pic_base;
+
+/* Main initialization */
+void nlm_hal_init(void)
+{
+ nlm_io_base = CKSEG1ADDR(XLP_DEFAULT_IO_BASE);
+ nlm_sys_base = nlm_get_sys_regbase(0); /* node 0 */
+ nlm_pic_base = nlm_get_pic_regbase(0); /* node 0 */
+}
+
+int nlm_irq_to_irt(int irq)
+{
+ if (!PIC_IRQ_IS_IRT(irq))
+ return -1;
+
+ switch (irq) {
+ case PIC_UART_0_IRQ:
+ return PIC_IRT_UART_0_INDEX;
+ case PIC_UART_1_IRQ:
+ return PIC_IRT_UART_1_INDEX;
+ default:
+ return -1;
+ }
+}
+
+int nlm_irt_to_irq(int irt)
+{
+ switch (irt) {
+ case PIC_IRT_UART_0_INDEX:
+ return PIC_UART_0_IRQ;
+ case PIC_IRT_UART_1_INDEX:
+ return PIC_UART_1_IRQ;
+ default:
+ return -1;
+ }
+}
+
+unsigned int nlm_get_core_frequency(int core)
+{
+ unsigned int pll_divf, pll_divr, dfs_div, ext_div;
+ unsigned int rstval, dfsval, denom;
+ uint64_t num;
+
+ rstval = nlm_read_sys_reg(nlm_sys_base, SYS_POWER_ON_RESET_CFG);
+ dfsval = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIV_VALUE);
+ pll_divf = ((rstval >> 10) & 0x7f) + 1;
+ pll_divr = ((rstval >> 8) & 0x3) + 1;
+ ext_div = ((rstval >> 30) & 0x3) + 1;
+ dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1;
+
+ num = 800000000ULL * pll_divf;
+ denom = 3 * pll_divr * ext_div * dfs_div;
+ do_div(num, denom);
+ return (unsigned int)num;
+}
+
+unsigned int nlm_get_cpu_frequency(void)
+{
+ return nlm_get_core_frequency(0);
+}
diff --git a/arch/mips/netlogic/xlp/platform.c b/arch/mips/netlogic/xlp/platform.c
new file mode 100644
index 000000000000..1f5e4cba891d
--- /dev/null
+++ b/arch/mips/netlogic/xlp/platform.c
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/pci.h>
+#include <linux/serial_reg.h>
+#include <linux/spinlock.h>
+
+#include <asm/time.h>
+#include <asm/addrspace.h>
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pic.h>
+#include <asm/netlogic/xlp-hal/uart.h>
+
+static unsigned int nlm_xlp_uart_in(struct uart_port *p, int offset)
+{
+ return nlm_read_reg(p->iobase, offset);
+}
+
+static void nlm_xlp_uart_out(struct uart_port *p, int offset, int value)
+{
+ nlm_write_reg(p->iobase, offset, value);
+}
+
+#define PORT(_irq) \
+ { \
+ .irq = _irq, \
+ .regshift = 2, \
+ .iotype = UPIO_MEM32, \
+ .flags = (UPF_SKIP_TEST|UPF_FIXED_TYPE|\
+ UPF_BOOT_AUTOCONF), \
+ .uartclk = XLP_IO_CLK, \
+ .type = PORT_16550A, \
+ .serial_in = nlm_xlp_uart_in, \
+ .serial_out = nlm_xlp_uart_out, \
+ }
+
+static struct plat_serial8250_port xlp_uart_data[] = {
+ PORT(PIC_UART_0_IRQ),
+ PORT(PIC_UART_1_IRQ),
+ {},
+};
+
+static struct platform_device uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = xlp_uart_data,
+ },
+};
+
+static int __init nlm_platform_uart_init(void)
+{
+ unsigned long mmio;
+
+ mmio = (unsigned long)nlm_get_uart_regbase(0, 0);
+ xlp_uart_data[0].iobase = mmio;
+ xlp_uart_data[0].membase = (void __iomem *)mmio;
+ xlp_uart_data[0].mapbase = mmio;
+
+ mmio = (unsigned long)nlm_get_uart_regbase(0, 1);
+ xlp_uart_data[1].iobase = mmio;
+ xlp_uart_data[1].membase = (void __iomem *)mmio;
+ xlp_uart_data[1].mapbase = mmio;
+
+ return platform_device_register(&uart_device);
+}
+
+arch_initcall(nlm_platform_uart_init);
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
new file mode 100644
index 000000000000..acb677a1227c
--- /dev/null
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/kernel.h>
+#include <linux/serial_8250.h>
+#include <linux/pm.h>
+
+#include <asm/reboot.h>
+#include <asm/time.h>
+#include <asm/bootinfo.h>
+
+#include <linux/of_fdt.h>
+
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
+
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/sys.h>
+
+unsigned long nlm_common_ebase = 0x0;
+
+/* default to uniprocessor */
+uint32_t nlm_coremask = 1, nlm_cpumask = 1;
+int nlm_threads_per_core = 1;
+
+static void nlm_linux_exit(void)
+{
+ nlm_write_sys_reg(nlm_sys_base, SYS_CHIP_RESET, 1);
+ for ( ; ; )
+ cpu_wait();
+}
+
+void __init plat_mem_setup(void)
+{
+ panic_timeout = 5;
+ _machine_restart = (void (*)(char *))nlm_linux_exit;
+ _machine_halt = nlm_linux_exit;
+ pm_power_off = nlm_linux_exit;
+}
+
+const char *get_system_type(void)
+{
+ return "Netlogic XLP Series";
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* Nothing yet */
+}
+
+void xlp_mmu_init(void)
+{
+ write_c0_config6(read_c0_config6() | 0x24);
+ current_cpu_data.tlbsize = ((read_c0_config6() >> 16) & 0xffff) + 1;
+ write_c0_config7(PM_DEFAULT_MASK >>
+ (13 + (ffz(PM_DEFAULT_MASK >> 13) / 2)));
+}
+
+void __init prom_init(void)
+{
+ void *fdtp;
+
+ fdtp = (void *)(long)fw_arg0;
+ xlp_mmu_init();
+ nlm_hal_init();
+ early_init_devtree(fdtp);
+
+ nlm_common_ebase = read_c0_ebase() & (~((1 << 12) - 1));
+#ifdef CONFIG_SMP
+ nlm_wakeup_secondary_cpus(0xffffffff);
+ register_smp_ops(&nlm_smp_ops);
+#endif
+}
diff --git a/arch/mips/netlogic/xlp/wakeup.c b/arch/mips/netlogic/xlp/wakeup.c
new file mode 100644
index 000000000000..44d923ff3846
--- /dev/null
+++ b/arch/mips/netlogic/xlp/wakeup.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
+ * reserved.
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the NetLogic
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/threads.h>
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/string.h>
+
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
+#include <asm/netlogic/mips-extns.h>
+
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/pic.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/sys.h>
+
+static void xlp_enable_secondary_cores(void)
+{
+ uint32_t core, value, coremask, syscoremask;
+ int count;
+
+ /* read cores in reset from SYS block */
+ syscoremask = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);
+
+ /* update user specified */
+ nlm_coremask = nlm_coremask & (syscoremask | 1);
+
+ for (core = 1; core < 8; core++) {
+ coremask = 1 << core;
+ if ((nlm_coremask & coremask) == 0)
+ continue;
+
+ /* Enable CPU clock */
+ value = nlm_read_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL);
+ value &= ~coremask;
+ nlm_write_sys_reg(nlm_sys_base, SYS_CORE_DFS_DIS_CTRL, value);
+
+ /* Remove CPU Reset */
+ value = nlm_read_sys_reg(nlm_sys_base, SYS_CPU_RESET);
+ value &= ~coremask;
+ nlm_write_sys_reg(nlm_sys_base, SYS_CPU_RESET, value);
+
+ /* Poll for CPU to mark itself coherent */
+ count = 100000;
+ do {
+ value = nlm_read_sys_reg(nlm_sys_base,
+ SYS_CPU_NONCOHERENT_MODE);
+ } while ((value & coremask) != 0 && count-- > 0);
+
+ if (count == 0)
+ pr_err("Failed to enable core %d\n", core);
+ }
+}
+
+void xlp_wakeup_secondary_cpus(void)
+{
+ /*
+ * In case of u-boot, the secondaries are in reset
+ * first wakeup core 0 threads
+ */
+ xlp_boot_core0_siblings();
+
+ /* now get other cores out of reset */
+ xlp_enable_secondary_cores();
+}
diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile
index 2dca585dd2f7..f01e4d7a0600 100644
--- a/arch/mips/netlogic/xlr/Makefile
+++ b/arch/mips/netlogic/xlr/Makefile
@@ -1,5 +1,2 @@
-obj-y += setup.o platform.o irq.o setup.o time.o
-obj-$(CONFIG_SMP) += smp.o smpboot.o
-obj-$(CONFIG_EARLY_PRINTK) += xlr_console.o
-
-ccflags-y += -Werror
+obj-y += setup.o platform.o
+obj-$(CONFIG_SMP) += wakeup.o
diff --git a/arch/mips/netlogic/xlr/irq.c b/arch/mips/netlogic/xlr/irq.c
deleted file mode 100644
index 521bb7377eb0..000000000000
--- a/arch/mips/netlogic/xlr/irq.c
+++ /dev/null
@@ -1,300 +0,0 @@
-/*
- * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights
- * reserved.
- *
- * This software is available to you under a choice of one of two
- * licenses. You may choose to be licensed under the terms of the GNU
- * General Public License (GPL) Version 2, available from the file
- * COPYING in the main directory of this source tree, or the NetLogic
- * license below:
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/linkage.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-
-#include <asm/mipsregs.h>
-
-#include <asm/netlogic/xlr/iomap.h>
-#include <asm/netlogic/xlr/pic.h>
-#include <asm/netlogic/xlr/xlr.h>
-
-#include <asm/netlogic/interrupt.h>
-#include <asm/netlogic/mips-extns.h>
-
-static u64 nlm_irq_mask;
-static DEFINE_SPINLOCK(nlm_pic_lock);
-
-static void xlr_pic_enable(struct irq_data *d)
-{
- nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
- unsigned long flags;
- nlm_reg_t reg;
- int irq = d->irq;
-
- WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
-
- spin_lock_irqsave(&nlm_pic_lock, flags);
- reg = netlogic_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE);
- netlogic_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE,
- reg | (1 << 6) | (1 << 30) | (1 << 31));
- spin_unlock_irqrestore(&nlm_pic_lock, flags);
-}
-
-static void xlr_pic_mask(struct irq_data *d)
-{
- nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
- unsigned long flags;
- nlm_reg_t reg;
- int irq = d->irq;
-
- WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
-
- spin_lock_irqsave(&nlm_pic_lock, flags);
- reg = netlogic_read_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE);
- netlogic_write_reg(mmio, PIC_IRT_1_BASE + irq - PIC_IRQ_BASE,
- reg | (1 << 6) | (1 << 30) | (0 << 31));
- spin_unlock_irqrestore(&nlm_pic_lock, flags);
-}
-
-#ifdef CONFIG_PCI
-/* Extra ACK needed for XLR on chip PCI controller */
-static void xlr_pci_ack(struct irq_data *d)
-{
- nlm_reg_t *pci_mmio = netlogic_io_mmio(NETLOGIC_IO_PCIX_OFFSET);
-
- netlogic_read_reg(pci_mmio, (0x140 >> 2));
-}
-
-/* Extra ACK needed for XLS on chip PCIe controller */
-static void xls_pcie_ack(struct irq_data *d)
-{
- nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET);
-
- switch (d->irq) {
- case PIC_PCIE_LINK0_IRQ:
- netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff);
- break;
- case PIC_PCIE_LINK1_IRQ:
- netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff);
- break;
- case PIC_PCIE_LINK2_IRQ:
- netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff);
- break;
- case PIC_PCIE_LINK3_IRQ:
- netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff);
- break;
- }
-}
-
-/* For XLS B silicon, the 3,4 PCI interrupts are different */
-static void xls_pcie_ack_b(struct irq_data *d)
-{
- nlm_reg_t *pcie_mmio_le = netlogic_io_mmio(NETLOGIC_IO_PCIE_1_OFFSET);
-
- switch (d->irq) {
- case PIC_PCIE_LINK0_IRQ:
- netlogic_write_reg(pcie_mmio_le, (0x90 >> 2), 0xffffffff);
- break;
- case PIC_PCIE_LINK1_IRQ:
- netlogic_write_reg(pcie_mmio_le, (0x94 >> 2), 0xffffffff);
- break;
- case PIC_PCIE_XLSB0_LINK2_IRQ:
- netlogic_write_reg(pcie_mmio_le, (0x190 >> 2), 0xffffffff);
- break;
- case PIC_PCIE_XLSB0_LINK3_IRQ:
- netlogic_write_reg(pcie_mmio_le, (0x194 >> 2), 0xffffffff);
- break;
- }
-}
-#endif
-
-static void xlr_pic_ack(struct irq_data *d)
-{
- unsigned long flags;
- nlm_reg_t *mmio;
- int irq = d->irq;
- void *hd = irq_data_get_irq_handler_data(d);
-
- WARN(!PIC_IRQ_IS_IRT(irq), "Bad irq %d", irq);
-
- if (hd) {
- void (*extra_ack)(void *) = hd;
- extra_ack(d);
- }
- mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
- spin_lock_irqsave(&nlm_pic_lock, flags);
- netlogic_write_reg(mmio, PIC_INT_ACK, (1 << (irq - PIC_IRQ_BASE)));
- spin_unlock_irqrestore(&nlm_pic_lock, flags);
-}
-
-/*
- * This chip definition handles interrupts routed thru the XLR
- * hardware PIC, currently IRQs 8-39 are mapped to hardware intr
- * 0-31 wired the XLR PIC
- */
-static struct irq_chip xlr_pic = {
- .name = "XLR-PIC",
- .irq_enable = xlr_pic_enable,
- .irq_mask = xlr_pic_mask,
- .irq_ack = xlr_pic_ack,
-};
-
-static void rsvd_irq_handler(struct irq_data *d)
-{
- WARN(d->irq >= PIC_IRQ_BASE, "Bad irq %d", d->irq);
-}
-
-/*
- * Chip definition for CPU originated interrupts(timer, msg) and
- * IPIs
- */
-struct irq_chip nlm_cpu_intr = {
- .name = "XLR-CPU-INTR",
- .irq_enable = rsvd_irq_handler,
- .irq_mask = rsvd_irq_handler,
- .irq_ack = rsvd_irq_handler,
-};
-
-void __init init_xlr_irqs(void)
-{
- nlm_reg_t *mmio = netlogic_io_mmio(NETLOGIC_IO_PIC_OFFSET);
- uint32_t thread_mask = 1;
- int level, i;
-
- pr_info("Interrupt thread mask [%x]\n", thread_mask);
- for (i = 0; i < PIC_NUM_IRTS; i++) {
- level = PIC_IRQ_IS_EDGE_TRIGGERED(i);
-
- /* Bind all PIC irqs to boot cpu */
- netlogic_write_reg(mmio, PIC_IRT_0_BASE + i, thread_mask);
-
- /*
- * Use local scheduling and high polarity for all IRTs
- * Invalidate all IRTs, by default
- */
- netlogic_write_reg(mmio, PIC_IRT_1_BASE + i,
- (level << 30) | (1 << 6) | (PIC_IRQ_BASE + i));
- }
-
- /* Make all IRQs as level triggered by default */
- for (i = 0; i < NR_IRQS; i++) {
- if (PIC_IRQ_IS_IRT(i))
- irq_set_chip_and_handler(i, &xlr_pic, handle_level_irq);
- else
- irq_set_chip_and_handler(i, &nlm_cpu_intr,
- handle_percpu_irq);
- }
-#ifdef CONFIG_SMP
- irq_set_chip_and_handler(IRQ_IPI_SMP_FUNCTION, &nlm_cpu_intr,
- nlm_smp_function_ipi_handler);
- irq_set_chip_and_handler(IRQ_IPI_SMP_RESCHEDULE, &nlm_cpu_intr,
- nlm_smp_resched_ipi_handler);
- nlm_irq_mask |=
- ((1ULL << IRQ_IPI_SMP_FUNCTION) | (1ULL << IRQ_IPI_SMP_RESCHEDULE));
-#endif
-
-#ifdef CONFIG_PCI
- /*
- * For PCI interrupts, we need to ack the PIC controller too, overload
- * irq handler data to do this
- */
- if (nlm_chip_is_xls()) {
- if (nlm_chip_is_xls_b()) {
- irq_set_handler_data(PIC_PCIE_LINK0_IRQ,
- xls_pcie_ack_b);
- irq_set_handler_data(PIC_PCIE_LINK1_IRQ,
- xls_pcie_ack_b);
- irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ,
- xls_pcie_ack_b);
- irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ,
- xls_pcie_ack_b);
- } else {
- irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack);
- irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack);
- irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack);
- irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack);
- }
- } else {
- /* XLR PCI controller ACK */
- irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack);
- }
-#endif
- /* unmask all PIC related interrupts. If no handler is installed by the
- * drivers, it'll just ack the interrupt and return
- */
- for (i = PIC_IRT_FIRST_IRQ; i <= PIC_IRT_LAST_IRQ; i++)
- nlm_irq_mask |= (1ULL << i);
-
- nlm_irq_mask |= (1ULL << IRQ_TIMER);
-}
-
-void __init arch_init_irq(void)
-{
- /* Initialize the irq descriptors */
- init_xlr_irqs();
- write_c0_eimr(nlm_irq_mask);
-}
-
-void __cpuinit nlm_smp_irq_init(void)
-{
- /* set interrupt mask for non-zero cpus */
- write_c0_eimr(nlm_irq_mask);
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
- uint64_t eirr;
- int i;
-
- eirr = read_c0_eirr() & read_c0_eimr();
- if (!eirr)
- return;
-
- /* no need of EIRR here, writing compare clears interrupt */
- if (eirr & (1 << IRQ_TIMER)) {
- do_IRQ(IRQ_TIMER);
- return;
- }
-
- /* use dcltz: optimize below code */
- for (i = 63; i != -1; i--) {
- if (eirr & (1ULL << i))
- break;
- }
- if (i == -1) {
- pr_err("no interrupt !!\n");
- return;
- }
-
- /* Ack eirr */
- write_c0_eirr(1ULL << i);
-
- do_IRQ(i);
-}
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c
index 609ec2534642..eab64b45dffd 100644
--- a/arch/mips/netlogic/xlr/platform.c
+++ b/arch/mips/netlogic/xlr/platform.c
@@ -15,18 +15,19 @@
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
+#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/xlr/iomap.h>
#include <asm/netlogic/xlr/pic.h>
#include <asm/netlogic/xlr/xlr.h>
unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
{
- nlm_reg_t *mmio;
+ uint64_t uartbase;
unsigned int value;
- /* XLR uart does not need any mapping of regs */
- mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift));
- value = netlogic_read_reg(mmio, 0);
+ /* sign extend to 64 bits, if needed */
+ uartbase = (uint64_t)(long)p->membase;
+ value = nlm_read_reg(uartbase, offset);
/* See XLR/XLS errata */
if (offset == UART_MSR)
@@ -39,10 +40,10 @@ unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
{
- nlm_reg_t *mmio;
+ uint64_t uartbase;
- /* XLR uart does not need any mapping of regs */
- mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift));
+ /* sign extend to 64 bits, if needed */
+ uartbase = (uint64_t)(long)p->membase;
/* See XLR/XLS errata */
if (offset == UART_MSR)
@@ -50,7 +51,7 @@ void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
else if (offset == UART_MCR)
value ^= 0x3;
- netlogic_write_reg(mmio, 0, value);
+ nlm_write_reg(uartbase, offset, value);
}
#define PORT(_irq) \
@@ -82,15 +83,15 @@ static struct platform_device uart_device = {
static int __init nlm_uart_init(void)
{
- nlm_reg_t *mmio;
+ unsigned long uartbase;
- mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
- xlr_uart_data[0].membase = (void __iomem *)mmio;
- xlr_uart_data[0].mapbase = CPHYSADDR((unsigned long)mmio);
+ uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
+ xlr_uart_data[0].membase = (void __iomem *)uartbase;
+ xlr_uart_data[0].mapbase = CPHYSADDR(uartbase);
- mmio = netlogic_io_mmio(NETLOGIC_IO_UART_1_OFFSET);
- xlr_uart_data[1].membase = (void __iomem *)mmio;
- xlr_uart_data[1].mapbase = CPHYSADDR((unsigned long)mmio);
+ uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_1_OFFSET);
+ xlr_uart_data[1].membase = (void __iomem *)uartbase;
+ xlr_uart_data[1].mapbase = CPHYSADDR(uartbase);
return platform_device_register(&uart_device);
}
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c
index cee25ddd0887..c9d066dedc4e 100644
--- a/arch/mips/netlogic/xlr/setup.c
+++ b/arch/mips/netlogic/xlr/setup.c
@@ -39,26 +39,33 @@
#include <asm/reboot.h>
#include <asm/time.h>
#include <asm/bootinfo.h>
-#include <asm/smp-ops.h>
#include <asm/netlogic/interrupt.h>
#include <asm/netlogic/psb-bootinfo.h>
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
#include <asm/netlogic/xlr/xlr.h>
#include <asm/netlogic/xlr/iomap.h>
#include <asm/netlogic/xlr/pic.h>
#include <asm/netlogic/xlr/gpio.h>
-unsigned long netlogic_io_base = (unsigned long)(DEFAULT_NETLOGIC_IO_BASE);
-unsigned long nlm_common_ebase = 0x0;
+uint64_t nlm_io_base = DEFAULT_NETLOGIC_IO_BASE;
+uint64_t nlm_pic_base;
struct psb_info nlm_prom_info;
+unsigned long nlm_common_ebase = 0x0;
+
+/* default to uniprocessor */
+uint32_t nlm_coremask = 1, nlm_cpumask = 1;
+int nlm_threads_per_core = 1;
+
static void __init nlm_early_serial_setup(void)
{
struct uart_port s;
- nlm_reg_t *uart_base;
+ unsigned long uart_base;
- uart_base = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
+ uart_base = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
memset(&s, 0, sizeof(s));
s.flags = ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST;
s.iotype = UPIO_MEM32;
@@ -67,18 +74,18 @@ static void __init nlm_early_serial_setup(void)
s.uartclk = PIC_CLKS_PER_SEC;
s.serial_in = nlm_xlr_uart_in;
s.serial_out = nlm_xlr_uart_out;
- s.mapbase = (unsigned long)uart_base;
+ s.mapbase = uart_base;
s.membase = (unsigned char __iomem *)uart_base;
early_serial_setup(&s);
}
static void nlm_linux_exit(void)
{
- nlm_reg_t *mmio;
+ uint64_t gpiobase;
- mmio = netlogic_io_mmio(NETLOGIC_IO_GPIO_OFFSET);
+ gpiobase = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET);
/* trigger a chip reset by writing 1 to GPIO_SWRESET_REG */
- netlogic_write_reg(mmio, NETLOGIC_GPIO_SWRESET_REG, 1);
+ nlm_write_reg(gpiobase, NETLOGIC_GPIO_SWRESET_REG, 1);
for ( ; ; )
cpu_wait();
}
@@ -96,6 +103,11 @@ const char *get_system_type(void)
return "Netlogic XLR/XLS Series";
}
+unsigned int nlm_get_cpu_frequency(void)
+{
+ return (unsigned int)nlm_prom_info.cpu_frequency;
+}
+
void __init prom_free_prom_memory(void)
{
/* Nothing yet */
@@ -175,6 +187,7 @@ void __init prom_init(void)
prom_infop = (struct psb_info *)(long)(int)fw_arg3;
nlm_prom_info = *prom_infop;
+ nlm_pic_base = nlm_mmio_base(NETLOGIC_IO_PIC_OFFSET);
nlm_early_serial_setup();
build_arcs_cmdline(argv);
diff --git a/arch/mips/netlogic/xlr/smpboot.S b/arch/mips/netlogic/xlr/wakeup.c
index 8cb7889ce0cc..db5d987d4881 100644
--- a/arch/mips/netlogic/xlr/smpboot.S
+++ b/arch/mips/netlogic/xlr/wakeup.c
@@ -33,68 +33,36 @@
*/
#include <linux/init.h>
+#include <linux/threads.h>
#include <asm/asm.h>
#include <asm/asm-offsets.h>
-#include <asm/regdef.h>
#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/string.h>
-/*
- * Early code for secondary CPUs. This will get them out of the bootloader
- * code and into linux. Needed because the bootloader area will be taken
- * and initialized by linux.
- */
- __CPUINIT
-NESTED(prom_pre_boot_secondary_cpus, 16, sp)
- .set mips64
- mfc0 t0, $15, 1 # read ebase
- andi t0, 0x1f # t0 has the processor_id()
- sll t0, 2 # offset in cpu array
-
- PTR_LA t1, nlm_cpu_ready # mark CPU ready
- PTR_ADDU t1, t0
- li t2, 1
- sw t2, 0(t1)
-
- PTR_LA t1, nlm_cpu_unblock
- PTR_ADDU t1, t0
-1: lw t2, 0(t1) # wait till unblocked
- beqz t2, 1b
- nop
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/common.h>
+#include <asm/netlogic/mips-extns.h>
- PTR_LA t1, nlm_next_sp
- PTR_L sp, 0(t1)
- PTR_LA t1, nlm_next_gp
- PTR_L gp, 0(t1)
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/pic.h>
- PTR_LA t0, nlm_early_init_secondary
- jalr t0
- nop
-
- PTR_LA t0, smp_bootstrap
- jr t0
- nop
-END(prom_pre_boot_secondary_cpus)
- __FINIT
-
-/*
- * NMI code, used for CPU wakeup, copied to reset entry
- */
-NESTED(nlm_boot_smp_nmi, 0, sp)
- .set push
- .set noat
- .set mips64
- .set noreorder
+int __cpuinit xlr_wakeup_secondary_cpus(void)
+{
+ unsigned int i, boot_cpu;
- /* Clear the NMI and BEV bits */
- MFC0 k0, CP0_STATUS
- li k1, 0xffb7ffff
- and k0, k0, k1
- MTC0 k0, CP0_STATUS
+ /*
+ * In case of RMI boot, hit with NMI to get the cores
+ * from bootloader to linux code.
+ */
+ boot_cpu = hard_smp_processor_id();
+ nlm_set_nmi_handler(nlm_rmiboot_preboot);
+ for (i = 0; i < NR_CPUS; i++) {
+ if (i == boot_cpu || (nlm_cpumask & (1u << i)) == 0)
+ continue;
+ nlm_pic_send_ipi(nlm_pic_base, i, 1, 1); /* send NMI */
+ }
- PTR_LA k1, secondary_entry_point
- PTR_L k0, 0(k1)
- jr k0
- nop
- .set pop
-END(nlm_boot_smp_nmi)
+ return 0;
+}
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index bb82cbdbc62a..c3ac4b086eb2 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o
obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \
ops-bcm63xx.o
obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o
+obj-$(CONFIG_SOC_AR724X) += pci-ath724x.o
#
# These are still pretty much in the old state, watch, go blind.
@@ -55,7 +56,7 @@ obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o
obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o
-obj-$(CONFIG_NLM_XLR) += pci-xlr.o
+obj-$(CONFIG_CPU_XLR) += pci-xlr.o
ifdef CONFIG_PCI_MSI
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index 5d530f89d872..d37be36dc659 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -162,7 +162,7 @@ msi_irq_allocated:
msg.address_hi = (0 + CVMX_NPEI_PCIE_MSI_RCV) >> 32;
break;
default:
- panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type\n");
+ panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type");
}
msg.data = irq - OCTEON_IRQ_MSI_BIT0;
diff --git a/arch/mips/pci/ops-pmcmsp.c b/arch/mips/pci/ops-pmcmsp.c
index 8fbfbf2b931c..389bf669d56e 100644
--- a/arch/mips/pci/ops-pmcmsp.c
+++ b/arch/mips/pci/ops-pmcmsp.c
@@ -405,7 +405,7 @@ int msp_pcibios_config_access(unsigned char access_type,
if (pciirqflag == 0) {
ret = request_irq(MSP_INT_PCI,/* Hardcoded internal MSP7120 wiring */
bpci_interrupt,
- IRQF_SHARED | IRQF_DISABLED,
+ IRQF_SHARED,
"PMC MSP PCI Host",
preg);
if (ret != 0)
diff --git a/arch/mips/pci/ops-tx3927.c b/arch/mips/pci/ops-tx3927.c
index 6a3bdb5ffa80..02d64f77e967 100644
--- a/arch/mips/pci/ops-tx3927.c
+++ b/arch/mips/pci/ops-tx3927.c
@@ -225,7 +225,7 @@ void __init tx3927_setup_pcierr_irq(void)
{
if (request_irq(TXX9_IRQ_BASE + TX3927_IR_PCI,
tx3927_pcierr_interrupt,
- IRQF_DISABLED, "PCI error",
+ 0, "PCI error",
(void *)TX3927_PCIC_REG))
printk(KERN_WARNING "Failed to request irq for PCIERR\n");
}
diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c
index b5ce041cdafb..ec125bed721c 100644
--- a/arch/mips/pci/pci-alchemy.c
+++ b/arch/mips/pci/pci-alchemy.c
@@ -13,9 +13,11 @@
#include <linux/platform_device.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/syscore_ops.h>
#include <linux/vmalloc.h>
#include <asm/mach-au1x00/au1000.h>
+#include <asm/tlbmisc.h>
#ifdef CONFIG_DEBUG_PCI
#define DBG(x...) printk(KERN_DEBUG x)
@@ -41,6 +43,12 @@ struct alchemy_pci_context {
int (*board_pci_idsel)(unsigned int devsel, int assert);
};
+/* for syscore_ops. There's only one PCI controller on Alchemy chips, so this
+ * should suffice for now.
+ */
+static struct alchemy_pci_context *__alchemy_pci_ctx;
+
+
/* IO/MEM resources for PCI. Keep the memres in sync with __fixup_bigphys_addr
* in arch/mips/alchemy/common/setup.c
*/
@@ -99,18 +107,6 @@ static int config_access(unsigned char access_type, struct pci_bus *bus,
return -1;
}
- /* YAMON on all db1xxx boards wipes the TLB and writes zero to C0_wired
- * on resume, clearing our wired entry. Unfortunately the ->resume()
- * callback is called way way way too late (and ->suspend() too early)
- * to have them destroy and recreate it. Instead just test if c0_wired
- * is now lower than the index we retrieved before suspending and then
- * recreate the entry if necessary. Of course this is totally bonkers
- * and breaks as soon as someone else adds another wired entry somewhere
- * else. Anyone have any ideas how to handle this better?
- */
- if (unlikely(read_c0_wired() < ctx->wired_entry))
- alchemy_pci_wired_entry(ctx);
-
local_irq_save(flags);
r = __raw_readl(ctx->regs + PCI_REG_STATCMD) & 0x0000ffff;
r |= PCI_STATCMD_STATUS(0x2000);
@@ -304,6 +300,62 @@ static int alchemy_pci_def_idsel(unsigned int devsel, int assert)
return 1; /* success */
}
+/* save PCI controller register contents. */
+static int alchemy_pci_suspend(void)
+{
+ struct alchemy_pci_context *ctx = __alchemy_pci_ctx;
+ if (!ctx)
+ return 0;
+
+ ctx->pm[0] = __raw_readl(ctx->regs + PCI_REG_CMEM);
+ ctx->pm[1] = __raw_readl(ctx->regs + PCI_REG_CONFIG) & 0x0009ffff;
+ ctx->pm[2] = __raw_readl(ctx->regs + PCI_REG_B2BMASK_CCH);
+ ctx->pm[3] = __raw_readl(ctx->regs + PCI_REG_B2BBASE0_VID);
+ ctx->pm[4] = __raw_readl(ctx->regs + PCI_REG_B2BBASE1_SID);
+ ctx->pm[5] = __raw_readl(ctx->regs + PCI_REG_MWMASK_DEV);
+ ctx->pm[6] = __raw_readl(ctx->regs + PCI_REG_MWBASE_REV_CCL);
+ ctx->pm[7] = __raw_readl(ctx->regs + PCI_REG_ID);
+ ctx->pm[8] = __raw_readl(ctx->regs + PCI_REG_CLASSREV);
+ ctx->pm[9] = __raw_readl(ctx->regs + PCI_REG_PARAM);
+ ctx->pm[10] = __raw_readl(ctx->regs + PCI_REG_MBAR);
+ ctx->pm[11] = __raw_readl(ctx->regs + PCI_REG_TIMEOUT);
+
+ return 0;
+}
+
+static void alchemy_pci_resume(void)
+{
+ struct alchemy_pci_context *ctx = __alchemy_pci_ctx;
+ if (!ctx)
+ return;
+
+ __raw_writel(ctx->pm[0], ctx->regs + PCI_REG_CMEM);
+ __raw_writel(ctx->pm[2], ctx->regs + PCI_REG_B2BMASK_CCH);
+ __raw_writel(ctx->pm[3], ctx->regs + PCI_REG_B2BBASE0_VID);
+ __raw_writel(ctx->pm[4], ctx->regs + PCI_REG_B2BBASE1_SID);
+ __raw_writel(ctx->pm[5], ctx->regs + PCI_REG_MWMASK_DEV);
+ __raw_writel(ctx->pm[6], ctx->regs + PCI_REG_MWBASE_REV_CCL);
+ __raw_writel(ctx->pm[7], ctx->regs + PCI_REG_ID);
+ __raw_writel(ctx->pm[8], ctx->regs + PCI_REG_CLASSREV);
+ __raw_writel(ctx->pm[9], ctx->regs + PCI_REG_PARAM);
+ __raw_writel(ctx->pm[10], ctx->regs + PCI_REG_MBAR);
+ __raw_writel(ctx->pm[11], ctx->regs + PCI_REG_TIMEOUT);
+ wmb();
+ __raw_writel(ctx->pm[1], ctx->regs + PCI_REG_CONFIG);
+ wmb();
+
+ /* YAMON on all db1xxx boards wipes the TLB and writes zero to C0_wired
+ * on resume, making it necessary to recreate it as soon as possible.
+ */
+ ctx->wired_entry = 8191; /* impossibly high value */
+ alchemy_pci_wired_entry(ctx); /* install it */
+}
+
+static struct syscore_ops alchemy_pci_pmops = {
+ .suspend = alchemy_pci_suspend,
+ .resume = alchemy_pci_resume,
+};
+
static int __devinit alchemy_pci_probe(struct platform_device *pdev)
{
struct alchemy_pci_platdata *pd = pdev->dev.platform_data;
@@ -396,7 +448,8 @@ static int __devinit alchemy_pci_probe(struct platform_device *pdev)
ret = -ENOMEM;
goto out4;
}
- ctx->wired_entry = 8192; /* impossibly high value */
+ ctx->wired_entry = 8191; /* impossibly high value */
+ alchemy_pci_wired_entry(ctx); /* install it */
set_io_port_base((unsigned long)ctx->alchemy_pci_ctrl.io_map_base);
@@ -408,7 +461,9 @@ static int __devinit alchemy_pci_probe(struct platform_device *pdev)
__raw_writel(val, ctx->regs + PCI_REG_CONFIG);
wmb();
+ __alchemy_pci_ctx = ctx;
platform_set_drvdata(pdev, ctx);
+ register_syscore_ops(&alchemy_pci_pmops);
register_pci_controller(&ctx->alchemy_pci_ctrl);
return 0;
@@ -425,68 +480,11 @@ out:
return ret;
}
-
-#ifdef CONFIG_PM
-/* save PCI controller register contents. */
-static int alchemy_pci_suspend(struct device *dev)
-{
- struct alchemy_pci_context *ctx = dev_get_drvdata(dev);
-
- ctx->pm[0] = __raw_readl(ctx->regs + PCI_REG_CMEM);
- ctx->pm[1] = __raw_readl(ctx->regs + PCI_REG_CONFIG) & 0x0009ffff;
- ctx->pm[2] = __raw_readl(ctx->regs + PCI_REG_B2BMASK_CCH);
- ctx->pm[3] = __raw_readl(ctx->regs + PCI_REG_B2BBASE0_VID);
- ctx->pm[4] = __raw_readl(ctx->regs + PCI_REG_B2BBASE1_SID);
- ctx->pm[5] = __raw_readl(ctx->regs + PCI_REG_MWMASK_DEV);
- ctx->pm[6] = __raw_readl(ctx->regs + PCI_REG_MWBASE_REV_CCL);
- ctx->pm[7] = __raw_readl(ctx->regs + PCI_REG_ID);
- ctx->pm[8] = __raw_readl(ctx->regs + PCI_REG_CLASSREV);
- ctx->pm[9] = __raw_readl(ctx->regs + PCI_REG_PARAM);
- ctx->pm[10] = __raw_readl(ctx->regs + PCI_REG_MBAR);
- ctx->pm[11] = __raw_readl(ctx->regs + PCI_REG_TIMEOUT);
-
- return 0;
-}
-
-static int alchemy_pci_resume(struct device *dev)
-{
- struct alchemy_pci_context *ctx = dev_get_drvdata(dev);
-
- __raw_writel(ctx->pm[0], ctx->regs + PCI_REG_CMEM);
- __raw_writel(ctx->pm[2], ctx->regs + PCI_REG_B2BMASK_CCH);
- __raw_writel(ctx->pm[3], ctx->regs + PCI_REG_B2BBASE0_VID);
- __raw_writel(ctx->pm[4], ctx->regs + PCI_REG_B2BBASE1_SID);
- __raw_writel(ctx->pm[5], ctx->regs + PCI_REG_MWMASK_DEV);
- __raw_writel(ctx->pm[6], ctx->regs + PCI_REG_MWBASE_REV_CCL);
- __raw_writel(ctx->pm[7], ctx->regs + PCI_REG_ID);
- __raw_writel(ctx->pm[8], ctx->regs + PCI_REG_CLASSREV);
- __raw_writel(ctx->pm[9], ctx->regs + PCI_REG_PARAM);
- __raw_writel(ctx->pm[10], ctx->regs + PCI_REG_MBAR);
- __raw_writel(ctx->pm[11], ctx->regs + PCI_REG_TIMEOUT);
- wmb();
- __raw_writel(ctx->pm[1], ctx->regs + PCI_REG_CONFIG);
- wmb();
-
- return 0;
-}
-
-static const struct dev_pm_ops alchemy_pci_pmops = {
- .suspend = alchemy_pci_suspend,
- .resume = alchemy_pci_resume,
-};
-
-#define ALCHEMY_PCICTL_PM (&alchemy_pci_pmops)
-
-#else
-#define ALCHEMY_PCICTL_PM NULL
-#endif
-
static struct platform_driver alchemy_pcictl_driver = {
.probe = alchemy_pci_probe,
.driver = {
.name = "alchemy-pci",
.owner = THIS_MODULE,
- .pm = ALCHEMY_PCICTL_PM,
},
};
diff --git a/arch/mips/pci/pci-ath724x.c b/arch/mips/pci/pci-ath724x.c
new file mode 100644
index 000000000000..a4dd24a4130b
--- /dev/null
+++ b/arch/mips/pci/pci-ath724x.c
@@ -0,0 +1,174 @@
+/*
+ * Atheros 724x PCI support
+ *
+ * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/pci.h>
+#include <asm/mach-ath79/pci-ath724x.h>
+
+#define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys))
+#define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val))
+
+#define ATH724X_PCI_DEV_BASE 0x14000000
+#define ATH724X_PCI_MEM_BASE 0x10000000
+#define ATH724X_PCI_MEM_SIZE 0x08000000
+
+static DEFINE_SPINLOCK(ath724x_pci_lock);
+static struct ath724x_pci_data *pci_data;
+static int pci_data_size;
+
+static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, uint32_t *value)
+{
+ unsigned long flags, addr, tval, mask;
+
+ if (devfn)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (where & (size - 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ spin_lock_irqsave(&ath724x_pci_lock, flags);
+
+ switch (size) {
+ case 1:
+ addr = where & ~3;
+ mask = 0xff000000 >> ((where % 4) * 8);
+ tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
+ tval = tval & ~mask;
+ *value = (tval >> ((4 - (where % 4))*8));
+ break;
+ case 2:
+ addr = where & ~3;
+ mask = 0xffff0000 >> ((where % 4)*8);
+ tval = reg_read(ATH724X_PCI_DEV_BASE + addr);
+ tval = tval & ~mask;
+ *value = (tval >> ((4 - (where % 4))*8));
+ break;
+ case 4:
+ *value = reg_read(ATH724X_PCI_DEV_BASE + where);
+ break;
+ default:
+ spin_unlock_irqrestore(&ath724x_pci_lock, flags);
+
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
+ spin_unlock_irqrestore(&ath724x_pci_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where,
+ int size, uint32_t value)
+{
+ unsigned long flags, tval, addr, mask;
+
+ if (devfn)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (where & (size - 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ spin_lock_irqsave(&ath724x_pci_lock, flags);
+
+ switch (size) {
+ case 1:
+ addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
+ mask = 0xff000000 >> ((where % 4)*8);
+ tval = reg_read(addr);
+ tval = tval & ~mask;
+ tval |= (value << ((4 - (where % 4))*8)) & mask;
+ reg_write(addr, tval);
+ break;
+ case 2:
+ addr = (ATH724X_PCI_DEV_BASE + where) & ~3;
+ mask = 0xffff0000 >> ((where % 4)*8);
+ tval = reg_read(addr);
+ tval = tval & ~mask;
+ tval |= (value << ((4 - (where % 4))*8)) & mask;
+ reg_write(addr, tval);
+ break;
+ case 4:
+ reg_write((ATH724X_PCI_DEV_BASE + where), value);
+ break;
+ default:
+ spin_unlock_irqrestore(&ath724x_pci_lock, flags);
+
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ }
+
+ spin_unlock_irqrestore(&ath724x_pci_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops ath724x_pci_ops = {
+ .read = ath724x_pci_read,
+ .write = ath724x_pci_write,
+};
+
+static struct resource ath724x_io_resource = {
+ .name = "PCI IO space",
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IO,
+};
+
+static struct resource ath724x_mem_resource = {
+ .name = "PCI memory space",
+ .start = ATH724X_PCI_MEM_BASE,
+ .end = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct pci_controller ath724x_pci_controller = {
+ .pci_ops = &ath724x_pci_ops,
+ .io_resource = &ath724x_io_resource,
+ .mem_resource = &ath724x_mem_resource,
+};
+
+void ath724x_pci_add_data(struct ath724x_pci_data *data, int size)
+{
+ pci_data = data;
+ pci_data_size = size;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
+{
+ unsigned int devfn = dev->devfn;
+ int irq = -1;
+
+ if (devfn > pci_data_size - 1)
+ return irq;
+
+ irq = pci_data[devfn].irq;
+
+ return irq;
+}
+
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ unsigned int devfn = dev->devfn;
+
+ if (devfn > pci_data_size - 1)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ dev->dev.platform_data = pci_data[devfn].pdata;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int __init ath724x_pcibios_init(void)
+{
+ register_pci_controller(&ath724x_pci_controller);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+arch_initcall(ath724x_pcibios_init);
diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c
index 82e0fde1dba0..39eb7c417e2f 100644
--- a/arch/mips/pci/pci-bcm63xx.c
+++ b/arch/mips/pci/pci-bcm63xx.c
@@ -99,7 +99,7 @@ static int __init bcm63xx_pci_init(void)
unsigned int mem_size;
u32 val;
- if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
+ if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368())
return -ENODEV;
if (!bcm63xx_pci_enabled)
@@ -159,7 +159,7 @@ static int __init bcm63xx_pci_init(void)
/* setup PCI to local bus access, used by PCI device to target
* local RAM while bus mastering */
bcm63xx_int_cfg_writel(0, PCI_BASE_ADDRESS_3);
- if (BCMCPU_IS_6358())
+ if (BCMCPU_IS_6358() || BCMCPU_IS_6368())
val = MPI_SP0_REMAP_ENABLE_MASK;
else
val = 0;
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index ed1c54284b8f..52a1ba70b3b6 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -99,7 +99,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
*/
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 64 / 4);
/* Set latency timers for all devices */
- pci_write_config_byte(dev, PCI_LATENCY_TIMER, 48);
+ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64);
/* Enable reporting System errors and parity errors on all devices */
/* Enable parity checking and error reporting */
@@ -109,7 +109,7 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
if (dev->subordinate) {
/* Set latency timers on sub bridges */
- pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 48);
+ pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 64);
/* More bridge error detection */
pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
@@ -121,14 +121,10 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
if (pos) {
/* Update Device Control */
pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
- /* Correctable Error Reporting */
- config |= PCI_EXP_DEVCTL_CERE;
- /* Non-Fatal Error Reporting */
- config |= PCI_EXP_DEVCTL_NFERE;
- /* Fatal Error Reporting */
- config |= PCI_EXP_DEVCTL_FERE;
- /* Unsupported Request */
- config |= PCI_EXP_DEVCTL_URRE;
+ config |= PCI_EXP_DEVCTL_CERE; /* Correctable Error Reporting */
+ config |= PCI_EXP_DEVCTL_NFERE; /* Non-Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_FERE; /* Fatal Error Reporting */
+ config |= PCI_EXP_DEVCTL_URRE; /* Unsupported Request */
pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
}
diff --git a/arch/mips/pci/pci-tx4927.c b/arch/mips/pci/pci-tx4927.c
index a5807406a7f1..a032ae0a533d 100644
--- a/arch/mips/pci/pci-tx4927.c
+++ b/arch/mips/pci/pci-tx4927.c
@@ -85,7 +85,7 @@ void __init tx4927_setup_pcierr_irq(void)
{
if (request_irq(TXX9_IRQ_BASE + TX4927_IR_PCIERR,
tx4927_pcierr_interrupt,
- IRQF_DISABLED, "PCI error",
+ 0, "PCI error",
(void *)TX4927_PCIC_REG))
printk(KERN_WARNING "Failed to request irq for PCIERR\n");
}
diff --git a/arch/mips/pci/pci-tx4938.c b/arch/mips/pci/pci-tx4938.c
index 20e45f30b2ef..141bba562488 100644
--- a/arch/mips/pci/pci-tx4938.c
+++ b/arch/mips/pci/pci-tx4938.c
@@ -136,7 +136,7 @@ void __init tx4938_setup_pcierr_irq(void)
{
if (request_irq(TXX9_IRQ_BASE + TX4938_IR_PCIERR,
tx4927_pcierr_interrupt,
- IRQF_DISABLED, "PCI error",
+ 0, "PCI error",
(void *)TX4927_PCIC_REG))
printk(KERN_WARNING "Failed to request irq for PCIERR\n");
}
diff --git a/arch/mips/pci/pci-tx4939.c b/arch/mips/pci/pci-tx4939.c
index 9ef840693baf..c10fbf2a19dc 100644
--- a/arch/mips/pci/pci-tx4939.c
+++ b/arch/mips/pci/pci-tx4939.c
@@ -101,7 +101,7 @@ void __init tx4939_setup_pcierr_irq(void)
{
if (request_irq(TXX9_IRQ_BASE + TX4939_IR_PCIERR,
tx4927_pcierr_interrupt,
- IRQF_DISABLED, "PCI error",
+ 0, "PCI error",
(void *)TX4939_PCIC_REG))
pr_warning("Failed to request irq for PCIERR\n");
}
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 38fece16c435..3d701a962ef4 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -36,12 +36,18 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/msi.h>
#include <linux/mm.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
#include <linux/console.h>
#include <asm/io.h>
#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/haldefs.h>
+
+#include <asm/netlogic/xlr/msidef.h>
#include <asm/netlogic/xlr/iomap.h>
#include <asm/netlogic/xlr/pic.h>
#include <asm/netlogic/xlr/xlr.h>
@@ -150,7 +156,7 @@ struct pci_controller nlm_pci_controller = {
.io_offset = 0x00000000UL,
};
-int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+static int get_irq_vector(const struct pci_dev *dev)
{
if (!nlm_chip_is_xls())
return PIC_PCIX_IRQ; /* for XLR just one IRQ*/
@@ -182,6 +188,101 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return 0;
}
+#ifdef CONFIG_PCI_MSI
+void destroy_irq(unsigned int irq)
+{
+ /* nothing to do yet */
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+ destroy_irq(irq);
+}
+
+int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+{
+ struct msi_msg msg;
+ int irq, ret;
+
+ irq = get_irq_vector(dev);
+ if (irq <= 0)
+ return 1;
+
+ msg.address_hi = MSI_ADDR_BASE_HI;
+ msg.address_lo = MSI_ADDR_BASE_LO |
+ MSI_ADDR_DEST_MODE_PHYSICAL |
+ MSI_ADDR_REDIRECTION_CPU;
+
+ msg.data = MSI_DATA_TRIGGER_EDGE |
+ MSI_DATA_LEVEL_ASSERT |
+ MSI_DATA_DELIVERY_FIXED;
+
+ ret = irq_set_msi_desc(irq, desc);
+ if (ret < 0) {
+ destroy_irq(irq);
+ return ret;
+ }
+
+ write_msi_msg(irq, &msg);
+ return 0;
+}
+#endif
+
+/* Extra ACK needed for XLR on chip PCI controller */
+static void xlr_pci_ack(struct irq_data *d)
+{
+ uint64_t pcibase = nlm_mmio_base(NETLOGIC_IO_PCIX_OFFSET);
+
+ nlm_read_reg(pcibase, (0x140 >> 2));
+}
+
+/* Extra ACK needed for XLS on chip PCIe controller */
+static void xls_pcie_ack(struct irq_data *d)
+{
+ uint64_t pciebase_le = nlm_mmio_base(NETLOGIC_IO_PCIE_1_OFFSET);
+
+ switch (d->irq) {
+ case PIC_PCIE_LINK0_IRQ:
+ nlm_write_reg(pciebase_le, (0x90 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_LINK1_IRQ:
+ nlm_write_reg(pciebase_le, (0x94 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_LINK2_IRQ:
+ nlm_write_reg(pciebase_le, (0x190 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_LINK3_IRQ:
+ nlm_write_reg(pciebase_le, (0x194 >> 2), 0xffffffff);
+ break;
+ }
+}
+
+/* For XLS B silicon, the 3,4 PCI interrupts are different */
+static void xls_pcie_ack_b(struct irq_data *d)
+{
+ uint64_t pciebase_le = nlm_mmio_base(NETLOGIC_IO_PCIE_1_OFFSET);
+
+ switch (d->irq) {
+ case PIC_PCIE_LINK0_IRQ:
+ nlm_write_reg(pciebase_le, (0x90 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_LINK1_IRQ:
+ nlm_write_reg(pciebase_le, (0x94 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_XLSB0_LINK2_IRQ:
+ nlm_write_reg(pciebase_le, (0x190 >> 2), 0xffffffff);
+ break;
+ case PIC_PCIE_XLSB0_LINK3_IRQ:
+ nlm_write_reg(pciebase_le, (0x194 >> 2), 0xffffffff);
+ break;
+ }
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return get_irq_vector(dev);
+}
+
/* Do platform specific device initialization at pci_enable_device() time */
int pcibios_plat_dev_init(struct pci_dev *dev)
{
@@ -204,6 +305,31 @@ static int __init pcibios_init(void)
pr_info("Registering XLR/XLS PCIX/PCIE Controller.\n");
register_pci_controller(&nlm_pci_controller);
+ /*
+ * For PCI interrupts, we need to ack the PCI controller too, overload
+ * irq handler data to do this
+ */
+ if (nlm_chip_is_xls()) {
+ if (nlm_chip_is_xls_b()) {
+ irq_set_handler_data(PIC_PCIE_LINK0_IRQ,
+ xls_pcie_ack_b);
+ irq_set_handler_data(PIC_PCIE_LINK1_IRQ,
+ xls_pcie_ack_b);
+ irq_set_handler_data(PIC_PCIE_XLSB0_LINK2_IRQ,
+ xls_pcie_ack_b);
+ irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ,
+ xls_pcie_ack_b);
+ } else {
+ irq_set_handler_data(PIC_PCIE_LINK0_IRQ, xls_pcie_ack);
+ irq_set_handler_data(PIC_PCIE_LINK1_IRQ, xls_pcie_ack);
+ irq_set_handler_data(PIC_PCIE_LINK2_IRQ, xls_pcie_ack);
+ irq_set_handler_data(PIC_PCIE_LINK3_IRQ, xls_pcie_ack);
+ }
+ } else {
+ /* XLR PCI controller ACK */
+ irq_set_handler_data(PIC_PCIE_XLSB0_LINK3_IRQ, xlr_pci_ack);
+ }
+
return 0;
}
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c
index fa8e378413b1..aec2b111d35b 100644
--- a/arch/mips/pci/pci.c
+++ b/arch/mips/pci/pci.c
@@ -4,8 +4,11 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
- * Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2003, 04, 11 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2011 Wind River Systems,
+ * written by Ralf Baechle (ralf@linux-mips.org)
*/
+#include <linux/bug.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
@@ -14,6 +17,8 @@
#include <linux/types.h>
#include <linux/pci.h>
+#include <asm/cpu-info.h>
+
/*
* Indicate whether we respect the PCI setup left by the firmware.
*
@@ -157,10 +162,32 @@ out:
"Skipping PCI bus scan due to resource conflict\n");
}
+static void __init pcibios_set_cache_line_size(void)
+{
+ struct cpuinfo_mips *c = &current_cpu_data;
+ unsigned int lsize;
+
+ /*
+ * Set PCI cacheline size to that of the highest level in the
+ * cache hierarchy.
+ */
+ lsize = c->dcache.linesz;
+ lsize = c->scache.linesz ? : lsize;
+ lsize = c->tcache.linesz ? : lsize;
+
+ BUG_ON(!lsize);
+
+ pci_dfl_cache_line_size = lsize >> 2;
+
+ pr_debug("PCI: pci_cache_line_size set to %d bytes\n", lsize);
+}
+
static int __init pcibios_init(void)
{
struct pci_controller *hose;
+ pcibios_set_cache_line_size();
+
/* Scan all of the recorded PCI controllers. */
for (hose = hose_head; hose; hose = hose->next)
pcibios_scanbus(hose);
diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c
index 0583c463e5f1..fdb4d558c0cc 100644
--- a/arch/mips/pci/pcie-octeon.c
+++ b/arch/mips/pci/pcie-octeon.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2007, 2008 Cavium Networks
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011 Cavium Networks
*/
#include <linux/kernel.h>
#include <linux/init.h>
@@ -11,15 +11,32 @@
#include <linux/interrupt.h>
#include <linux/time.h>
#include <linux/delay.h>
+#include <linux/module.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-npei-defs.h>
#include <asm/octeon/cvmx-pciercx-defs.h>
#include <asm/octeon/cvmx-pescx-defs.h>
#include <asm/octeon/cvmx-pexp-defs.h>
+#include <asm/octeon/cvmx-pemx-defs.h>
+#include <asm/octeon/cvmx-dpi-defs.h>
+#include <asm/octeon/cvmx-sli-defs.h>
+#include <asm/octeon/cvmx-sriox-defs.h>
#include <asm/octeon/cvmx-helper-errata.h>
#include <asm/octeon/pci-octeon.h>
+#define MRRS_CN5XXX 0 /* 128 byte Max Read Request Size */
+#define MPS_CN5XXX 0 /* 128 byte Max Packet Size (Limit of most PCs) */
+#define MRRS_CN6XXX 3 /* 1024 byte Max Read Request Size */
+#define MPS_CN6XXX 0 /* 128 byte Max Packet Size (Limit of most PCs) */
+
+/* Module parameter to disable PCI probing */
+static int pcie_disable;
+module_param(pcie_disable, int, S_IRUGO);
+
+static int enable_pcie_14459_war;
+static int enable_pcie_bus_num_war[2];
+
union cvmx_pcie_address {
uint64_t u64;
struct {
@@ -75,6 +92,8 @@ union cvmx_pcie_address {
} mem;
};
+static int cvmx_pcie_rc_initialize(int pcie_port);
+
#include <dma-coherence.h>
/**
@@ -154,12 +173,21 @@ static inline uint64_t cvmx_pcie_get_mem_size(int pcie_port)
*/
static uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset)
{
- union cvmx_pescx_cfg_rd pescx_cfg_rd;
- pescx_cfg_rd.u64 = 0;
- pescx_cfg_rd.s.addr = cfg_offset;
- cvmx_write_csr(CVMX_PESCX_CFG_RD(pcie_port), pescx_cfg_rd.u64);
- pescx_cfg_rd.u64 = cvmx_read_csr(CVMX_PESCX_CFG_RD(pcie_port));
- return pescx_cfg_rd.s.data;
+ if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
+ union cvmx_pescx_cfg_rd pescx_cfg_rd;
+ pescx_cfg_rd.u64 = 0;
+ pescx_cfg_rd.s.addr = cfg_offset;
+ cvmx_write_csr(CVMX_PESCX_CFG_RD(pcie_port), pescx_cfg_rd.u64);
+ pescx_cfg_rd.u64 = cvmx_read_csr(CVMX_PESCX_CFG_RD(pcie_port));
+ return pescx_cfg_rd.s.data;
+ } else {
+ union cvmx_pemx_cfg_rd pemx_cfg_rd;
+ pemx_cfg_rd.u64 = 0;
+ pemx_cfg_rd.s.addr = cfg_offset;
+ cvmx_write_csr(CVMX_PEMX_CFG_RD(pcie_port), pemx_cfg_rd.u64);
+ pemx_cfg_rd.u64 = cvmx_read_csr(CVMX_PEMX_CFG_RD(pcie_port));
+ return pemx_cfg_rd.s.data;
+ }
}
/**
@@ -173,11 +201,19 @@ static uint32_t cvmx_pcie_cfgx_read(int pcie_port, uint32_t cfg_offset)
static void cvmx_pcie_cfgx_write(int pcie_port, uint32_t cfg_offset,
uint32_t val)
{
- union cvmx_pescx_cfg_wr pescx_cfg_wr;
- pescx_cfg_wr.u64 = 0;
- pescx_cfg_wr.s.addr = cfg_offset;
- pescx_cfg_wr.s.data = val;
- cvmx_write_csr(CVMX_PESCX_CFG_WR(pcie_port), pescx_cfg_wr.u64);
+ if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
+ union cvmx_pescx_cfg_wr pescx_cfg_wr;
+ pescx_cfg_wr.u64 = 0;
+ pescx_cfg_wr.s.addr = cfg_offset;
+ pescx_cfg_wr.s.data = val;
+ cvmx_write_csr(CVMX_PESCX_CFG_WR(pcie_port), pescx_cfg_wr.u64);
+ } else {
+ union cvmx_pemx_cfg_wr pemx_cfg_wr;
+ pemx_cfg_wr.u64 = 0;
+ pemx_cfg_wr.s.addr = cfg_offset;
+ pemx_cfg_wr.s.data = val;
+ cvmx_write_csr(CVMX_PEMX_CFG_WR(pcie_port), pemx_cfg_wr.u64);
+ }
}
/**
@@ -348,7 +384,6 @@ static void cvmx_pcie_config_write32(int pcie_port, int bus, int dev, int fn,
static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
{
union cvmx_pciercx_cfg030 pciercx_cfg030;
- union cvmx_npei_ctl_status2 npei_ctl_status2;
union cvmx_pciercx_cfg070 pciercx_cfg070;
union cvmx_pciercx_cfg001 pciercx_cfg001;
union cvmx_pciercx_cfg032 pciercx_cfg032;
@@ -365,21 +400,21 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
/* Max Read Request Size (PCIE*_CFG030[MRRS]) */
/* Relaxed-order, no-snoop enables (PCIE*_CFG030[RO_EN,NS_EN] */
/* Error Message Enables (PCIE*_CFG030[CE_EN,NFE_EN,FE_EN,UR_EN]) */
- pciercx_cfg030.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG030(pcie_port));
- /*
- * Max payload size = 128 bytes for best Octeon DMA
- * performance.
- */
- pciercx_cfg030.s.mps = 0;
+
+ pciercx_cfg030.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG030(pcie_port));
+ if (OCTEON_IS_MODEL(OCTEON_CN5XXX)) {
+ pciercx_cfg030.s.mps = MPS_CN5XXX;
+ pciercx_cfg030.s.mrrs = MRRS_CN5XXX;
+ } else {
+ pciercx_cfg030.s.mps = MPS_CN6XXX;
+ pciercx_cfg030.s.mrrs = MRRS_CN6XXX;
+ }
/*
- * Max read request size = 128 bytes for best Octeon DMA
- * performance.
+ * Enable relaxed order processing. This will allow devices to
+ * affect read response ordering.
*/
- pciercx_cfg030.s.mrrs = 0;
- /* Enable relaxed ordering. */
pciercx_cfg030.s.ro_en = 1;
- /* Enable no snoop. */
+ /* Enable no snoop processing. Not used by Octeon */
pciercx_cfg030.s.ns_en = 1;
/* Correctable error reporting enable. */
pciercx_cfg030.s.ce_en = 1;
@@ -389,50 +424,67 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
pciercx_cfg030.s.fe_en = 1;
/* Unsupported request reporting enable. */
pciercx_cfg030.s.ur_en = 1;
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG030(pcie_port),
- pciercx_cfg030.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG030(pcie_port), pciercx_cfg030.u32);
- /*
- * Max Payload Size (NPEI_CTL_STATUS2[MPS]) must match
- * PCIE*_CFG030[MPS]
- *
- * Max Read Request Size (NPEI_CTL_STATUS2[MRRS]) must not
- * exceed PCIE*_CFG030[MRRS].
- */
- npei_ctl_status2.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS2);
- /* Max payload size = 128 bytes for best Octeon DMA performance */
- npei_ctl_status2.s.mps = 0;
- /* Max read request size = 128 bytes for best Octeon DMA performance */
- npei_ctl_status2.s.mrrs = 0;
- if (pcie_port)
- npei_ctl_status2.s.c1_b1_s = 3; /* Port1 BAR1 Size 256MB */
- else
- npei_ctl_status2.s.c0_b1_s = 3; /* Port0 BAR1 Size 256MB */
- cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64);
+
+ if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
+ union cvmx_npei_ctl_status2 npei_ctl_status2;
+ /*
+ * Max Payload Size (NPEI_CTL_STATUS2[MPS]) must match
+ * PCIE*_CFG030[MPS]. Max Read Request Size
+ * (NPEI_CTL_STATUS2[MRRS]) must not exceed
+ * PCIE*_CFG030[MRRS]
+ */
+ npei_ctl_status2.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS2);
+ /* Max payload size = 128 bytes for best Octeon DMA performance */
+ npei_ctl_status2.s.mps = MPS_CN5XXX;
+ /* Max read request size = 128 bytes for best Octeon DMA performance */
+ npei_ctl_status2.s.mrrs = MRRS_CN5XXX;
+ if (pcie_port)
+ npei_ctl_status2.s.c1_b1_s = 3; /* Port1 BAR1 Size 256MB */
+ else
+ npei_ctl_status2.s.c0_b1_s = 3; /* Port0 BAR1 Size 256MB */
+
+ cvmx_write_csr(CVMX_PEXP_NPEI_CTL_STATUS2, npei_ctl_status2.u64);
+ } else {
+ /*
+ * Max Payload Size (DPI_SLI_PRTX_CFG[MPS]) must match
+ * PCIE*_CFG030[MPS]. Max Read Request Size
+ * (DPI_SLI_PRTX_CFG[MRRS]) must not exceed
+ * PCIE*_CFG030[MRRS].
+ */
+ union cvmx_dpi_sli_prtx_cfg prt_cfg;
+ union cvmx_sli_s2m_portx_ctl sli_s2m_portx_ctl;
+ prt_cfg.u64 = cvmx_read_csr(CVMX_DPI_SLI_PRTX_CFG(pcie_port));
+ prt_cfg.s.mps = MPS_CN6XXX;
+ prt_cfg.s.mrrs = MRRS_CN6XXX;
+ /* Max outstanding load request. */
+ prt_cfg.s.molr = 32;
+ cvmx_write_csr(CVMX_DPI_SLI_PRTX_CFG(pcie_port), prt_cfg.u64);
+
+ sli_s2m_portx_ctl.u64 = cvmx_read_csr(CVMX_PEXP_SLI_S2M_PORTX_CTL(pcie_port));
+ sli_s2m_portx_ctl.s.mrrs = MRRS_CN6XXX;
+ cvmx_write_csr(CVMX_PEXP_SLI_S2M_PORTX_CTL(pcie_port), sli_s2m_portx_ctl.u64);
+ }
/* ECRC Generation (PCIE*_CFG070[GE,CE]) */
- pciercx_cfg070.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG070(pcie_port));
+ pciercx_cfg070.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG070(pcie_port));
pciercx_cfg070.s.ge = 1; /* ECRC generation enable. */
pciercx_cfg070.s.ce = 1; /* ECRC check enable. */
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG070(pcie_port),
- pciercx_cfg070.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG070(pcie_port), pciercx_cfg070.u32);
/*
- * Access Enables (PCIE*_CFG001[MSAE,ME]) ME and MSAE should
- * always be set.
- *
- * Interrupt Disable (PCIE*_CFG001[I_DIS]) System Error
- * Message Enable (PCIE*_CFG001[SEE])
+ * Access Enables (PCIE*_CFG001[MSAE,ME])
+ * ME and MSAE should always be set.
+ * Interrupt Disable (PCIE*_CFG001[I_DIS])
+ * System Error Message Enable (PCIE*_CFG001[SEE])
*/
- pciercx_cfg001.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG001(pcie_port));
+ pciercx_cfg001.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG001(pcie_port));
pciercx_cfg001.s.msae = 1; /* Memory space enable. */
pciercx_cfg001.s.me = 1; /* Bus master enable. */
pciercx_cfg001.s.i_dis = 1; /* INTx assertion disable. */
pciercx_cfg001.s.see = 1; /* SERR# enable */
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG001(pcie_port),
- pciercx_cfg001.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG001(pcie_port), pciercx_cfg001.u32);
/* Advanced Error Recovery Message Enables */
/* (PCIE*_CFG066,PCIE*_CFG067,PCIE*_CFG069) */
@@ -440,14 +492,11 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
/* Use CVMX_PCIERCX_CFG067 hardware default */
cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG069(pcie_port), 0);
- /* Active State Power Management (PCIE*_CFG032[ASLPC]) */
- pciercx_cfg032.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
- pciercx_cfg032.s.aslpc = 0; /* Active state Link PM control. */
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG032(pcie_port),
- pciercx_cfg032.u32);
- /* Entrance Latencies (PCIE*_CFG451[L0EL,L1EL]) */
+ /* Active State Power Management (PCIE*_CFG032[ASLPC]) */
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ pciercx_cfg032.s.aslpc = 0; /* Active state Link PM control. */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG032(pcie_port), pciercx_cfg032.u32);
/*
* Link Width Mode (PCIERCn_CFG452[LME]) - Set during
@@ -462,8 +511,8 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
pciercx_cfg006.s.pbnum = 1;
pciercx_cfg006.s.sbnum = 1;
pciercx_cfg006.s.subbnum = 1;
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG006(pcie_port),
- pciercx_cfg006.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG006(pcie_port), pciercx_cfg006.u32);
+
/*
* Memory-mapped I/O BAR (PCIERCn_CFG008)
@@ -473,8 +522,8 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
pciercx_cfg008.u32 = 0;
pciercx_cfg008.s.mb_addr = 0x100;
pciercx_cfg008.s.ml_addr = 0;
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG008(pcie_port),
- pciercx_cfg008.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG008(pcie_port), pciercx_cfg008.u32);
+
/*
* Prefetchable BAR (PCIERCn_CFG009,PCIERCn_CFG010,PCIERCn_CFG011)
@@ -482,72 +531,51 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
* PCIERCn_CFG011[UMEM_LIMIT],PCIERCn_CFG009[LMEM_LIMIT] <
* PCIERCn_CFG010[UMEM_BASE],PCIERCn_CFG009[LMEM_BASE]
*/
- pciercx_cfg009.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG009(pcie_port));
- pciercx_cfg010.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG010(pcie_port));
- pciercx_cfg011.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG011(pcie_port));
+ pciercx_cfg009.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG009(pcie_port));
+ pciercx_cfg010.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG010(pcie_port));
+ pciercx_cfg011.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG011(pcie_port));
pciercx_cfg009.s.lmem_base = 0x100;
pciercx_cfg009.s.lmem_limit = 0;
pciercx_cfg010.s.umem_base = 0x100;
pciercx_cfg011.s.umem_limit = 0;
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG009(pcie_port),
- pciercx_cfg009.u32);
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG010(pcie_port),
- pciercx_cfg010.u32);
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG011(pcie_port),
- pciercx_cfg011.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG009(pcie_port), pciercx_cfg009.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG010(pcie_port), pciercx_cfg010.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG011(pcie_port), pciercx_cfg011.u32);
/*
* System Error Interrupt Enables (PCIERCn_CFG035[SECEE,SEFEE,SENFEE])
* PME Interrupt Enables (PCIERCn_CFG035[PMEIE])
- */
- pciercx_cfg035.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG035(pcie_port));
- /* System error on correctable error enable. */
- pciercx_cfg035.s.secee = 1;
- /* System error on fatal error enable. */
- pciercx_cfg035.s.sefee = 1;
- /* System error on non-fatal error enable. */
- pciercx_cfg035.s.senfee = 1;
- /* PME interrupt enable. */
- pciercx_cfg035.s.pmeie = 1;
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG035(pcie_port),
- pciercx_cfg035.u32);
+ */
+ pciercx_cfg035.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG035(pcie_port));
+ pciercx_cfg035.s.secee = 1; /* System error on correctable error enable. */
+ pciercx_cfg035.s.sefee = 1; /* System error on fatal error enable. */
+ pciercx_cfg035.s.senfee = 1; /* System error on non-fatal error enable. */
+ pciercx_cfg035.s.pmeie = 1; /* PME interrupt enable. */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG035(pcie_port), pciercx_cfg035.u32);
/*
* Advanced Error Recovery Interrupt Enables
* (PCIERCn_CFG075[CERE,NFERE,FERE])
*/
- pciercx_cfg075.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG075(pcie_port));
- /* Correctable error reporting enable. */
- pciercx_cfg075.s.cere = 1;
- /* Non-fatal error reporting enable. */
- pciercx_cfg075.s.nfere = 1;
- /* Fatal error reporting enable. */
- pciercx_cfg075.s.fere = 1;
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG075(pcie_port),
- pciercx_cfg075.u32);
+ pciercx_cfg075.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG075(pcie_port));
+ pciercx_cfg075.s.cere = 1; /* Correctable error reporting enable. */
+ pciercx_cfg075.s.nfere = 1; /* Non-fatal error reporting enable. */
+ pciercx_cfg075.s.fere = 1; /* Fatal error reporting enable. */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG075(pcie_port), pciercx_cfg075.u32);
- /* HP Interrupt Enables (PCIERCn_CFG034[HPINT_EN],
+ /*
+ * HP Interrupt Enables (PCIERCn_CFG034[HPINT_EN],
* PCIERCn_CFG034[DLLS_EN,CCINT_EN])
*/
- pciercx_cfg034.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG034(pcie_port));
- /* Hot-plug interrupt enable. */
- pciercx_cfg034.s.hpint_en = 1;
- /* Data Link Layer state changed enable */
- pciercx_cfg034.s.dlls_en = 1;
- /* Command completed interrupt enable. */
- pciercx_cfg034.s.ccint_en = 1;
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG034(pcie_port),
- pciercx_cfg034.u32);
+ pciercx_cfg034.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG034(pcie_port));
+ pciercx_cfg034.s.hpint_en = 1; /* Hot-plug interrupt enable. */
+ pciercx_cfg034.s.dlls_en = 1; /* Data Link Layer state changed enable */
+ pciercx_cfg034.s.ccint_en = 1; /* Command completed interrupt enable. */
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG034(pcie_port), pciercx_cfg034.u32);
}
/**
- * Initialize a host mode PCIe link. This function takes a PCIe
+ * Initialize a host mode PCIe gen 1 link. This function takes a PCIe
* port from reset to a link up state. Software can then begin
* configuring the rest of the link.
*
@@ -555,7 +583,7 @@ static void __cvmx_pcie_rc_initialize_config_space(int pcie_port)
*
* Returns Zero on success
*/
-static int __cvmx_pcie_rc_initialize_link(int pcie_port)
+static int __cvmx_pcie_rc_initialize_link_gen1(int pcie_port)
{
uint64_t start_cycle;
union cvmx_pescx_ctl_status pescx_ctl_status;
@@ -564,18 +592,15 @@ static int __cvmx_pcie_rc_initialize_link(int pcie_port)
union cvmx_pciercx_cfg448 pciercx_cfg448;
/* Set the lane width */
- pciercx_cfg452.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG452(pcie_port));
+ pciercx_cfg452.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG452(pcie_port));
pescx_ctl_status.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS(pcie_port));
- if (pescx_ctl_status.s.qlm_cfg == 0) {
+ if (pescx_ctl_status.s.qlm_cfg == 0)
/* We're in 8 lane (56XX) or 4 lane (54XX) mode */
pciercx_cfg452.s.lme = 0xf;
- } else {
+ else
/* We're in 4 lane (56XX) or 2 lane (52XX) mode */
pciercx_cfg452.s.lme = 0x7;
- }
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG452(pcie_port),
- pciercx_cfg452.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG452(pcie_port), pciercx_cfg452.u32);
/*
* CN52XX pass 1.x has an errata where length mismatches on UR
@@ -584,19 +609,15 @@ static int __cvmx_pcie_rc_initialize_link(int pcie_port)
*/
if (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
union cvmx_pciercx_cfg455 pciercx_cfg455;
- pciercx_cfg455.u32 =
- cvmx_pcie_cfgx_read(pcie_port,
- CVMX_PCIERCX_CFG455(pcie_port));
+ pciercx_cfg455.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG455(pcie_port));
pciercx_cfg455.s.m_cpl_len_err = 1;
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG455(pcie_port),
- pciercx_cfg455.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG455(pcie_port), pciercx_cfg455.u32);
}
/* Lane swap needs to be manually enabled for CN52XX */
if (OCTEON_IS_MODEL(OCTEON_CN52XX) && (pcie_port == 1)) {
pescx_ctl_status.s.lane_swp = 1;
- cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port),
- pescx_ctl_status.u64);
+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS(pcie_port), pescx_ctl_status.u64);
}
/* Bring up the link */
@@ -612,24 +633,18 @@ static int __cvmx_pcie_rc_initialize_link(int pcie_port)
__cvmx_helper_errata_qlm_disable_2nd_order_cdr(0);
/* Wait for the link to come up */
- cvmx_dprintf("PCIe: Waiting for port %d link\n", pcie_port);
start_cycle = cvmx_get_cycle();
do {
- if (cvmx_get_cycle() - start_cycle >
- 2 * cvmx_sysinfo_get()->cpu_clock_hz) {
- cvmx_dprintf("PCIe: Port %d link timeout\n",
- pcie_port);
+ if (cvmx_get_cycle() - start_cycle > 2 * octeon_get_clock_rate()) {
+ cvmx_dprintf("PCIe: Port %d link timeout\n", pcie_port);
return -1;
}
cvmx_wait(10000);
- pciercx_cfg032.u32 =
- cvmx_pcie_cfgx_read(pcie_port,
- CVMX_PCIERCX_CFG032(pcie_port));
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
} while (pciercx_cfg032.s.dlla == 0);
- /* Display the link status */
- cvmx_dprintf("PCIe: Port %d link active, %d lanes\n", pcie_port,
- pciercx_cfg032.s.nlw);
+ /* Clear all pending errors */
+ cvmx_write_csr(CVMX_PEXP_NPEI_INT_SUM, cvmx_read_csr(CVMX_PEXP_NPEI_INT_SUM));
/*
* Update the Replay Time Limit. Empirically, some PCIe
@@ -639,8 +654,7 @@ static int __cvmx_pcie_rc_initialize_link(int pcie_port)
* our actual 256 byte MPS. The numbers below are directly
* from the PCIe spec table 3-4.
*/
- pciercx_cfg448.u32 =
- cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port));
+ pciercx_cfg448.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port));
switch (pciercx_cfg032.s.nlw) {
case 1: /* 1 lane */
pciercx_cfg448.s.rtl = 1677;
@@ -655,21 +669,28 @@ static int __cvmx_pcie_rc_initialize_link(int pcie_port)
pciercx_cfg448.s.rtl = 258;
break;
}
- cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port),
- pciercx_cfg448.u32);
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port), pciercx_cfg448.u32);
return 0;
}
+static void __cvmx_increment_ba(union cvmx_sli_mem_access_subidx *pmas)
+{
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ pmas->cn68xx.ba++;
+ else
+ pmas->cn63xx.ba++;
+}
+
/**
- * Initialize a PCIe port for use in host(RC) mode. It doesn't
+ * Initialize a PCIe gen 1 port for use in host(RC) mode. It doesn't
* enumerate the bus.
*
* @pcie_port: PCIe port to initialize
*
* Returns Zero on success
*/
-static int cvmx_pcie_rc_initialize(int pcie_port)
+static int __cvmx_pcie_rc_initialize_gen1(int pcie_port)
{
int i;
int base;
@@ -682,16 +703,17 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
union cvmx_npei_mem_access_subidx mem_access_subid;
union cvmx_npei_dbg_data npei_dbg_data;
union cvmx_pescx_ctl_status2 pescx_ctl_status2;
+ union cvmx_pciercx_cfg032 pciercx_cfg032;
union cvmx_npei_bar1_indexx bar1_index;
+retry:
/*
* Make sure we aren't trying to setup a target mode interface
* in host mode.
*/
npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
if ((pcie_port == 0) && !npei_ctl_status.s.host_mode) {
- cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() called "
- "on port0, but port0 is not in host mode\n");
+ cvmx_dprintf("PCIe: Port %d in endpoint mode\n", pcie_port);
return -1;
}
@@ -702,9 +724,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
if ((pcie_port == 1) && npei_dbg_data.cn52xx.qlm0_link_width) {
- cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() "
- "called on port1, but port1 is "
- "disabled\n");
+ cvmx_dprintf("PCIe: ERROR: cvmx_pcie_rc_initialize() called on port1, but port1 is disabled\n");
return -1;
}
}
@@ -733,7 +753,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
* the board. As a workaround for this bug, we bring
* both PCIe ports out of reset at the same time
* instead of on separate calls. So for port 0, we
- * bring both out of reset and do nothing on port 1.
+ * bring both out of reset and do nothing on port 1
*/
if (pcie_port == 0) {
ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
@@ -746,13 +766,10 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
if (ciu_soft_prst.s.soft_prst == 0) {
/* Reset the ports */
ciu_soft_prst.s.soft_prst = 1;
- cvmx_write_csr(CVMX_CIU_SOFT_PRST,
- ciu_soft_prst.u64);
- ciu_soft_prst.u64 =
- cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
ciu_soft_prst.s.soft_prst = 1;
- cvmx_write_csr(CVMX_CIU_SOFT_PRST1,
- ciu_soft_prst.u64);
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
/* Wait until pcie resets the ports. */
udelay(2000);
}
@@ -782,11 +799,9 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
/* Reset the port */
ciu_soft_prst.s.soft_prst = 1;
if (pcie_port)
- cvmx_write_csr(CVMX_CIU_SOFT_PRST1,
- ciu_soft_prst.u64);
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
else
- cvmx_write_csr(CVMX_CIU_SOFT_PRST,
- ciu_soft_prst.u64);
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
/* Wait until pcie resets the ports. */
udelay(2000);
}
@@ -808,25 +823,21 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
*/
cvmx_wait(400000);
- /* PESCX_BIST_STATUS2[PCLK_RUN] was missing on pass 1 of CN56XX and
- CN52XX, so we only probe it on newer chips */
- if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)
- && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ /*
+ * PESCX_BIST_STATUS2[PCLK_RUN] was missing on pass 1 of
+ * CN56XX and CN52XX, so we only probe it on newer chips
+ */
+ if (!OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) && !OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
/* Clear PCLK_RUN so we can check if the clock is running */
- pescx_ctl_status2.u64 =
- cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
+ pescx_ctl_status2.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
pescx_ctl_status2.s.pclk_run = 1;
- cvmx_write_csr(CVMX_PESCX_CTL_STATUS2(pcie_port),
- pescx_ctl_status2.u64);
- /*
- * Now that we cleared PCLK_RUN, wait for it to be set
- * again telling us the clock is running.
+ cvmx_write_csr(CVMX_PESCX_CTL_STATUS2(pcie_port), pescx_ctl_status2.u64);
+ /* Now that we cleared PCLK_RUN, wait for it to be set
+ * again telling us the clock is running
*/
if (CVMX_WAIT_FOR_FIELD64(CVMX_PESCX_CTL_STATUS2(pcie_port),
- union cvmx_pescx_ctl_status2,
- pclk_run, ==, 1, 10000)) {
- cvmx_dprintf("PCIe: Port %d isn't clocked, skipping.\n",
- pcie_port);
+ union cvmx_pescx_ctl_status2, pclk_run, ==, 1, 10000)) {
+ cvmx_dprintf("PCIe: Port %d isn't clocked, skipping.\n", pcie_port);
return -1;
}
}
@@ -836,30 +847,26 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
* the board probably hasn't wired the clocks up and the
* interface should be skipped.
*/
- pescx_ctl_status2.u64 =
- cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
+ pescx_ctl_status2.u64 = cvmx_read_csr(CVMX_PESCX_CTL_STATUS2(pcie_port));
if (pescx_ctl_status2.s.pcierst) {
- cvmx_dprintf("PCIe: Port %d stuck in reset, skipping.\n",
- pcie_port);
+ cvmx_dprintf("PCIe: Port %d stuck in reset, skipping.\n", pcie_port);
return -1;
}
/*
- * Check BIST2 status. If any bits are set skip this interface. This
- * is an attempt to catch PCIE-813 on pass 1 parts.
+ * Check BIST2 status. If any bits are set skip this
+ * interface. This is an attempt to catch PCIE-813 on pass 1
+ * parts.
*/
- pescx_bist_status2.u64 =
- cvmx_read_csr(CVMX_PESCX_BIST_STATUS2(pcie_port));
+ pescx_bist_status2.u64 = cvmx_read_csr(CVMX_PESCX_BIST_STATUS2(pcie_port));
if (pescx_bist_status2.u64) {
- cvmx_dprintf("PCIe: Port %d BIST2 failed. Most likely this "
- "port isn't hooked up, skipping.\n",
+ cvmx_dprintf("PCIe: Port %d BIST2 failed. Most likely this port isn't hooked up, skipping.\n",
pcie_port);
return -1;
}
/* Check BIST status */
- pescx_bist_status.u64 =
- cvmx_read_csr(CVMX_PESCX_BIST_STATUS(pcie_port));
+ pescx_bist_status.u64 = cvmx_read_csr(CVMX_PESCX_BIST_STATUS(pcie_port));
if (pescx_bist_status.u64)
cvmx_dprintf("PCIe: BIST FAILED for port %d (0x%016llx)\n",
pcie_port, CAST64(pescx_bist_status.u64));
@@ -868,50 +875,37 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
__cvmx_pcie_rc_initialize_config_space(pcie_port);
/* Bring the link up */
- if (__cvmx_pcie_rc_initialize_link(pcie_port)) {
- cvmx_dprintf
- ("PCIe: ERROR: cvmx_pcie_rc_initialize_link() failed\n");
+ if (__cvmx_pcie_rc_initialize_link_gen1(pcie_port)) {
+ cvmx_dprintf("PCIe: Failed to initialize port %d, probably the slot is empty\n",
+ pcie_port);
return -1;
}
/* Store merge control (NPEI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */
npei_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL);
- /* Allow 16 words to combine */
- npei_mem_access_ctl.s.max_word = 0;
- /* Wait up to 127 cycles for more data */
- npei_mem_access_ctl.s.timer = 127;
+ npei_mem_access_ctl.s.max_word = 0; /* Allow 16 words to combine */
+ npei_mem_access_ctl.s.timer = 127; /* Wait up to 127 cycles for more data */
cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_CTL, npei_mem_access_ctl.u64);
/* Setup Mem access SubDIDs */
mem_access_subid.u64 = 0;
- /* Port the request is sent to. */
- mem_access_subid.s.port = pcie_port;
- /* Due to an errata on pass 1 chips, no merging is allowed. */
- mem_access_subid.s.nmerge = 1;
- /* Endian-swap for Reads. */
- mem_access_subid.s.esr = 1;
- /* Endian-swap for Writes. */
- mem_access_subid.s.esw = 1;
- /* No Snoop for Reads. */
- mem_access_subid.s.nsr = 1;
- /* No Snoop for Writes. */
- mem_access_subid.s.nsw = 1;
- /* Disable Relaxed Ordering for Reads. */
- mem_access_subid.s.ror = 0;
- /* Disable Relaxed Ordering for Writes. */
- mem_access_subid.s.row = 0;
- /* PCIe Address Bits <63:34>. */
- mem_access_subid.s.ba = 0;
+ mem_access_subid.s.port = pcie_port; /* Port the request is sent to. */
+ mem_access_subid.s.nmerge = 1; /* Due to an errata on pass 1 chips, no merging is allowed. */
+ mem_access_subid.s.esr = 1; /* Endian-swap for Reads. */
+ mem_access_subid.s.esw = 1; /* Endian-swap for Writes. */
+ mem_access_subid.s.nsr = 0; /* Enable Snooping for Reads. Octeon doesn't care, but devices might want this more conservative setting */
+ mem_access_subid.s.nsw = 0; /* Enable Snoop for Writes. */
+ mem_access_subid.s.ror = 0; /* Disable Relaxed Ordering for Reads. */
+ mem_access_subid.s.row = 0; /* Disable Relaxed Ordering for Writes. */
+ mem_access_subid.s.ba = 0; /* PCIe Adddress Bits <63:34>. */
/*
* Setup mem access 12-15 for port 0, 16-19 for port 1,
* supplying 36 bits of address space.
*/
for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) {
- cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(i),
- mem_access_subid.u64);
- /* Set each SUBID to extend the addressable range */
- mem_access_subid.s.ba += 1;
+ cvmx_write_csr(CVMX_PEXP_NPEI_MEM_ACCESS_SUBIDX(i), mem_access_subid.u64);
+ mem_access_subid.s.ba += 1; /* Set each SUBID to extend the addressable range */
}
/*
@@ -927,7 +921,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
/* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
cvmx_write_csr(CVMX_PESCX_P2N_BAR0_START(pcie_port), 0);
- /* BAR1 follows BAR2 with a gap. */
+ /* BAR1 follows BAR2 with a gap so it has the same address as for gen2. */
cvmx_write_csr(CVMX_PESCX_P2N_BAR1_START(pcie_port), CVMX_PCIE_BAR1_RC_BASE);
bar1_index.u32 = 0;
@@ -992,14 +986,474 @@ static int cvmx_pcie_rc_initialize(int pcie_port)
npei_ctl_port.s.waitl_com = 0;
cvmx_write_csr(CVMX_PEXP_NPEI_CTL_PORT0, npei_ctl_port.u64);
}
+
+ /*
+ * Both pass 1 and pass 2 of CN52XX and CN56XX have an errata
+ * that causes TLP ordering to not be preserved after multiple
+ * PCIe port resets. This code detects this fault and corrects
+ * it by aligning the TLP counters properly. Another link
+ * reset is then performed. See PCIE-13340
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X)) {
+ union cvmx_npei_dbg_data dbg_data;
+ int old_in_fif_p_count;
+ int in_fif_p_count;
+ int out_p_count;
+ int in_p_offset = (OCTEON_IS_MODEL(OCTEON_CN52XX_PASS1_X) || OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_X)) ? 4 : 1;
+ int i;
+
+ /*
+ * Choose a write address of 1MB. It should be
+ * harmless as all bars haven't been setup.
+ */
+ uint64_t write_address = (cvmx_pcie_get_mem_base_address(pcie_port) + 0x100000) | (1ull<<63);
+
+ /*
+ * Make sure at least in_p_offset have been executed before we try and
+ * read in_fif_p_count
+ */
+ i = in_p_offset;
+ while (i--) {
+ cvmx_write64_uint32(write_address, 0);
+ cvmx_wait(10000);
+ }
+
+ /*
+ * Read the IN_FIF_P_COUNT from the debug
+ * select. IN_FIF_P_COUNT can be unstable sometimes so
+ * read it twice with a write between the reads. This
+ * way we can tell the value is good as it will
+ * increment by one due to the write
+ */
+ cvmx_write_csr(CVMX_PEXP_NPEI_DBG_SELECT, (pcie_port) ? 0xd7fc : 0xcffc);
+ cvmx_read_csr(CVMX_PEXP_NPEI_DBG_SELECT);
+ do {
+ dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+ old_in_fif_p_count = dbg_data.s.data & 0xff;
+ cvmx_write64_uint32(write_address, 0);
+ cvmx_wait(10000);
+ dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+ in_fif_p_count = dbg_data.s.data & 0xff;
+ } while (in_fif_p_count != ((old_in_fif_p_count+1) & 0xff));
+
+ /* Update in_fif_p_count for it's offset with respect to out_p_count */
+ in_fif_p_count = (in_fif_p_count + in_p_offset) & 0xff;
+
+ /* Read the OUT_P_COUNT from the debug select */
+ cvmx_write_csr(CVMX_PEXP_NPEI_DBG_SELECT, (pcie_port) ? 0xd00f : 0xc80f);
+ cvmx_read_csr(CVMX_PEXP_NPEI_DBG_SELECT);
+ dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+ out_p_count = (dbg_data.s.data>>1) & 0xff;
+
+ /* Check that the two counters are aligned */
+ if (out_p_count != in_fif_p_count) {
+ cvmx_dprintf("PCIe: Port %d aligning TLP counters as workaround to maintain ordering\n", pcie_port);
+ while (in_fif_p_count != 0) {
+ cvmx_write64_uint32(write_address, 0);
+ cvmx_wait(10000);
+ in_fif_p_count = (in_fif_p_count + 1) & 0xff;
+ }
+ /*
+ * The EBH5200 board swapped the PCIe reset
+ * lines on the board. This means we must
+ * bring both links down and up, which will
+ * cause the PCIe0 to need alignment
+ * again. Lots of messages will be displayed,
+ * but everything should work
+ */
+ if ((cvmx_sysinfo_get()->board_type == CVMX_BOARD_TYPE_EBH5200) &&
+ (pcie_port == 1))
+ cvmx_pcie_rc_initialize(0);
+ /* Rety bringing this port up */
+ goto retry;
+ }
+ }
+
+ /* Display the link status */
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ cvmx_dprintf("PCIe: Port %d link active, %d lanes\n", pcie_port, pciercx_cfg032.s.nlw);
+
return 0;
}
+/**
+ * Initialize a host mode PCIe gen 2 link. This function takes a PCIe
+ * port from reset to a link up state. Software can then begin
+ * configuring the rest of the link.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Return Zero on success.
+ */
+static int __cvmx_pcie_rc_initialize_link_gen2(int pcie_port)
+{
+ uint64_t start_cycle;
+ union cvmx_pemx_ctl_status pem_ctl_status;
+ union cvmx_pciercx_cfg032 pciercx_cfg032;
+ union cvmx_pciercx_cfg448 pciercx_cfg448;
-/* Above was cvmx-pcie.c, below original pcie.c */
+ /* Bring up the link */
+ pem_ctl_status.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(pcie_port));
+ pem_ctl_status.s.lnk_enb = 1;
+ cvmx_write_csr(CVMX_PEMX_CTL_STATUS(pcie_port), pem_ctl_status.u64);
+
+ /* Wait for the link to come up */
+ start_cycle = cvmx_get_cycle();
+ do {
+ if (cvmx_get_cycle() - start_cycle > octeon_get_clock_rate())
+ return -1;
+ cvmx_wait(10000);
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ } while ((pciercx_cfg032.s.dlla == 0) || (pciercx_cfg032.s.lt == 1));
+
+ /*
+ * Update the Replay Time Limit. Empirically, some PCIe
+ * devices take a little longer to respond than expected under
+ * load. As a workaround for this we configure the Replay Time
+ * Limit to the value expected for a 512 byte MPS instead of
+ * our actual 256 byte MPS. The numbers below are directly
+ * from the PCIe spec table 3-4
+ */
+ pciercx_cfg448.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG448(pcie_port));
+ switch (pciercx_cfg032.s.nlw) {
+ case 1: /* 1 lane */
+ pciercx_cfg448.s.rtl = 1677;
+ break;
+ case 2: /* 2 lanes */
+ pciercx_cfg448.s.rtl = 867;
+ break;
+ case 4: /* 4 lanes */
+ pciercx_cfg448.s.rtl = 462;
+ break;
+ case 8: /* 8 lanes */
+ pciercx_cfg448.s.rtl = 258;
+ break;
+ }
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG448(pcie_port), pciercx_cfg448.u32);
+
+ return 0;
+}
/**
+ * Initialize a PCIe gen 2 port for use in host(RC) mode. It doesn't enumerate
+ * the bus.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Returns Zero on success.
+ */
+static int __cvmx_pcie_rc_initialize_gen2(int pcie_port)
+{
+ int i;
+ union cvmx_ciu_soft_prst ciu_soft_prst;
+ union cvmx_mio_rst_ctlx mio_rst_ctl;
+ union cvmx_pemx_bar_ctl pemx_bar_ctl;
+ union cvmx_pemx_ctl_status pemx_ctl_status;
+ union cvmx_pemx_bist_status pemx_bist_status;
+ union cvmx_pemx_bist_status2 pemx_bist_status2;
+ union cvmx_pciercx_cfg032 pciercx_cfg032;
+ union cvmx_pciercx_cfg515 pciercx_cfg515;
+ union cvmx_sli_ctl_portx sli_ctl_portx;
+ union cvmx_sli_mem_access_ctl sli_mem_access_ctl;
+ union cvmx_sli_mem_access_subidx mem_access_subid;
+ union cvmx_sriox_status_reg sriox_status_reg;
+ union cvmx_pemx_bar1_indexx bar1_index;
+
+ if (octeon_has_feature(OCTEON_FEATURE_SRIO)) {
+ /* Make sure this interface isn't SRIO */
+ if (OCTEON_IS_MODEL(OCTEON_CN66XX)) {
+ /*
+ * The CN66XX requires reading the
+ * MIO_QLMX_CFG register to figure out the
+ * port type.
+ */
+ union cvmx_mio_qlmx_cfg qlmx_cfg;
+ qlmx_cfg.u64 = cvmx_read_csr(CVMX_MIO_QLMX_CFG(pcie_port));
+
+ if (qlmx_cfg.s.qlm_spd == 15) {
+ pr_notice("PCIe: Port %d is disabled, skipping.\n", pcie_port);
+ return -1;
+ }
+
+ switch (qlmx_cfg.s.qlm_spd) {
+ case 0x1: /* SRIO 1x4 short */
+ case 0x3: /* SRIO 1x4 long */
+ case 0x4: /* SRIO 2x2 short */
+ case 0x6: /* SRIO 2x2 long */
+ pr_notice("PCIe: Port %d is SRIO, skipping.\n", pcie_port);
+ return -1;
+ case 0x9: /* SGMII */
+ pr_notice("PCIe: Port %d is SGMII, skipping.\n", pcie_port);
+ return -1;
+ case 0xb: /* XAUI */
+ pr_notice("PCIe: Port %d is XAUI, skipping.\n", pcie_port);
+ return -1;
+ case 0x0: /* PCIE gen2 */
+ case 0x8: /* PCIE gen2 (alias) */
+ case 0x2: /* PCIE gen1 */
+ case 0xa: /* PCIE gen1 (alias) */
+ break;
+ default:
+ pr_notice("PCIe: Port %d is unknown, skipping.\n", pcie_port);
+ return -1;
+ }
+ } else {
+ sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(pcie_port));
+ if (sriox_status_reg.s.srio) {
+ pr_notice("PCIe: Port %d is SRIO, skipping.\n", pcie_port);
+ return -1;
+ }
+ }
+ }
+
+#if 0
+ /* This code is so that the PCIe analyzer is able to see 63XX traffic */
+ pr_notice("PCIE : init for pcie analyzer.\n");
+ cvmx_helper_qlm_jtag_init();
+ cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
+ cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
+ cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
+ cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
+ cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
+ cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
+ cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
+ cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
+ cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
+ cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 85);
+ cvmx_helper_qlm_jtag_shift(pcie_port, 1, 1);
+ cvmx_helper_qlm_jtag_shift_zeros(pcie_port, 300-86);
+ cvmx_helper_qlm_jtag_update(pcie_port);
+#endif
+
+ /* Make sure we aren't trying to setup a target mode interface in host mode */
+ mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(pcie_port));
+ if (!mio_rst_ctl.s.host_mode) {
+ pr_notice("PCIe: Port %d in endpoint mode.\n", pcie_port);
+ return -1;
+ }
+
+ /* CN63XX Pass 1.0 errata G-14395 requires the QLM De-emphasis be programmed */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_0)) {
+ if (pcie_port) {
+ union cvmx_ciu_qlm1 ciu_qlm;
+ ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM1);
+ ciu_qlm.s.txbypass = 1;
+ ciu_qlm.s.txdeemph = 5;
+ ciu_qlm.s.txmargin = 0x17;
+ cvmx_write_csr(CVMX_CIU_QLM1, ciu_qlm.u64);
+ } else {
+ union cvmx_ciu_qlm0 ciu_qlm;
+ ciu_qlm.u64 = cvmx_read_csr(CVMX_CIU_QLM0);
+ ciu_qlm.s.txbypass = 1;
+ ciu_qlm.s.txdeemph = 5;
+ ciu_qlm.s.txmargin = 0x17;
+ cvmx_write_csr(CVMX_CIU_QLM0, ciu_qlm.u64);
+ }
+ }
+ /* Bring the PCIe out of reset */
+ if (pcie_port)
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ else
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ /*
+ * After a chip reset the PCIe will also be in reset. If it
+ * isn't, most likely someone is trying to init it again
+ * without a proper PCIe reset
+ */
+ if (ciu_soft_prst.s.soft_prst == 0) {
+ /* Reset the port */
+ ciu_soft_prst.s.soft_prst = 1;
+ if (pcie_port)
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
+ else
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+ /* Wait until pcie resets the ports. */
+ udelay(2000);
+ }
+ if (pcie_port) {
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST1);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST1, ciu_soft_prst.u64);
+ } else {
+ ciu_soft_prst.u64 = cvmx_read_csr(CVMX_CIU_SOFT_PRST);
+ ciu_soft_prst.s.soft_prst = 0;
+ cvmx_write_csr(CVMX_CIU_SOFT_PRST, ciu_soft_prst.u64);
+ }
+
+ /* Wait for PCIe reset to complete */
+ udelay(1000);
+
+ /*
+ * Check and make sure PCIe came out of reset. If it doesn't
+ * the board probably hasn't wired the clocks up and the
+ * interface should be skipped.
+ */
+ if (CVMX_WAIT_FOR_FIELD64(CVMX_MIO_RST_CTLX(pcie_port), union cvmx_mio_rst_ctlx, rst_done, ==, 1, 10000)) {
+ pr_notice("PCIe: Port %d stuck in reset, skipping.\n", pcie_port);
+ return -1;
+ }
+
+ /* Check BIST status */
+ pemx_bist_status.u64 = cvmx_read_csr(CVMX_PEMX_BIST_STATUS(pcie_port));
+ if (pemx_bist_status.u64)
+ pr_notice("PCIe: BIST FAILED for port %d (0x%016llx)\n", pcie_port, CAST64(pemx_bist_status.u64));
+ pemx_bist_status2.u64 = cvmx_read_csr(CVMX_PEMX_BIST_STATUS2(pcie_port));
+ /* Errata PCIE-14766 may cause the lower 6 bits to be randomly set on CN63XXp1 */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X))
+ pemx_bist_status2.u64 &= ~0x3full;
+ if (pemx_bist_status2.u64)
+ pr_notice("PCIe: BIST2 FAILED for port %d (0x%016llx)\n", pcie_port, CAST64(pemx_bist_status2.u64));
+
+ /* Initialize the config space CSRs */
+ __cvmx_pcie_rc_initialize_config_space(pcie_port);
+
+ /* Enable gen2 speed selection */
+ pciercx_cfg515.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG515(pcie_port));
+ pciercx_cfg515.s.dsc = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG515(pcie_port), pciercx_cfg515.u32);
+
+ /* Bring the link up */
+ if (__cvmx_pcie_rc_initialize_link_gen2(pcie_port)) {
+ /*
+ * Some gen1 devices don't handle the gen 2 training
+ * correctly. Disable gen2 and try again with only
+ * gen1
+ */
+ union cvmx_pciercx_cfg031 pciercx_cfg031;
+ pciercx_cfg031.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG031(pcie_port));
+ pciercx_cfg031.s.mls = 1;
+ cvmx_pcie_cfgx_write(pcie_port, CVMX_PCIERCX_CFG031(pcie_port), pciercx_cfg031.u32);
+ if (__cvmx_pcie_rc_initialize_link_gen2(pcie_port)) {
+ pr_notice("PCIe: Link timeout on port %d, probably the slot is empty\n", pcie_port);
+ return -1;
+ }
+ }
+
+ /* Store merge control (SLI_MEM_ACCESS_CTL[TIMER,MAX_WORD]) */
+ sli_mem_access_ctl.u64 = cvmx_read_csr(CVMX_PEXP_SLI_MEM_ACCESS_CTL);
+ sli_mem_access_ctl.s.max_word = 0; /* Allow 16 words to combine */
+ sli_mem_access_ctl.s.timer = 127; /* Wait up to 127 cycles for more data */
+ cvmx_write_csr(CVMX_PEXP_SLI_MEM_ACCESS_CTL, sli_mem_access_ctl.u64);
+
+ /* Setup Mem access SubDIDs */
+ mem_access_subid.u64 = 0;
+ mem_access_subid.s.port = pcie_port; /* Port the request is sent to. */
+ mem_access_subid.s.nmerge = 0; /* Allow merging as it works on CN6XXX. */
+ mem_access_subid.s.esr = 1; /* Endian-swap for Reads. */
+ mem_access_subid.s.esw = 1; /* Endian-swap for Writes. */
+ mem_access_subid.s.wtype = 0; /* "No snoop" and "Relaxed ordering" are not set */
+ mem_access_subid.s.rtype = 0; /* "No snoop" and "Relaxed ordering" are not set */
+ /* PCIe Adddress Bits <63:34>. */
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ mem_access_subid.cn68xx.ba = 0;
+ else
+ mem_access_subid.cn63xx.ba = 0;
+
+ /*
+ * Setup mem access 12-15 for port 0, 16-19 for port 1,
+ * supplying 36 bits of address space.
+ */
+ for (i = 12 + pcie_port * 4; i < 16 + pcie_port * 4; i++) {
+ cvmx_write_csr(CVMX_PEXP_SLI_MEM_ACCESS_SUBIDX(i), mem_access_subid.u64);
+ /* Set each SUBID to extend the addressable range */
+ __cvmx_increment_ba(&mem_access_subid);
+ }
+
+ /*
+ * Disable the peer to peer forwarding register. This must be
+ * setup by the OS after it enumerates the bus and assigns
+ * addresses to the PCIe busses.
+ */
+ for (i = 0; i < 4; i++) {
+ cvmx_write_csr(CVMX_PEMX_P2P_BARX_START(i, pcie_port), -1);
+ cvmx_write_csr(CVMX_PEMX_P2P_BARX_END(i, pcie_port), -1);
+ }
+
+ /* Set Octeon's BAR0 to decode 0-16KB. It overlaps with Bar2 */
+ cvmx_write_csr(CVMX_PEMX_P2N_BAR0_START(pcie_port), 0);
+
+ /*
+ * Set Octeon's BAR2 to decode 0-2^41. Bar0 and Bar1 take
+ * precedence where they overlap. It also overlaps with the
+ * device addresses, so make sure the peer to peer forwarding
+ * is set right.
+ */
+ cvmx_write_csr(CVMX_PEMX_P2N_BAR2_START(pcie_port), 0);
+
+ /*
+ * Setup BAR2 attributes
+ * Relaxed Ordering (NPEI_CTL_PORTn[PTLP_RO,CTLP_RO, WAIT_COM])
+ * - PTLP_RO,CTLP_RO should normally be set (except for debug).
+ * - WAIT_COM=0 will likely work for all applications.
+ * Load completion relaxed ordering (NPEI_CTL_PORTn[WAITL_COM])
+ */
+ pemx_bar_ctl.u64 = cvmx_read_csr(CVMX_PEMX_BAR_CTL(pcie_port));
+ pemx_bar_ctl.s.bar1_siz = 3; /* 256MB BAR1*/
+ pemx_bar_ctl.s.bar2_enb = 1;
+ pemx_bar_ctl.s.bar2_esx = 1;
+ pemx_bar_ctl.s.bar2_cax = 0;
+ cvmx_write_csr(CVMX_PEMX_BAR_CTL(pcie_port), pemx_bar_ctl.u64);
+ sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(pcie_port));
+ sli_ctl_portx.s.ptlp_ro = 1;
+ sli_ctl_portx.s.ctlp_ro = 1;
+ sli_ctl_portx.s.wait_com = 0;
+ sli_ctl_portx.s.waitl_com = 0;
+ cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(pcie_port), sli_ctl_portx.u64);
+
+ /* BAR1 follows BAR2 */
+ cvmx_write_csr(CVMX_PEMX_P2N_BAR1_START(pcie_port), CVMX_PCIE_BAR1_RC_BASE);
+
+ bar1_index.u64 = 0;
+ bar1_index.s.addr_idx = (CVMX_PCIE_BAR1_PHYS_BASE >> 22);
+ bar1_index.s.ca = 1; /* Not Cached */
+ bar1_index.s.end_swp = 1; /* Endian Swap mode */
+ bar1_index.s.addr_v = 1; /* Valid entry */
+
+ for (i = 0; i < 16; i++) {
+ cvmx_write_csr(CVMX_PEMX_BAR1_INDEXX(i, pcie_port), bar1_index.u64);
+ /* 256MB / 16 >> 22 == 4 */
+ bar1_index.s.addr_idx += (((1ull << 28) / 16ull) >> 22);
+ }
+
+ /*
+ * Allow config retries for 250ms. Count is based off the 5Ghz
+ * SERDES clock.
+ */
+ pemx_ctl_status.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(pcie_port));
+ pemx_ctl_status.s.cfg_rtry = 250 * 5000000 / 0x10000;
+ cvmx_write_csr(CVMX_PEMX_CTL_STATUS(pcie_port), pemx_ctl_status.u64);
+
+ /* Display the link status */
+ pciercx_cfg032.u32 = cvmx_pcie_cfgx_read(pcie_port, CVMX_PCIERCX_CFG032(pcie_port));
+ pr_notice("PCIe: Port %d link active, %d lanes, speed gen%d\n", pcie_port, pciercx_cfg032.s.nlw, pciercx_cfg032.s.ls);
+
+ return 0;
+}
+
+/**
+ * Initialize a PCIe port for use in host(RC) mode. It doesn't enumerate the bus.
+ *
+ * @pcie_port: PCIe port to initialize
+ *
+ * Returns Zero on success
+ */
+static int cvmx_pcie_rc_initialize(int pcie_port)
+{
+ int result;
+ if (octeon_has_feature(OCTEON_FEATURE_NPEI))
+ result = __cvmx_pcie_rc_initialize_gen1(pcie_port);
+ else
+ result = __cvmx_pcie_rc_initialize_gen2(pcie_port);
+ return result;
+}
+
+/* Above was cvmx-pcie.c, below original pcie.c */
+
+/**
* Map a PCI device to the appropriate interrupt line
*
* @dev: The Linux PCI device structure for the device to map
@@ -1027,11 +1481,12 @@ int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev,
*/
while (dev->bus && dev->bus->parent)
dev = to_pci_dev(dev->bus->bridge);
- /* If the root bus is number 0 and the PEX 8114 is the
+ /*
+ * If the root bus is number 0 and the PEX 8114 is the
* root, assume we are behind the miswired bus. We
* need to correct the swizzle level by two. Yuck.
*/
- if ((dev->bus->number == 0) &&
+ if ((dev->bus->number == 1) &&
(dev->vendor == 0x10b5) && (dev->device == 0x8114)) {
/*
* The pin field is one based, not zero. We
@@ -1048,39 +1503,73 @@ int __init octeon_pcie_pcibios_map_irq(const struct pci_dev *dev,
return pin - 1 + OCTEON_IRQ_PCI_INT0;
}
-/**
+static void set_cfg_read_retry(u32 retry_cnt)
+{
+ union cvmx_pemx_ctl_status pemx_ctl;
+ pemx_ctl.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(1));
+ pemx_ctl.s.cfg_rtry = retry_cnt;
+ cvmx_write_csr(CVMX_PEMX_CTL_STATUS(1), pemx_ctl.u64);
+}
+
+
+static u32 disable_cfg_read_retry(void)
+{
+ u32 retry_cnt;
+
+ union cvmx_pemx_ctl_status pemx_ctl;
+ pemx_ctl.u64 = cvmx_read_csr(CVMX_PEMX_CTL_STATUS(1));
+ retry_cnt = pemx_ctl.s.cfg_rtry;
+ pemx_ctl.s.cfg_rtry = 0;
+ cvmx_write_csr(CVMX_PEMX_CTL_STATUS(1), pemx_ctl.u64);
+ return retry_cnt;
+}
+
+static int is_cfg_retry(void)
+{
+ union cvmx_pemx_int_sum pemx_int_sum;
+ pemx_int_sum.u64 = cvmx_read_csr(CVMX_PEMX_INT_SUM(1));
+ if (pemx_int_sum.s.crs_dr)
+ return 1;
+ return 0;
+}
+
+/*
* Read a value from configuration space
*
- * @bus:
- * @devfn:
- * @reg:
- * @size:
- * @val:
- * Returns
*/
-static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus,
- unsigned int devfn, int reg, int size,
- u32 *val)
+static int octeon_pcie_read_config(unsigned int pcie_port, struct pci_bus *bus,
+ unsigned int devfn, int reg, int size,
+ u32 *val)
{
union octeon_cvmemctl cvmmemctl;
union octeon_cvmemctl cvmmemctl_save;
int bus_number = bus->number;
+ int cfg_retry = 0;
+ int retry_cnt = 0;
+ int max_retry_cnt = 10;
+ u32 cfg_retry_cnt = 0;
+ cvmmemctl_save.u64 = 0;
+ BUG_ON(pcie_port >= ARRAY_SIZE(enable_pcie_bus_num_war));
/*
* For the top level bus make sure our hardware bus number
- * matches the software one.
+ * matches the software one
*/
if (bus->parent == NULL) {
- union cvmx_pciercx_cfg006 pciercx_cfg006;
- pciercx_cfg006.u32 = cvmx_pcie_cfgx_read(pcie_port,
- CVMX_PCIERCX_CFG006(pcie_port));
- if (pciercx_cfg006.s.pbnum != bus_number) {
- pciercx_cfg006.s.pbnum = bus_number;
- pciercx_cfg006.s.sbnum = bus_number;
- pciercx_cfg006.s.subbnum = bus_number;
- cvmx_pcie_cfgx_write(pcie_port,
- CVMX_PCIERCX_CFG006(pcie_port),
- pciercx_cfg006.u32);
+ if (enable_pcie_bus_num_war[pcie_port])
+ bus_number = 0;
+ else {
+ union cvmx_pciercx_cfg006 pciercx_cfg006;
+ pciercx_cfg006.u32 = cvmx_pcie_cfgx_read(pcie_port,
+ CVMX_PCIERCX_CFG006(pcie_port));
+ if (pciercx_cfg006.s.pbnum != bus_number) {
+ pciercx_cfg006.s.pbnum = bus_number;
+ pciercx_cfg006.s.sbnum = bus_number;
+ pciercx_cfg006.s.subbnum = bus_number;
+ cvmx_pcie_cfgx_write(pcie_port,
+ CVMX_PCIERCX_CFG006(pcie_port),
+ pciercx_cfg006.u32);
+ }
}
}
@@ -1116,29 +1605,52 @@ static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus,
*/
#if 1
/* Use this option if you aren't using either slot */
- if (bus_number == 1)
+ if (bus_number == 2)
return PCIBIOS_FUNC_NOT_SUPPORTED;
#elif 0
/*
* Use this option if you are using the first slot but
* not the second.
*/
- if ((bus_number == 1) && (devfn >> 3 != 2))
+ if ((bus_number == 2) && (devfn >> 3 != 2))
return PCIBIOS_FUNC_NOT_SUPPORTED;
#elif 0
/*
* Use this option if you are using the second slot
* but not the first.
*/
- if ((bus_number == 1) && (devfn >> 3 != 3))
+ if ((bus_number == 2) && (devfn >> 3 != 3))
return PCIBIOS_FUNC_NOT_SUPPORTED;
#elif 0
/* Use this opion if you are using both slots */
- if ((bus_number == 1) &&
+ if ((bus_number == 2) &&
!((devfn == (2 << 3)) || (devfn == (3 << 3))))
return PCIBIOS_FUNC_NOT_SUPPORTED;
#endif
+ /* The following #if gives a more complicated example. This is
+ the required checks for running a Nitrox CN16XX-NHBX in the
+ slot of the EBH5600. This card has a PLX PCIe bridge with
+ four Nitrox PLX parts behind it */
+#if 0
+ /* PLX bridge with 4 ports */
+ if ((bus_number == 4) &&
+ !((devfn >> 3 >= 1) && (devfn >> 3 <= 4)))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ /* Nitrox behind PLX 1 */
+ if ((bus_number == 5) && (devfn >> 3 != 0))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ /* Nitrox behind PLX 2 */
+ if ((bus_number == 6) && (devfn >> 3 != 0))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ /* Nitrox behind PLX 3 */
+ if ((bus_number == 7) && (devfn >> 3 != 0))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ /* Nitrox behind PLX 4 */
+ if ((bus_number == 8) && (devfn >> 3 != 0))
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+#endif
+
/*
* Shorten the DID timeout so bus errors for PCIe
* config reads from non existent devices happen
@@ -1152,26 +1664,48 @@ static inline int octeon_pcie_read_config(int pcie_port, struct pci_bus *bus,
__write_64bit_c0_register($11, 7, cvmmemctl.u64);
}
- switch (size) {
- case 4:
- *val = cvmx_pcie_config_read32(pcie_port, bus_number,
- devfn >> 3, devfn & 0x7, reg);
+ if ((OCTEON_IS_MODEL(OCTEON_CN63XX)) && (enable_pcie_14459_war))
+ cfg_retry_cnt = disable_cfg_read_retry();
+
+ pr_debug("pcie_cfg_rd port=%d b=%d devfn=0x%03x reg=0x%03x"
+ " size=%d ", pcie_port, bus_number, devfn, reg, size);
+ do {
+ switch (size) {
+ case 4:
+ *val = cvmx_pcie_config_read32(pcie_port, bus_number,
+ devfn >> 3, devfn & 0x7, reg);
break;
- case 2:
- *val = cvmx_pcie_config_read16(pcie_port, bus_number,
- devfn >> 3, devfn & 0x7, reg);
+ case 2:
+ *val = cvmx_pcie_config_read16(pcie_port, bus_number,
+ devfn >> 3, devfn & 0x7, reg);
break;
- case 1:
- *val = cvmx_pcie_config_read8(pcie_port, bus_number, devfn >> 3,
- devfn & 0x7, reg);
+ case 1:
+ *val = cvmx_pcie_config_read8(pcie_port, bus_number,
+ devfn >> 3, devfn & 0x7, reg);
break;
- default:
- return PCIBIOS_FUNC_NOT_SUPPORTED;
- }
+ default:
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX))
+ set_cfg_read_retry(cfg_retry_cnt);
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+ }
+ if ((OCTEON_IS_MODEL(OCTEON_CN63XX)) &&
+ (enable_pcie_14459_war)) {
+ cfg_retry = is_cfg_retry();
+ retry_cnt++;
+ if (retry_cnt > max_retry_cnt) {
+ pr_err(" pcie cfg_read retries failed. retry_cnt=%d\n",
+ retry_cnt);
+ cfg_retry = 0;
+ }
+ }
+ } while (cfg_retry);
+ if ((OCTEON_IS_MODEL(OCTEON_CN63XX)) && (enable_pcie_14459_war))
+ set_cfg_read_retry(cfg_retry_cnt);
+ pr_debug("val=%08x : tries=%02d\n", *val, retry_cnt);
if (OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1) ||
OCTEON_IS_MODEL(OCTEON_CN56XX_PASS1_1))
- __write_64bit_c0_register($11, 7, cvmmemctl_save.u64);
+ write_c0_cvmmemctl(cvmmemctl_save.u64);
return PCIBIOS_SUCCESSFUL;
}
@@ -1187,42 +1721,56 @@ static int octeon_pcie1_read_config(struct pci_bus *bus, unsigned int devfn,
return octeon_pcie_read_config(1, bus, devfn, reg, size, val);
}
+static int octeon_dummy_read_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 *val)
+{
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
-
-/**
+/*
* Write a value to PCI configuration space
- *
- * @bus:
- * @devfn:
- * @reg:
- * @size:
- * @val:
- * Returns
*/
-static inline int octeon_pcie_write_config(int pcie_port, struct pci_bus *bus,
- unsigned int devfn, int reg,
- int size, u32 val)
+static int octeon_pcie_write_config(unsigned int pcie_port, struct pci_bus *bus,
+ unsigned int devfn, int reg,
+ int size, u32 val)
{
int bus_number = bus->number;
+ BUG_ON(pcie_port >= ARRAY_SIZE(enable_pcie_bus_num_war));
+
+ if ((bus->parent == NULL) && (enable_pcie_bus_num_war[pcie_port]))
+ bus_number = 0;
+
+ pr_debug("pcie_cfg_wr port=%d b=%d devfn=0x%03x"
+ " reg=0x%03x size=%d val=%08x\n", pcie_port, bus_number, devfn,
+ reg, size, val);
+
+
switch (size) {
case 4:
cvmx_pcie_config_write32(pcie_port, bus_number, devfn >> 3,
devfn & 0x7, reg, val);
- return PCIBIOS_SUCCESSFUL;
+ break;
case 2:
cvmx_pcie_config_write16(pcie_port, bus_number, devfn >> 3,
devfn & 0x7, reg, val);
- return PCIBIOS_SUCCESSFUL;
+ break;
case 1:
cvmx_pcie_config_write8(pcie_port, bus_number, devfn >> 3,
devfn & 0x7, reg, val);
- return PCIBIOS_SUCCESSFUL;
+ break;
+ default:
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
}
#if PCI_CONFIG_SPACE_DELAY
+ /*
+ * Delay on writes so that devices have time to come up. Some
+ * bridges need this to allow time for the secondary busses to
+ * work
+ */
udelay(PCI_CONFIG_SPACE_DELAY);
#endif
- return PCIBIOS_FUNC_NOT_SUPPORTED;
+ return PCIBIOS_SUCCESSFUL;
}
static int octeon_pcie0_write_config(struct pci_bus *bus, unsigned int devfn,
@@ -1237,6 +1785,12 @@ static int octeon_pcie1_write_config(struct pci_bus *bus, unsigned int devfn,
return octeon_pcie_write_config(1, bus, devfn, reg, size, val);
}
+static int octeon_dummy_write_config(struct pci_bus *bus, unsigned int devfn,
+ int reg, int size, u32 val)
+{
+ return PCIBIOS_FUNC_NOT_SUPPORTED;
+}
+
static struct pci_ops octeon_pcie0_ops = {
octeon_pcie0_read_config,
octeon_pcie0_write_config,
@@ -1279,6 +1833,35 @@ static struct pci_controller octeon_pcie1_controller = {
.io_resource = &octeon_pcie1_io_resource,
};
+static struct pci_ops octeon_dummy_ops = {
+ octeon_dummy_read_config,
+ octeon_dummy_write_config,
+};
+
+static struct resource octeon_dummy_mem_resource = {
+ .name = "Virtual PCIe MEM",
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource octeon_dummy_io_resource = {
+ .name = "Virtual PCIe IO",
+ .flags = IORESOURCE_IO,
+};
+
+static struct pci_controller octeon_dummy_controller = {
+ .pci_ops = &octeon_dummy_ops,
+ .mem_resource = &octeon_dummy_mem_resource,
+ .io_resource = &octeon_dummy_io_resource,
+};
+
+static int device_needs_bus_num_war(uint32_t deviceid)
+{
+#define IDT_VENDOR_ID 0x111d
+
+ if ((deviceid & 0xffff) == IDT_VENDOR_ID)
+ return 1;
+ return 0;
+}
/**
* Initialize the Octeon PCIe controllers
@@ -1287,19 +1870,27 @@ static struct pci_controller octeon_pcie1_controller = {
*/
static int __init octeon_pcie_setup(void)
{
- union cvmx_npei_ctl_status npei_ctl_status;
int result;
+ int host_mode;
+ int srio_war15205 = 0, port;
+ union cvmx_sli_ctl_portx sli_ctl_portx;
+ union cvmx_sriox_status_reg sriox_status_reg;
/* These chips don't have PCIe */
if (!octeon_has_feature(OCTEON_FEATURE_PCIE))
return 0;
+ /* No PCIe simulation */
+ if (octeon_is_simulation())
+ return 0;
+
+ /* Disable PCI if instructed on the command line */
+ if (pcie_disable)
+ return 0;
+
/* Point pcibios_map_irq() to the PCIe version of it */
octeon_pcibios_map_irq = octeon_pcie_pcibios_map_irq;
- /* Use the PCIe based DMA mappings */
- octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE;
-
/*
* PCIe I/O range. It is based on port 0 but includes up until
* port 1's end.
@@ -1310,11 +1901,43 @@ static int __init octeon_pcie_setup(void)
cvmx_pcie_get_io_base_address(1) -
cvmx_pcie_get_io_base_address(0) + cvmx_pcie_get_io_size(1) - 1;
- npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
- if (npei_ctl_status.s.host_mode) {
+ /*
+ * Create a dummy PCIe controller to swallow up bus 0. IDT bridges
+ * don't work if the primary bus number is zero. Here we add a fake
+ * PCIe controller that the kernel will give bus 0. This allows
+ * us to not change the normal kernel bus enumeration
+ */
+ octeon_dummy_controller.io_map_base = -1;
+ octeon_dummy_controller.mem_resource->start = (1ull<<48);
+ octeon_dummy_controller.mem_resource->end = (1ull<<48);
+ register_pci_controller(&octeon_dummy_controller);
+
+ if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
+ union cvmx_npei_ctl_status npei_ctl_status;
+ npei_ctl_status.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_CTL_STATUS);
+ host_mode = npei_ctl_status.s.host_mode;
+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE;
+ } else {
+ union cvmx_mio_rst_ctlx mio_rst_ctl;
+ mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(0));
+ host_mode = mio_rst_ctl.s.host_mode;
+ octeon_dma_bar_type = OCTEON_DMA_BAR_TYPE_PCIE2;
+ }
+
+ if (host_mode) {
pr_notice("PCIe: Initializing port 0\n");
+ /* CN63XX pass 1_x/2.0 errata PCIe-15205 */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
+ sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(0));
+ if (sriox_status_reg.s.srio) {
+ srio_war15205 += 1; /* Port is SRIO */
+ port = 0;
+ }
+ }
result = cvmx_pcie_rc_initialize(0);
if (result == 0) {
+ uint32_t device0;
/* Memory offsets are physical addresses */
octeon_pcie0_controller.mem_offset =
cvmx_pcie_get_mem_base_address(0);
@@ -1343,60 +1966,134 @@ static int __init octeon_pcie_setup(void)
octeon_pcie0_controller.io_resource->start = 4 << 10;
octeon_pcie0_controller.io_resource->end =
cvmx_pcie_get_io_size(0) - 1;
+ msleep(100); /* Some devices need extra time */
register_pci_controller(&octeon_pcie0_controller);
+ device0 = cvmx_pcie_config_read32(0, 0, 0, 0, 0);
+ enable_pcie_bus_num_war[0] =
+ device_needs_bus_num_war(device0);
}
} else {
pr_notice("PCIe: Port 0 in endpoint mode, skipping.\n");
+ /* CN63XX pass 1_x/2.0 errata PCIe-15205 */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
+ srio_war15205 += 1;
+ port = 0;
+ }
}
- /* Skip the 2nd port on CN52XX if port 0 is in 4 lane mode */
- if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
- union cvmx_npei_dbg_data npei_dbg_data;
- npei_dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
- if (npei_dbg_data.cn52xx.qlm0_link_width)
- return 0;
+ if (octeon_has_feature(OCTEON_FEATURE_NPEI)) {
+ host_mode = 1;
+ /* Skip the 2nd port on CN52XX if port 0 is in 4 lane mode */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+ union cvmx_npei_dbg_data dbg_data;
+ dbg_data.u64 = cvmx_read_csr(CVMX_PEXP_NPEI_DBG_DATA);
+ if (dbg_data.cn52xx.qlm0_link_width)
+ host_mode = 0;
+ }
+ } else {
+ union cvmx_mio_rst_ctlx mio_rst_ctl;
+ mio_rst_ctl.u64 = cvmx_read_csr(CVMX_MIO_RST_CTLX(1));
+ host_mode = mio_rst_ctl.s.host_mode;
}
- pr_notice("PCIe: Initializing port 1\n");
- result = cvmx_pcie_rc_initialize(1);
- if (result == 0) {
- /* Memory offsets are physical addresses */
- octeon_pcie1_controller.mem_offset =
- cvmx_pcie_get_mem_base_address(1);
- /* IO offsets are Mips virtual addresses */
- octeon_pcie1_controller.io_map_base =
- CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(1));
- octeon_pcie1_controller.io_offset =
- cvmx_pcie_get_io_base_address(1) -
- cvmx_pcie_get_io_base_address(0);
- /*
- * To keep things similar to PCI, we start device
- * addresses at the same place as PCI uisng big bar
- * support. This normally translates to 4GB-256MB,
- * which is the same as most x86 PCs.
- */
- octeon_pcie1_controller.mem_resource->start =
- cvmx_pcie_get_mem_base_address(1) + (4ul << 30) -
- (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
- octeon_pcie1_controller.mem_resource->end =
- cvmx_pcie_get_mem_base_address(1) +
- cvmx_pcie_get_mem_size(1) - 1;
- /*
- * Ports must be above 16KB for the ISA bus filtering
- * in the PCI-X to PCI bridge.
- */
- octeon_pcie1_controller.io_resource->start =
- cvmx_pcie_get_io_base_address(1) -
- cvmx_pcie_get_io_base_address(0);
- octeon_pcie1_controller.io_resource->end =
- octeon_pcie1_controller.io_resource->start +
- cvmx_pcie_get_io_size(1) - 1;
- register_pci_controller(&octeon_pcie1_controller);
+ if (host_mode) {
+ pr_notice("PCIe: Initializing port 1\n");
+ /* CN63XX pass 1_x/2.0 errata PCIe-15205 */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
+ sriox_status_reg.u64 = cvmx_read_csr(CVMX_SRIOX_STATUS_REG(1));
+ if (sriox_status_reg.s.srio) {
+ srio_war15205 += 1; /* Port is SRIO */
+ port = 1;
+ }
+ }
+ result = cvmx_pcie_rc_initialize(1);
+ if (result == 0) {
+ uint32_t device0;
+ /* Memory offsets are physical addresses */
+ octeon_pcie1_controller.mem_offset =
+ cvmx_pcie_get_mem_base_address(1);
+ /*
+ * To calculate the address for accessing the 2nd PCIe device,
+ * either 'io_map_base' (pci_iomap()), or 'mips_io_port_base'
+ * (ioport_map()) value is added to
+ * pci_resource_start(dev,bar)). The 'mips_io_port_base' is set
+ * only once based on first PCIe. Also changing 'io_map_base'
+ * based on first slot's value so that both the routines will
+ * work properly.
+ */
+ octeon_pcie1_controller.io_map_base =
+ CVMX_ADD_IO_SEG(cvmx_pcie_get_io_base_address(0));
+ /* IO offsets are Mips virtual addresses */
+ octeon_pcie1_controller.io_offset =
+ cvmx_pcie_get_io_base_address(1) -
+ cvmx_pcie_get_io_base_address(0);
+ /*
+ * To keep things similar to PCI, we start device
+ * addresses at the same place as PCI uisng big bar
+ * support. This normally translates to 4GB-256MB,
+ * which is the same as most x86 PCs.
+ */
+ octeon_pcie1_controller.mem_resource->start =
+ cvmx_pcie_get_mem_base_address(1) + (4ul << 30) -
+ (OCTEON_PCI_BAR1_HOLE_SIZE << 20);
+ octeon_pcie1_controller.mem_resource->end =
+ cvmx_pcie_get_mem_base_address(1) +
+ cvmx_pcie_get_mem_size(1) - 1;
+ /*
+ * Ports must be above 16KB for the ISA bus filtering
+ * in the PCI-X to PCI bridge.
+ */
+ octeon_pcie1_controller.io_resource->start =
+ cvmx_pcie_get_io_base_address(1) -
+ cvmx_pcie_get_io_base_address(0);
+ octeon_pcie1_controller.io_resource->end =
+ octeon_pcie1_controller.io_resource->start +
+ cvmx_pcie_get_io_size(1) - 1;
+ msleep(100); /* Some devices need extra time */
+ register_pci_controller(&octeon_pcie1_controller);
+ device0 = cvmx_pcie_config_read32(1, 0, 0, 0, 0);
+ enable_pcie_bus_num_war[1] =
+ device_needs_bus_num_war(device0);
+ }
+ } else {
+ pr_notice("PCIe: Port 1 not in root complex mode, skipping.\n");
+ /* CN63XX pass 1_x/2.0 errata PCIe-15205 */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
+ srio_war15205 += 1;
+ port = 1;
+ }
+ }
+
+ /*
+ * CN63XX pass 1_x/2.0 errata PCIe-15205 requires setting all
+ * of SRIO MACs SLI_CTL_PORT*[INT*_MAP] to similar value and
+ * all of PCIe Macs SLI_CTL_PORT*[INT*_MAP] to different value
+ * from the previous set values
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN63XX_PASS1_X) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX_PASS2_0)) {
+ if (srio_war15205 == 1) {
+ sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(port));
+ sli_ctl_portx.s.inta_map = 1;
+ sli_ctl_portx.s.intb_map = 1;
+ sli_ctl_portx.s.intc_map = 1;
+ sli_ctl_portx.s.intd_map = 1;
+ cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(port), sli_ctl_portx.u64);
+
+ sli_ctl_portx.u64 = cvmx_read_csr(CVMX_PEXP_SLI_CTL_PORTX(!port));
+ sli_ctl_portx.s.inta_map = 0;
+ sli_ctl_portx.s.intb_map = 0;
+ sli_ctl_portx.s.intc_map = 0;
+ sli_ctl_portx.s.intd_map = 0;
+ cvmx_write_csr(CVMX_PEXP_SLI_CTL_PORTX(!port), sli_ctl_portx.u64);
+ }
}
octeon_pci_dma_init();
return 0;
}
-
arch_initcall(octeon_pcie_setup);
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
index c841f083a7f5..bb57ed9ea2bd 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_hwbutton.c
@@ -149,7 +149,7 @@ static int msp_hwbutton_register(struct hwbutton_interrupt *hirq)
CIC_EXT_SET_ACTIVE_HI(cic_ext, hirq->eirq);
*CIC_EXT_CFG_REG = cic_ext;
- return request_irq(hirq->irq, hwbutton_handler, IRQF_DISABLED,
+ return request_irq(hirq->irq, hwbutton_handler, 0,
hirq->name, hirq);
}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_setup.c b/arch/mips/pmc-sierra/msp71xx/msp_setup.c
index 655308a4e1cd..7a834b2f8a5f 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_setup.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_setup.c
@@ -209,7 +209,7 @@ void __init prom_init(void)
default:
/* we don't recognize the machine */
mips_machtype = MACH_UNKNOWN;
- panic("***Bogosity factor five***, exiting\n");
+ panic("***Bogosity factor five***, exiting");
break;
}
diff --git a/arch/mips/pmc-sierra/msp71xx/msp_smp.c b/arch/mips/pmc-sierra/msp71xx/msp_smp.c
index bec17901ff03..10170580a2de 100644
--- a/arch/mips/pmc-sierra/msp71xx/msp_smp.c
+++ b/arch/mips/pmc-sierra/msp71xx/msp_smp.c
@@ -51,13 +51,13 @@ static irqreturn_t ipi_call_interrupt(int irq, void *dev_id)
static struct irqaction irq_resched = {
.handler = ipi_resched_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_PERCPU,
.name = "IPI_resched"
};
static struct irqaction irq_call = {
.handler = ipi_call_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU,
+ .flags = IRQF_PERCPU,
.name = "IPI_call"
};
diff --git a/arch/mips/pnx8550/common/int.c b/arch/mips/pnx8550/common/int.c
index 1ebe22bdadc8..ec684b8c3f79 100644
--- a/arch/mips/pnx8550/common/int.c
+++ b/arch/mips/pnx8550/common/int.c
@@ -167,13 +167,13 @@ static struct irq_chip level_irq_type = {
static struct irqaction gic_action = {
.handler = no_action,
- .flags = IRQF_DISABLED | IRQF_NO_THREAD,
+ .flags = IRQF_NO_THREAD,
.name = "GIC",
};
static struct irqaction timer_action = {
.handler = no_action,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_TIMER,
.name = "Timer",
};
diff --git a/arch/mips/pnx8550/common/time.c b/arch/mips/pnx8550/common/time.c
index 8836c6203df0..831d6b369e9c 100644
--- a/arch/mips/pnx8550/common/time.c
+++ b/arch/mips/pnx8550/common/time.c
@@ -59,7 +59,7 @@ static irqreturn_t pnx8xxx_timer_interrupt(int irq, void *dev_id)
static struct irqaction pnx8xxx_timer_irq = {
.handler = pnx8xxx_timer_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
.name = "pnx8xxx_timer",
};
@@ -72,7 +72,7 @@ static irqreturn_t monotonic_interrupt(int irq, void *dev_id)
static struct irqaction monotonic_irqaction = {
.handler = monotonic_interrupt,
- .flags = IRQF_DISABLED | IRQF_TIMER,
+ .flags = IRQF_TIMER,
.name = "Monotonic timer",
};
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile
index cc538493cae1..411cda9ee030 100644
--- a/arch/mips/sgi-ip22/Makefile
+++ b/arch/mips/sgi-ip22/Makefile
@@ -4,7 +4,7 @@
#
obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-time.o ip22-nvram.o \
- ip22-platform.o ip22-reset.o ip22-setup.o
+ ip22-platform.o ip22-reset.o ip22-setup.o ip22-gio.o
obj-$(CONFIG_SGI_IP22) += ip22-berr.o
obj-$(CONFIG_SGI_IP28) += ip28-berr.o
diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c
new file mode 100644
index 000000000000..f5ebc092aed5
--- /dev/null
+++ b/arch/mips/sgi-ip22/ip22-gio.c
@@ -0,0 +1,428 @@
+#include <linux/export.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+
+#include <asm/addrspace.h>
+#include <asm/paccess.h>
+#include <asm/gio_device.h>
+#include <asm/sgi/gio.h>
+#include <asm/sgi/hpc3.h>
+#include <asm/sgi/mc.h>
+#include <asm/sgi/ip22.h>
+
+static struct bus_type gio_bus_type;
+
+static struct {
+ const char *name;
+ __u8 id;
+} gio_name_table[] = {
+ { .name = "SGI Impact", .id = 0x10 },
+ { .name = "Phobos G160", .id = 0x35 },
+ /* fake IDs */
+ { .name = "SGI Newport", .id = 0x7e },
+ { .name = "SGI GR2/GR3", .id = 0x7f },
+};
+
+static struct device gio_bus = {
+ .init_name = "gio",
+};
+
+/**
+ * gio_match_device - Tell if an of_device structure has a matching
+ * gio_match structure
+ * @ids: array of of device match structures to search in
+ * @dev: the of device structure to match against
+ *
+ * Used by a driver to check whether an of_device present in the
+ * system is in its list of supported devices.
+ */
+const struct gio_device_id *gio_match_device(const struct gio_device_id *match,
+ const struct gio_device *dev)
+{
+ const struct gio_device_id *ids;
+
+ for (ids = match; ids->id != 0xff; ids++)
+ if (ids->id == dev->id.id)
+ return ids;
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(gio_match_device);
+
+struct gio_device *gio_dev_get(struct gio_device *dev)
+{
+ struct device *tmp;
+
+ if (!dev)
+ return NULL;
+ tmp = get_device(&dev->dev);
+ if (tmp)
+ return to_gio_device(tmp);
+ else
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(gio_dev_get);
+
+void gio_dev_put(struct gio_device *dev)
+{
+ if (dev)
+ put_device(&dev->dev);
+}
+EXPORT_SYMBOL_GPL(gio_dev_put);
+
+/**
+ * gio_release_dev - free an gio device structure when all users of it are finished.
+ * @dev: device that's been disconnected
+ *
+ * Will be called only by the device core when all users of this gio device are
+ * done.
+ */
+void gio_release_dev(struct device *dev)
+{
+ struct gio_device *giodev;
+
+ giodev = to_gio_device(dev);
+ kfree(giodev);
+}
+EXPORT_SYMBOL_GPL(gio_release_dev);
+
+int gio_device_register(struct gio_device *giodev)
+{
+ giodev->dev.bus = &gio_bus_type;
+ giodev->dev.parent = &gio_bus;
+ return device_register(&giodev->dev);
+}
+EXPORT_SYMBOL_GPL(gio_device_register);
+
+void gio_device_unregister(struct gio_device *giodev)
+{
+ device_unregister(&giodev->dev);
+}
+EXPORT_SYMBOL_GPL(gio_device_unregister);
+
+static int gio_bus_match(struct device *dev, struct device_driver *drv)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *gio_drv = to_gio_driver(drv);
+
+ return gio_match_device(gio_drv->id_table, gio_dev) != NULL;
+}
+
+static int gio_device_probe(struct device *dev)
+{
+ int error = -ENODEV;
+ struct gio_driver *drv;
+ struct gio_device *gio_dev;
+ const struct gio_device_id *match;
+
+ drv = to_gio_driver(dev->driver);
+ gio_dev = to_gio_device(dev);
+
+ if (!drv->probe)
+ return error;
+
+ gio_dev_get(gio_dev);
+
+ match = gio_match_device(drv->id_table, gio_dev);
+ if (match)
+ error = drv->probe(gio_dev, match);
+ if (error)
+ gio_dev_put(gio_dev);
+
+ return error;
+}
+
+static int gio_device_remove(struct device *dev)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *drv = to_gio_driver(dev->driver);
+
+ if (dev->driver && drv->remove)
+ drv->remove(gio_dev);
+ return 0;
+}
+
+static int gio_device_suspend(struct device *dev, pm_message_t state)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *drv = to_gio_driver(dev->driver);
+ int error = 0;
+
+ if (dev->driver && drv->suspend)
+ error = drv->suspend(gio_dev, state);
+ return error;
+}
+
+static int gio_device_resume(struct device *dev)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *drv = to_gio_driver(dev->driver);
+ int error = 0;
+
+ if (dev->driver && drv->resume)
+ error = drv->resume(gio_dev);
+ return error;
+}
+
+static void gio_device_shutdown(struct device *dev)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ struct gio_driver *drv = to_gio_driver(dev->driver);
+
+ if (dev->driver && drv->shutdown)
+ drv->shutdown(gio_dev);
+}
+
+static ssize_t modalias_show(struct device *dev, struct device_attribute *a,
+ char *buf)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+ int len = snprintf(buf, PAGE_SIZE, "gio:%x\n", gio_dev->id.id);
+
+ return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len;
+}
+
+static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gio_device *giodev;
+
+ giodev = to_gio_device(dev);
+ return sprintf(buf, "%s", giodev->name);
+}
+
+static ssize_t id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct gio_device *giodev;
+
+ giodev = to_gio_device(dev);
+ return sprintf(buf, "%x", giodev->id.id);
+}
+
+static struct device_attribute gio_dev_attrs[] = {
+ __ATTR_RO(modalias),
+ __ATTR_RO(name),
+ __ATTR_RO(id),
+ __ATTR_NULL,
+};
+
+static int gio_device_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct gio_device *gio_dev = to_gio_device(dev);
+
+ add_uevent_var(env, "MODALIAS=gio:%x", gio_dev->id.id);
+ return 0;
+}
+
+int gio_register_driver(struct gio_driver *drv)
+{
+ /* initialize common driver fields */
+ if (!drv->driver.name)
+ drv->driver.name = drv->name;
+ if (!drv->driver.owner)
+ drv->driver.owner = drv->owner;
+ drv->driver.bus = &gio_bus_type;
+
+ /* register with core */
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(gio_register_driver);
+
+void gio_unregister_driver(struct gio_driver *drv)
+{
+ driver_unregister(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(gio_unregister_driver);
+
+void gio_set_master(struct gio_device *dev)
+{
+ u32 tmp = sgimc->giopar;
+
+ switch (dev->slotno) {
+ case 0:
+ tmp |= SGIMC_GIOPAR_MASTERGFX;
+ break;
+ case 1:
+ tmp |= SGIMC_GIOPAR_MASTEREXP0;
+ break;
+ case 2:
+ tmp |= SGIMC_GIOPAR_MASTEREXP1;
+ break;
+ }
+ sgimc->giopar = tmp;
+}
+EXPORT_SYMBOL_GPL(gio_set_master);
+
+void ip22_gio_set_64bit(int slotno)
+{
+ u32 tmp = sgimc->giopar;
+
+ switch (slotno) {
+ case 0:
+ tmp |= SGIMC_GIOPAR_GFX64;
+ break;
+ case 1:
+ tmp |= SGIMC_GIOPAR_EXP064;
+ break;
+ case 2:
+ tmp |= SGIMC_GIOPAR_EXP164;
+ break;
+ }
+ sgimc->giopar = tmp;
+}
+
+static int ip22_gio_id(unsigned long addr, u32 *res)
+{
+ u8 tmp8;
+ u8 tmp16;
+ u32 tmp32;
+ u8 *ptr8;
+ u16 *ptr16;
+ u32 *ptr32;
+
+ ptr32 = (void *)CKSEG1ADDR(addr);
+ if (!get_dbe(tmp32, ptr32)) {
+ /*
+ * We got no DBE, but this doesn't mean anything.
+ * If GIO is pipelined (which can't be disabled
+ * for GFX slot) we don't get a DBE, but we see
+ * the transfer size as data. So we do an 8bit
+ * and a 16bit access and check whether the common
+ * data matches
+ */
+ ptr8 = (void *)CKSEG1ADDR(addr + 3);
+ get_dbe(tmp8, ptr8);
+ ptr16 = (void *)CKSEG1ADDR(addr + 2);
+ get_dbe(tmp16, ptr16);
+ if (tmp8 == (tmp16 & 0xff) &&
+ tmp8 == (tmp32 & 0xff) &&
+ tmp16 == (tmp32 & 0xffff)) {
+ *res = tmp32;
+ return 1;
+ }
+ }
+ return 0; /* nothing here */
+}
+
+#define HQ2_MYSTERY_OFFS 0x6A07C
+#define NEWPORT_USTATUS_OFFS 0xF133C
+
+static int ip22_is_gr2(unsigned long addr)
+{
+ u32 tmp;
+ u32 *ptr;
+
+ /* HQ2 only allows 32bit accesses */
+ ptr = (void *)CKSEG1ADDR(addr + HQ2_MYSTERY_OFFS);
+ if (!get_dbe(tmp, ptr)) {
+ if (tmp == 0xdeadbeef)
+ return 1;
+ }
+ return 0;
+}
+
+
+static void ip22_check_gio(int slotno, unsigned long addr)
+{
+ const char *name = "Unknown";
+ struct gio_device *gio_dev;
+ u32 tmp;
+ __u8 id;
+ int i;
+
+ /* first look for GR2/GR3 by checking mystery register */
+ if (ip22_is_gr2(addr))
+ tmp = 0x7f;
+ else {
+ if (!ip22_gio_id(addr, &tmp)) {
+ /*
+ * no GIO signature at start address of slot, but
+ * Newport doesn't have one, so let's check usea
+ * status register
+ */
+ if (ip22_gio_id(addr + NEWPORT_USTATUS_OFFS, &tmp))
+ tmp = 0x7e;
+ else
+ tmp = 0;
+ }
+ }
+ if (tmp) {
+ id = GIO_ID(tmp);
+ if (tmp & GIO_32BIT_ID) {
+ if (tmp & GIO_64BIT_IFACE)
+ ip22_gio_set_64bit(slotno);
+ }
+ for (i = 0; i < ARRAY_SIZE(gio_name_table); i++) {
+ if (id == gio_name_table[i].id) {
+ name = gio_name_table[i].name;
+ break;
+ }
+ }
+ printk(KERN_INFO "GIO: slot %d : %s (id %x)\n",
+ slotno, name, id);
+ gio_dev = kzalloc(sizeof *gio_dev, GFP_KERNEL);
+ gio_dev->name = name;
+ gio_dev->slotno = slotno;
+ gio_dev->id.id = id;
+ gio_dev->resource.start = addr;
+ gio_dev->resource.end = addr + 0x3fffff;
+ gio_dev->resource.flags = IORESOURCE_MEM;
+ dev_set_name(&gio_dev->dev, "%d", slotno);
+ gio_device_register(gio_dev);
+ } else
+ printk(KERN_INFO "GIO: slot %d : Empty\n", slotno);
+}
+
+static struct bus_type gio_bus_type = {
+ .name = "gio",
+ .dev_attrs = gio_dev_attrs,
+ .match = gio_bus_match,
+ .probe = gio_device_probe,
+ .remove = gio_device_remove,
+ .suspend = gio_device_suspend,
+ .resume = gio_device_resume,
+ .shutdown = gio_device_shutdown,
+ .uevent = gio_device_uevent,
+};
+
+static struct resource gio_bus_resource = {
+ .start = GIO_SLOT_GFX_BASE,
+ .end = GIO_SLOT_GFX_BASE + 0x9fffff,
+ .name = "GIO Bus",
+ .flags = IORESOURCE_MEM,
+};
+
+int __init ip22_gio_init(void)
+{
+ unsigned int pbdma __maybe_unused;
+ int ret;
+
+ ret = device_register(&gio_bus);
+ if (ret)
+ return ret;
+
+ ret = bus_register(&gio_bus_type);
+ if (!ret) {
+ request_resource(&iomem_resource, &gio_bus_resource);
+ printk(KERN_INFO "GIO: Probing bus...\n");
+
+ if (ip22_is_fullhouse() ||
+ !get_dbe(pbdma, (unsigned int *)&hpc3c1->pbdma[1])) {
+ /* Indigo2 and ChallengeS */
+ ip22_check_gio(0, GIO_SLOT_GFX_BASE);
+ ip22_check_gio(1, GIO_SLOT_EXP0_BASE);
+ } else {
+ /* Indy */
+ ip22_check_gio(0, GIO_SLOT_GFX_BASE);
+ ip22_check_gio(1, GIO_SLOT_EXP0_BASE);
+ ip22_check_gio(2, GIO_SLOT_EXP1_BASE);
+ }
+ } else
+ device_unregister(&gio_bus);
+
+ return ret;
+}
+
+subsys_initcall(ip22_gio_init);
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index f72c336ea27b..3f2b7633f946 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -155,32 +155,32 @@ static void __irq_entry indy_buserror_irq(void)
static struct irqaction local0_cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED | IRQF_NO_THREAD,
+ .flags = IRQF_NO_THREAD,
.name = "local0 cascade",
};
static struct irqaction local1_cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED | IRQF_NO_THREAD,
+ .flags = IRQF_NO_THREAD,
.name = "local1 cascade",
};
static struct irqaction buserr = {
.handler = no_action,
- .flags = IRQF_DISABLED | IRQF_NO_THREAD,
+ .flags = IRQF_NO_THREAD,
.name = "Bus Error",
};
static struct irqaction map0_cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED | IRQF_NO_THREAD,
+ .flags = IRQF_NO_THREAD,
.name = "mapable0 cascade",
};
#ifdef USE_LIO3_IRQ
static struct irqaction map1_cascade = {
.handler = no_action,
- .flags = IRQF_DISABLED | IRQF_NO_THREAD,
+ .flags = IRQF_NO_THREAD,
.name = "mapable1 cascade",
};
#define SGI_INTERRUPTS SGINT_END
diff --git a/arch/mips/sgi-ip22/ip22-mc.c b/arch/mips/sgi-ip22/ip22-mc.c
index d22262ee6853..75ada8a9713b 100644
--- a/arch/mips/sgi-ip22/ip22-mc.c
+++ b/arch/mips/sgi-ip22/ip22-mc.c
@@ -139,11 +139,11 @@ void __init sgimc_init(void)
* zero.
*/
/* don't touch parity settings for IP28 */
-#ifndef CONFIG_SGI_IP28
tmp = sgimc->cpuctrl0;
- tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
- SGIMC_CCTRL0_R4KNOCHKPARR);
+#ifndef CONFIG_SGI_IP28
+ tmp |= SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM;
#endif
+ tmp |= SGIMC_CCTRL0_R4KNOCHKPARR;
sgimc->cpuctrl0 = tmp;
/* Step 3: Setup the MC write buffer depth, this is controlled
@@ -178,7 +178,8 @@ void __init sgimc_init(void)
*/
/* First the basic invariants across all GIO64 implementations. */
- tmp = SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */
+ tmp = sgimc->giopar & SGIMC_GIOPAR_GFX64; /* keep gfx 64bit settings */
+ tmp |= SGIMC_GIOPAR_HPC64; /* All 1st HPC's interface at 64bits */
tmp |= SGIMC_GIOPAR_ONEBUS; /* Only one physical GIO bus exists */
if (ip22_is_fullhouse()) {
@@ -193,7 +194,6 @@ void __init sgimc_init(void)
tmp |= SGIMC_GIOPAR_PLINEEXP0; /* exp[01] pipelined */
tmp |= SGIMC_GIOPAR_PLINEEXP1;
tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */
- tmp |= SGIMC_GIOPAR_GFX64; /* GFX at 64 bits */
}
} else {
/* Guiness specific settings. */
diff --git a/arch/mips/sgi-ip22/ip22-setup.c b/arch/mips/sgi-ip22/ip22-setup.c
index 5e6621349471..c7bdfe43df5b 100644
--- a/arch/mips/sgi-ip22/ip22-setup.c
+++ b/arch/mips/sgi-ip22/ip22-setup.c
@@ -26,9 +26,6 @@
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>
-unsigned long sgi_gfxaddr;
-EXPORT_SYMBOL_GPL(sgi_gfxaddr);
-
extern void ip22_be_init(void) __init;
void __init plat_mem_setup(void)
@@ -78,22 +75,4 @@ void __init plat_mem_setup(void)
prom_flags |= PROM_FLAG_USE_AS_CONSOLE;
add_preferred_console("arc", 0, NULL);
}
-
-#if defined(CONFIG_VT) && defined(CONFIG_SGI_NEWPORT_CONSOLE)
- {
- ULONG *gfxinfo;
- ULONG * (*__vec)(void) = (void *) (long)
- *((_PULONG *)(long)((PROMBLOCK)->pvector + 0x20));
-
- gfxinfo = __vec();
- sgi_gfxaddr = ((gfxinfo[1] >= 0xa0000000
- && gfxinfo[1] <= 0xc0000000)
- ? gfxinfo[1] - 0xa0000000 : 0);
-
- /* newport addresses? */
- if (sgi_gfxaddr == 0x1f0f0000 || sgi_gfxaddr == 0x1f4f0000) {
- conswitchp = &newport_con;
- }
- }
-#endif
}
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c
index f90dce315e04..23642238c689 100644
--- a/arch/mips/sgi-ip27/ip27-irq.c
+++ b/arch/mips/sgi-ip27/ip27-irq.c
@@ -73,7 +73,7 @@ static inline int alloc_level(int cpu, int irq)
level = find_first_zero_bit(hub->irq_alloc_mask, LEVELS_PER_SLICE);
if (level >= LEVELS_PER_SLICE)
- panic("Cpu %d flooded with devices\n", cpu);
+ panic("Cpu %d flooded with devices", cpu);
__set_bit(level, hub->irq_alloc_mask);
si->level_to_irq[level] = irq;
@@ -96,7 +96,7 @@ static inline int find_level(cpuid_t *cpunum, int irq)
}
}
- panic("Could not identify cpu/level for irq %d\n", irq);
+ panic("Could not identify cpu/level for irq %d", irq);
}
/*
@@ -116,7 +116,7 @@ static int ms1bit(unsigned long x)
}
/*
- * This code is unnecessarily complex, because we do IRQF_DISABLED
+ * This code is unnecessarily complex, because we do
* intr enabling. Basically, once we grab the set of intrs we need
* to service, we must mask _all_ these interrupts; firstly, to make
* sure the same intr does not intr again, causing recursion that
diff --git a/arch/mips/sgi-ip27/ip27-timer.c b/arch/mips/sgi-ip27/ip27-timer.c
index ef74f3267f91..13cfeab50528 100644
--- a/arch/mips/sgi-ip27/ip27-timer.c
+++ b/arch/mips/sgi-ip27/ip27-timer.c
@@ -91,7 +91,7 @@ static irqreturn_t hub_rt_counter_handler(int irq, void *dev_id)
struct irqaction hub_rt_irqaction = {
.handler = hub_rt_counter_handler,
- .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
.name = "hub-rt",
};
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c
index c65ea76d56c7..a092860d5196 100644
--- a/arch/mips/sgi-ip32/ip32-irq.c
+++ b/arch/mips/sgi-ip32/ip32-irq.c
@@ -113,13 +113,11 @@ extern irqreturn_t crime_cpuerr_intr(int irq, void *dev_id);
static struct irqaction memerr_irq = {
.handler = crime_memerr_intr,
- .flags = IRQF_DISABLED,
.name = "CRIME memory error",
};
static struct irqaction cpuerr_irq = {
.handler = crime_cpuerr_intr,
- .flags = IRQF_DISABLED,
.name = "CRIME CPU error",
};
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c
index e8e72bb3a9af..5a4ec75382e2 100644
--- a/arch/mips/sni/irq.c
+++ b/arch/mips/sni/irq.c
@@ -42,7 +42,7 @@ static irqreturn_t sni_isa_irq_handler(int dummy, void *p)
struct irqaction sni_isa_irq = {
.handler = sni_isa_irq_handler,
.name = "ISA",
- .flags = IRQF_SHARED | IRQF_DISABLED
+ .flags = IRQF_SHARED
};
/*
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c
index ec0be14996a4..494c9e7847aa 100644
--- a/arch/mips/sni/time.c
+++ b/arch/mips/sni/time.c
@@ -68,7 +68,7 @@ static irqreturn_t a20r_interrupt(int irq, void *dev_id)
static struct irqaction a20r_irqaction = {
.handler = a20r_interrupt,
- .flags = IRQF_DISABLED | IRQF_PERCPU | IRQF_TIMER,
+ .flags = IRQF_PERCPU | IRQF_TIMER,
.name = "a20r-timer",
};
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
index 85a87de17eb4..682efb0c108d 100644
--- a/arch/mips/txx9/generic/pci.c
+++ b/arch/mips/txx9/generic/pci.c
@@ -262,7 +262,7 @@ txx9_i8259_irq_setup(int irq)
int err;
init_i8259_irqs();
- err = request_irq(irq, &i8259_interrupt, IRQF_DISABLED|IRQF_SHARED,
+ err = request_irq(irq, &i8259_interrupt, IRQF_SHARED,
"cascade(i8259)", (void *)(long)irq);
if (!err)
printk(KERN_INFO "PCI-ISA bridge PIC (irq %d)\n", irq);
diff --git a/arch/mn10300/include/asm/param.h b/arch/mn10300/include/asm/param.h
index 789b1df41fcb..02a0ca6f13ce 100644
--- a/arch/mn10300/include/asm/param.h
+++ b/arch/mn10300/include/asm/param.h
@@ -11,24 +11,8 @@
#ifndef _ASM_PARAM_H
#define _ASM_PARAM_H
-#ifdef __KERNEL__
-#define HZ CONFIG_HZ /* Internal kernel timer frequency */
-#define USER_HZ 100 /* .. some user interfaces are in
- * "ticks" */
-#define CLOCKS_PER_SEC (USER_HZ) /* like times() */
-#endif
+#include <asm-generic/param.h>
-#ifndef HZ
-#define HZ 100
-#endif
-
-#define EXEC_PAGESIZE 4096
-
-#ifndef NOGROUP
-#define NOGROUP (-1)
-#endif
-
-#define MAXHOSTNAMELEN 64 /* max length of hostname */
#define COMMAND_LINE_SIZE 256
#endif /* _ASM_PARAM_H */
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 7c66ce13da89..0a48bf5db6c8 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -50,12 +50,6 @@ static int __init powersave_off(char *arg)
}
__setup("powersave=off", powersave_off);
-#if defined(CONFIG_PPC_PSERIES) && defined(CONFIG_TRACEPOINTS)
-static const bool idle_uses_rcu = 1;
-#else
-static const bool idle_uses_rcu;
-#endif
-
/*
* The body of the idle task.
*/
@@ -67,8 +61,7 @@ void cpu_idle(void)
set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
tick_nohz_idle_enter();
- if (!idle_uses_rcu)
- rcu_idle_enter();
+ rcu_idle_enter();
while (!need_resched() && !cpu_should_die()) {
ppc64_runlatch_off();
@@ -106,8 +99,7 @@ void cpu_idle(void)
HMT_medium();
ppc64_runlatch_on();
- if (!idle_uses_rcu)
- rcu_idle_exit();
+ rcu_idle_exit();
tick_nohz_idle_exit();
preempt_enable_no_resched();
if (cpu_should_die())
diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S
index fd05fdee576a..3ce73d0052b1 100644
--- a/arch/powerpc/platforms/pseries/hvCall.S
+++ b/arch/powerpc/platforms/pseries/hvCall.S
@@ -36,6 +36,7 @@ BEGIN_FTR_SECTION; \
b 1f; \
END_FTR_SECTION(0, 1); \
ld r12,hcall_tracepoint_refcount@toc(r2); \
+ std r12,32(r1); \
cmpdi r12,0; \
beq+ 1f; \
mflr r0; \
@@ -74,7 +75,7 @@ END_FTR_SECTION(0, 1); \
BEGIN_FTR_SECTION; \
b 1f; \
END_FTR_SECTION(0, 1); \
- ld r12,hcall_tracepoint_refcount@toc(r2); \
+ ld r12,32(r1); \
cmpdi r12,0; \
beq+ 1f; \
mflr r0; \
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 948e0e3b3547..7bc73af6c7b9 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -546,6 +546,13 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
unsigned long flags;
unsigned int *depth;
+ /*
+ * We cannot call tracepoints inside RCU idle regions which
+ * means we must not trace H_CEDE.
+ */
+ if (opcode == H_CEDE)
+ return;
+
local_irq_save(flags);
depth = &__get_cpu_var(hcall_trace_depth);
@@ -556,8 +563,6 @@ void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
(*depth)++;
preempt_disable();
trace_hcall_entry(opcode, args);
- if (opcode == H_CEDE)
- rcu_idle_enter();
(*depth)--;
out:
@@ -570,6 +575,9 @@ void __trace_hcall_exit(long opcode, unsigned long retval,
unsigned long flags;
unsigned int *depth;
+ if (opcode == H_CEDE)
+ return;
+
local_irq_save(flags);
depth = &__get_cpu_var(hcall_trace_depth);
@@ -578,8 +586,6 @@ void __trace_hcall_exit(long opcode, unsigned long retval,
goto out;
(*depth)++;
- if (opcode == H_CEDE)
- rcu_idle_exit();
trace_hcall_exit(opcode, retval, retbuf);
preempt_enable();
(*depth)--;
diff --git a/arch/s390/include/asm/chpid.h b/arch/s390/include/asm/chpid.h
index fc71d8a6709b..8e88e2221771 100644
--- a/arch/s390/include/asm/chpid.h
+++ b/arch/s390/include/asm/chpid.h
@@ -6,7 +6,7 @@
*/
#ifndef _ASM_S390_CHPID_H
-#define _ASM_S390_CHPID_H _ASM_S390_CHPID_H
+#define _ASM_S390_CHPID_H
#include <linux/string.h>
#include <linux/types.h>
diff --git a/arch/s390/include/asm/itcw.h b/arch/s390/include/asm/itcw.h
index a9bc5c36b32a..fb1bedd3dc0d 100644
--- a/arch/s390/include/asm/itcw.h
+++ b/arch/s390/include/asm/itcw.h
@@ -6,7 +6,7 @@
*/
#ifndef _ASM_S390_ITCW_H
-#define _ASM_S390_ITCW_H _ASM_S390_ITCW_H
+#define _ASM_S390_ITCW_H
#include <linux/types.h>
#include <asm/fcx.h>
diff --git a/arch/s390/include/asm/mman.h b/arch/s390/include/asm/mman.h
index 4e9c8ae0a637..d49760e63506 100644
--- a/arch/s390/include/asm/mman.h
+++ b/arch/s390/include/asm/mman.h
@@ -11,9 +11,11 @@
#include <asm-generic/mman.h>
-#if defined(__KERNEL__) && !defined(__ASSEMBLY__) && defined(CONFIG_64BIT)
+#if defined(__KERNEL__)
+#if !defined(__ASSEMBLY__) && defined(CONFIG_64BIT)
int s390_mmap_check(unsigned long addr, unsigned long len);
#define arch_mmap_check(addr,len,flags) s390_mmap_check(addr,len)
#endif
+#endif
#endif /* __S390_MMAN_H__ */
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c
index 74d49c01783b..6418e95c2b6b 100644
--- a/arch/sh/boards/mach-ap325rxa/setup.c
+++ b/arch/sh/boards/mach-ap325rxa/setup.c
@@ -207,7 +207,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.clock_source = LCDC_CLK_EXTERNAL,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.interface_type = RGB18,
.clock_divider = 1,
.lcd_cfg = ap325rxa_lcdc_modes,
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c
index 9a19fb07276c..033ef2ba621f 100644
--- a/arch/sh/boards/mach-ecovec24/setup.c
+++ b/arch/sh/boards/mach-ecovec24/setup.c
@@ -324,7 +324,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.ch[0] = {
.interface_type = RGB18,
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.lcd_size_cfg = { /* 7.0 inch */
.width = 152,
.height = 91,
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c
index 5c3c71366848..2a18b06abdaf 100644
--- a/arch/sh/boards/mach-kfr2r09/setup.c
+++ b/arch/sh/boards/mach-kfr2r09/setup.c
@@ -143,7 +143,7 @@ static struct sh_mobile_lcdc_info kfr2r09_sh_lcdc_info = {
.clock_source = LCDC_CLK_BUS,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.interface_type = SYS18,
.clock_divider = 6,
.flags = LCDC_FLAGS_DWPOL,
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c
index f8f9377d5684..68c3d6f42896 100644
--- a/arch/sh/boards/mach-migor/setup.c
+++ b/arch/sh/boards/mach-migor/setup.c
@@ -241,7 +241,7 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
.clock_source = LCDC_CLK_BUS,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.interface_type = RGB16,
.clock_divider = 2,
.lcd_cfg = migor_lcd_modes,
@@ -255,7 +255,7 @@ static struct sh_mobile_lcdc_info sh_mobile_lcdc_info = {
.clock_source = LCDC_CLK_PERIPHERAL,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.interface_type = SYS16A,
.clock_divider = 10,
.lcd_cfg = migor_lcd_modes,
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c
index 2585733e9bce..036fe1adaef1 100644
--- a/arch/sh/boards/mach-se/7724/setup.c
+++ b/arch/sh/boards/mach-se/7724/setup.c
@@ -179,7 +179,7 @@ static struct sh_mobile_lcdc_info lcdc_info = {
.clock_source = LCDC_CLK_EXTERNAL,
.ch[0] = {
.chan = LCDC_CHAN_MAINLCD,
- .bpp = 16,
+ .fourcc = V4L2_PIX_FMT_RGB565,
.clock_divider = 1,
.lcd_size_cfg = { /* 7.0 inch */
.width = 152,
diff --git a/arch/sparc/include/asm/siginfo.h b/arch/sparc/include/asm/siginfo.h
index 988e5d8ed11a..215900fce21b 100644
--- a/arch/sparc/include/asm/siginfo.h
+++ b/arch/sparc/include/asm/siginfo.h
@@ -16,8 +16,6 @@
#ifdef __KERNEL__
-#include <linux/compat.h>
-
#ifdef CONFIG_COMPAT
struct compat_siginfo;
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h
index 1e1e616783eb..1e5e49aad548 100644
--- a/arch/tile/include/asm/signal.h
+++ b/arch/tile/include/asm/signal.h
@@ -23,7 +23,8 @@
#include <asm-generic/signal.h>
-#if defined(__KERNEL__) && !defined(__ASSEMBLY__)
+#if defined(__KERNEL__)
+#if !defined(__ASSEMBLY__)
struct pt_regs;
int restore_sigcontext(struct pt_regs *, struct sigcontext __user *);
int setup_sigcontext(struct sigcontext __user *, struct pt_regs *);
@@ -33,5 +34,6 @@ void signal_fault(const char *type, struct pt_regs *,
void trace_unhandled_signal(const char *type, struct pt_regs *regs,
unsigned long address, int signo);
#endif
+#endif
#endif /* _ASM_TILE_SIGNAL_H */
diff --git a/arch/x86/kernel/apm_32.c b/arch/x86/kernel/apm_32.c
index a46bd383953c..f76623cbe263 100644
--- a/arch/x86/kernel/apm_32.c
+++ b/arch/x86/kernel/apm_32.c
@@ -383,21 +383,21 @@ static int ignore_sys_suspend;
static int ignore_normal_resume;
static int bounce_interval __read_mostly = DEFAULT_BOUNCE_INTERVAL;
-static int debug __read_mostly;
-static int smp __read_mostly;
+static bool debug __read_mostly;
+static bool smp __read_mostly;
static int apm_disabled = -1;
#ifdef CONFIG_SMP
-static int power_off;
+static bool power_off;
#else
-static int power_off = 1;
+static bool power_off = 1;
#endif
-static int realmode_power_off;
+static bool realmode_power_off;
#ifdef CONFIG_APM_ALLOW_INTS
-static int allow_ints = 1;
+static bool allow_ints = 1;
#else
-static int allow_ints;
+static bool allow_ints;
#endif
-static int broken_psr;
+static bool broken_psr;
static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
static DECLARE_WAIT_QUEUE_HEAD(apm_suspend_waitqueue);
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index f22a9f7f6390..29ba3297e480 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -2011,7 +2011,7 @@ static __cpuinit int mce_device_create(unsigned int cpu)
if (!mce_available(&boot_cpu_data))
return -EIO;
- memset(&dev->kobj, 0, sizeof(struct kobject));
+ memset(dev, 0, sizeof(struct device));
dev->id = cpu;
dev->bus = &mce_subsys;
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
index 2a2a9b40db19..224b02c3cda9 100644
--- a/arch/x86/kvm/mmu.c
+++ b/arch/x86/kvm/mmu.c
@@ -74,7 +74,7 @@ enum {
#endif
#ifdef MMU_DEBUG
-static int dbg = 0;
+static bool dbg = 0;
module_param(dbg, bool, 0644);
#endif
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 906a7e84200f..d29216c462b3 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -51,29 +51,29 @@
MODULE_AUTHOR("Qumranet");
MODULE_LICENSE("GPL");
-static int __read_mostly enable_vpid = 1;
+static bool __read_mostly enable_vpid = 1;
module_param_named(vpid, enable_vpid, bool, 0444);
-static int __read_mostly flexpriority_enabled = 1;
+static bool __read_mostly flexpriority_enabled = 1;
module_param_named(flexpriority, flexpriority_enabled, bool, S_IRUGO);
-static int __read_mostly enable_ept = 1;
+static bool __read_mostly enable_ept = 1;
module_param_named(ept, enable_ept, bool, S_IRUGO);
-static int __read_mostly enable_unrestricted_guest = 1;
+static bool __read_mostly enable_unrestricted_guest = 1;
module_param_named(unrestricted_guest,
enable_unrestricted_guest, bool, S_IRUGO);
-static int __read_mostly emulate_invalid_guest_state = 0;
+static bool __read_mostly emulate_invalid_guest_state = 0;
module_param(emulate_invalid_guest_state, bool, S_IRUGO);
-static int __read_mostly vmm_exclusive = 1;
+static bool __read_mostly vmm_exclusive = 1;
module_param(vmm_exclusive, bool, S_IRUGO);
-static int __read_mostly yield_on_hlt = 1;
+static bool __read_mostly yield_on_hlt = 1;
module_param(yield_on_hlt, bool, S_IRUGO);
-static int __read_mostly fasteoi = 1;
+static bool __read_mostly fasteoi = 1;
module_param(fasteoi, bool, S_IRUGO);
/*
@@ -81,7 +81,7 @@ module_param(fasteoi, bool, S_IRUGO);
* VMX and be a hypervisor for its own guests. If nested=0, guests may not
* use VMX instructions.
*/
-static int __read_mostly nested = 0;
+static bool __read_mostly nested = 0;
module_param(nested, bool, S_IRUGO);
#define KVM_GUEST_CR0_MASK_UNRESTRICTED_GUEST \
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 1171def5f96b..14d6cadc4ba6 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -88,8 +88,8 @@ static void process_nmi(struct kvm_vcpu *vcpu);
struct kvm_x86_ops *kvm_x86_ops;
EXPORT_SYMBOL_GPL(kvm_x86_ops);
-int ignore_msrs = 0;
-module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR);
+static bool ignore_msrs = 0;
+module_param(ignore_msrs, bool, S_IRUGO | S_IWUSR);
bool kvm_has_tsc_control;
EXPORT_SYMBOL_GPL(kvm_has_tsc_control);
diff --git a/arch/x86/mm/mmio-mod.c b/arch/x86/mm/mmio-mod.c
index de54b9b278a7..dc0b727742f4 100644
--- a/arch/x86/mm/mmio-mod.c
+++ b/arch/x86/mm/mmio-mod.c
@@ -75,8 +75,8 @@ static LIST_HEAD(trace_list); /* struct remap_trace */
/* module parameters */
static unsigned long filter_offset;
-static int nommiotrace;
-static int trace_pc;
+static bool nommiotrace;
+static bool trace_pc;
module_param(filter_offset, ulong, 0);
module_param(nommiotrace, bool, 0);
diff --git a/arch/x86/platform/geode/alix.c b/arch/x86/platform/geode/alix.c
index ca1973699d3d..dc5f1d32aced 100644
--- a/arch/x86/platform/geode/alix.c
+++ b/arch/x86/platform/geode/alix.c
@@ -27,7 +27,7 @@
#include <asm/geode.h>
-static int force = 0;
+static bool force = 0;
module_param(force, bool, 0444);
/* FIXME: Award bios is not automatically detected as Alix platform */
MODULE_PARM_DESC(force, "Force detection as ALIX.2/ALIX.3 platform");
diff --git a/arch/x86/platform/iris/iris.c b/arch/x86/platform/iris/iris.c
index 1ba7f5ed8c9b..5917eb56b313 100644
--- a/arch/x86/platform/iris/iris.c
+++ b/arch/x86/platform/iris/iris.c
@@ -42,7 +42,7 @@ MODULE_AUTHOR("Sébastien Hinderer <Sebastien.Hinderer@ens-lyon.org>");
MODULE_DESCRIPTION("A power_off handler for Iris devices from EuroBraille");
MODULE_SUPPORTED_DEVICE("Eurobraille/Iris");
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Set to one to force poweroff handler installation.");
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index fbdf0d802ec4..260fa80ef575 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -24,6 +24,7 @@
#include <linux/capability.h>
#include <linux/completion.h>
#include <linux/cdrom.h>
+#include <linux/ratelimit.h>
#include <linux/slab.h>
#include <linux/times.h>
#include <asm/uaccess.h>
@@ -690,6 +691,57 @@ int scsi_cmd_ioctl(struct request_queue *q, struct gendisk *bd_disk, fmode_t mod
}
EXPORT_SYMBOL(scsi_cmd_ioctl);
+int scsi_verify_blk_ioctl(struct block_device *bd, unsigned int cmd)
+{
+ if (bd && bd == bd->bd_contains)
+ return 0;
+
+ /* Actually none of these is particularly useful on a partition,
+ * but they are safe.
+ */
+ switch (cmd) {
+ case SCSI_IOCTL_GET_IDLUN:
+ case SCSI_IOCTL_GET_BUS_NUMBER:
+ case SCSI_IOCTL_GET_PCI:
+ case SCSI_IOCTL_PROBE_HOST:
+ case SG_GET_VERSION_NUM:
+ case SG_SET_TIMEOUT:
+ case SG_GET_TIMEOUT:
+ case SG_GET_RESERVED_SIZE:
+ case SG_SET_RESERVED_SIZE:
+ case SG_EMULATED_HOST:
+ return 0;
+ case CDROM_GET_CAPABILITY:
+ /* Keep this until we remove the printk below. udev sends it
+ * and we do not want to spam dmesg about it. CD-ROMs do
+ * not have partitions, so we get here only for disks.
+ */
+ return -ENOIOCTLCMD;
+ default:
+ break;
+ }
+
+ /* In particular, rule out all resets and host-specific ioctls. */
+ printk_ratelimited(KERN_WARNING
+ "%s: sending ioctl %x to a partition!\n", current->comm, cmd);
+
+ return capable(CAP_SYS_RAWIO) ? 0 : -ENOIOCTLCMD;
+}
+EXPORT_SYMBOL(scsi_verify_blk_ioctl);
+
+int scsi_cmd_blk_ioctl(struct block_device *bd, fmode_t mode,
+ unsigned int cmd, void __user *arg)
+{
+ int ret;
+
+ ret = scsi_verify_blk_ioctl(bd, cmd);
+ if (ret < 0)
+ return ret;
+
+ return scsi_cmd_ioctl(bd->bd_disk->queue, bd->bd_disk, mode, cmd, arg);
+}
+EXPORT_SYMBOL(scsi_cmd_blk_ioctl);
+
static int __init blk_scsi_ioctl_init(void)
{
blk_set_cmd_filter_defaults(&blk_default_cmd_filter);
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
index 3ba6ef508869..16f8693cc147 100644
--- a/crypto/crypto_user.c
+++ b/crypto/crypto_user.c
@@ -382,7 +382,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
type -= CRYPTO_MSG_BASE;
link = &crypto_dispatch[type];
- if (security_netlink_recv(skb, CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) &&
diff --git a/drivers/Makefile b/drivers/Makefile
index 1b3142127bf5..c07be024b962 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -97,7 +97,7 @@ obj-$(CONFIG_EISA) += eisa/
obj-y += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_CPU_IDLE) += cpuidle/
-obj-$(CONFIG_MMC) += mmc/
+obj-y += mmc/
obj-$(CONFIG_MEMSTICK) += memstick/
obj-y += leds/
obj-$(CONFIG_INFINIBAND) += infiniband/
diff --git a/drivers/accessibility/braille/braille_console.c b/drivers/accessibility/braille/braille_console.c
index cb423f5aef24..c339a0880e6e 100644
--- a/drivers/accessibility/braille/braille_console.c
+++ b/drivers/accessibility/braille/braille_console.c
@@ -44,7 +44,7 @@ MODULE_LICENSE("GPL");
*/
/* Emit various sounds */
-static int sound;
+static bool sound;
module_param(sound, bool, 0);
MODULE_PARM_DESC(sound, "emit sounds");
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 76dc02f15574..e6652d716e45 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -108,7 +108,7 @@ u8 ACPI_INIT_GLOBAL(acpi_gbl_use_default_register_widths, TRUE);
/*
* Optionally enable output from the AML Debug Object.
*/
-u32 ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE);
+bool ACPI_INIT_GLOBAL(acpi_gbl_enable_aml_debug_object, FALSE);
/*
* Optionally copy the entire DSDT to local memory (instead of simply
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
index b8e08cb67a18..ebaf037a787b 100644
--- a/drivers/acpi/apei/ghes.c
+++ b/drivers/acpi/apei/ghes.c
@@ -118,7 +118,7 @@ struct ghes_estatus_cache {
struct rcu_head rcu;
};
-int ghes_disable;
+bool ghes_disable;
module_param_named(disable, ghes_disable, bool, 0);
static int ghes_panic_timeout __read_mostly = 30;
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c
index 05fee06f4d6e..ee7fddc4665c 100644
--- a/drivers/acpi/apei/hest.c
+++ b/drivers/acpi/apei/hest.c
@@ -41,7 +41,7 @@
#define HEST_PFX "HEST: "
-int hest_disable;
+bool hest_disable;
EXPORT_SYMBOL_GPL(hest_disable);
/* HEST table parsing */
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 19a61136d848..88eb14304667 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -43,7 +43,7 @@ MODULE_AUTHOR("Kristen Carlson Accardi");
MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
MODULE_LICENSE("GPL");
-static int immediate_undock = 1;
+static bool immediate_undock = 1;
module_param(immediate_undock, bool, 0644);
MODULE_PARM_DESC(immediate_undock, "1 (default) will cause the driver to "
"undock immediately when the undock button is pressed, 0 will cause"
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c
index 07f7fea8a4e2..e50e31a518af 100644
--- a/drivers/acpi/pci_slot.c
+++ b/drivers/acpi/pci_slot.c
@@ -34,7 +34,7 @@
#include <acpi/acpi_drivers.h>
#include <linux/dmi.h>
-static int debug;
+static bool debug;
static int check_sta_before_sun;
#define DRIVER_VERSION "0.1"
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 08a44b532f7c..eaef02afc7cf 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -69,21 +69,21 @@ MODULE_AUTHOR("Bruno Ducrot");
MODULE_DESCRIPTION("ACPI Video Driver");
MODULE_LICENSE("GPL");
-static int brightness_switch_enabled = 1;
+static bool brightness_switch_enabled = 1;
module_param(brightness_switch_enabled, bool, 0644);
/*
* By default, we don't allow duplicate ACPI video bus devices
* under the same VGA controller
*/
-static int allow_duplicates;
+static bool allow_duplicates;
module_param(allow_duplicates, bool, 0644);
/*
* Some BIOSes claim they use minimum backlight at boot,
* and this may bring dimming screen after boot
*/
-static int use_bios_initial_backlight = 1;
+static bool use_bios_initial_backlight = 1;
module_param(use_bios_initial_backlight, bool, 0644);
static int register_count = 0;
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index e0bc9646a38e..55d6179dde58 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -599,9 +599,9 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-static int adma_enabled;
-static int swncq_enabled = 1;
-static int msi_enabled;
+static bool adma_enabled;
+static bool swncq_enabled = 1;
+static bool msi_enabled;
static void nv_adma_register_mode(struct ata_port *ap)
{
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 1e9140626a83..e7e610aa9a7a 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -417,7 +417,7 @@ static struct ata_port_operations sil24_ops = {
#endif
};
-static int sata_sil24_msi; /* Disable MSI */
+static bool sata_sil24_msi; /* Disable MSI */
module_param_named(msi, sata_sil24_msi, bool, S_IRUGO);
MODULE_PARM_DESC(msi, "Enable MSI (Default: false)");
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index 9a51df4f5b74..b182c2f7d777 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -112,12 +112,12 @@ static u8 read_prom_byte(struct he_dev *he_dev, int addr);
/* globals */
static struct he_dev *he_devs;
-static int disable64;
+static bool disable64;
static short nvpibits = -1;
static short nvcibits = -1;
static short rx_skb_reserve = 16;
-static int irq_coalesce = 1;
-static int sdh = 0;
+static bool irq_coalesce = 1;
+static bool sdh = 0;
/* Read from EEPROM = 0000 0011b */
static unsigned int readtab[] = {
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index fcbec8ac134d..7be9f79018e9 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -179,7 +179,7 @@ config GENERIC_CPU_DEVICES
source "drivers/base/regmap/Kconfig"
config DMA_SHARED_BUFFER
- bool "Buffer framework to be shared between drivers"
+ bool
default n
select ANON_INODES
depends on EXPERIMENTAL
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 587cce57adae..b0f553b26d0f 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1735,7 +1735,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
case CCISS_BIG_PASSTHRU:
return cciss_bigpassthru(h, argp);
- /* scsi_cmd_ioctl handles these, below, though some are not */
+ /* scsi_cmd_blk_ioctl handles these, below, though some are not */
/* very meaningful for cciss. SG_IO is the main one people want. */
case SG_GET_VERSION_NUM:
@@ -1746,9 +1746,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
case SG_EMULATED_HOST:
case SG_IO:
case SCSI_IOCTL_SEND_COMMAND:
- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
+ return scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
- /* scsi_cmd_ioctl would normally handle these, below, but */
+ /* scsi_cmd_blk_ioctl would normally handle these, below, but */
/* they aren't a good fit for cciss, as CD-ROMs are */
/* not supported, and we don't have any bus/target/lun */
/* which we present to the kernel. */
diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h
index 9cf20355ceec..8d680562ba73 100644
--- a/drivers/block/drbd/drbd_int.h
+++ b/drivers/block/drbd/drbd_int.h
@@ -59,8 +59,8 @@
/* module parameter, defined in drbd_main.c */
extern unsigned int minor_count;
-extern int disable_sendpage;
-extern int allow_oos;
+extern bool disable_sendpage;
+extern bool allow_oos;
extern unsigned int cn_idx;
#ifdef CONFIG_DRBD_FAULT_INJECTION
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 0358e55356c8..211fc44f84be 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -117,8 +117,8 @@ module_param(fault_devs, int, 0644);
/* module parameter, defined */
unsigned int minor_count = DRBD_MINOR_COUNT_DEF;
-int disable_sendpage;
-int allow_oos;
+bool disable_sendpage;
+bool allow_oos;
unsigned int cn_idx = CN_IDX_DRBD;
int proc_details; /* Detail level in proc drbd*/
diff --git a/drivers/block/paride/bpck6.c b/drivers/block/paride/bpck6.c
index ad124525ac23..ec64e7f5d1ce 100644
--- a/drivers/block/paride/bpck6.c
+++ b/drivers/block/paride/bpck6.c
@@ -20,9 +20,6 @@
*/
-/* PARAMETERS */
-static int verbose; /* set this to 1 to see debugging messages and whatnot */
-
#define BACKPACK_VERSION "2.0.2"
#include <linux/module.h>
@@ -36,6 +33,8 @@ static int verbose; /* set this to 1 to see debugging messages and whatnot */
#include "ppc6lnx.c"
#include "paride.h"
+/* PARAMETERS */
+static bool verbose; /* set this to 1 to see debugging messages and whatnot */
#define PPCSTRUCT(pi) ((Interface *)(pi->private))
diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
index 46b8136c31bb..ba2b6b5e5910 100644
--- a/drivers/block/paride/pcd.c
+++ b/drivers/block/paride/pcd.c
@@ -144,7 +144,7 @@ enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
static DEFINE_MUTEX(pcd_mutex);
static DEFINE_SPINLOCK(pcd_lock);
-module_param(verbose, bool, 0644);
+module_param(verbose, int, 0644);
module_param(major, int, 0);
module_param(name, charp, 0);
module_param(nice, int, 0);
diff --git a/drivers/block/paride/pd.c b/drivers/block/paride/pd.c
index 869e7676d46f..831e3ac156e6 100644
--- a/drivers/block/paride/pd.c
+++ b/drivers/block/paride/pd.c
@@ -124,8 +124,9 @@
by default.
*/
+#include <linux/types.h>
-static int verbose = 0;
+static bool verbose = 0;
static int major = PD_MAJOR;
static char *name = PD_NAME;
static int cluster = 64;
diff --git a/drivers/block/paride/pf.c b/drivers/block/paride/pf.c
index f21b520ef419..ec8f9ed6326e 100644
--- a/drivers/block/paride/pf.c
+++ b/drivers/block/paride/pf.c
@@ -118,13 +118,15 @@
#define PF_NAME "pf"
#define PF_UNITS 4
+#include <linux/types.h>
+
/* Here are things one can override from the insmod command.
Most are autoprobed by paride unless set here. Verbose is off
by default.
*/
-static int verbose = 0;
+static bool verbose = 0;
static int major = PF_MAJOR;
static char *name = PF_NAME;
static int cluster = 64;
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index a79fb4f7ff62..4a27b1de5fcb 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -130,13 +130,14 @@
#define PI_PG 4
#endif
+#include <linux/types.h>
/* Here are things one can override from the insmod command.
Most are autoprobed by paride unless set here. Verbose is 0
by default.
*/
-static int verbose = 0;
+static bool verbose = 0;
static int major = PG_MAJOR;
static char *name = PG_NAME;
static int disable = 0;
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 7179f79d7468..2596042eb987 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -109,13 +109,15 @@
#define PT_NAME "pt"
#define PT_UNITS 4
+#include <linux/types.h>
+
/* Here are things one can override from the insmod command.
Most are autoprobed by paride unless set here. Verbose is on
by default.
*/
-static int verbose = 0;
+static bool verbose = 0;
static int major = PT_MAJOR;
static char *name = PT_NAME;
static int disable = 0;
diff --git a/drivers/block/ub.c b/drivers/block/ub.c
index 0e376d46bdd1..7333b9e44411 100644
--- a/drivers/block/ub.c
+++ b/drivers/block/ub.c
@@ -1744,12 +1744,11 @@ static int ub_bd_release(struct gendisk *disk, fmode_t mode)
static int ub_bd_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
- struct gendisk *disk = bdev->bd_disk;
void __user *usermem = (void __user *) arg;
int ret;
mutex_lock(&ub_mutex);
- ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, usermem);
+ ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, usermem);
mutex_unlock(&ub_mutex);
return ret;
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index ffd5ca919295..c4a60badf252 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -250,8 +250,8 @@ static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
return -ENOTTY;
- return scsi_cmd_ioctl(disk->queue, disk, mode, cmd,
- (void __user *)data);
+ return scsi_cmd_blk_ioctl(bdev, mode, cmd,
+ (void __user *)data);
}
/* We provide getgeo only to please some old bootloader/partitioning tools */
diff --git a/drivers/block/xd.c b/drivers/block/xd.c
index 4abd2bcd20fb..51a972704db5 100644
--- a/drivers/block/xd.c
+++ b/drivers/block/xd.c
@@ -148,7 +148,7 @@ static volatile int xdc_busy;
static struct timer_list xd_watchdog_int;
static volatile u_char xd_error;
-static int nodma = XD_DONT_USE_DMA;
+static bool nodma = XD_DONT_USE_DMA;
static struct request_queue *xd_queue;
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 55ac349695c4..f00f596c1029 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -37,13 +37,13 @@
#define VERSION "0.6"
-static int ignore_dga;
-static int ignore_csr;
-static int ignore_sniffer;
-static int disable_scofix;
-static int force_scofix;
+static bool ignore_dga;
+static bool ignore_csr;
+static bool ignore_sniffer;
+static bool disable_scofix;
+static bool force_scofix;
-static int reset = 1;
+static bool reset = 1;
static struct usb_driver btusb_driver;
diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 9c5b2dc38e29..a767d4de45a4 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -49,8 +49,8 @@
#define VERSION "0.3"
-static int txcrc = 1;
-static int hciextn = 1;
+static bool txcrc = 1;
+static bool hciextn = 1;
#define BCSP_TXWINSIZE 4
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c
index 48ad2a7ab080..07114489994f 100644
--- a/drivers/bluetooth/hci_ldisc.c
+++ b/drivers/bluetooth/hci_ldisc.c
@@ -48,7 +48,7 @@
#define VERSION "2.2"
-static int reset = 0;
+static bool reset = 0;
static struct hci_uart_proto *hup[HCI_UART_MAX_PROTO];
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 2118211aff99..55eaf474d32c 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -285,17 +285,17 @@
#include <asm/uaccess.h>
/* used to tell the module to turn on full debugging messages */
-static int debug;
+static bool debug;
/* used to keep tray locked at all times */
static int keeplocked;
/* default compatibility mode */
-static int autoclose=1;
-static int autoeject;
-static int lockdoor = 1;
+static bool autoclose=1;
+static bool autoeject;
+static bool lockdoor = 1;
/* will we ever get to use this... sigh. */
-static int check_media_type;
+static bool check_media_type;
/* automatically restart mrw format */
-static int mrw_format_restart = 1;
+static bool mrw_format_restart = 1;
module_param(debug, bool, 0);
module_param(autoclose, bool, 0);
module_param(autoeject, bool, 0);
@@ -2746,12 +2746,11 @@ int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
{
void __user *argp = (void __user *)arg;
int ret;
- struct gendisk *disk = bdev->bd_disk;
/*
* Try the generic SCSI command ioctl's first.
*/
- ret = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, argp);
+ ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
if (ret != -ENOTTY)
return ret;
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index 780498d76581..444f8b6ab411 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -33,7 +33,7 @@
#define ULI_X86_64_ENU_SCR_REG 0x54
static struct resource *aperture_resource;
-static int __initdata agp_try_unsupported = 1;
+static bool __initdata agp_try_unsupported = 1;
static int agp_bridges_found;
static void amd64_tlbflush(struct agp_memory *temp)
diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c
index 29aacd81de78..08704ae53956 100644
--- a/drivers/char/agp/sis-agp.c
+++ b/drivers/char/agp/sis-agp.c
@@ -17,7 +17,7 @@
#define PCI_DEVICE_ID_SI_662 0x0662
#define PCI_DEVICE_ID_SI_671 0x0671
-static int __devinitdata agp_sis_force_delay = 0;
+static bool __devinitdata agp_sis_force_delay = 0;
static int __devinitdata agp_sis_agp_spec = -1;
static int sis_fetch_size(void)
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c
index 6e40072fbf67..40cc0cf2ded6 100644
--- a/drivers/char/i8k.c
+++ b/drivers/char/i8k.c
@@ -69,19 +69,19 @@ MODULE_AUTHOR("Massimo Dal Zotto (dz@debian.org)");
MODULE_DESCRIPTION("Driver for accessing SMM BIOS on Dell laptops");
MODULE_LICENSE("GPL");
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force loading without checking for supported models");
-static int ignore_dmi;
+static bool ignore_dmi;
module_param(ignore_dmi, bool, 0);
MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
-static int restricted;
+static bool restricted;
module_param(restricted, bool, 0);
MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
-static int power_status;
+static bool power_status;
module_param(power_status, bool, 0600);
MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index 9397ab49b72e..50fcf9c04569 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -1227,7 +1227,7 @@ static int smi_num; /* Used to sequence the SMIs */
#define DEFAULT_REGSPACING 1
#define DEFAULT_REGSIZE 1
-static int si_trydefaults = 1;
+static bool si_trydefaults = 1;
static char *si_type[SI_MAX_PARMS];
#define MAX_SI_TYPE_STR 30
static char si_type_str[MAX_SI_TYPE_STR];
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 97c3edb95ae7..f43485607063 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -829,7 +829,7 @@ static struct console lpcons = {
static int parport_nr[LP_NO] = { [0 ... LP_NO-1] = LP_PARPORT_UNSPEC };
static char *parport[LP_NO];
-static int reset;
+static bool reset;
module_param_array(parport, charp, NULL, 0);
module_param(reset, bool, 0);
diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c
index a12f52400dbc..bf586ae1ee83 100644
--- a/drivers/char/nwflash.c
+++ b/drivers/char/nwflash.c
@@ -51,7 +51,7 @@ static int write_block(unsigned long p, const char __user *buf, int count);
#define KFLASH_ID 0x89A6 //Intel flash
#define KFLASH_ID4 0xB0D4 //Intel flash 4Meg
-static int flashdebug; //if set - we will display progress msgs
+static bool flashdebug; //if set - we will display progress msgs
static int gbWriteEnable;
static int gbWriteBase64Enable;
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 15781396af25..07f6a5abe372 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -439,7 +439,7 @@ static int mgslpc_device_count = 0;
* .text section address and breakpoint on module load.
* This is useful for use with gdb and add-symbol-file command.
*/
-static int break_on_load=0;
+static bool break_on_load=0;
/*
* Driver major number, defaults to zero to get auto
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 85da8740586b..732215b805c1 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -387,7 +387,7 @@ static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
static struct fasync_struct *fasync;
#if 0
-static int debug;
+static bool debug;
module_param(debug, bool, 0644);
#define DEBUG_ENT(fmt, arg...) do { \
if (debug) \
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 10cc44ceb5d1..a1748621111b 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -255,7 +255,7 @@ out:
return size;
}
-static int itpm;
+static bool itpm;
module_param(itpm, bool, 0444);
MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)");
@@ -500,7 +500,7 @@ static irqreturn_t tis_int_handler(int dummy, void *dev_id)
return IRQ_HANDLED;
}
-static int interrupts = 1;
+static bool interrupts = 1;
module_param(interrupts, bool, 0444);
MODULE_PARM_DESC(interrupts, "Enable interrupts");
@@ -828,7 +828,7 @@ static struct platform_driver tis_drv = {
static struct platform_device *pdev;
-static int force;
+static bool force;
module_param(force, bool, 0444);
MODULE_PARM_DESC(force, "Force device probe rather than using ACPI entry");
static int __init init_tis(void)
diff --git a/drivers/edac/r82600_edac.c b/drivers/edac/r82600_edac.c
index b153674431f1..e294e1b3616c 100644
--- a/drivers/edac/r82600_edac.c
+++ b/drivers/edac/r82600_edac.c
@@ -131,7 +131,7 @@ struct r82600_error_info {
u32 eapr;
};
-static unsigned int disable_hardware_scrub;
+static bool disable_hardware_scrub;
static struct edac_pci_ctl_info *r82600_pci;
diff --git a/drivers/firewire/sbp2.c b/drivers/firewire/sbp2.c
index 68375bc3aef6..80e95aa3bf14 100644
--- a/drivers/firewire/sbp2.c
+++ b/drivers/firewire/sbp2.c
@@ -66,7 +66,7 @@
*
* Concurrent logins are useful together with cluster filesystems.
*/
-static int sbp2_param_exclusive_login = 1;
+static bool sbp2_param_exclusive_login = 1;
module_param_named(exclusive_login, sbp2_param_exclusive_login, bool, 0644);
MODULE_PARM_DESC(exclusive_login, "Exclusive login to sbp2 device "
"(default = Y, use N for concurrent initiators)");
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 573532f7553e..37c4bd1cacd5 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -138,6 +138,7 @@ config GPIO_MXS
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
+ select GENERIC_IRQ_CHIP
help
Say yes here to support the PrimeCell PL061 GPIO device
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 62e641e79e8f..fa10df604c01 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -2,7 +2,7 @@
ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG
-obj-$(CONFIG_GPIOLIB) += gpiolib.o
+obj-$(CONFIG_GPIOLIB) += gpiolib.o devres.o
# Device drivers. Generally keep list sorted alphabetically
obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o
diff --git a/drivers/gpio/devres.c b/drivers/gpio/devres.c
new file mode 100644
index 000000000000..3dd29399cef5
--- /dev/null
+++ b/drivers/gpio/devres.c
@@ -0,0 +1,90 @@
+/*
+ * drivers/gpio/devres.c - managed gpio resources
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ * This file is based on kernel/irq/devres.c
+ *
+ * Copyright (c) 2011 John Crispin <blogic@openwrt.org>
+ */
+
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/device.h>
+#include <linux/gfp.h>
+
+static void devm_gpio_release(struct device *dev, void *res)
+{
+ unsigned *gpio = res;
+
+ gpio_free(*gpio);
+}
+
+static int devm_gpio_match(struct device *dev, void *res, void *data)
+{
+ unsigned *this = res, *gpio = data;
+
+ return *this == *gpio;
+}
+
+/**
+ * devm_gpio_request - request a gpio for a managed device
+ * @dev: device to request the gpio for
+ * @gpio: gpio to allocate
+ * @label: the name of the requested gpio
+ *
+ * Except for the extra @dev argument, this function takes the
+ * same arguments and performs the same function as
+ * gpio_request(). GPIOs requested with this function will be
+ * automatically freed on driver detach.
+ *
+ * If an GPIO allocated with this function needs to be freed
+ * separately, devm_gpio_free() must be used.
+ */
+
+int devm_gpio_request(struct device *dev, unsigned gpio, const char *label)
+{
+ unsigned *dr;
+ int rc;
+
+ dr = devres_alloc(devm_gpio_release, sizeof(unsigned), GFP_KERNEL);
+ if (!dr)
+ return -ENOMEM;
+
+ rc = gpio_request(gpio, label);
+ if (rc) {
+ devres_free(dr);
+ return rc;
+ }
+
+ *dr = gpio;
+ devres_add(dev, dr);
+
+ return 0;
+}
+EXPORT_SYMBOL(devm_gpio_request);
+
+/**
+ * devm_gpio_free - free an interrupt
+ * @dev: device to free gpio for
+ * @gpio: gpio to free
+ *
+ * Except for the extra @dev argument, this function takes the
+ * same arguments and performs the same function as gpio_free().
+ * This function instead of gpio_free() should be used to manually
+ * free GPIOs allocated with devm_gpio_request().
+ */
+void devm_gpio_free(struct device *dev, unsigned int gpio)
+{
+
+ WARN_ON(devres_destroy(dev, devm_gpio_release, devm_gpio_match,
+ &gpio));
+ gpio_free(gpio);
+}
+EXPORT_SYMBOL(devm_gpio_free);
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 8f79c03049f3..77c9cc70fa77 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -12,7 +12,6 @@
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/module.h>
-#include <linux/list.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
@@ -23,6 +22,8 @@
#include <linux/amba/bus.h>
#include <linux/amba/pl061.h>
#include <linux/slab.h>
+#include <linux/pm.h>
+#include <asm/mach/irq.h>
#define GPIODIR 0x400
#define GPIOIS 0x404
@@ -35,25 +36,33 @@
#define PL061_GPIO_NR 8
-struct pl061_gpio {
- /* We use a list of pl061_gpio structs for each trigger IRQ in the main
- * interrupts controller of the system. We need this to support systems
- * in which more that one PL061s are connected to the same IRQ. The ISR
- * interates through this list to find the source of the interrupt.
- */
- struct list_head list;
+#ifdef CONFIG_PM
+struct pl061_context_save_regs {
+ u8 gpio_data;
+ u8 gpio_dir;
+ u8 gpio_is;
+ u8 gpio_ibe;
+ u8 gpio_iev;
+ u8 gpio_ie;
+};
+#endif
+struct pl061_gpio {
/* Each of the two spinlocks protects a different set of hardware
* regiters and data structurs. This decouples the code of the IRQ from
* the GPIO code. This also makes the case of a GPIO routine call from
* the IRQ code simpler.
*/
spinlock_t lock; /* GPIO registers */
- spinlock_t irq_lock; /* IRQ registers */
void __iomem *base;
- unsigned irq_base;
+ int irq_base;
+ struct irq_chip_generic *irq_gc;
struct gpio_chip gc;
+
+#ifdef CONFIG_PM
+ struct pl061_context_save_regs csave_regs;
+#endif
};
static int pl061_direction_input(struct gpio_chip *gc, unsigned offset)
@@ -118,46 +127,16 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
- if (chip->irq_base == NO_IRQ)
+ if (chip->irq_base <= 0)
return -EINVAL;
return chip->irq_base + offset;
}
-/*
- * PL061 GPIO IRQ
- */
-static void pl061_irq_disable(struct irq_data *d)
-{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
- int offset = d->irq - chip->irq_base;
- unsigned long flags;
- u8 gpioie;
-
- spin_lock_irqsave(&chip->irq_lock, flags);
- gpioie = readb(chip->base + GPIOIE);
- gpioie &= ~(1 << offset);
- writeb(gpioie, chip->base + GPIOIE);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
-}
-
-static void pl061_irq_enable(struct irq_data *d)
-{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
- int offset = d->irq - chip->irq_base;
- unsigned long flags;
- u8 gpioie;
-
- spin_lock_irqsave(&chip->irq_lock, flags);
- gpioie = readb(chip->base + GPIOIE);
- gpioie |= 1 << offset;
- writeb(gpioie, chip->base + GPIOIE);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
-}
-
static int pl061_irq_type(struct irq_data *d, unsigned trigger)
{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct pl061_gpio *chip = gc->private;
int offset = d->irq - chip->irq_base;
unsigned long flags;
u8 gpiois, gpioibe, gpioiev;
@@ -165,7 +144,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
if (offset < 0 || offset >= PL061_GPIO_NR)
return -EINVAL;
- spin_lock_irqsave(&chip->irq_lock, flags);
+ raw_spin_lock_irqsave(&gc->lock, flags);
gpioiev = readb(chip->base + GPIOIEV);
@@ -194,49 +173,54 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
writeb(gpioiev, chip->base + GPIOIEV);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
+ raw_spin_unlock_irqrestore(&gc->lock, flags);
return 0;
}
-static struct irq_chip pl061_irqchip = {
- .name = "GPIO",
- .irq_enable = pl061_irq_enable,
- .irq_disable = pl061_irq_disable,
- .irq_set_type = pl061_irq_type,
-};
-
static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
{
- struct list_head *chip_list = irq_get_handler_data(irq);
- struct list_head *ptr;
- struct pl061_gpio *chip;
-
- desc->irq_data.chip->irq_ack(&desc->irq_data);
- list_for_each(ptr, chip_list) {
- unsigned long pending;
- int offset;
+ unsigned long pending;
+ int offset;
+ struct pl061_gpio *chip = irq_desc_get_handler_data(desc);
+ struct irq_chip *irqchip = irq_desc_get_chip(desc);
- chip = list_entry(ptr, struct pl061_gpio, list);
- pending = readb(chip->base + GPIOMIS);
- writeb(pending, chip->base + GPIOIC);
-
- if (pending == 0)
- continue;
+ chained_irq_enter(irqchip, desc);
+ pending = readb(chip->base + GPIOMIS);
+ writeb(pending, chip->base + GPIOIC);
+ if (pending) {
for_each_set_bit(offset, &pending, PL061_GPIO_NR)
generic_handle_irq(pl061_to_irq(&chip->gc, offset));
}
- desc->irq_data.chip->irq_unmask(&desc->irq_data);
+
+ chained_irq_exit(irqchip, desc);
+}
+
+static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
+{
+ struct irq_chip_type *ct;
+
+ chip->irq_gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base,
+ chip->base, handle_simple_irq);
+ chip->irq_gc->private = chip;
+
+ ct = chip->irq_gc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+ ct->chip.irq_set_type = pl061_irq_type;
+ ct->chip.irq_set_wake = irq_gc_set_wake;
+ ct->regs.mask = GPIOIE;
+
+ irq_setup_generic_chip(chip->irq_gc, IRQ_MSK(PL061_GPIO_NR),
+ IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
}
static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
{
struct pl061_platform_data *pdata;
struct pl061_gpio *chip;
- struct list_head *chip_list;
int ret, irq, i;
- static DECLARE_BITMAP(init_irq, NR_IRQS);
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
@@ -248,7 +232,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
chip->irq_base = pdata->irq_base;
} else if (dev->dev.of_node) {
chip->gc.base = -1;
- chip->irq_base = NO_IRQ;
+ chip->irq_base = 0;
} else {
ret = -ENODEV;
goto free_mem;
@@ -267,8 +251,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
}
spin_lock_init(&chip->lock);
- spin_lock_init(&chip->irq_lock);
- INIT_LIST_HEAD(&chip->list);
chip->gc.direction_input = pl061_direction_input;
chip->gc.direction_output = pl061_direction_output;
@@ -288,9 +270,11 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
* irq_chip support
*/
- if (chip->irq_base == NO_IRQ)
+ if (chip->irq_base <= 0)
return 0;
+ pl061_init_gc(chip, chip->irq_base);
+
writeb(0, chip->base + GPIOIE); /* disable irqs */
irq = dev->irq[0];
if (irq < 0) {
@@ -298,18 +282,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
goto iounmap;
}
irq_set_chained_handler(irq, pl061_irq_handler);
- if (!test_and_set_bit(irq, init_irq)) { /* list initialized? */
- chip_list = kmalloc(sizeof(*chip_list), GFP_KERNEL);
- if (chip_list == NULL) {
- clear_bit(irq, init_irq);
- ret = -ENOMEM;
- goto iounmap;
- }
- INIT_LIST_HEAD(chip_list);
- irq_set_handler_data(irq, chip_list);
- } else
- chip_list = irq_get_handler_data(irq);
- list_add(&chip->list, chip_list);
+ irq_set_handler_data(irq, chip);
for (i = 0; i < PL061_GPIO_NR; i++) {
if (pdata) {
@@ -319,13 +292,10 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
else
pl061_direction_input(&chip->gc, i);
}
-
- irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip,
- handle_simple_irq);
- set_irq_flags(i+chip->irq_base, IRQF_VALID);
- irq_set_chip_data(i + chip->irq_base, chip);
}
+ amba_set_drvdata(dev, chip);
+
return 0;
iounmap:
@@ -338,6 +308,53 @@ free_mem:
return ret;
}
+#ifdef CONFIG_PM
+static int pl061_suspend(struct device *dev)
+{
+ struct pl061_gpio *chip = dev_get_drvdata(dev);
+ int offset;
+
+ chip->csave_regs.gpio_data = 0;
+ chip->csave_regs.gpio_dir = readb(chip->base + GPIODIR);
+ chip->csave_regs.gpio_is = readb(chip->base + GPIOIS);
+ chip->csave_regs.gpio_ibe = readb(chip->base + GPIOIBE);
+ chip->csave_regs.gpio_iev = readb(chip->base + GPIOIEV);
+ chip->csave_regs.gpio_ie = readb(chip->base + GPIOIE);
+
+ for (offset = 0; offset < PL061_GPIO_NR; offset++) {
+ if (chip->csave_regs.gpio_dir & (1 << offset))
+ chip->csave_regs.gpio_data |=
+ pl061_get_value(&chip->gc, offset) << offset;
+ }
+
+ return 0;
+}
+
+static int pl061_resume(struct device *dev)
+{
+ struct pl061_gpio *chip = dev_get_drvdata(dev);
+ int offset;
+
+ for (offset = 0; offset < PL061_GPIO_NR; offset++) {
+ if (chip->csave_regs.gpio_dir & (1 << offset))
+ pl061_direction_output(&chip->gc, offset,
+ chip->csave_regs.gpio_data &
+ (1 << offset));
+ else
+ pl061_direction_input(&chip->gc, offset);
+ }
+
+ writeb(chip->csave_regs.gpio_is, chip->base + GPIOIS);
+ writeb(chip->csave_regs.gpio_ibe, chip->base + GPIOIBE);
+ writeb(chip->csave_regs.gpio_iev, chip->base + GPIOIEV);
+ writeb(chip->csave_regs.gpio_ie, chip->base + GPIOIE);
+
+ return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(pl061_dev_pm_ops, pl061_suspend, pl061_resume);
+#endif
+
static struct amba_id pl061_ids[] = {
{
.id = 0x00041061,
@@ -351,6 +368,9 @@ MODULE_DEVICE_TABLE(amba, pl061_ids);
static struct amba_driver pl061_gpio_driver = {
.drv = {
.name = "pl061_gpio",
+#ifdef CONFIG_PM
+ .pm = &pl061_dev_pm_ops,
+#endif
},
.id_table = pl061_ids,
.probe = pl061_probe,
diff --git a/drivers/gpio/gpio-sa1100.c b/drivers/gpio/gpio-sa1100.c
index b6c1f6d80649..7eecf69362ee 100644
--- a/drivers/gpio/gpio-sa1100.c
+++ b/drivers/gpio/gpio-sa1100.c
@@ -47,12 +47,18 @@ static int sa1100_direction_output(struct gpio_chip *chip, unsigned offset, int
return 0;
}
+static int sa1100_to_irq(struct gpio_chip *chip, unsigned offset)
+{
+ return offset < 11 ? (IRQ_GPIO0 + offset) : (IRQ_GPIO11 - 11 + offset);
+}
+
static struct gpio_chip sa1100_gpio_chip = {
.label = "gpio",
.direction_input = sa1100_direction_input,
.direction_output = sa1100_direction_output,
.set = sa1100_gpio_set,
.get = sa1100_gpio_get,
+ .to_irq = sa1100_to_irq,
.base = 0,
.ngpio = GPIO_MAX + 1,
};
diff --git a/drivers/gpio/gpio-stmpe.c b/drivers/gpio/gpio-stmpe.c
index 4c980b573328..87a68a896abf 100644
--- a/drivers/gpio/gpio-stmpe.c
+++ b/drivers/gpio/gpio-stmpe.c
@@ -65,7 +65,14 @@ static void stmpe_gpio_set(struct gpio_chip *chip, unsigned offset, int val)
u8 reg = stmpe->regs[which] - (offset / 8);
u8 mask = 1 << (offset % 8);
- stmpe_reg_write(stmpe, reg, mask);
+ /*
+ * Some variants have single register for gpio set/clear functionality.
+ * For them we need to write 0 to clear and 1 to set.
+ */
+ if (stmpe->regs[STMPE_IDX_GPSR_LSB] == stmpe->regs[STMPE_IDX_GPCR_LSB])
+ stmpe_set_bits(stmpe, reg, mask, val ? mask : 0);
+ else
+ stmpe_reg_write(stmpe, reg, mask);
}
static int stmpe_gpio_direction_output(struct gpio_chip *chip,
@@ -132,6 +139,10 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type)
if (type == IRQ_TYPE_LEVEL_LOW || type == IRQ_TYPE_LEVEL_HIGH)
return -EINVAL;
+ /* STMPE801 doesn't have RE and FE registers */
+ if (stmpe_gpio->stmpe->partnum == STMPE801)
+ return 0;
+
if (type == IRQ_TYPE_EDGE_RISING)
stmpe_gpio->regs[REG_RE][regoffset] |= mask;
else
@@ -165,6 +176,11 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d)
int i, j;
for (i = 0; i < CACHE_NR_REGS; i++) {
+ /* STMPE801 doesn't have RE and FE registers */
+ if ((stmpe->partnum == STMPE801) &&
+ (i != REG_IE))
+ continue;
+
for (j = 0; j < num_banks; j++) {
u8 old = stmpe_gpio->oldregs[i][j];
u8 new = stmpe_gpio->regs[i][j];
@@ -241,8 +257,11 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev)
}
stmpe_reg_write(stmpe, statmsbreg + i, status[i]);
- stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB] + i,
- status[i]);
+
+ /* Edge detect register is not present on 801 */
+ if (stmpe->partnum != STMPE801)
+ stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB]
+ + i, status[i]);
}
return IRQ_HANDLED;
diff --git a/drivers/gpio/gpio-tegra.c b/drivers/gpio/gpio-tegra.c
index 61044c889f7f..bdc293791590 100644
--- a/drivers/gpio/gpio-tegra.c
+++ b/drivers/gpio/gpio-tegra.c
@@ -361,14 +361,7 @@ static int __devinit tegra_gpio_probe(struct platform_device *pdev)
return -ENODEV;
}
- if (!devm_request_mem_region(&pdev->dev, res->start,
- resource_size(res),
- dev_name(&pdev->dev))) {
- dev_err(&pdev->dev, "Couldn't request MEM resource\n");
- return -ENODEV;
- }
-
- regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+ regs = devm_request_and_ioremap(&pdev->dev, res);
if (!regs) {
dev_err(&pdev->dev, "Couldn't ioremap regs\n");
return -ENODEV;
diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c
index 6d0f10b7569c..c100f3e9c920 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_crt.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c
@@ -66,6 +66,7 @@ static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode)
static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
+ struct drm_psb_private *dev_priv = connector->dev->dev_private;
int max_clock = 0;
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
@@ -82,6 +83,11 @@ static int cdv_intel_crt_mode_valid(struct drm_connector *connector,
if (mode->hdisplay > 1680 || mode->vdisplay > 1050)
return MODE_PANEL;
+ /* We assume worst case scenario of 32 bpp here, since we don't know */
+ if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
+ dev_priv->vram_stolen_size)
+ return MODE_MEM;
+
return MODE_OK;
}
diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
index 50d7cfb51662..de25560e629d 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c
@@ -241,6 +241,7 @@ static int cdv_hdmi_get_modes(struct drm_connector *connector)
static int cdv_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
+ struct drm_psb_private *dev_priv = connector->dev->dev_private;
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
@@ -255,14 +256,11 @@ static int cdv_hdmi_mode_valid(struct drm_connector *connector,
if (mode->flags & DRM_MODE_FLAG_INTERLACE)
return MODE_NO_INTERLACE;
- /*
- * FIXME: for now we limit the size to 1680x1050 on CDV, otherwise it
- * will go beyond the stolen memory size allocated to the framebuffer
- */
- if (mode->hdisplay > 1680)
- return MODE_PANEL;
- if (mode->vdisplay > 1050)
- return MODE_PANEL;
+ /* We assume worst case scenario of 32 bpp here, since we don't know */
+ if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
+ dev_priv->vram_stolen_size)
+ return MODE_MEM;
+
return MODE_OK;
}
diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
index 36878a60080d..025d30970cc0 100644
--- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c
+++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c
@@ -506,6 +506,7 @@ int oaktrail_crtc_hdmi_mode_set(struct drm_crtc *crtc,
static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
+ struct drm_psb_private *dev_priv = connector->dev->dev_private;
if (mode->clock > 165000)
return MODE_CLOCK_HIGH;
if (mode->clock < 20000)
@@ -514,6 +515,11 @@ static int oaktrail_hdmi_mode_valid(struct drm_connector *connector,
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
return MODE_NO_DBLESCAN;
+ /* We assume worst case scenario of 32 bpp here, since we don't know */
+ if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
+ dev_priv->vram_stolen_size)
+ return MODE_MEM;
+
return MODE_OK;
}
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
index 4882b29119e0..88b42971c0fd 100644
--- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c
+++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c
@@ -1141,6 +1141,7 @@ static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
+ struct drm_psb_private *dev_priv = connector->dev->dev_private;
struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector);
if (mode->flags & DRM_MODE_FLAG_DBLSCAN)
@@ -1160,6 +1161,11 @@ static int psb_intel_sdvo_mode_valid(struct drm_connector *connector,
return MODE_PANEL;
}
+ /* We assume worst case scenario of 32 bpp here, since we don't know */
+ if ((ALIGN(mode->hdisplay * 4, 64) * mode->vdisplay) >
+ dev_priv->vram_stolen_size)
+ return MODE_MEM;
+
return MODE_OK;
}
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
index 525744d593c1..7814a760c164 100644
--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
+++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
@@ -18,12 +18,6 @@
#include <linux/vga_switcheroo.h>
-#define NOUVEAU_DSM_SUPPORTED 0x00
-#define NOUVEAU_DSM_SUPPORTED_FUNCTIONS 0x00
-
-#define NOUVEAU_DSM_ACTIVE 0x01
-#define NOUVEAU_DSM_ACTIVE_QUERY 0x00
-
#define NOUVEAU_DSM_LED 0x02
#define NOUVEAU_DSM_LED_STATE 0x00
#define NOUVEAU_DSM_LED_OFF 0x10
@@ -35,6 +29,9 @@
#define NOUVEAU_DSM_POWER_SPEED 0x01
#define NOUVEAU_DSM_POWER_STAMINA 0x02
+#define NOUVEAU_DSM_OPTIMUS_FN 0x1A
+#define NOUVEAU_DSM_OPTIMUS_ARGS 0x03000001
+
static struct nouveau_dsm_priv {
bool dsm_detected;
bool optimus_detected;
@@ -61,7 +58,8 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
struct acpi_object_list input;
union acpi_object params[4];
union acpi_object *obj;
- int err;
+ int i, err;
+ char args_buff[4];
input.count = 4;
input.pointer = params;
@@ -73,7 +71,11 @@ static int nouveau_optimus_dsm(acpi_handle handle, int func, int arg, uint32_t *
params[2].type = ACPI_TYPE_INTEGER;
params[2].integer.value = func;
params[3].type = ACPI_TYPE_BUFFER;
- params[3].buffer.length = 0;
+ params[3].buffer.length = 4;
+ /* ACPI is little endian, AABBCCDD becomes {DD,CC,BB,AA} */
+ for (i = 0; i < 4; i++)
+ args_buff[i] = (arg >> i * 8) & 0xFF;
+ params[3].buffer.pointer = args_buff;
err = acpi_evaluate_object(handle, "_DSM", &input, &output);
if (err) {
@@ -148,6 +150,23 @@ static int nouveau_dsm(acpi_handle handle, int func, int arg, uint32_t *result)
return 0;
}
+/* Returns 1 if a DSM function is usable and 0 otherwise */
+static int nouveau_test_dsm(acpi_handle test_handle,
+ int (*dsm_func)(acpi_handle, int, int, uint32_t *),
+ int sfnc)
+{
+ u32 result = 0;
+
+ /* Function 0 returns a Buffer containing available functions. The args
+ * parameter is ignored for function 0, so just put 0 in it */
+ if (dsm_func(test_handle, 0, 0, &result))
+ return 0;
+
+ /* ACPI Spec v4 9.14.1: if bit 0 is zero, no function is supported. If
+ * the n-th bit is enabled, function n is supported */
+ return result & 1 && result & (1 << sfnc);
+}
+
static int nouveau_dsm_switch_mux(acpi_handle handle, int mux_id)
{
mxm_wmi_call_mxmx(mux_id == NOUVEAU_DSM_LED_STAMINA ? MXM_MXDS_ADAPTER_IGD : MXM_MXDS_ADAPTER_0);
@@ -168,6 +187,10 @@ static int nouveau_dsm_set_discrete_state(acpi_handle handle, enum vga_switchero
static int nouveau_dsm_switchto(enum vga_switcheroo_client_id id)
{
+ /* perhaps the _DSM functions are mutually exclusive, but prepare for
+ * the future */
+ if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
+ return 0;
if (id == VGA_SWITCHEROO_IGD)
return nouveau_dsm_switch_mux(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_LED_STAMINA);
else
@@ -180,6 +203,11 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id,
if (id == VGA_SWITCHEROO_IGD)
return 0;
+ /* Optimus laptops have the card already disabled in
+ * nouveau_switcheroo_set_state */
+ if (!nouveau_dsm_priv.dsm_detected && nouveau_dsm_priv.optimus_detected)
+ return 0;
+
return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state);
}
@@ -212,8 +240,7 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
{
acpi_handle dhandle, nvidia_handle;
acpi_status status;
- int ret, retval = 0;
- uint32_t result;
+ int retval = 0;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
if (!dhandle)
@@ -224,13 +251,11 @@ static int nouveau_dsm_pci_probe(struct pci_dev *pdev)
return false;
}
- ret = nouveau_dsm(dhandle, NOUVEAU_DSM_SUPPORTED,
- NOUVEAU_DSM_SUPPORTED_FUNCTIONS, &result);
- if (ret == 0)
+ if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER))
retval |= NOUVEAU_DSM_HAS_MUX;
- ret = nouveau_optimus_dsm(dhandle, 0, 0, &result);
- if (ret == 0)
+ if (nouveau_test_dsm(dhandle, nouveau_optimus_dsm,
+ NOUVEAU_DSM_OPTIMUS_FN))
retval |= NOUVEAU_DSM_HAS_OPT;
if (retval)
@@ -269,15 +294,22 @@ static bool nouveau_dsm_detect(void)
}
if (vga_count == 2 && has_dsm && guid_valid) {
- acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, &buffer);
+ acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
+ &buffer);
printk(KERN_INFO "VGA switcheroo: detected DSM switching method %s handle\n",
- acpi_method_name);
+ acpi_method_name);
nouveau_dsm_priv.dsm_detected = true;
ret = true;
}
- if (has_optimus == 1)
+ if (has_optimus == 1) {
+ acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME,
+ &buffer);
+ printk(KERN_INFO "VGA switcheroo: detected Optimus DSM method %s handle\n",
+ acpi_method_name);
nouveau_dsm_priv.optimus_detected = true;
+ ret = true;
+ }
return ret;
}
@@ -293,6 +325,17 @@ void nouveau_register_dsm_handler(void)
vga_switcheroo_register_handler(&nouveau_dsm_handler);
}
+/* Must be called for Optimus models before the card can be turned off */
+void nouveau_switcheroo_optimus_dsm(void)
+{
+ u32 result = 0;
+ if (!nouveau_dsm_priv.optimus_detected)
+ return;
+
+ nouveau_optimus_dsm(nouveau_dsm_priv.dhandle, NOUVEAU_DSM_OPTIMUS_FN,
+ NOUVEAU_DSM_OPTIMUS_ARGS, &result);
+}
+
void nouveau_unregister_dsm_handler(void)
{
vga_switcheroo_unregister_handler();
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 38134a9c7578..b82709828931 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1055,12 +1055,14 @@ extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size);
#if defined(CONFIG_ACPI)
void nouveau_register_dsm_handler(void);
void nouveau_unregister_dsm_handler(void);
+void nouveau_switcheroo_optimus_dsm(void);
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
int nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
#else
static inline void nouveau_register_dsm_handler(void) {}
static inline void nouveau_unregister_dsm_handler(void) {}
+static inline void nouveau_switcheroo_optimus_dsm(void) {}
static inline bool nouveau_acpi_rom_supported(struct pci_dev *pdev) { return false; }
static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
static inline int nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return -EINVAL; }
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c
index f5e98910d17f..f80c5e0762ff 100644
--- a/drivers/gpu/drm/nouveau/nouveau_state.c
+++ b/drivers/gpu/drm/nouveau/nouveau_state.c
@@ -525,6 +525,7 @@ static void nouveau_switcheroo_set_state(struct pci_dev *pdev,
printk(KERN_ERR "VGA switcheroo: switched nouveau off\n");
dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
drm_kms_helper_poll_disable(dev);
+ nouveau_switcheroo_optimus_dsm();
nouveau_pci_suspend(pdev, pmm);
dev->switch_power_state = DRM_SWITCH_POWER_OFF;
}
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index f7442e62c03f..8e8cd85e5c00 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -1793,10 +1793,12 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
ret = -EINVAL;
break;
case PACKET_TYPE2:
+ idx += 1;
break;
case PACKET_TYPE3:
pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]);
ret = evergreen_vm_packet3_check(rdev, ib->ptr, &pkt);
+ idx += pkt.count + 2;
break;
default:
dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type);
@@ -1805,7 +1807,6 @@ int evergreen_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
}
if (ret)
break;
- idx += pkt.count + 2;
} while (idx < ib->length_dw);
return ret;
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c
index 3ec81c3d5108..bfd36ab643a6 100644
--- a/drivers/gpu/drm/radeon/r100.c
+++ b/drivers/gpu/drm/radeon/r100.c
@@ -2186,7 +2186,6 @@ bool r100_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
void r100_bm_disable(struct radeon_device *rdev)
{
u32 tmp;
- u16 tmp16;
/* disable bus mastering */
tmp = RREG32(R_000030_BUS_CNTL);
@@ -2197,8 +2196,7 @@ void r100_bm_disable(struct radeon_device *rdev)
WREG32(R_000030_BUS_CNTL, (tmp & 0xFFFFFFFF) | 0x00000040);
tmp = RREG32(RADEON_BUS_CNTL);
mdelay(1);
- pci_read_config_word(rdev->pdev, 0x4, &tmp16);
- pci_write_config_word(rdev->pdev, 0x4, tmp16 & 0xFFFB);
+ pci_clear_master(rdev->pdev);
mdelay(1);
}
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 31da622eef63..8032f1fedb11 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -145,7 +145,7 @@ module_param_named(vramlimit, radeon_vram_limit, int, 0600);
MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)");
module_param_named(agpmode, radeon_agpmode, int, 0444);
-MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32,64, etc)\n");
+MODULE_PARM_DESC(gartsize, "Size of PCIE/IGP gart to setup in megabytes (32, 64, etc)");
module_param_named(gartsize, radeon_gart_size, int, 0600);
MODULE_PARM_DESC(benchmark, "Run benchmark");
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c
index 803e0d3c1773..ec46eb45e34c 100644
--- a/drivers/gpu/drm/radeon/rs600.c
+++ b/drivers/gpu/drm/radeon/rs600.c
@@ -322,16 +322,6 @@ void rs600_hpd_fini(struct radeon_device *rdev)
}
}
-void rs600_bm_disable(struct radeon_device *rdev)
-{
- u16 tmp;
-
- /* disable bus mastering */
- pci_read_config_word(rdev->pdev, 0x4, &tmp);
- pci_write_config_word(rdev->pdev, 0x4, tmp & 0xFFFB);
- mdelay(1);
-}
-
int rs600_asic_reset(struct radeon_device *rdev)
{
struct rv515_mc_save save;
@@ -355,7 +345,8 @@ int rs600_asic_reset(struct radeon_device *rdev)
WREG32(RADEON_CP_RB_CNTL, tmp);
pci_save_state(rdev->pdev);
/* disable bus mastering */
- rs600_bm_disable(rdev);
+ pci_clear_master(rdev->pdev);
+ mdelay(1);
/* reset GA+VAP */
WREG32(R_0000F0_RBBM_SOFT_RESET, S_0000F0_SOFT_RESET_VAP(1) |
S_0000F0_SOFT_RESET_GA(1));
diff --git a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
index 37ead6995c87..0c46d8cdc6ea 100644
--- a/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
+++ b/drivers/gpu/drm/ttm/ttm_page_alloc_dma.c
@@ -952,10 +952,9 @@ void ttm_dma_unpopulate(struct ttm_dma_tt *ttm_dma, struct device *dev)
type = ttm_to_type(ttm->page_flags, ttm->caching_state);
pool = ttm_dma_find_pool(dev, type);
- if (!pool) {
- WARN_ON(!pool);
+ if (!pool)
return;
- }
+
is_cached = (ttm_dma_find_pool(pool->dev,
ttm_to_type(ttm->page_flags, tt_cached)) == pool);
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c
index f779009104eb..b71b77ab0dc7 100644
--- a/drivers/hid/hid-prodikeys.c
+++ b/drivers/hid/hid-prodikeys.c
@@ -90,7 +90,7 @@ static const char longname[] = "Prodikeys PC-MIDI Keyboard";
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
module_param_array(id, charp, NULL, 0444);
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index 65a35cf5b3c5..3b728e8f169b 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -145,7 +145,7 @@ static const u8 abituguru_pwm_max[5] = { 0, 255, 255, 75, 75 };
/* Insmod parameters */
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Set to one to force detection.");
static int bank1_types[ABIT_UGURU_MAX_BANK1_SENSORS] = { -1, -1, -1, -1, -1,
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index d30855a75786..34a14a77e008 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -603,11 +603,11 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
/* Insmod parameters */
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Set to one to force detection.");
/* Default verbose is 1, since this driver is still in the testing phase */
-static int verbose = 1;
+static bool verbose = 1;
module_param(verbose, bool, 0644);
MODULE_PARM_DESC(verbose, "Enable/disable verbose error reporting");
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c
index 522860ab6ce8..554f046bcf20 100644
--- a/drivers/hwmon/acpi_power_meter.c
+++ b/drivers/hwmon/acpi_power_meter.c
@@ -58,7 +58,7 @@ ACPI_MODULE_NAME(ACPI_POWER_METER_NAME);
#define POWER_ALARM_NAME "power1_alarm"
static int cap_in_hardware;
-static int force_cap_on;
+static bool force_cap_on;
static int can_cap_in_hardware(void)
{
diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c
index 1ad0a885c5a5..0158cc35cb2e 100644
--- a/drivers/hwmon/adm1021.c
+++ b/drivers/hwmon/adm1021.c
@@ -103,7 +103,7 @@ static int adm1021_remove(struct i2c_client *client);
static struct adm1021_data *adm1021_update_device(struct device *dev);
/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
-static int read_only;
+static bool read_only;
static const struct i2c_device_id adm1021_id[] = {
diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
index cfcc3b6fb6bf..ed60242d6a0a 100644
--- a/drivers/hwmon/ads7828.c
+++ b/drivers/hwmon/ads7828.c
@@ -48,8 +48,8 @@ static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
I2C_CLIENT_END };
/* Module parameters */
-static int se_input = 1; /* Default is SE, 0 == diff */
-static int int_vref = 1; /* Default is internal ref ON */
+static bool se_input = 1; /* Default is SE, 0 == diff */
+static bool int_vref = 1; /* Default is internal ref ON */
static int vref_mv = ADS7828_INT_VREF_MV; /* set if vref != 2.5V */
module_param(se_input, bool, S_IRUGO);
module_param(int_vref, bool, S_IRUGO);
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index d9803958e49f..ffb229af7861 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -45,7 +45,7 @@
static struct platform_device *pdev;
/* Module load parameters */
-static int force_start;
+static bool force_start;
module_param(force_start, bool, 0);
MODULE_PARM_DESC(force_start, "Force the chip to start monitoring inputs");
@@ -53,7 +53,7 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
-static int probe_all_addr;
+static bool probe_all_addr;
module_param(probe_all_addr, bool, 0);
MODULE_PARM_DESC(probe_all_addr, "Include probing of non-standard LPC "
"addresses");
diff --git a/drivers/hwmon/emc2103.c b/drivers/hwmon/emc2103.c
index 848a2b0bc83f..865063914d76 100644
--- a/drivers/hwmon/emc2103.c
+++ b/drivers/hwmon/emc2103.c
@@ -55,7 +55,7 @@ static const u8 REG_TEMP_MAX[4] = { 0x34, 0x30, 0x31, 0x32 };
* it. Default is to leave the device in the state it's already in (-1).
* This parameter allows APD mode to be optionally forced on or off */
static int apd = -1;
-module_param(apd, bool, 0);
+module_param(apd, bint, 0);
MODULE_PARM_DESC(init, "Set to zero to disable anti-parallel diode mode");
struct temperature {
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 38c0b87676de..603ef2af2707 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -146,10 +146,10 @@ static inline void superio_exit(void)
#define IT87_SIO_BEEP_PIN_REG 0xf6 /* Beep pin mapping */
/* Update battery voltage after every reading if true */
-static int update_vbat;
+static bool update_vbat;
/* Not all BIOSes properly configure the PWM registers */
-static int fix_pwm_polarity;
+static bool fix_pwm_polarity;
/* Many IT87 constants specified below */
diff --git a/drivers/hwmon/lm93.c b/drivers/hwmon/lm93.c
index 3b43df418613..8bd6c5c9e05b 100644
--- a/drivers/hwmon/lm93.c
+++ b/drivers/hwmon/lm93.c
@@ -151,12 +151,12 @@ static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
/* Insmod parameters */
-static int disable_block;
+static bool disable_block;
module_param(disable_block, bool, 0);
MODULE_PARM_DESC(disable_block,
"Set to non-zero to disable SMBus block data transactions.");
-static int init;
+static bool init;
module_param(init, bool, 0);
MODULE_PARM_DESC(init, "Set to non-zero to force chip initialization.");
diff --git a/drivers/hwmon/max1668.c b/drivers/hwmon/max1668.c
index 6914195cfd35..88953f99e914 100644
--- a/drivers/hwmon/max1668.c
+++ b/drivers/hwmon/max1668.c
@@ -59,7 +59,7 @@ static unsigned short max1668_addr_list[] = {
#define DEV_ID_MAX1989 0xb
/* read only mode module parameter */
-static int read_only;
+static bool read_only;
module_param(read_only, bool, 0);
MODULE_PARM_DESC(read_only, "Don't set any values, read only mode");
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index bde50e34d013..374118f2b9f9 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -71,7 +71,7 @@ module_param(force_i2c, byte, 0);
MODULE_PARM_DESC(force_i2c,
"Initialize the i2c address of the sensors");
-static int init = 1;
+static bool init = 1;
module_param(init, bool, 0);
MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 65b685e2c7b7..17a8fa2d9ae9 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -67,11 +67,11 @@ module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
-static int reset;
+static bool reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Set to one to reset chip on load");
-static int init = 1;
+static bool init = 1;
module_param(init, bool, 0);
MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
diff --git a/drivers/hwmon/w83791d.c b/drivers/hwmon/w83791d.c
index 6e5d0ae594b0..35aa5149307a 100644
--- a/drivers/hwmon/w83791d.c
+++ b/drivers/hwmon/w83791d.c
@@ -58,11 +58,11 @@ module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
-static int reset;
+static bool reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Set to one to force a hardware chip reset");
-static int init;
+static bool init;
module_param(init, bool, 0);
MODULE_PARM_DESC(init, "Set to one to force extra software initialization");
diff --git a/drivers/hwmon/w83792d.c b/drivers/hwmon/w83792d.c
index 9ded133e43f0..d3100eab6b2f 100644
--- a/drivers/hwmon/w83792d.c
+++ b/drivers/hwmon/w83792d.c
@@ -56,7 +56,7 @@ module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
-static int init;
+static bool init;
module_param(init, bool, 0);
MODULE_PARM_DESC(init, "Set to one to force chip initialization");
diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c
index 3cc6fef22087..45ec7e7c3c27 100644
--- a/drivers/hwmon/w83793.c
+++ b/drivers/hwmon/w83793.c
@@ -61,7 +61,7 @@ module_param_array(force_subclients, short, NULL, 0);
MODULE_PARM_DESC(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
-static int reset;
+static bool reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index 3ee398d0e4c9..aa58b25565bc 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -42,7 +42,7 @@ static const unsigned short normal_i2c[] = {
};
-static int reset;
+static bool reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c
index 0254e181893d..063bd9508d8a 100644
--- a/drivers/hwmon/w83l786ng.c
+++ b/drivers/hwmon/w83l786ng.c
@@ -39,7 +39,7 @@ static const unsigned short normal_i2c[] = { 0x2e, 0x2f, I2C_CLIENT_END };
/* Insmod parameters */
-static int reset;
+static bool reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index a3afac4be734..cbe7a2fb779f 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -299,11 +299,11 @@ config I2C_AT91
unless your system can cope with those limitations.
config I2C_AU1550
- tristate "Au1550/Au1200 SMBus interface"
+ tristate "Au1550/Au1200/Au1300 SMBus interface"
depends on MIPS_ALCHEMY
help
If you say yes to this option, support will be included for the
- Au1550 and Au1200 SMBus interface.
+ Au1550/Au1200/Au1300 SMBus interface.
This driver can also be built as a module. If so, the module
will be called i2c-au1550.
diff --git a/drivers/i2c/busses/i2c-ali1535.c b/drivers/i2c/busses/i2c-ali1535.c
index b6807db7b36f..e66d248fc126 100644
--- a/drivers/i2c/busses/i2c-ali1535.c
+++ b/drivers/i2c/busses/i2c-ali1535.c
@@ -132,7 +132,8 @@
#define ALI1535_SMBIO_EN 0x04 /* SMB I/O Space enable */
static struct pci_driver ali1535_driver;
-static unsigned short ali1535_smba;
+static unsigned long ali1535_smba;
+static unsigned short ali1535_offset;
/* Detect whether a ALI1535 can be found, and initialize it, where necessary.
Note the differences between kernels with the old PCI BIOS interface and
@@ -140,7 +141,7 @@ static unsigned short ali1535_smba;
defined to make the transition easier. */
static int __devinit ali1535_setup(struct pci_dev *dev)
{
- int retval = -ENODEV;
+ int retval;
unsigned char temp;
/* Check the following things:
@@ -149,15 +150,28 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
- We can use the addresses
*/
+ retval = pci_enable_device(dev);
+ if (retval) {
+ dev_err(&dev->dev, "ALI1535_smb can't enable device\n");
+ goto exit;
+ }
+
/* Determine the address of the SMBus area */
- pci_read_config_word(dev, SMBBA, &ali1535_smba);
- ali1535_smba &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
- if (ali1535_smba == 0) {
+ pci_read_config_word(dev, SMBBA, &ali1535_offset);
+ dev_dbg(&dev->dev, "ALI1535_smb is at offset 0x%04x\n", ali1535_offset);
+ ali1535_offset &= (0xffff & ~(ALI1535_SMB_IOSIZE - 1));
+ if (ali1535_offset == 0) {
dev_warn(&dev->dev,
"ALI1535_smb region uninitialized - upgrade BIOS?\n");
+ retval = -ENODEV;
goto exit;
}
+ if (pci_resource_flags(dev, 0) & IORESOURCE_IO)
+ ali1535_smba = pci_resource_start(dev, 0) + ali1535_offset;
+ else
+ ali1535_smba = ali1535_offset;
+
retval = acpi_check_region(ali1535_smba, ALI1535_SMB_IOSIZE,
ali1535_driver.name);
if (retval)
@@ -165,8 +179,9 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
if (!request_region(ali1535_smba, ALI1535_SMB_IOSIZE,
ali1535_driver.name)) {
- dev_err(&dev->dev, "ALI1535_smb region 0x%x already in use!\n",
+ dev_err(&dev->dev, "ALI1535_smb region 0x%lx already in use!\n",
ali1535_smba);
+ retval = -EBUSY;
goto exit;
}
@@ -174,6 +189,7 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
pci_read_config_byte(dev, SMBCFG, &temp);
if ((temp & ALI1535_SMBIO_EN) == 0) {
dev_err(&dev->dev, "SMB device not enabled - upgrade BIOS?\n");
+ retval = -ENODEV;
goto exit_free;
}
@@ -181,6 +197,7 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
pci_read_config_byte(dev, SMBHSTCFG, &temp);
if ((temp & 1) == 0) {
dev_err(&dev->dev, "SMBus controller not enabled - upgrade BIOS?\n");
+ retval = -ENODEV;
goto exit_free;
}
@@ -196,14 +213,13 @@ static int __devinit ali1535_setup(struct pci_dev *dev)
*/
pci_read_config_byte(dev, SMBREV, &temp);
dev_dbg(&dev->dev, "SMBREV = 0x%X\n", temp);
- dev_dbg(&dev->dev, "ALI1535_smba = 0x%X\n", ali1535_smba);
+ dev_dbg(&dev->dev, "ALI1535_smba = 0x%lx\n", ali1535_smba);
- retval = 0;
-exit:
- return retval;
+ return 0;
exit_free:
release_region(ali1535_smba, ALI1535_SMB_IOSIZE);
+exit:
return retval;
}
@@ -498,7 +514,7 @@ static int __devinit ali1535_probe(struct pci_dev *dev, const struct pci_device_
ali1535_adapter.dev.parent = &dev->dev;
snprintf(ali1535_adapter.name, sizeof(ali1535_adapter.name),
- "SMBus ALI1535 adapter at %04x", ali1535_smba);
+ "SMBus ALI1535 adapter at %04x", ali1535_offset);
return i2c_add_adapter(&ali1535_adapter);
}
diff --git a/drivers/i2c/busses/i2c-ali1563.c b/drivers/i2c/busses/i2c-ali1563.c
index a409cfcf0629..47ae0091e027 100644
--- a/drivers/i2c/busses/i2c-ali1563.c
+++ b/drivers/i2c/busses/i2c-ali1563.c
@@ -417,7 +417,7 @@ static void __devexit ali1563_remove(struct pci_dev * dev)
ali1563_shutdown(dev);
}
-static const struct pci_device_id ali1563_id_table[] __devinitconst = {
+static DEFINE_PCI_DEVICE_TABLE(ali1563_id_table) = {
{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1563) },
{},
};
diff --git a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
index 83e8a60cdc86..087ea9caa74d 100644
--- a/drivers/i2c/busses/i2c-ali15x3.c
+++ b/drivers/i2c/busses/i2c-ali15x3.c
@@ -477,7 +477,7 @@ static struct i2c_adapter ali15x3_adapter = {
.algo = &smbus_algorithm,
};
-static const struct pci_device_id ali15x3_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(ali15x3_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101) },
{ 0, }
};
diff --git a/drivers/i2c/busses/i2c-amd756.c b/drivers/i2c/busses/i2c-amd756.c
index 03bcd07c4697..eb778bf15c18 100644
--- a/drivers/i2c/busses/i2c-amd756.c
+++ b/drivers/i2c/busses/i2c-amd756.c
@@ -308,7 +308,7 @@ static const char* chipname[] = {
"nVidia nForce", "AMD8111",
};
-static const struct pci_device_id amd756_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(amd756_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_740B),
.driver_data = AMD756 },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_VIPER_7413),
diff --git a/drivers/i2c/busses/i2c-amd8111.c b/drivers/i2c/busses/i2c-amd8111.c
index 6b6a6b1d7025..e5ac53b99b04 100644
--- a/drivers/i2c/busses/i2c-amd8111.c
+++ b/drivers/i2c/busses/i2c-amd8111.c
@@ -415,7 +415,7 @@ static const struct i2c_algorithm smbus_algorithm = {
};
-static const struct pci_device_id amd8111_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(amd8111_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_SMBUS2) },
{ 0, }
};
diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c
index 305c07504f7e..1679deef9c89 100644
--- a/drivers/i2c/busses/i2c-at91.c
+++ b/drivers/i2c/busses/i2c-at91.c
@@ -295,9 +295,6 @@ static int at91_i2c_resume(struct platform_device *pdev)
#define at91_i2c_resume NULL
#endif
-/* work with "modprobe at91_i2c" from hotplugging or coldplugging */
-MODULE_ALIAS("platform:at91_i2c");
-
static struct platform_driver at91_i2c_driver = {
.probe = at91_i2c_probe,
.remove = __devexit_p(at91_i2c_remove),
@@ -309,19 +306,9 @@ static struct platform_driver at91_i2c_driver = {
},
};
-static int __init at91_i2c_init(void)
-{
- return platform_driver_register(&at91_i2c_driver);
-}
-
-static void __exit at91_i2c_exit(void)
-{
- platform_driver_unregister(&at91_i2c_driver);
-}
-
-module_init(at91_i2c_init);
-module_exit(at91_i2c_exit);
+module_platform_driver(at91_i2c_driver);
MODULE_AUTHOR("Rick Bronson");
MODULE_DESCRIPTION("I2C (TWI) driver for Atmel AT91");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_i2c");
diff --git a/drivers/i2c/busses/i2c-au1550.c b/drivers/i2c/busses/i2c-au1550.c
index f314d7f433d3..582d616db346 100644
--- a/drivers/i2c/busses/i2c-au1550.c
+++ b/drivers/i2c/busses/i2c-au1550.c
@@ -426,20 +426,9 @@ static struct platform_driver au1xpsc_smbus_driver = {
.remove = __devexit_p(i2c_au1550_remove),
};
-static int __init i2c_au1550_init(void)
-{
- return platform_driver_register(&au1xpsc_smbus_driver);
-}
-
-static void __exit i2c_au1550_exit(void)
-{
- platform_driver_unregister(&au1xpsc_smbus_driver);
-}
+module_platform_driver(au1xpsc_smbus_driver);
MODULE_AUTHOR("Dan Malek, Embedded Edge, LLC.");
MODULE_DESCRIPTION("SMBus adapter Alchemy pb1550");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:au1xpsc_smbus");
-
-module_init (i2c_au1550_init);
-module_exit (i2c_au1550_exit);
diff --git a/drivers/i2c/busses/i2c-cpm.c b/drivers/i2c/busses/i2c-cpm.c
index b1d9cd28d8da..c1e1096ba069 100644
--- a/drivers/i2c/busses/i2c-cpm.c
+++ b/drivers/i2c/busses/i2c-cpm.c
@@ -724,18 +724,7 @@ static struct platform_driver cpm_i2c_driver = {
},
};
-static int __init cpm_i2c_init(void)
-{
- return platform_driver_register(&cpm_i2c_driver);
-}
-
-static void __exit cpm_i2c_exit(void)
-{
- platform_driver_unregister(&cpm_i2c_driver);
-}
-
-module_init(cpm_i2c_init);
-module_exit(cpm_i2c_exit);
+module_platform_driver(cpm_i2c_driver);
MODULE_AUTHOR("Jochen Friedrich <jochen@scram.de>");
MODULE_DESCRIPTION("I2C-Bus adapter routines for CPM boards");
diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c
index 9e89e7313d62..37f42113af31 100644
--- a/drivers/i2c/busses/i2c-designware-pcidrv.c
+++ b/drivers/i2c/busses/i2c-designware-pcidrv.c
@@ -349,7 +349,7 @@ static void __devexit i2c_dw_pci_remove(struct pci_dev *pdev)
/* work with hotplug and coldplug */
MODULE_ALIAS("i2c_designware-pci");
-DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = {
+static DEFINE_PCI_DEVICE_TABLE(i2_designware_pci_ids) = {
/* Moorestown */
{ PCI_VDEVICE(INTEL, 0x0802), moorestown_0 },
{ PCI_VDEVICE(INTEL, 0x0803), moorestown_1 },
diff --git a/drivers/i2c/busses/i2c-eg20t.c b/drivers/i2c/busses/i2c-eg20t.c
index 18936ac9d51c..3ef3557b6e32 100644
--- a/drivers/i2c/busses/i2c-eg20t.c
+++ b/drivers/i2c/busses/i2c-eg20t.c
@@ -185,7 +185,7 @@ static DEFINE_MUTEX(pch_mutex);
#define PCI_DEVICE_ID_ML7213_I2C 0x802D
#define PCI_DEVICE_ID_ML7223_I2C 0x8010
-static struct pci_device_id __devinitdata pch_pcidev_id[] = {
+static DEFINE_PCI_DEVICE_TABLE(pch_pcidev_id) = {
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PCH_I2C), 1, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7213_I2C), 2, },
{ PCI_VDEVICE(ROHM, PCI_DEVICE_ID_ML7223_I2C), 1, },
diff --git a/drivers/i2c/busses/i2c-highlander.c b/drivers/i2c/busses/i2c-highlander.c
index 63bb1cc2a042..19515df61021 100644
--- a/drivers/i2c/busses/i2c-highlander.c
+++ b/drivers/i2c/busses/i2c-highlander.c
@@ -52,7 +52,7 @@ struct highlander_i2c_dev {
size_t buf_len;
};
-static int iic_force_poll, iic_force_normal;
+static bool iic_force_poll, iic_force_normal;
static int iic_timeout = 1000, iic_read_delay;
static inline void highlander_i2c_irq_enable(struct highlander_i2c_dev *dev)
@@ -468,18 +468,7 @@ static struct platform_driver highlander_i2c_driver = {
.remove = __devexit_p(highlander_i2c_remove),
};
-static int __init highlander_i2c_init(void)
-{
- return platform_driver_register(&highlander_i2c_driver);
-}
-
-static void __exit highlander_i2c_exit(void)
-{
- platform_driver_unregister(&highlander_i2c_driver);
-}
-
-module_init(highlander_i2c_init);
-module_exit(highlander_i2c_exit);
+module_platform_driver(highlander_i2c_driver);
MODULE_AUTHOR("Paul Mundt");
MODULE_DESCRIPTION("Renesas Highlander FPGA I2C/SMBus adapter");
diff --git a/drivers/i2c/busses/i2c-hydra.c b/drivers/i2c/busses/i2c-hydra.c
index 9ff1695d8458..c527de17db4f 100644
--- a/drivers/i2c/busses/i2c-hydra.c
+++ b/drivers/i2c/busses/i2c-hydra.c
@@ -105,7 +105,7 @@ static struct i2c_adapter hydra_adap = {
.algo_data = &hydra_bit_data,
};
-static const struct pci_device_id hydra_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(hydra_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_HYDRA) },
{ 0, }
};
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index ab26840d0c70..5d2e2816831f 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -609,7 +609,7 @@ static const struct i2c_algorithm smbus_algorithm = {
.functionality = i801_func,
};
-static const struct pci_device_id i801_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(i801_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_2) },
diff --git a/drivers/i2c/busses/i2c-ibm_iic.c b/drivers/i2c/busses/i2c-ibm_iic.c
index 3c110fbc409b..806e225f3de7 100644
--- a/drivers/i2c/busses/i2c-ibm_iic.c
+++ b/drivers/i2c/busses/i2c-ibm_iic.c
@@ -51,11 +51,11 @@
MODULE_DESCRIPTION("IBM IIC driver v" DRIVER_VERSION);
MODULE_LICENSE("GPL");
-static int iic_force_poll;
+static bool iic_force_poll;
module_param(iic_force_poll, bool, 0);
MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
-static int iic_force_fast;
+static bool iic_force_fast;
module_param(iic_force_fast, bool, 0);
MODULE_PARM_DESC(iic_force_fast, "Force fast mode (400 kHz)");
@@ -815,15 +815,4 @@ static struct platform_driver ibm_iic_driver = {
.remove = __devexit_p(iic_remove),
};
-static int __init iic_init(void)
-{
- return platform_driver_register(&ibm_iic_driver);
-}
-
-static void __exit iic_exit(void)
-{
- platform_driver_unregister(&ibm_iic_driver);
-}
-
-module_init(iic_init);
-module_exit(iic_exit);
+module_platform_driver(ibm_iic_driver);
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c
index e828ac85cfa7..365bad5b890b 100644
--- a/drivers/i2c/busses/i2c-intel-mid.c
+++ b/drivers/i2c/busses/i2c-intel-mid.c
@@ -1093,7 +1093,7 @@ static void __devexit intel_mid_i2c_remove(struct pci_dev *dev)
pci_release_region(dev, 0);
}
-static struct pci_device_id intel_mid_i2c_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(intel_mid_i2c_ids) = {
/* Moorestown */
{ PCI_VDEVICE(INTEL, 0x0802), 0 },
{ PCI_VDEVICE(INTEL, 0x0803), 1 },
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index f09c9319a2ba..93f147a96b62 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -523,21 +523,7 @@ static struct platform_driver iop3xx_i2c_driver = {
},
};
-static int __init
-i2c_iop3xx_init (void)
-{
- return platform_driver_register(&iop3xx_i2c_driver);
-}
-
-static void __exit
-i2c_iop3xx_exit (void)
-{
- platform_driver_unregister(&iop3xx_i2c_driver);
- return;
-}
-
-module_init (i2c_iop3xx_init);
-module_exit (i2c_iop3xx_exit);
+module_platform_driver(iop3xx_i2c_driver);
MODULE_AUTHOR("D-TACQ Solutions Ltd <www.d-tacq.com>");
MODULE_DESCRIPTION("IOP3xx iic algorithm and driver");
diff --git a/drivers/i2c/busses/i2c-isch.c b/drivers/i2c/busses/i2c-isch.c
index 0682f8f277b0..6561d275b8cf 100644
--- a/drivers/i2c/busses/i2c-isch.c
+++ b/drivers/i2c/busses/i2c-isch.c
@@ -306,20 +306,9 @@ static struct platform_driver smbus_sch_driver = {
.remove = __devexit_p(smbus_sch_remove),
};
-static int __init i2c_sch_init(void)
-{
- return platform_driver_register(&smbus_sch_driver);
-}
-
-static void __exit i2c_sch_exit(void)
-{
- platform_driver_unregister(&smbus_sch_driver);
-}
+module_platform_driver(smbus_sch_driver);
MODULE_AUTHOR("Jacob Pan <jacob.jun.pan@intel.com>");
MODULE_DESCRIPTION("Intel SCH SMBus driver");
MODULE_LICENSE("GPL");
-
-module_init(i2c_sch_init);
-module_exit(i2c_sch_exit);
MODULE_ALIAS("platform:isch_smbus");
diff --git a/drivers/i2c/busses/i2c-ixp2000.c b/drivers/i2c/busses/i2c-ixp2000.c
index c01e9519f6c1..5d263f9014d6 100644
--- a/drivers/i2c/busses/i2c-ixp2000.c
+++ b/drivers/i2c/busses/i2c-ixp2000.c
@@ -148,18 +148,7 @@ static struct platform_driver ixp2000_i2c_driver = {
},
};
-static int __init ixp2000_i2c_init(void)
-{
- return platform_driver_register(&ixp2000_i2c_driver);
-}
-
-static void __exit ixp2000_i2c_exit(void)
-{
- platform_driver_unregister(&ixp2000_i2c_driver);
-}
-
-module_init(ixp2000_i2c_init);
-module_exit(ixp2000_i2c_exit);
+module_platform_driver(ixp2000_i2c_driver);
MODULE_AUTHOR ("Deepak Saxena <dsaxena@plexity.net>");
MODULE_DESCRIPTION("IXP2000 GPIO-based I2C bus driver");
diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c
index 107397a606b4..a8ebb84e23f9 100644
--- a/drivers/i2c/busses/i2c-mpc.c
+++ b/drivers/i2c/busses/i2c-mpc.c
@@ -715,18 +715,7 @@ static struct platform_driver mpc_i2c_driver = {
},
};
-static int __init fsl_i2c_init(void)
-{
- return platform_driver_register(&mpc_i2c_driver);
-}
-
-static void __exit fsl_i2c_exit(void)
-{
- platform_driver_unregister(&mpc_i2c_driver);
-}
-
-module_init(fsl_i2c_init);
-module_exit(fsl_i2c_exit);
+module_platform_driver(mpc_i2c_driver);
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
index a9941c65f226..4f44a33017b0 100644
--- a/drivers/i2c/busses/i2c-mv64xxx.c
+++ b/drivers/i2c/busses/i2c-mv64xxx.c
@@ -611,20 +611,7 @@ static struct platform_driver mv64xxx_i2c_driver = {
},
};
-static int __init
-mv64xxx_i2c_init(void)
-{
- return platform_driver_register(&mv64xxx_i2c_driver);
-}
-
-static void __exit
-mv64xxx_i2c_exit(void)
-{
- platform_driver_unregister(&mv64xxx_i2c_driver);
-}
-
-module_init(mv64xxx_i2c_init);
-module_exit(mv64xxx_i2c_exit);
+module_platform_driver(mv64xxx_i2c_driver);
MODULE_AUTHOR("Mark A. Greer <mgreer@mvista.com>");
MODULE_DESCRIPTION("Marvell mv64xxx host bridge i2c ctlr driver");
diff --git a/drivers/i2c/busses/i2c-nforce2.c b/drivers/i2c/busses/i2c-nforce2.c
index ff1e127dfea8..43a96a123920 100644
--- a/drivers/i2c/busses/i2c-nforce2.c
+++ b/drivers/i2c/busses/i2c-nforce2.c
@@ -309,7 +309,7 @@ static struct i2c_algorithm smbus_algorithm = {
};
-static const struct pci_device_id nforce2_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(nforce2_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS) },
{ PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS) },
@@ -356,7 +356,7 @@ static int __devinit nforce2_probe_smb (struct pci_dev *dev, int bar,
error = acpi_check_region(smbus->base, smbus->size,
nforce2_driver.name);
if (error)
- return -1;
+ return error;
if (!request_region(smbus->base, smbus->size, nforce2_driver.name)) {
dev_err(&smbus->adapter.dev, "Error requesting region %02x .. %02X for %s\n",
diff --git a/drivers/i2c/busses/i2c-ocores.c b/drivers/i2c/busses/i2c-ocores.c
index 1b46a9d9f907..18068dee48f1 100644
--- a/drivers/i2c/busses/i2c-ocores.c
+++ b/drivers/i2c/busses/i2c-ocores.c
@@ -394,9 +394,6 @@ static struct of_device_id ocores_i2c_match[] = {
};
MODULE_DEVICE_TABLE(of, ocores_i2c_match);
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:ocores-i2c");
-
static struct platform_driver ocores_i2c_driver = {
.probe = ocores_i2c_probe,
.remove = __devexit_p(ocores_i2c_remove),
@@ -409,19 +406,9 @@ static struct platform_driver ocores_i2c_driver = {
},
};
-static int __init ocores_i2c_init(void)
-{
- return platform_driver_register(&ocores_i2c_driver);
-}
-
-static void __exit ocores_i2c_exit(void)
-{
- platform_driver_unregister(&ocores_i2c_driver);
-}
-
-module_init(ocores_i2c_init);
-module_exit(ocores_i2c_exit);
+module_platform_driver(ocores_i2c_driver);
MODULE_AUTHOR("Peter Korsgaard <jacmet@sunsite.dk>");
MODULE_DESCRIPTION("OpenCores I2C bus driver");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ocores-i2c");
diff --git a/drivers/i2c/busses/i2c-octeon.c b/drivers/i2c/busses/i2c-octeon.c
index 56dbe54e8811..ee139a598814 100644
--- a/drivers/i2c/busses/i2c-octeon.c
+++ b/drivers/i2c/busses/i2c-octeon.c
@@ -629,24 +629,10 @@ static struct platform_driver octeon_i2c_driver = {
},
};
-static int __init octeon_i2c_init(void)
-{
- int rv;
-
- rv = platform_driver_register(&octeon_i2c_driver);
- return rv;
-}
-
-static void __exit octeon_i2c_exit(void)
-{
- platform_driver_unregister(&octeon_i2c_driver);
-}
+module_platform_driver(octeon_i2c_driver);
MODULE_AUTHOR("Michael Lawnick <michael.lawnick.ext@nsn.com>");
MODULE_DESCRIPTION("I2C-Bus adapter for Cavium OCTEON processors");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_ALIAS("platform:" DRV_NAME);
-
-module_init(octeon_i2c_init);
-module_exit(octeon_i2c_exit);
diff --git a/drivers/i2c/busses/i2c-pasemi.c b/drivers/i2c/busses/i2c-pasemi.c
index 837b8c1aa02a..eaaea73209c5 100644
--- a/drivers/i2c/busses/i2c-pasemi.c
+++ b/drivers/i2c/busses/i2c-pasemi.c
@@ -401,7 +401,7 @@ static void __devexit pasemi_smb_remove(struct pci_dev *dev)
kfree(smbus);
}
-static const struct pci_device_id pasemi_smb_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(pasemi_smb_ids) = {
{ PCI_DEVICE(0x1959, 0xa003) },
{ 0, }
};
diff --git a/drivers/i2c/busses/i2c-pca-platform.c b/drivers/i2c/busses/i2c-pca-platform.c
index ace67995d7de..2adbf1a8fdea 100644
--- a/drivers/i2c/busses/i2c-pca-platform.c
+++ b/drivers/i2c/busses/i2c-pca-platform.c
@@ -286,20 +286,8 @@ static struct platform_driver i2c_pca_pf_driver = {
},
};
-static int __init i2c_pca_pf_init(void)
-{
- return platform_driver_register(&i2c_pca_pf_driver);
-}
-
-static void __exit i2c_pca_pf_exit(void)
-{
- platform_driver_unregister(&i2c_pca_pf_driver);
-}
+module_platform_driver(i2c_pca_pf_driver);
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
MODULE_DESCRIPTION("I2C-PCA9564/PCA9665 platform driver");
MODULE_LICENSE("GPL");
-
-module_init(i2c_pca_pf_init);
-module_exit(i2c_pca_pf_exit);
-
diff --git a/drivers/i2c/busses/i2c-piix4.c b/drivers/i2c/busses/i2c-piix4.c
index 6d14ac2e3c41..c14d48dd601a 100644
--- a/drivers/i2c/busses/i2c-piix4.c
+++ b/drivers/i2c/busses/i2c-piix4.c
@@ -472,7 +472,7 @@ static struct i2c_adapter piix4_adapter = {
.algo = &smbus_algorithm,
};
-static const struct pci_device_id piix4_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(piix4_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3) },
{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3) },
diff --git a/drivers/i2c/busses/i2c-pmcmsp.c b/drivers/i2c/busses/i2c-pmcmsp.c
index 127051b06921..07b7447ecbc9 100644
--- a/drivers/i2c/busses/i2c-pmcmsp.c
+++ b/drivers/i2c/busses/i2c-pmcmsp.c
@@ -627,9 +627,6 @@ static struct i2c_adapter pmcmsptwi_adapter = {
.name = DRV_NAME,
};
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:" DRV_NAME);
-
static struct platform_driver pmcmsptwi_driver = {
.probe = pmcmsptwi_probe,
.remove = __devexit_p(pmcmsptwi_remove),
@@ -639,18 +636,8 @@ static struct platform_driver pmcmsptwi_driver = {
},
};
-static int __init pmcmsptwi_init(void)
-{
- return platform_driver_register(&pmcmsptwi_driver);
-}
-
-static void __exit pmcmsptwi_exit(void)
-{
- platform_driver_unregister(&pmcmsptwi_driver);
-}
+module_platform_driver(pmcmsptwi_driver);
MODULE_DESCRIPTION("PMC MSP TWI/SMBus/I2C driver");
MODULE_LICENSE("GPL");
-
-module_init(pmcmsptwi_init);
-module_exit(pmcmsptwi_exit);
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/i2c/busses/i2c-powermac.c b/drivers/i2c/busses/i2c-powermac.c
index b289ec99eeba..7b397c6f607e 100644
--- a/drivers/i2c/busses/i2c-powermac.c
+++ b/drivers/i2c/busses/i2c-powermac.c
@@ -312,10 +312,6 @@ static int __devinit i2c_powermac_probe(struct platform_device *dev)
return rc;
}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:i2c-powermac");
-
static struct platform_driver i2c_powermac_driver = {
.probe = i2c_powermac_probe,
.remove = __devexit_p(i2c_powermac_remove),
@@ -325,17 +321,6 @@ static struct platform_driver i2c_powermac_driver = {
},
};
-static int __init i2c_powermac_init(void)
-{
- platform_driver_register(&i2c_powermac_driver);
- return 0;
-}
+module_platform_driver(i2c_powermac_driver);
-
-static void __exit i2c_powermac_cleanup(void)
-{
- platform_driver_unregister(&i2c_powermac_driver);
-}
-
-module_init(i2c_powermac_init);
-module_exit(i2c_powermac_cleanup);
+MODULE_ALIAS("platform:i2c-powermac");
diff --git a/drivers/i2c/busses/i2c-pxa-pci.c b/drivers/i2c/busses/i2c-pxa-pci.c
index 632e088760a3..a05817980556 100644
--- a/drivers/i2c/busses/i2c-pxa-pci.c
+++ b/drivers/i2c/busses/i2c-pxa-pci.c
@@ -150,7 +150,7 @@ static void __devexit ce4100_i2c_remove(struct pci_dev *dev)
kfree(sds);
}
-static struct pci_device_id ce4100_i2c_devices[] __devinitdata = {
+static DEFINE_PCI_DEVICE_TABLE(ce4100_i2c_devices) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x2e68)},
{ },
};
diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c
index a67132b2e092..c0c9dffbdb12 100644
--- a/drivers/i2c/busses/i2c-sh7760.c
+++ b/drivers/i2c/busses/i2c-sh7760.c
@@ -560,18 +560,7 @@ static struct platform_driver sh7760_i2c_drv = {
.remove = __devexit_p(sh7760_i2c_remove),
};
-static int __init sh7760_i2c_init(void)
-{
- return platform_driver_register(&sh7760_i2c_drv);
-}
-
-static void __exit sh7760_i2c_exit(void)
-{
- platform_driver_unregister(&sh7760_i2c_drv);
-}
-
-module_init(sh7760_i2c_init);
-module_exit(sh7760_i2c_exit);
+module_platform_driver(sh7760_i2c_drv);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("SH7760 I2C bus driver");
diff --git a/drivers/i2c/busses/i2c-simtec.c b/drivers/i2c/busses/i2c-simtec.c
index 2fc08fbf67a2..4fc87e7c94c9 100644
--- a/drivers/i2c/busses/i2c-simtec.c
+++ b/drivers/i2c/busses/i2c-simtec.c
@@ -156,12 +156,8 @@ static int simtec_i2c_remove(struct platform_device *dev)
return 0;
}
-
/* device driver */
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:simtec-i2c");
-
static struct platform_driver simtec_i2c_driver = {
.driver = {
.name = "simtec-i2c",
@@ -171,19 +167,9 @@ static struct platform_driver simtec_i2c_driver = {
.remove = simtec_i2c_remove,
};
-static int __init i2c_adap_simtec_init(void)
-{
- return platform_driver_register(&simtec_i2c_driver);
-}
-
-static void __exit i2c_adap_simtec_exit(void)
-{
- platform_driver_unregister(&simtec_i2c_driver);
-}
-
-module_init(i2c_adap_simtec_init);
-module_exit(i2c_adap_simtec_exit);
+module_platform_driver(simtec_i2c_driver);
MODULE_DESCRIPTION("Simtec Generic I2C Bus driver");
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:simtec-i2c");
diff --git a/drivers/i2c/busses/i2c-sis5595.c b/drivers/i2c/busses/i2c-sis5595.c
index 437586611d4a..87e5126d449c 100644
--- a/drivers/i2c/busses/i2c-sis5595.c
+++ b/drivers/i2c/busses/i2c-sis5595.c
@@ -147,7 +147,7 @@ static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev)
u16 a;
u8 val;
int *i;
- int retval = -ENODEV;
+ int retval;
/* Look for imposters */
for (i = blacklist; *i != 0; i++) {
@@ -223,7 +223,7 @@ static int __devinit sis5595_setup(struct pci_dev *SIS5595_dev)
error:
release_region(sis5595_base + SMB_INDEX, 2);
- return retval;
+ return -ENODEV;
}
static int sis5595_transaction(struct i2c_adapter *adap)
@@ -369,7 +369,7 @@ static struct i2c_adapter sis5595_adapter = {
.algo = &smbus_algorithm,
};
-static const struct pci_device_id sis5595_ids[] __devinitconst = {
+static DEFINE_PCI_DEVICE_TABLE(sis5595_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
{ 0, }
};
diff --git a/drivers/i2c/busses/i2c-sis630.c b/drivers/i2c/busses/i2c-sis630.c
index e6f539e26f65..15cf78f65ce0 100644
--- a/drivers/i2c/busses/i2c-sis630.c
+++ b/drivers/i2c/busses/i2c-sis630.c
@@ -93,8 +93,8 @@
static struct pci_driver sis630_driver;
/* insmod parameters */
-static int high_clock;
-static int force;
+static bool high_clock;
+static bool force;
module_param(high_clock, bool, 0);
MODULE_PARM_DESC(high_clock, "Set Host Master Clock to 56KHz (default 14KHz).");
module_param(force, bool, 0);
@@ -393,7 +393,7 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev)
{
unsigned char b;
struct pci_dev *dummy = NULL;
- int retval = -ENODEV, i;
+ int retval, i;
/* check for supported SiS devices */
for (i=0; supported[i] > 0 ; i++) {
@@ -418,18 +418,21 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev)
*/
if (pci_read_config_byte(sis630_dev, SIS630_BIOS_CTL_REG,&b)) {
dev_err(&sis630_dev->dev, "Error: Can't read bios ctl reg\n");
+ retval = -ENODEV;
goto exit;
}
/* if ACPI already enabled , do nothing */
if (!(b & 0x80) &&
pci_write_config_byte(sis630_dev, SIS630_BIOS_CTL_REG, b | 0x80)) {
dev_err(&sis630_dev->dev, "Error: Can't enable ACPI\n");
+ retval = -ENODEV;
goto exit;
}
/* Determine the ACPI base address */
if (pci_read_config_word(sis630_dev,SIS630_ACPI_BASE_REG,&acpi_base)) {
dev_err(&sis630_dev->dev, "Error: Can't determine ACPI base address\n");
+ retval = -ENODEV;
goto exit;
}
@@ -445,6 +448,7 @@ static int __devinit sis630_setup(struct pci_dev *sis630_dev)
sis630_driver.name)) {
dev_err(&sis630_dev->dev, "SMBus registers 0x%04x-0x%04x already "
"in use!\n", acpi_base + SMB_STS, acpi_base + SMB_SAA);
+ retval = -EBUSY;
goto exit;
}
@@ -468,7 +472,7 @@ static struct i2c_adapter sis630_adapter = {
.algo = &smbus_algorithm,
};
-static const struct pci_device_id sis630_ids[] __devinitconst = {
+static DEFINE_PCI_DEVICE_TABLE(sis630_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503) },
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC) },
{ 0, }
diff --git a/drivers/i2c/busses/i2c-sis96x.c b/drivers/i2c/busses/i2c-sis96x.c
index 86837f0c4cb9..cc5d149413f7 100644
--- a/drivers/i2c/busses/i2c-sis96x.c
+++ b/drivers/i2c/busses/i2c-sis96x.c
@@ -245,7 +245,7 @@ static struct i2c_adapter sis96x_adapter = {
.algo = &smbus_algorithm,
};
-static const struct pci_device_id sis96x_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(sis96x_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_SMBUS) },
{ 0, }
};
diff --git a/drivers/i2c/busses/i2c-via.c b/drivers/i2c/busses/i2c-via.c
index 7799fe5bda88..713d31ade26b 100644
--- a/drivers/i2c/busses/i2c-via.c
+++ b/drivers/i2c/busses/i2c-via.c
@@ -89,7 +89,7 @@ static struct i2c_adapter vt586b_adapter = {
};
-static const struct pci_device_id vt586b_ids[] __devinitconst = {
+static DEFINE_PCI_DEVICE_TABLE(vt586b_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3) },
{ 0, }
};
diff --git a/drivers/i2c/busses/i2c-viapro.c b/drivers/i2c/busses/i2c-viapro.c
index 0b012f1f8ac5..333011c83d52 100644
--- a/drivers/i2c/busses/i2c-viapro.c
+++ b/drivers/i2c/busses/i2c-viapro.c
@@ -91,7 +91,7 @@ static unsigned short SMBHSTCFG = 0xD2;
/* If force is set to anything different from 0, we forcibly enable the
VT596. DANGEROUS! */
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Forcibly enable the SMBus. DANGEROUS!");
@@ -324,7 +324,7 @@ static int __devinit vt596_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
unsigned char temp;
- int error = -ENODEV;
+ int error;
/* Determine the address of the SMBus areas */
if (force_addr) {
@@ -390,6 +390,7 @@ found:
dev_err(&pdev->dev, "SMBUS: Error: Host SMBus "
"controller not enabled! - upgrade BIOS or "
"use force=1\n");
+ error = -ENODEV;
goto release_region;
}
}
@@ -422,9 +423,11 @@ found:
"SMBus Via Pro adapter at %04x", vt596_smba);
vt596_pdev = pci_dev_get(pdev);
- if (i2c_add_adapter(&vt596_adapter)) {
+ error = i2c_add_adapter(&vt596_adapter);
+ if (error) {
pci_dev_put(vt596_pdev);
vt596_pdev = NULL;
+ goto release_region;
}
/* Always return failure here. This is to allow other drivers to bind
@@ -438,7 +441,7 @@ release_region:
return error;
}
-static const struct pci_device_id vt596_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(vt596_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596_3),
.driver_data = SMBBA1 },
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C596B_3),
diff --git a/drivers/i2c/busses/i2c-xiic.c b/drivers/i2c/busses/i2c-xiic.c
index ac083a28ae08..2bded7647ef2 100644
--- a/drivers/i2c/busses/i2c-xiic.c
+++ b/drivers/i2c/busses/i2c-xiic.c
@@ -795,10 +795,6 @@ static int __devexit xiic_i2c_remove(struct platform_device* pdev)
return 0;
}
-
-/* work with hotplug and coldplug */
-MODULE_ALIAS("platform:"DRIVER_NAME);
-
static struct platform_driver xiic_i2c_driver = {
.probe = xiic_i2c_probe,
.remove = __devexit_p(xiic_i2c_remove),
@@ -808,19 +804,9 @@ static struct platform_driver xiic_i2c_driver = {
},
};
-static int __init xiic_i2c_init(void)
-{
- return platform_driver_register(&xiic_i2c_driver);
-}
-
-static void __exit xiic_i2c_exit(void)
-{
- platform_driver_unregister(&xiic_i2c_driver);
-}
-
-module_init(xiic_i2c_init);
-module_exit(xiic_i2c_exit);
+module_platform_driver(xiic_i2c_driver);
MODULE_AUTHOR("info@mocean-labs.com");
MODULE_DESCRIPTION("Xilinx I2C bus driver");
MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:"DRIVER_NAME);
diff --git a/drivers/i2c/busses/scx200_acb.c b/drivers/i2c/busses/scx200_acb.c
index 91e349c884c5..2eacb7784d56 100644
--- a/drivers/i2c/busses/scx200_acb.c
+++ b/drivers/i2c/busses/scx200_acb.c
@@ -559,7 +559,7 @@ static struct platform_driver scx200_pci_driver = {
.remove = __devexit_p(scx200_remove),
};
-static const struct pci_device_id scx200_isa[] __initconst = {
+static DEFINE_PCI_DEVICE_TABLE(scx200_isa) = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_BRIDGE) },
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SC1100_BRIDGE) },
{ 0, }
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 57a45ce84b2d..10e7f1e76586 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -251,15 +251,10 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
return -EINVAL;
- rdwr_pa = kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL);
- if (!rdwr_pa)
- return -ENOMEM;
-
- if (copy_from_user(rdwr_pa, rdwr_arg.msgs,
- rdwr_arg.nmsgs * sizeof(struct i2c_msg))) {
- kfree(rdwr_pa);
- return -EFAULT;
- }
+ rdwr_pa = memdup_user(rdwr_arg.msgs,
+ rdwr_arg.nmsgs * sizeof(struct i2c_msg));
+ if (IS_ERR(rdwr_pa))
+ return PTR_ERR(rdwr_pa);
data_ptrs = kmalloc(rdwr_arg.nmsgs * sizeof(u8 __user *), GFP_KERNEL);
if (data_ptrs == NULL) {
diff --git a/drivers/i2c/muxes/gpio-i2cmux.c b/drivers/i2c/muxes/gpio-i2cmux.c
index 7b6ce624cd6e..e5fa695eb0fa 100644
--- a/drivers/i2c/muxes/gpio-i2cmux.c
+++ b/drivers/i2c/muxes/gpio-i2cmux.c
@@ -165,18 +165,7 @@ static struct platform_driver gpiomux_driver = {
},
};
-static int __init gpiomux_init(void)
-{
- return platform_driver_register(&gpiomux_driver);
-}
-
-static void __exit gpiomux_exit(void)
-{
- platform_driver_unregister(&gpiomux_driver);
-}
-
-module_init(gpiomux_init);
-module_exit(gpiomux_exit);
+module_platform_driver(gpiomux_driver);
MODULE_DESCRIPTION("GPIO-based I2C multiplexer driver");
MODULE_AUTHOR("Peter Korsgaard <peter.korsgaard@barco.com>");
diff --git a/drivers/ide/ali14xx.c b/drivers/ide/ali14xx.c
index 25b9fe3a9f8e..d3be99fb4154 100644
--- a/drivers/ide/ali14xx.c
+++ b/drivers/ide/ali14xx.c
@@ -221,7 +221,7 @@ static int __init ali14xx_probe(void)
return ide_legacy_device_add(&ali14xx_port_info, 0);
}
-static int probe_ali14xx;
+static bool probe_ali14xx;
module_param_named(probe, probe_ali14xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets");
diff --git a/drivers/ide/cmd640.c b/drivers/ide/cmd640.c
index a81bd7575792..14717304b388 100644
--- a/drivers/ide/cmd640.c
+++ b/drivers/ide/cmd640.c
@@ -111,7 +111,7 @@
#define DRV_NAME "cmd640"
-static int cmd640_vlb;
+static bool cmd640_vlb;
/*
* CMD640 specific registers definition.
diff --git a/drivers/ide/dtc2278.c b/drivers/ide/dtc2278.c
index 6929f7fce93a..46af4743b3e6 100644
--- a/drivers/ide/dtc2278.c
+++ b/drivers/ide/dtc2278.c
@@ -130,7 +130,7 @@ static int __init dtc2278_probe(void)
return ide_legacy_device_add(&dtc2278_port_info, 0);
}
-static int probe_dtc2278;
+static bool probe_dtc2278;
module_param_named(probe, probe_dtc2278, bool, 0);
MODULE_PARM_DESC(probe, "probe for DTC2278xx chipsets");
diff --git a/drivers/ide/gayle.c b/drivers/ide/gayle.c
index 3feaa26410be..51beb85250d4 100644
--- a/drivers/ide/gayle.c
+++ b/drivers/ide/gayle.c
@@ -50,7 +50,7 @@
GAYLE_NUM_HWIFS-1)
#define GAYLE_HAS_CONTROL_REG (!ide_doubler)
-static int ide_doubler;
+static bool ide_doubler;
module_param_named(doubler, ide_doubler, bool, 0);
MODULE_PARM_DESC(doubler, "enable support for IDE doublers");
diff --git a/drivers/ide/ht6560b.c b/drivers/ide/ht6560b.c
index 808bcdcbf8e1..986f2513eab4 100644
--- a/drivers/ide/ht6560b.c
+++ b/drivers/ide/ht6560b.c
@@ -317,7 +317,7 @@ static void __init ht6560b_init_dev(ide_drive_t *drive)
ide_set_drivedata(drive, (void *)t);
}
-static int probe_ht6560b;
+static bool probe_ht6560b;
module_param_named(probe, probe_ht6560b, bool, 0);
MODULE_PARM_DESC(probe, "probe for HT6560B chipset");
diff --git a/drivers/ide/ide-4drives.c b/drivers/ide/ide-4drives.c
index 979d342c338a..547d7cf2e016 100644
--- a/drivers/ide/ide-4drives.c
+++ b/drivers/ide/ide-4drives.c
@@ -6,7 +6,7 @@
#define DRV_NAME "ide-4drives"
-static int probe_4drives;
+static bool probe_4drives;
module_param_named(probe, probe_4drives, bool, 0);
MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c
index f22edc66b030..f1a6796b165c 100644
--- a/drivers/ide/ide-acpi.c
+++ b/drivers/ide/ide-acpi.c
@@ -53,15 +53,15 @@ struct ide_acpi_hwif_link {
#define DEBPRINT(fmt, args...) do {} while (0)
#endif /* DEBUGGING */
-static int ide_noacpi;
+static bool ide_noacpi;
module_param_named(noacpi, ide_noacpi, bool, 0);
MODULE_PARM_DESC(noacpi, "disable IDE ACPI support");
-static int ide_acpigtf;
+static bool ide_acpigtf;
module_param_named(acpigtf, ide_acpigtf, bool, 0);
MODULE_PARM_DESC(acpigtf, "enable IDE ACPI _GTF support");
-static int ide_acpionboot;
+static bool ide_acpionboot;
module_param_named(acpionboot, ide_acpionboot, bool, 0);
MODULE_PARM_DESC(acpionboot, "call IDE ACPI methods on boot");
diff --git a/drivers/ide/ide-floppy_ioctl.c b/drivers/ide/ide-floppy_ioctl.c
index d267b7affad6..a22ca8467010 100644
--- a/drivers/ide/ide-floppy_ioctl.c
+++ b/drivers/ide/ide-floppy_ioctl.c
@@ -292,8 +292,7 @@ int ide_floppy_ioctl(ide_drive_t *drive, struct block_device *bdev,
* and CDROM_SEND_PACKET (legacy) ioctls
*/
if (cmd != CDROM_SEND_PACKET && cmd != SCSI_IOCTL_SEND_COMMAND)
- err = scsi_cmd_ioctl(bdev->bd_disk->queue, bdev->bd_disk,
- mode, cmd, argp);
+ err = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
if (err == -ENOTTY)
err = generic_ide_ioctl(drive, bdev, cmd, arg);
diff --git a/drivers/ide/ide-pci-generic.c b/drivers/ide/ide-pci-generic.c
index a743e68a8903..7f56b738d762 100644
--- a/drivers/ide/ide-pci-generic.c
+++ b/drivers/ide/ide-pci-generic.c
@@ -28,7 +28,7 @@
#define DRV_NAME "ide_pci_generic"
-static int ide_generic_all; /* Set to claim all devices */
+static bool ide_generic_all; /* Set to claim all devices */
module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
diff --git a/drivers/ide/qd65xx.c b/drivers/ide/qd65xx.c
index 3f0244fd8e62..8bbfe5557c7b 100644
--- a/drivers/ide/qd65xx.c
+++ b/drivers/ide/qd65xx.c
@@ -417,7 +417,7 @@ static int __init qd_probe(int base)
return rc;
}
-static int probe_qd65xx;
+static bool probe_qd65xx;
module_param_named(probe, probe_qd65xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for QD65xx chipsets");
diff --git a/drivers/ide/umc8672.c b/drivers/ide/umc8672.c
index 47adcd09cb26..5cfb78120669 100644
--- a/drivers/ide/umc8672.c
+++ b/drivers/ide/umc8672.c
@@ -160,7 +160,7 @@ static int __init umc8672_probe(void)
return ide_legacy_device_add(&umc8672_port_info, 0);
}
-static int probe_umc8672;
+static bool probe_umc8672;
module_param_named(probe, probe_umc8672, bool, 0);
MODULE_PARM_DESC(probe, "probe for UMC8672 chipset");
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index aaf6023a4835..f08f6eaf3fa8 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -379,8 +379,8 @@ extern spinlock_t shca_list_lock;
extern int ehca_static_rate;
extern int ehca_port_act_time;
-extern int ehca_use_hp_mr;
-extern int ehca_scaling_code;
+extern bool ehca_use_hp_mr;
+extern bool ehca_scaling_code;
extern int ehca_lock_hcalls;
extern int ehca_nr_ports;
extern int ehca_max_cq;
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index c240e9972cb0..832e7a7d0aee 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -59,16 +59,16 @@ MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
MODULE_VERSION(HCAD_VERSION);
-static int ehca_open_aqp1 = 0;
+static bool ehca_open_aqp1 = 0;
static int ehca_hw_level = 0;
-static int ehca_poll_all_eqs = 1;
+static bool ehca_poll_all_eqs = 1;
int ehca_debug_level = 0;
int ehca_nr_ports = -1;
-int ehca_use_hp_mr = 0;
+bool ehca_use_hp_mr = 0;
int ehca_port_act_time = 30;
int ehca_static_rate = -1;
-int ehca_scaling_code = 0;
+bool ehca_scaling_code = 0;
int ehca_lock_hcalls = -1;
int ehca_max_cq = -1;
int ehca_max_qp = -1;
@@ -82,7 +82,7 @@ module_param_named(port_act_time, ehca_port_act_time, int, S_IRUGO);
module_param_named(poll_all_eqs, ehca_poll_all_eqs, bool, S_IRUGO);
module_param_named(static_rate, ehca_static_rate, int, S_IRUGO);
module_param_named(scaling_code, ehca_scaling_code, bool, S_IRUGO);
-module_param_named(lock_hcalls, ehca_lock_hcalls, bool, S_IRUGO);
+module_param_named(lock_hcalls, ehca_lock_hcalls, bint, S_IRUGO);
module_param_named(number_of_cqs, ehca_max_cq, int, S_IRUGO);
module_param_named(number_of_qps, ehca_max_qp, int, S_IRUGO);
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index 5965b3df8f2f..7013da5e9eda 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -96,7 +96,7 @@ unsigned int wqm_quanta = 0x10000;
module_param(wqm_quanta, int, 0644);
MODULE_PARM_DESC(wqm_quanta, "WQM quanta");
-static unsigned int limit_maxrdreqsz;
+static bool limit_maxrdreqsz;
module_param(limit_maxrdreqsz, bool, 0644);
MODULE_PARM_DESC(limit_maxrdreqsz, "Limit max read request size to 256 Bytes");
diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
index 32bbd4c77b7c..fd7a0d5bc94d 100644
--- a/drivers/input/joystick/xpad.c
+++ b/drivers/input/joystick/xpad.c
@@ -98,15 +98,15 @@
#define XTYPE_XBOX360W 2
#define XTYPE_UNKNOWN 3
-static int dpad_to_buttons;
+static bool dpad_to_buttons;
module_param(dpad_to_buttons, bool, S_IRUGO);
MODULE_PARM_DESC(dpad_to_buttons, "Map D-PAD to buttons rather than axes for unknown pads");
-static int triggers_to_buttons;
+static bool triggers_to_buttons;
module_param(triggers_to_buttons, bool, S_IRUGO);
MODULE_PARM_DESC(triggers_to_buttons, "Map triggers to buttons rather than axes for unknown pads");
-static int sticks_to_null;
+static bool sticks_to_null;
module_param(sticks_to_null, bool, S_IRUGO);
MODULE_PARM_DESC(sticks_to_null, "Do not map sticks at all for unknown pads");
diff --git a/drivers/input/misc/ab8500-ponkey.c b/drivers/input/misc/ab8500-ponkey.c
index 79d901633635..350fd0c385d2 100644
--- a/drivers/input/misc/ab8500-ponkey.c
+++ b/drivers/input/misc/ab8500-ponkey.c
@@ -12,7 +12,7 @@
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/interrupt.h>
-#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <linux/slab.h>
/**
diff --git a/drivers/input/misc/wistron_btns.c b/drivers/input/misc/wistron_btns.c
index 52b419348983..e2bdfd4bea70 100644
--- a/drivers/input/misc/wistron_btns.c
+++ b/drivers/input/misc/wistron_btns.c
@@ -48,7 +48,7 @@ MODULE_DESCRIPTION("Wistron laptop button driver");
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.3");
-static int force; /* = 0; */
+static bool force; /* = 0; */
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Load even if computer is not in database");
diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
index de7e8bc17b1f..e6c9931f02c7 100644
--- a/drivers/input/mouse/psmouse-base.c
+++ b/drivers/input/mouse/psmouse-base.c
@@ -60,7 +60,7 @@ static unsigned int psmouse_rate = 100;
module_param_named(rate, psmouse_rate, uint, 0644);
MODULE_PARM_DESC(rate, "Report rate, in reports per second.");
-static unsigned int psmouse_smartscroll = 1;
+static bool psmouse_smartscroll = 1;
module_param_named(smartscroll, psmouse_smartscroll, bool, 0644);
MODULE_PARM_DESC(smartscroll, "Logitech Smartscroll autorepeat, 1 = enabled (default), 0 = disabled.");
diff --git a/drivers/input/mouse/synaptics_i2c.c b/drivers/input/mouse/synaptics_i2c.c
index 4b755cb5b38c..1c58aafa523f 100644
--- a/drivers/input/mouse/synaptics_i2c.c
+++ b/drivers/input/mouse/synaptics_i2c.c
@@ -185,17 +185,17 @@
#define NO_DATA_SLEEP_MSECS (MSEC_PER_SEC / 4)
/* Control touchpad's No Deceleration option */
-static int no_decel = 1;
+static bool no_decel = 1;
module_param(no_decel, bool, 0644);
MODULE_PARM_DESC(no_decel, "No Deceleration. Default = 1 (on)");
/* Control touchpad's Reduced Reporting option */
-static int reduce_report;
+static bool reduce_report;
module_param(reduce_report, bool, 0644);
MODULE_PARM_DESC(reduce_report, "Reduced Reporting. Default = 0 (off)");
/* Control touchpad's No Filter option */
-static int no_filter;
+static bool no_filter;
module_param(no_filter, bool, 0644);
MODULE_PARM_DESC(no_filter, "No Filter. Default = 0 (off)");
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 979c443bf1ef..be3316073ae7 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -105,7 +105,7 @@ EXPORT_SYMBOL(__hp_sdc_enqueue_transaction);
EXPORT_SYMBOL(hp_sdc_enqueue_transaction);
EXPORT_SYMBOL(hp_sdc_dequeue_transaction);
-static unsigned int hp_sdc_disabled;
+static bool hp_sdc_disabled;
module_param_named(no_hpsdc, hp_sdc_disabled, bool, 0);
MODULE_PARM_DESC(no_hpsdc, "Do not enable HP SDC driver.");
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c
index 7f8f538a9806..1df19bb8534a 100644
--- a/drivers/input/touchscreen/eeti_ts.c
+++ b/drivers/input/touchscreen/eeti_ts.c
@@ -35,11 +35,11 @@
#include <linux/input/eeti_ts.h>
#include <linux/slab.h>
-static int flip_x;
+static bool flip_x;
module_param(flip_x, bool, 0644);
MODULE_PARM_DESC(flip_x, "flip x coordinate");
-static int flip_y;
+static bool flip_y;
module_param(flip_y, bool, 0644);
MODULE_PARM_DESC(flip_y, "flip y coordinate");
diff --git a/drivers/input/touchscreen/htcpen.c b/drivers/input/touchscreen/htcpen.c
index 81e338623944..d13143b68b3e 100644
--- a/drivers/input/touchscreen/htcpen.c
+++ b/drivers/input/touchscreen/htcpen.c
@@ -40,10 +40,10 @@ MODULE_LICENSE("GPL");
#define X_AXIS_MAX 2040
#define Y_AXIS_MAX 2040
-static int invert_x;
+static bool invert_x;
module_param(invert_x, bool, 0644);
MODULE_PARM_DESC(invert_x, "If set, X axis is inverted");
-static int invert_y;
+static bool invert_y;
module_param(invert_y, bool, 0644);
MODULE_PARM_DESC(invert_y, "If set, Y axis is inverted");
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index d2b57536feea..46e83ad53f43 100644
--- a/drivers/input/touchscreen/ucb1400_ts.c
+++ b/drivers/input/touchscreen/ucb1400_ts.c
@@ -30,7 +30,7 @@
#define UCB1400_TS_POLL_PERIOD 10 /* ms */
-static int adcsync;
+static bool adcsync;
static int ts_delay = 55; /* us */
static int ts_delay_pressure; /* us */
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c
index 06cef3ccc63a..3a5ebf452e81 100644
--- a/drivers/input/touchscreen/usbtouchscreen.c
+++ b/drivers/input/touchscreen/usbtouchscreen.c
@@ -60,11 +60,11 @@
#define DRIVER_AUTHOR "Daniel Ritz <daniel.ritz@gmx.ch>"
#define DRIVER_DESC "USB Touchscreen Driver"
-static int swap_xy;
+static bool swap_xy;
module_param(swap_xy, bool, 0644);
MODULE_PARM_DESC(swap_xy, "If set X and Y axes are swapped.");
-static int hwcalib_xy;
+static bool hwcalib_xy;
module_param(hwcalib_xy, bool, 0644);
MODULE_PARM_DESC(hwcalib_xy, "If set hw-calibrated X/Y are used if available");
diff --git a/drivers/isdn/hardware/avm/b1dma.c b/drivers/isdn/hardware/avm/b1dma.c
index 9c8d7aa053c5..a0ed668d4d2a 100644
--- a/drivers/isdn/hardware/avm/b1dma.c
+++ b/drivers/isdn/hardware/avm/b1dma.c
@@ -40,7 +40,7 @@ MODULE_DESCRIPTION("CAPI4Linux: DMA support for active AVM cards");
MODULE_AUTHOR("Carsten Paeth");
MODULE_LICENSE("GPL");
-static int suppress_pollack = 0;
+static bool suppress_pollack = 0;
module_param(suppress_pollack, bool, 0);
/* ------------------------------------------------------------- */
diff --git a/drivers/isdn/hardware/avm/c4.c b/drivers/isdn/hardware/avm/c4.c
index d3530f6e8115..9743b24ef9d6 100644
--- a/drivers/isdn/hardware/avm/c4.c
+++ b/drivers/isdn/hardware/avm/c4.c
@@ -40,7 +40,7 @@ static char *revision = "$Revision: 1.1.2.2 $";
/* ------------------------------------------------------------- */
-static int suppress_pollack;
+static bool suppress_pollack;
static struct pci_device_id c4_pci_tbl[] = {
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, PCI_VENDOR_ID_AVM, PCI_DEVICE_ID_AVM_C4, 0, 0, (unsigned long)4 },
diff --git a/drivers/isdn/sc/init.c b/drivers/isdn/sc/init.c
index ca710ab278ec..023de789f250 100644
--- a/drivers/isdn/sc/init.c
+++ b/drivers/isdn/sc/init.c
@@ -30,7 +30,7 @@ static const char *boardname[] = { "DataCommute/BRI", "DataCommute/PRI", "TeleCo
static unsigned int io[] = {0,0,0,0};
static unsigned char irq[] = {0,0,0,0};
static unsigned long ram[] = {0,0,0,0};
-static int do_reset = 0;
+static bool do_reset = 0;
module_param_array(io, int, NULL, 0);
module_param_array(irq, int, NULL, 0);
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig
index 897a77dfa9d7..c957c344233f 100644
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -396,6 +396,13 @@ config LEDS_TCA6507
LED driver chips accessed via the I2C bus.
Driver support brightness control and hardware-assisted blinking.
+config LEDS_MAX8997
+ tristate "LED support for MAX8997 PMIC"
+ depends on LEDS_CLASS && MFD_MAX8997
+ help
+ This option enables support for on-chip LED drivers on
+ MAXIM MAX8997 PMIC.
+
config LEDS_TRIGGERS
bool "LED Trigger support"
depends on LEDS_CLASS
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile
index 5c9dc4b000d5..b8a9723477f0 100644
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o
obj-$(CONFIG_LEDS_RENESAS_TPU) += leds-renesas-tpu.o
+obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o
# LED SPI Drivers
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
diff --git a/drivers/leds/leds-clevo-mail.c b/drivers/leds/leds-clevo-mail.c
index a498135a4e80..1ed1677c916f 100644
--- a/drivers/leds/leds-clevo-mail.c
+++ b/drivers/leds/leds-clevo-mail.c
@@ -18,7 +18,7 @@ MODULE_AUTHOR("Márton Németh <nm127@freemail.hu>");
MODULE_DESCRIPTION("Clevo mail LED driver");
MODULE_LICENSE("GPL");
-static unsigned int __initdata nodetect;
+static bool __initdata nodetect;
module_param_named(nodetect, nodetect, bool, 0);
MODULE_PARM_DESC(nodetect, "Skip DMI hardware detection");
diff --git a/drivers/leds/leds-max8997.c b/drivers/leds/leds-max8997.c
new file mode 100644
index 000000000000..f4c0e37fad1e
--- /dev/null
+++ b/drivers/leds/leds-max8997.c
@@ -0,0 +1,372 @@
+/*
+ * leds-max8997.c - LED class driver for MAX8997 LEDs.
+ *
+ * Copyright (C) 2011 Samsung Electronics
+ * Donggeun Kim <dg77.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/workqueue.h>
+#include <linux/leds.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+#include <linux/platform_device.h>
+
+#define MAX8997_LED_FLASH_SHIFT 3
+#define MAX8997_LED_FLASH_CUR_MASK 0xf8
+#define MAX8997_LED_MOVIE_SHIFT 4
+#define MAX8997_LED_MOVIE_CUR_MASK 0xf0
+
+#define MAX8997_LED_FLASH_MAX_BRIGHTNESS 0x1f
+#define MAX8997_LED_MOVIE_MAX_BRIGHTNESS 0xf
+#define MAX8997_LED_NONE_MAX_BRIGHTNESS 0
+
+#define MAX8997_LED0_FLASH_MASK 0x1
+#define MAX8997_LED0_FLASH_PIN_MASK 0x5
+#define MAX8997_LED0_MOVIE_MASK 0x8
+#define MAX8997_LED0_MOVIE_PIN_MASK 0x28
+
+#define MAX8997_LED1_FLASH_MASK 0x2
+#define MAX8997_LED1_FLASH_PIN_MASK 0x6
+#define MAX8997_LED1_MOVIE_MASK 0x10
+#define MAX8997_LED1_MOVIE_PIN_MASK 0x30
+
+#define MAX8997_LED_BOOST_ENABLE_MASK (1 << 6)
+
+struct max8997_led {
+ struct max8997_dev *iodev;
+ struct led_classdev cdev;
+ bool enabled;
+ int id;
+ enum max8997_led_mode led_mode;
+ struct mutex mutex;
+};
+
+static void max8997_led_clear_mode(struct max8997_led *led,
+ enum max8997_led_mode mode)
+{
+ struct i2c_client *client = led->iodev->i2c;
+ u8 val = 0, mask = 0;
+ int ret;
+
+ switch (mode) {
+ case MAX8997_FLASH_MODE:
+ mask = led->id ?
+ MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK;
+ break;
+ case MAX8997_MOVIE_MODE:
+ mask = led->id ?
+ MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK;
+ break;
+ case MAX8997_FLASH_PIN_CONTROL_MODE:
+ mask = led->id ?
+ MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK;
+ break;
+ case MAX8997_MOVIE_PIN_CONTROL_MODE:
+ mask = led->id ?
+ MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK;
+ break;
+ default:
+ break;
+ }
+
+ if (mask) {
+ ret = max8997_update_reg(client,
+ MAX8997_REG_LEN_CNTL, val, mask);
+ if (ret)
+ dev_err(led->iodev->dev,
+ "failed to update register(%d)\n", ret);
+ }
+}
+
+static void max8997_led_set_mode(struct max8997_led *led,
+ enum max8997_led_mode mode)
+{
+ int ret;
+ struct i2c_client *client = led->iodev->i2c;
+ u8 mask = 0;
+
+ /* First, clear the previous mode */
+ max8997_led_clear_mode(led, led->led_mode);
+
+ switch (mode) {
+ case MAX8997_FLASH_MODE:
+ mask = led->id ?
+ MAX8997_LED1_FLASH_MASK : MAX8997_LED0_FLASH_MASK;
+ led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS;
+ break;
+ case MAX8997_MOVIE_MODE:
+ mask = led->id ?
+ MAX8997_LED1_MOVIE_MASK : MAX8997_LED0_MOVIE_MASK;
+ led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS;
+ break;
+ case MAX8997_FLASH_PIN_CONTROL_MODE:
+ mask = led->id ?
+ MAX8997_LED1_FLASH_PIN_MASK : MAX8997_LED0_FLASH_PIN_MASK;
+ led->cdev.max_brightness = MAX8997_LED_FLASH_MAX_BRIGHTNESS;
+ break;
+ case MAX8997_MOVIE_PIN_CONTROL_MODE:
+ mask = led->id ?
+ MAX8997_LED1_MOVIE_PIN_MASK : MAX8997_LED0_MOVIE_PIN_MASK;
+ led->cdev.max_brightness = MAX8997_LED_MOVIE_MAX_BRIGHTNESS;
+ break;
+ default:
+ led->cdev.max_brightness = MAX8997_LED_NONE_MAX_BRIGHTNESS;
+ break;
+ }
+
+ if (mask) {
+ ret = max8997_update_reg(client,
+ MAX8997_REG_LEN_CNTL, mask, mask);
+ if (ret)
+ dev_err(led->iodev->dev,
+ "failed to update register(%d)\n", ret);
+ }
+
+ led->led_mode = mode;
+}
+
+static void max8997_led_enable(struct max8997_led *led, bool enable)
+{
+ int ret;
+ struct i2c_client *client = led->iodev->i2c;
+ u8 val = 0, mask = MAX8997_LED_BOOST_ENABLE_MASK;
+
+ if (led->enabled == enable)
+ return;
+
+ val = enable ? MAX8997_LED_BOOST_ENABLE_MASK : 0;
+
+ ret = max8997_update_reg(client, MAX8997_REG_BOOST_CNTL, val, mask);
+ if (ret)
+ dev_err(led->iodev->dev,
+ "failed to update register(%d)\n", ret);
+
+ led->enabled = enable;
+}
+
+static void max8997_led_set_current(struct max8997_led *led,
+ enum led_brightness value)
+{
+ int ret;
+ struct i2c_client *client = led->iodev->i2c;
+ u8 val = 0, mask = 0, reg = 0;
+
+ switch (led->led_mode) {
+ case MAX8997_FLASH_MODE:
+ case MAX8997_FLASH_PIN_CONTROL_MODE:
+ val = value << MAX8997_LED_FLASH_SHIFT;
+ mask = MAX8997_LED_FLASH_CUR_MASK;
+ reg = led->id ? MAX8997_REG_FLASH2_CUR : MAX8997_REG_FLASH1_CUR;
+ break;
+ case MAX8997_MOVIE_MODE:
+ case MAX8997_MOVIE_PIN_CONTROL_MODE:
+ val = value << MAX8997_LED_MOVIE_SHIFT;
+ mask = MAX8997_LED_MOVIE_CUR_MASK;
+ reg = MAX8997_REG_MOVIE_CUR;
+ break;
+ default:
+ break;
+ }
+
+ if (mask) {
+ ret = max8997_update_reg(client, reg, val, mask);
+ if (ret)
+ dev_err(led->iodev->dev,
+ "failed to update register(%d)\n", ret);
+ }
+}
+
+static void max8997_led_brightness_set(struct led_classdev *led_cdev,
+ enum led_brightness value)
+{
+ struct max8997_led *led =
+ container_of(led_cdev, struct max8997_led, cdev);
+
+ if (value) {
+ max8997_led_set_current(led, value);
+ max8997_led_enable(led, true);
+ } else {
+ max8997_led_set_current(led, value);
+ max8997_led_enable(led, false);
+ }
+}
+
+static ssize_t max8997_led_show_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct max8997_led *led =
+ container_of(led_cdev, struct max8997_led, cdev);
+ ssize_t ret = 0;
+
+ mutex_lock(&led->mutex);
+
+ switch (led->led_mode) {
+ case MAX8997_FLASH_MODE:
+ ret += sprintf(buf, "FLASH\n");
+ break;
+ case MAX8997_MOVIE_MODE:
+ ret += sprintf(buf, "MOVIE\n");
+ break;
+ case MAX8997_FLASH_PIN_CONTROL_MODE:
+ ret += sprintf(buf, "FLASH_PIN_CONTROL\n");
+ break;
+ case MAX8997_MOVIE_PIN_CONTROL_MODE:
+ ret += sprintf(buf, "MOVIE_PIN_CONTROL\n");
+ break;
+ default:
+ ret += sprintf(buf, "NONE\n");
+ break;
+ }
+
+ mutex_unlock(&led->mutex);
+
+ return ret;
+}
+
+static ssize_t max8997_led_store_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct led_classdev *led_cdev = dev_get_drvdata(dev);
+ struct max8997_led *led =
+ container_of(led_cdev, struct max8997_led, cdev);
+ enum max8997_led_mode mode;
+
+ mutex_lock(&led->mutex);
+
+ if (!strncmp(buf, "FLASH_PIN_CONTROL", 17))
+ mode = MAX8997_FLASH_PIN_CONTROL_MODE;
+ else if (!strncmp(buf, "MOVIE_PIN_CONTROL", 17))
+ mode = MAX8997_MOVIE_PIN_CONTROL_MODE;
+ else if (!strncmp(buf, "FLASH", 5))
+ mode = MAX8997_FLASH_MODE;
+ else if (!strncmp(buf, "MOVIE", 5))
+ mode = MAX8997_MOVIE_MODE;
+ else
+ mode = MAX8997_NONE;
+
+ max8997_led_set_mode(led, mode);
+
+ mutex_unlock(&led->mutex);
+
+ return size;
+}
+
+static DEVICE_ATTR(mode, 0644, max8997_led_show_mode, max8997_led_store_mode);
+
+static int __devinit max8997_led_probe(struct platform_device *pdev)
+{
+ struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
+ struct max8997_led *led;
+ char name[20];
+ int ret = 0;
+
+ if (pdata == NULL) {
+ dev_err(&pdev->dev, "no platform data\n");
+ return -ENODEV;
+ }
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (led == NULL) {
+ ret = -ENOMEM;
+ goto err_mem;
+ }
+
+ led->id = pdev->id;
+ snprintf(name, sizeof(name), "max8997-led%d", pdev->id);
+
+ led->cdev.name = name;
+ led->cdev.brightness_set = max8997_led_brightness_set;
+ led->cdev.flags |= LED_CORE_SUSPENDRESUME;
+ led->cdev.brightness = 0;
+ led->iodev = iodev;
+
+ /* initialize mode and brightness according to platform_data */
+ if (pdata->led_pdata) {
+ u8 mode = 0, brightness = 0;
+
+ mode = pdata->led_pdata->mode[led->id];
+ brightness = pdata->led_pdata->brightness[led->id];
+
+ max8997_led_set_mode(led, pdata->led_pdata->mode[led->id]);
+
+ if (brightness > led->cdev.max_brightness)
+ brightness = led->cdev.max_brightness;
+ max8997_led_set_current(led, brightness);
+ led->cdev.brightness = brightness;
+ } else {
+ max8997_led_set_mode(led, MAX8997_NONE);
+ max8997_led_set_current(led, 0);
+ }
+
+ mutex_init(&led->mutex);
+
+ platform_set_drvdata(pdev, led);
+
+ ret = led_classdev_register(&pdev->dev, &led->cdev);
+ if (ret < 0)
+ goto err_led;
+
+ ret = device_create_file(led->cdev.dev, &dev_attr_mode);
+ if (ret != 0) {
+ dev_err(&pdev->dev,
+ "failed to create file: %d\n", ret);
+ goto err_file;
+ }
+
+ return 0;
+
+err_file:
+ led_classdev_unregister(&led->cdev);
+err_led:
+ kfree(led);
+err_mem:
+ return ret;
+}
+
+static int __devexit max8997_led_remove(struct platform_device *pdev)
+{
+ struct max8997_led *led = platform_get_drvdata(pdev);
+
+ device_remove_file(led->cdev.dev, &dev_attr_mode);
+ led_classdev_unregister(&led->cdev);
+ kfree(led);
+
+ return 0;
+}
+
+static struct platform_driver max8997_led_driver = {
+ .driver = {
+ .name = "max8997-led",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8997_led_probe,
+ .remove = __devexit_p(max8997_led_remove),
+};
+
+static int __init max8997_led_init(void)
+{
+ return platform_driver_register(&max8997_led_driver);
+}
+module_init(max8997_led_init);
+
+static void __exit max8997_led_exit(void)
+{
+ platform_driver_unregister(&max8997_led_driver);
+}
+module_exit(max8997_led_exit);
+
+MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
+MODULE_DESCRIPTION("MAX8997 LED driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:max8997-led");
diff --git a/drivers/leds/leds-ss4200.c b/drivers/leds/leds-ss4200.c
index 614ebebaaa28..57371e1485ab 100644
--- a/drivers/leds/leds-ss4200.c
+++ b/drivers/leds/leds-ss4200.c
@@ -79,7 +79,7 @@ static int __init ss4200_led_dmi_callback(const struct dmi_system_id *id)
return 1;
}
-static unsigned int __initdata nodetect;
+static bool __initdata nodetect;
module_param_named(nodetect, nodetect, bool, 0);
MODULE_PARM_DESC(nodetect, "Skip DMI-based hardware detection");
diff --git a/drivers/macintosh/ams/ams-core.c b/drivers/macintosh/ams/ams-core.c
index 399beb1638d1..5c6a2d876562 100644
--- a/drivers/macintosh/ams/ams-core.c
+++ b/drivers/macintosh/ams/ams-core.c
@@ -31,7 +31,7 @@
/* There is only one motion sensor per machine */
struct ams ams_info;
-static unsigned int verbose;
+static bool verbose;
module_param(verbose, bool, 0644);
MODULE_PARM_DESC(verbose, "Show free falls and shocks in kernel output");
diff --git a/drivers/macintosh/ams/ams-input.c b/drivers/macintosh/ams/ams-input.c
index 8a712392cd38..b27e530a87a4 100644
--- a/drivers/macintosh/ams/ams-input.c
+++ b/drivers/macintosh/ams/ams-input.c
@@ -19,11 +19,11 @@
#include "ams.h"
-static unsigned int joystick;
+static bool joystick;
module_param(joystick, bool, S_IRUGO);
MODULE_PARM_DESC(joystick, "Enable the input class device on module load");
-static unsigned int invert;
+static bool invert;
module_param(invert, bool, S_IWUSR | S_IRUGO);
MODULE_PARM_DESC(invert, "Invert input data on X and Y axis");
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index 02367308ff2e..c60d025044ee 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -52,7 +52,7 @@ static const char *sensor_location[3];
static int limit_adjust;
static int fan_speed = -1;
-static int verbose;
+static bool verbose;
MODULE_AUTHOR("Colin Leroy <colin@colino.net>");
MODULE_DESCRIPTION("Driver for ADT746x thermostat in iBook G4 and "
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
index f84c08029b21..9fb18c147825 100644
--- a/drivers/md/dm-flakey.c
+++ b/drivers/md/dm-flakey.c
@@ -368,8 +368,17 @@ static int flakey_status(struct dm_target *ti, status_type_t type,
static int flakey_ioctl(struct dm_target *ti, unsigned int cmd, unsigned long arg)
{
struct flakey_c *fc = ti->private;
+ struct dm_dev *dev = fc->dev;
+ int r = 0;
- return __blkdev_driver_ioctl(fc->dev->bdev, fc->dev->mode, cmd, arg);
+ /*
+ * Only pass ioctls through if the device sizes match exactly.
+ */
+ if (fc->start ||
+ ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
+ r = scsi_verify_blk_ioctl(NULL, cmd);
+
+ return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
}
static int flakey_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
diff --git a/drivers/md/dm-linear.c b/drivers/md/dm-linear.c
index 3921e3bb43c1..9728839f844a 100644
--- a/drivers/md/dm-linear.c
+++ b/drivers/md/dm-linear.c
@@ -116,7 +116,17 @@ static int linear_ioctl(struct dm_target *ti, unsigned int cmd,
unsigned long arg)
{
struct linear_c *lc = (struct linear_c *) ti->private;
- return __blkdev_driver_ioctl(lc->dev->bdev, lc->dev->mode, cmd, arg);
+ struct dm_dev *dev = lc->dev;
+ int r = 0;
+
+ /*
+ * Only pass ioctls through if the device sizes match exactly.
+ */
+ if (lc->start ||
+ ti->len != i_size_read(dev->bdev->bd_inode) >> SECTOR_SHIFT)
+ r = scsi_verify_blk_ioctl(NULL, cmd);
+
+ return r ? : __blkdev_driver_ioctl(dev->bdev, dev->mode, cmd, arg);
}
static int linear_merge(struct dm_target *ti, struct bvec_merge_data *bvm,
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
index 5e0090ef4182..801d92d237cf 100644
--- a/drivers/md/dm-mpath.c
+++ b/drivers/md/dm-mpath.c
@@ -1520,6 +1520,12 @@ static int multipath_ioctl(struct dm_target *ti, unsigned int cmd,
spin_unlock_irqrestore(&m->lock, flags);
+ /*
+ * Only pass ioctls through if the device sizes match exactly.
+ */
+ if (!r && ti->len != i_size_read(bdev->bd_inode) >> SECTOR_SHIFT)
+ r = scsi_verify_blk_ioctl(NULL, cmd);
+
return r ? : __blkdev_driver_ioctl(bdev, mode, cmd, arg);
}
diff --git a/drivers/media/dvb/dvb-usb/af9005.c b/drivers/media/dvb/dvb-usb/af9005.c
index bd51a764351b..4fc024d77040 100644
--- a/drivers/media/dvb/dvb-usb/af9005.c
+++ b/drivers/media/dvb/dvb-usb/af9005.c
@@ -30,7 +30,7 @@ MODULE_PARM_DESC(debug,
"set debugging level (1=info,xfer=2,rc=4,reg=8,i2c=16,fw=32 (or-able))."
DVB_USB_DEBUG_STATUS);
/* enable obnoxious led */
-int dvb_usb_af9005_led = 1;
+bool dvb_usb_af9005_led = 1;
module_param_named(led, dvb_usb_af9005_led, bool, 0644);
MODULE_PARM_DESC(led, "enable led (default: 1).");
diff --git a/drivers/media/dvb/dvb-usb/af9005.h b/drivers/media/dvb/dvb-usb/af9005.h
index c71c77bd7f4b..6a2bf3de8456 100644
--- a/drivers/media/dvb/dvb-usb/af9005.h
+++ b/drivers/media/dvb/dvb-usb/af9005.h
@@ -35,7 +35,7 @@ extern int dvb_usb_af9005_debug;
#define deb_i2c(args...) dprintk(dvb_usb_af9005_debug,0x10,args)
#define deb_fw(args...) dprintk(dvb_usb_af9005_debug,0x20,args)
-extern int dvb_usb_af9005_led;
+extern bool dvb_usb_af9005_led;
/* firmware */
#define FW_BULKOUT_SIZE 250
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c
index edadc8449a3d..36ce0611c037 100644
--- a/drivers/media/radio/radio-gemtek.c
+++ b/drivers/media/radio/radio-gemtek.c
@@ -47,11 +47,11 @@ MODULE_VERSION("0.0.4");
#endif
static int io = CONFIG_RADIO_GEMTEK_PORT;
-static int probe = CONFIG_RADIO_GEMTEK_PROBE;
-static int hardmute;
-static int shutdown = 1;
-static int keepmuted = 1;
-static int initmute = 1;
+static bool probe = CONFIG_RADIO_GEMTEK_PROBE;
+static bool hardmute;
+static bool shutdown = 1;
+static bool keepmuted = 1;
+static bool initmute = 1;
static int radio_nr = -1;
module_param(io, int, 0444);
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c
index 3fb76e3834c9..87c1ee13b058 100644
--- a/drivers/media/radio/radio-miropcm20.c
+++ b/drivers/media/radio/radio-miropcm20.c
@@ -23,7 +23,7 @@ static int radio_nr = -1;
module_param(radio_nr, int, 0);
MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
-static int mono;
+static bool mono;
module_param(mono, bool, 0);
MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c
index 27997a9ceb0d..ca12d3289bfe 100644
--- a/drivers/media/rc/lirc_dev.c
+++ b/drivers/media/rc/lirc_dev.c
@@ -38,7 +38,7 @@
#include <media/lirc.h>
#include <media/lirc_dev.h>
-static int debug;
+static bool debug;
#define IRCTL_DEV_NAME "BaseRemoteCtl"
#define NOPLUG -1
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index 20bb12d6fbbe..21105bf9594d 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -156,9 +156,9 @@
/* module parameters */
#ifdef CONFIG_USB_DEBUG
-static int debug = 1;
+static bool debug = 1;
#else
-static int debug;
+static bool debug;
#endif
#define mce_dbg(dev, fmt, ...) \
diff --git a/drivers/media/rc/streamzap.c b/drivers/media/rc/streamzap.c
index b1d29d09eeae..d6f4bfe09391 100644
--- a/drivers/media/rc/streamzap.c
+++ b/drivers/media/rc/streamzap.c
@@ -43,9 +43,9 @@
#define DRIVER_DESC "Streamzap Remote Control driver"
#ifdef CONFIG_USB_DEBUG
-static int debug = 1;
+static bool debug = 1;
#else
-static int debug;
+static bool debug;
#endif
#define USB_STREAMZAP_VENDOR_ID 0x0e9c
diff --git a/drivers/media/rc/winbond-cir.c b/drivers/media/rc/winbond-cir.c
index e7f7a57bf684..b09c5fae489b 100644
--- a/drivers/media/rc/winbond-cir.c
+++ b/drivers/media/rc/winbond-cir.c
@@ -226,11 +226,11 @@ module_param(protocol, uint, 0444);
MODULE_PARM_DESC(protocol, "IR protocol to use for the power-on command "
"(0 = RC5, 1 = NEC, 2 = RC6A, default)");
-static int invert; /* default = 0 */
+static bool invert; /* default = 0 */
module_param(invert, bool, 0444);
MODULE_PARM_DESC(invert, "Invert the signal from the IR receiver");
-static int txandrx; /* default = 0 */
+static bool txandrx; /* default = 0 */
module_param(txandrx, bool, 0444);
MODULE_PARM_DESC(invert, "Allow simultaneous TX and RX");
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c
index cd8ff0473184..fda32f52554a 100644
--- a/drivers/media/video/c-qcam.c
+++ b/drivers/media/video/c-qcam.c
@@ -72,7 +72,7 @@ struct qcam {
static int parport[MAX_CAMS] = { [1 ... MAX_CAMS-1] = -1 };
static int probe = 2;
-static int force_rgb;
+static bool force_rgb;
static int video_nr = -1;
/* FIXME: parport=auto would never have worked, surely? --RR */
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 5909f2557ab4..1d64af9adf71 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -31,7 +31,7 @@ MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
MODULE_AUTHOR("Hans Verkuil");
MODULE_LICENSE("GPL");
-static int debug;
+static bool debug;
module_param(debug, bool, 0644);
diff --git a/drivers/media/video/cs53l32a.c b/drivers/media/video/cs53l32a.c
index d93e5ab45fd3..51c5b9ad67d8 100644
--- a/drivers/media/video/cs53l32a.c
+++ b/drivers/media/video/cs53l32a.c
@@ -35,7 +35,7 @@ MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
MODULE_AUTHOR("Martin Vaughan");
MODULE_LICENSE("GPL");
-static int debug;
+static bool debug;
module_param(debug, bool, 0644);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index c6ff32a6137c..349bd9c2aff5 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -75,7 +75,7 @@ static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1 };
static unsigned cardtype_c = 1;
static unsigned tuner_c = 1;
-static unsigned radio_c = 1;
+static bool radio_c = 1;
static char pal[] = "--";
static char secam[] = "--";
static char ntsc[] = "-";
diff --git a/drivers/media/video/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c
index 09e99de5fd21..58be4f3bb3cb 100644
--- a/drivers/media/video/cx25821/cx25821-alsa.c
+++ b/drivers/media/video/cx25821/cx25821-alsa.c
@@ -102,7 +102,7 @@ struct cx25821_audio_dev {
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = { 1, [1 ... (SNDRV_CARDS - 1)] = 1 };
+static bool enable[SNDRV_CARDS] = { 1, [1 ... (SNDRV_CARDS - 1)] = 1 };
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 68d1240f493c..04bf6627d362 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -96,7 +96,7 @@ typedef struct cx88_audio_dev snd_cx88_card_t;
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static const char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
-static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
+static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable cx88x soundcard. default enabled.");
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index 40f214ab924f..5539f09440ac 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -76,8 +76,8 @@ MODULE_PARM_DESC(video_nr,
"\none and for every other camera."
"\n");
-static short force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
- ET61X251_FORCE_MUNMAP};
+static bool force_munmap[] = {[0 ... ET61X251_MAX_DEVICES-1] =
+ ET61X251_FORCE_MUNMAP};
module_param_array(force_munmap, bool, NULL, 0444);
MODULE_PARM_DESC(force_munmap,
"\n<0|1[,...]> Force the application to unmap previously"
diff --git a/drivers/media/video/gspca/m5602/m5602_core.c b/drivers/media/video/gspca/m5602/m5602_core.c
index 9fe3816b2aa0..0c4493675438 100644
--- a/drivers/media/video/gspca/m5602/m5602_core.c
+++ b/drivers/media/video/gspca/m5602/m5602_core.c
@@ -27,8 +27,8 @@
/* Kernel module parameters */
int force_sensor;
-static int dump_bridge;
-int dump_sensor;
+static bool dump_bridge;
+bool dump_sensor;
static const struct usb_device_id m5602_table[] = {
{USB_DEVICE(0x0402, 0x5602)},
diff --git a/drivers/media/video/gspca/m5602/m5602_mt9m111.h b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
index b1f0c492036a..8c672b5c8c6a 100644
--- a/drivers/media/video/gspca/m5602/m5602_mt9m111.h
+++ b/drivers/media/video/gspca/m5602/m5602_mt9m111.h
@@ -106,7 +106,7 @@
/* Kernel module parameters */
extern int force_sensor;
-extern int dump_sensor;
+extern bool dump_sensor;
int mt9m111_probe(struct sd *sd);
int mt9m111_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 2efd607987ec..2b6a13b508f7 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -86,7 +86,7 @@
/* Kernel module parameters */
extern int force_sensor;
-extern int dump_sensor;
+extern bool dump_sensor;
int ov7660_probe(struct sd *sd);
int ov7660_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_ov9650.h b/drivers/media/video/gspca/m5602/m5602_ov9650.h
index da9a129b739d..f7aa5bf68983 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov9650.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov9650.h
@@ -135,7 +135,7 @@
/* Kernel module parameters */
extern int force_sensor;
-extern int dump_sensor;
+extern bool dump_sensor;
int ov9650_probe(struct sd *sd);
int ov9650_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_po1030.h b/drivers/media/video/gspca/m5602/m5602_po1030.h
index 338359596398..81a2bcb88fe3 100644
--- a/drivers/media/video/gspca/m5602/m5602_po1030.h
+++ b/drivers/media/video/gspca/m5602/m5602_po1030.h
@@ -147,7 +147,7 @@
/* Kernel module parameters */
extern int force_sensor;
-extern int dump_sensor;
+extern bool dump_sensor;
int po1030_probe(struct sd *sd);
int po1030_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
index 8cc7a3f6da72..8e0035e731c7 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.h
@@ -65,7 +65,7 @@
/* Kernel module parameters */
extern int force_sensor;
-extern int dump_sensor;
+extern bool dump_sensor;
int s5k4aa_probe(struct sd *sd);
int s5k4aa_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k83a.h b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
index 80a63a236e24..79952247b534 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k83a.h
+++ b/drivers/media/video/gspca/m5602/m5602_s5k83a.h
@@ -41,7 +41,7 @@
/* Kernel module parameters */
extern int force_sensor;
-extern int dump_sensor;
+extern bool dump_sensor;
int s5k83a_probe(struct sd *sd);
int s5k83a_init(struct sd *sd);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 0ab425fbea9a..6f878f6c6e99 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -36,8 +36,8 @@ MODULE_AUTHOR("Erik Andrén");
MODULE_DESCRIPTION("STV06XX USB Camera Driver");
MODULE_LICENSE("GPL");
-static int dump_bridge;
-static int dump_sensor;
+static bool dump_bridge;
+static bool dump_sensor;
int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
{
diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c
index 3f1a5b1beeba..e5eb56a5b618 100644
--- a/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/drivers/media/video/hdpvr/hdpvr-core.c
@@ -49,7 +49,7 @@ module_param(default_audio_input, uint, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(default_audio_input, "default audio input: 0=RCA back / "
"1=RCA front / 2=S/PDIF");
-static int boost_audio;
+static bool boost_audio;
module_param(boost_audio, bool, S_IRUGO|S_IWUSR);
MODULE_PARM_DESC(boost_audio, "boost the audio signal");
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 41108a9a195e..544af91cbdc1 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -99,7 +99,7 @@ static int i2c_clock_period[IVTV_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1,
static unsigned int cardtype_c = 1;
static unsigned int tuner_c = 1;
-static unsigned int radio_c = 1;
+static bool radio_c = 1;
static unsigned int i2c_clock_period_c = 1;
static char pal[] = "---";
static char secam[] = "--";
diff --git a/drivers/media/video/ivtv/ivtvfb.c b/drivers/media/video/ivtv/ivtvfb.c
index 6b7c9c823330..d0fbfcf7133d 100644
--- a/drivers/media/video/ivtv/ivtvfb.c
+++ b/drivers/media/video/ivtv/ivtvfb.c
@@ -58,7 +58,7 @@
/* card parameters */
static int ivtvfb_card_id = -1;
static int ivtvfb_debug = 0;
-static int osd_laced;
+static bool osd_laced;
static int osd_depth;
static int osd_upper;
static int osd_left;
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
index 80ec64d2d6d8..2c8fc0f6d690 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/video/marvell-ccic/mcam-core.c
@@ -51,7 +51,7 @@ static int delivered;
* sense.
*/
-static int alloc_bufs_at_read;
+static bool alloc_bufs_at_read;
module_param(alloc_bufs_at_read, bool, 0444);
MODULE_PARM_DESC(alloc_bufs_at_read,
"Non-zero value causes DMA buffers to be allocated when the "
@@ -73,11 +73,11 @@ MODULE_PARM_DESC(dma_buf_size,
"parameters require larger buffers, an attempt to reallocate "
"will be made.");
#else /* MCAM_MODE_VMALLOC */
-static const int alloc_bufs_at_read = 0;
+static const bool alloc_bufs_at_read = 0;
static const int n_dma_bufs = 3; /* Used by S/G_PARM */
#endif /* MCAM_MODE_VMALLOC */
-static int flip;
+static bool flip;
module_param(flip, bool, 0444);
MODULE_PARM_DESC(flip,
"If set, the sensor will be instructed to flip the image "
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c
index d0f538857285..d7cd0f633f63 100644
--- a/drivers/media/video/msp3400-driver.c
+++ b/drivers/media/video/msp3400-driver.c
@@ -69,12 +69,12 @@ MODULE_LICENSE("GPL");
/* module parameters */
static int opmode = OPMODE_AUTO;
int msp_debug; /* msp_debug output */
-int msp_once; /* no continuous stereo monitoring */
-int msp_amsound; /* hard-wire AM sound at 6.5 Hz (france),
+bool msp_once; /* no continuous stereo monitoring */
+bool msp_amsound; /* hard-wire AM sound at 6.5 Hz (france),
the autoscan seems work well only with FM... */
int msp_standard = 1; /* Override auto detect of audio msp_standard,
if needed. */
-int msp_dolby;
+bool msp_dolby;
int msp_stereo_thresh = 0x190; /* a2 threshold for stereo/bilingual
(msp34xxg only) 0x00a0-0x03c0 */
diff --git a/drivers/media/video/msp3400-driver.h b/drivers/media/video/msp3400-driver.h
index 831e8db4368c..fbe5e0715f93 100644
--- a/drivers/media/video/msp3400-driver.h
+++ b/drivers/media/video/msp3400-driver.h
@@ -44,10 +44,10 @@
/* module parameters */
extern int msp_debug;
-extern int msp_once;
-extern int msp_amsound;
+extern bool msp_once;
+extern bool msp_amsound;
extern int msp_standard;
-extern int msp_dolby;
+extern bool msp_dolby;
extern int msp_stereo_thresh;
struct msp_state {
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index ee0d0b39cd17..a378c2ce1273 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -70,9 +70,9 @@ static u32 video1_numbuffers = 3;
static u32 video2_numbuffers = 3;
static u32 video1_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
static u32 video2_bufsize = OMAP_VOUT_MAX_BUF_SIZE;
-static u32 vid1_static_vrfb_alloc;
-static u32 vid2_static_vrfb_alloc;
-static int debug;
+static bool vid1_static_vrfb_alloc;
+static bool vid2_static_vrfb_alloc;
+static bool debug;
/* Module parameters */
module_param(video1_numbuffers, uint, S_IRUGO);
@@ -424,7 +424,7 @@ static int omapvid_setup_overlay(struct omap_vout_device *vout,
"%s enable=%d addr=%x width=%d\n height=%d color_mode=%d\n"
"rotation=%d mirror=%d posx=%d posy=%d out_width = %d \n"
"out_height=%d rotation_type=%d screen_width=%d\n",
- __func__, info.enabled, info.paddr, info.width, info.height,
+ __func__, ovl->is_enabled(ovl), info.paddr, info.width, info.height,
info.color_mode, info.rotation, info.mirror, info.pos_x,
info.pos_y, info.out_width, info.out_height, info.rotation_type,
info.screen_width);
@@ -943,12 +943,8 @@ static int omap_vout_release(struct file *file)
/* Disable all the overlay managers connected with this interface */
for (i = 0; i < ovid->num_overlays; i++) {
struct omap_overlay *ovl = ovid->overlays[i];
- if (ovl->manager && ovl->manager->device) {
- struct omap_overlay_info info;
- ovl->get_overlay_info(ovl, &info);
- info.enabled = 0;
- ovl->set_overlay_info(ovl, &info);
- }
+ if (ovl->manager && ovl->manager->device)
+ ovl->disable(ovl);
}
/* Turn off the pipeline */
ret = omapvid_apply_changes(vout);
@@ -1668,7 +1664,6 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
if (ovl->manager && ovl->manager->device) {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
- info.enabled = 1;
info.paddr = addr;
if (ovl->set_overlay_info(ovl, &info)) {
ret = -EINVAL;
@@ -1687,6 +1682,16 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
if (ret)
v4l2_err(&vout->vid_dev->v4l2_dev, "failed to change mode\n");
+ for (j = 0; j < ovid->num_overlays; j++) {
+ struct omap_overlay *ovl = ovid->overlays[j];
+
+ if (ovl->manager && ovl->manager->device) {
+ ret = ovl->enable(ovl);
+ if (ret)
+ goto streamon_err1;
+ }
+ }
+
ret = 0;
streamon_err1:
@@ -1716,16 +1721,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j];
- if (ovl->manager && ovl->manager->device) {
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
- info.enabled = 0;
- ret = ovl->set_overlay_info(ovl, &info);
- if (ret)
- v4l2_err(&vout->vid_dev->v4l2_dev,
- "failed to update overlay info in streamoff\n");
- }
+ if (ovl->manager && ovl->manager->device)
+ ovl->disable(ovl);
}
/* Turn of the pipeline */
diff --git a/drivers/media/video/omap/omap_vout_vrfb.c b/drivers/media/video/omap/omap_vout_vrfb.c
index ebebcac49225..4be26abf6cea 100644
--- a/drivers/media/video/omap/omap_vout_vrfb.c
+++ b/drivers/media/video/omap/omap_vout_vrfb.c
@@ -84,7 +84,7 @@ void omap_vout_free_vrfb_buffers(struct omap_vout_device *vout)
}
int omap_vout_setup_vrfb_bufs(struct platform_device *pdev, int vid_num,
- u32 static_vrfb_allocation)
+ bool static_vrfb_allocation)
{
int ret = 0, i, j;
struct omap_vout_device *vout;
diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c
index 8aa058531280..6a564964853a 100644
--- a/drivers/media/video/ov7670.c
+++ b/drivers/media/video/ov7670.c
@@ -25,7 +25,7 @@ MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
MODULE_DESCRIPTION("A low-level driver for OmniVision ov7670 sensors");
MODULE_LICENSE("GPL");
-static int debug;
+static bool debug;
module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
diff --git a/drivers/media/video/saa7115.c b/drivers/media/video/saa7115.c
index 5cfdbc78b918..0ef5484696b6 100644
--- a/drivers/media/video/saa7115.c
+++ b/drivers/media/video/saa7115.c
@@ -57,7 +57,7 @@ MODULE_AUTHOR( "Maxim Yevtyushkin, Kevin Thayer, Chris Kennedy, "
"Hans Verkuil, Mauro Carvalho Chehab");
MODULE_LICENSE("GPL");
-static int debug;
+static bool debug;
module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 7025be129286..c2882fa5be85 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -75,8 +75,8 @@ MODULE_PARM_DESC(video_nr,
"\none and for every other camera."
"\n");
-static short force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
- SN9C102_FORCE_MUNMAP};
+static bool force_munmap[] = {[0 ... SN9C102_MAX_DEVICES-1] =
+ SN9C102_FORCE_MUNMAP};
module_param_array(force_munmap, bool, NULL, 0444);
MODULE_PARM_DESC(force_munmap,
" <0|1[,...]>"
diff --git a/drivers/media/video/stk-webcam.c b/drivers/media/video/stk-webcam.c
index b7fb5a5cad7e..3c61aec517ac 100644
--- a/drivers/media/video/stk-webcam.c
+++ b/drivers/media/video/stk-webcam.c
@@ -38,11 +38,11 @@
#include "stk-webcam.h"
-static int hflip = 1;
+static bool hflip = 1;
module_param(hflip, bool, 0444);
MODULE_PARM_DESC(hflip, "Horizontal image flip (mirror). Defaults to 1");
-static int vflip = 1;
+static bool vflip = 1;
module_param(vflip, bool, 0444);
MODULE_PARM_DESC(vflip, "Vertical image flip. Defaults to 1");
diff --git a/drivers/media/video/tm6000/tm6000-alsa.c b/drivers/media/video/tm6000/tm6000-alsa.c
index 7d675c72fd47..bb2047c10358 100644
--- a/drivers/media/video/tm6000/tm6000-alsa.c
+++ b/drivers/media/video/tm6000/tm6000-alsa.c
@@ -42,7 +42,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
+static bool enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable tm6000x soundcard. default enabled.");
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 926f03931156..dd26cacd0556 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -52,7 +52,7 @@
#define LOCK_RETRY_DELAY (200)
/* Debug functions */
-static int debug;
+static bool debug;
module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index 7875e80cb2ff..236c559d5f51 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -63,7 +63,7 @@ MODULE_LICENSE("GPL");
#define TVP7002_CL_MASK 0x0f
/* Debug functions */
-static int debug;
+static bool debug;
module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-2)");
diff --git a/drivers/media/video/upd64083.c b/drivers/media/video/upd64083.c
index 9bbe61700fd5..65d065aa6091 100644
--- a/drivers/media/video/upd64083.c
+++ b/drivers/media/video/upd64083.c
@@ -34,7 +34,7 @@ MODULE_DESCRIPTION("uPD64083 driver");
MODULE_AUTHOR("T. Adachi, Takeru KOMORIYA, Hans Verkuil");
MODULE_LICENSE("GPL");
-static int debug;
+static bool debug;
module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debug level (0-1)");
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index cbf13d09b4ac..bfae41ba53c3 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -34,13 +34,13 @@ MODULE_AUTHOR("Jonathan Corbet <corbet@lwn.net>");
MODULE_DESCRIPTION("VIA framebuffer-based camera controller driver");
MODULE_LICENSE("GPL");
-static int flip_image;
+static bool flip_image;
module_param(flip_image, bool, 0444);
MODULE_PARM_DESC(flip_image,
"If set, the sensor will be instructed to flip the image "
"vertically.");
-static int override_serial;
+static bool override_serial;
module_param(override_serial, bool, 0444);
MODULE_PARM_DESC(override_serial,
"The camera driver will normally refuse to load if "
diff --git a/drivers/media/video/zoran/zoran_device.c b/drivers/media/video/zoran/zoran_device.c
index e8a27844bf39..e86173bd1327 100644
--- a/drivers/media/video/zoran/zoran_device.c
+++ b/drivers/media/video/zoran/zoran_device.c
@@ -57,7 +57,7 @@
ZR36057_ISR_GIRQ1 | \
ZR36057_ISR_JPEGRepIRQ )
-static int lml33dpath; /* default = 0
+static bool lml33dpath; /* default = 0
* 1 will use digital path in capture
* mode instead of analog. It can be
* used for picture adjustments using
diff --git a/drivers/media/video/zoran/zr36060.c b/drivers/media/video/zoran/zr36060.c
index 5e4f57cbf314..f08546fe2234 100644
--- a/drivers/media/video/zoran/zr36060.c
+++ b/drivers/media/video/zoran/zr36060.c
@@ -50,7 +50,7 @@
/* amount of chips attached via this driver */
static int zr36060_codecs;
-static int low_bitrate;
+static bool low_bitrate;
module_param(low_bitrate, bool, 0);
MODULE_PARM_DESC(low_bitrate, "Buz compatibility option, halves bitrate");
diff --git a/drivers/memstick/host/jmb38x_ms.c b/drivers/memstick/host/jmb38x_ms.c
index 6ce70e9615d3..5319e9b65847 100644
--- a/drivers/memstick/host/jmb38x_ms.c
+++ b/drivers/memstick/host/jmb38x_ms.c
@@ -21,7 +21,7 @@
#define DRIVER_NAME "jmb38x_ms"
-static int no_dma;
+static bool no_dma;
module_param(no_dma, bool, 0644);
enum {
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c
index 668f5c6a0399..29b2172ae18f 100644
--- a/drivers/memstick/host/r592.c
+++ b/drivers/memstick/host/r592.c
@@ -23,7 +23,7 @@
#include <linux/swab.h>
#include "r592.h"
-static int r592_enable_dma = 1;
+static bool r592_enable_dma = 1;
static int debug;
static const char *tpc_names[] = {
diff --git a/drivers/memstick/host/tifm_ms.c b/drivers/memstick/host/tifm_ms.c
index b7aacf47703a..6902b83eb1b4 100644
--- a/drivers/memstick/host/tifm_ms.c
+++ b/drivers/memstick/host/tifm_ms.c
@@ -22,7 +22,7 @@
#define DRIVER_NAME "tifm_ms"
-static int no_dma;
+static bool no_dma;
module_param(no_dma, bool, 0644);
/*
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index e017dc88622a..f93dd9571c3c 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -12,51 +12,20 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/regmap.h>
#include <linux/mfd/88pm860x.h>
#include <linux/slab.h>
-static inline int pm860x_read_device(struct i2c_client *i2c,
- int reg, int bytes, void *dest)
-{
- unsigned char data;
- int ret;
-
- data = (unsigned char)reg;
- ret = i2c_master_send(i2c, &data, 1);
- if (ret < 0)
- return ret;
-
- ret = i2c_master_recv(i2c, dest, bytes);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static inline int pm860x_write_device(struct i2c_client *i2c,
- int reg, int bytes, void *src)
-{
- unsigned char buf[bytes + 1];
- int ret;
-
- buf[0] = (unsigned char)reg;
- memcpy(&buf[1], src, bytes);
-
- ret = i2c_master_send(i2c, buf, bytes + 1);
- if (ret < 0)
- return ret;
- return 0;
-}
-
int pm860x_reg_read(struct i2c_client *i2c, int reg)
{
struct pm860x_chip *chip = i2c_get_clientdata(i2c);
- unsigned char data;
+ struct regmap *map = (i2c == chip->client) ? chip->regmap
+ : chip->regmap_companion;
+ unsigned int data;
int ret;
- mutex_lock(&chip->io_lock);
- ret = pm860x_read_device(i2c, reg, 1, &data);
- mutex_unlock(&chip->io_lock);
-
+ ret = regmap_read(map, reg, &data);
if (ret < 0)
return ret;
else
@@ -68,12 +37,11 @@ int pm860x_reg_write(struct i2c_client *i2c, int reg,
unsigned char data)
{
struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+ struct regmap *map = (i2c == chip->client) ? chip->regmap
+ : chip->regmap_companion;
int ret;
- mutex_lock(&chip->io_lock);
- ret = pm860x_write_device(i2c, reg, 1, &data);
- mutex_unlock(&chip->io_lock);
-
+ ret = regmap_write(map, reg, data);
return ret;
}
EXPORT_SYMBOL(pm860x_reg_write);
@@ -82,12 +50,11 @@ int pm860x_bulk_read(struct i2c_client *i2c, int reg,
int count, unsigned char *buf)
{
struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+ struct regmap *map = (i2c == chip->client) ? chip->regmap
+ : chip->regmap_companion;
int ret;
- mutex_lock(&chip->io_lock);
- ret = pm860x_read_device(i2c, reg, count, buf);
- mutex_unlock(&chip->io_lock);
-
+ ret = regmap_raw_read(map, reg, buf, count);
return ret;
}
EXPORT_SYMBOL(pm860x_bulk_read);
@@ -96,12 +63,11 @@ int pm860x_bulk_write(struct i2c_client *i2c, int reg,
int count, unsigned char *buf)
{
struct pm860x_chip *chip = i2c_get_clientdata(i2c);
+ struct regmap *map = (i2c == chip->client) ? chip->regmap
+ : chip->regmap_companion;
int ret;
- mutex_lock(&chip->io_lock);
- ret = pm860x_write_device(i2c, reg, count, buf);
- mutex_unlock(&chip->io_lock);
-
+ ret = regmap_raw_write(map, reg, buf, count);
return ret;
}
EXPORT_SYMBOL(pm860x_bulk_write);
@@ -110,39 +76,78 @@ int pm860x_set_bits(struct i2c_client *i2c, int reg,
unsigned char mask, unsigned char data)
{
struct pm860x_chip *chip = i2c_get_clientdata(i2c);
- unsigned char value;
+ struct regmap *map = (i2c == chip->client) ? chip->regmap
+ : chip->regmap_companion;
int ret;
- mutex_lock(&chip->io_lock);
- ret = pm860x_read_device(i2c, reg, 1, &value);
- if (ret < 0)
- goto out;
- value &= ~mask;
- value |= data;
- ret = pm860x_write_device(i2c, reg, 1, &value);
-out:
- mutex_unlock(&chip->io_lock);
+ ret = regmap_update_bits(map, reg, mask, data);
return ret;
}
EXPORT_SYMBOL(pm860x_set_bits);
+static int read_device(struct i2c_client *i2c, int reg,
+ int bytes, void *dest)
+{
+ unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX + 3];
+ unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX + 2];
+ struct i2c_adapter *adap = i2c->adapter;
+ struct i2c_msg msg[2] = {{i2c->addr, 0, 1, msgbuf0},
+ {i2c->addr, I2C_M_RD, 0, msgbuf1},
+ };
+ int num = 1, ret = 0;
+
+ if (dest == NULL)
+ return -EINVAL;
+ msgbuf0[0] = (unsigned char)reg; /* command */
+ msg[1].len = bytes;
+
+ /* if data needs to read back, num should be 2 */
+ if (bytes > 0)
+ num = 2;
+ ret = adap->algo->master_xfer(adap, msg, num);
+ memcpy(dest, msgbuf1, bytes);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
+static int write_device(struct i2c_client *i2c, int reg,
+ int bytes, void *src)
+{
+ unsigned char buf[bytes + 1];
+ struct i2c_adapter *adap = i2c->adapter;
+ struct i2c_msg msg;
+ int ret;
+
+ buf[0] = (unsigned char)reg;
+ memcpy(&buf[1], src, bytes);
+ msg.addr = i2c->addr;
+ msg.flags = 0;
+ msg.len = bytes + 1;
+ msg.buf = buf;
+
+ ret = adap->algo->master_xfer(adap, &msg, 1);
+ if (ret < 0)
+ return ret;
+ return 0;
+}
+
int pm860x_page_reg_read(struct i2c_client *i2c, int reg)
{
- struct pm860x_chip *chip = i2c_get_clientdata(i2c);
unsigned char zero = 0;
unsigned char data;
int ret;
- mutex_lock(&chip->io_lock);
- pm860x_write_device(i2c, 0xFA, 0, &zero);
- pm860x_write_device(i2c, 0xFB, 0, &zero);
- pm860x_write_device(i2c, 0xFF, 0, &zero);
- ret = pm860x_read_device(i2c, reg, 1, &data);
+ i2c_lock_adapter(i2c->adapter);
+ read_device(i2c, 0xFA, 0, &zero);
+ read_device(i2c, 0xFB, 0, &zero);
+ read_device(i2c, 0xFF, 0, &zero);
+ ret = read_device(i2c, reg, 1, &data);
if (ret >= 0)
ret = (int)data;
- pm860x_write_device(i2c, 0xFE, 0, &zero);
- pm860x_write_device(i2c, 0xFC, 0, &zero);
- mutex_unlock(&chip->io_lock);
+ read_device(i2c, 0xFE, 0, &zero);
+ read_device(i2c, 0xFC, 0, &zero);
+ i2c_unlock_adapter(i2c->adapter);
return ret;
}
EXPORT_SYMBOL(pm860x_page_reg_read);
@@ -150,18 +155,17 @@ EXPORT_SYMBOL(pm860x_page_reg_read);
int pm860x_page_reg_write(struct i2c_client *i2c, int reg,
unsigned char data)
{
- struct pm860x_chip *chip = i2c_get_clientdata(i2c);
unsigned char zero;
int ret;
- mutex_lock(&chip->io_lock);
- pm860x_write_device(i2c, 0xFA, 0, &zero);
- pm860x_write_device(i2c, 0xFB, 0, &zero);
- pm860x_write_device(i2c, 0xFF, 0, &zero);
- ret = pm860x_write_device(i2c, reg, 1, &data);
- pm860x_write_device(i2c, 0xFE, 0, &zero);
- pm860x_write_device(i2c, 0xFC, 0, &zero);
- mutex_unlock(&chip->io_lock);
+ i2c_lock_adapter(i2c->adapter);
+ read_device(i2c, 0xFA, 0, &zero);
+ read_device(i2c, 0xFB, 0, &zero);
+ read_device(i2c, 0xFF, 0, &zero);
+ ret = write_device(i2c, reg, 1, &data);
+ read_device(i2c, 0xFE, 0, &zero);
+ read_device(i2c, 0xFC, 0, &zero);
+ i2c_unlock_adapter(i2c->adapter);
return ret;
}
EXPORT_SYMBOL(pm860x_page_reg_write);
@@ -169,18 +173,17 @@ EXPORT_SYMBOL(pm860x_page_reg_write);
int pm860x_page_bulk_read(struct i2c_client *i2c, int reg,
int count, unsigned char *buf)
{
- struct pm860x_chip *chip = i2c_get_clientdata(i2c);
unsigned char zero = 0;
int ret;
- mutex_lock(&chip->io_lock);
- pm860x_write_device(i2c, 0xFA, 0, &zero);
- pm860x_write_device(i2c, 0xFB, 0, &zero);
- pm860x_write_device(i2c, 0xFF, 0, &zero);
- ret = pm860x_read_device(i2c, reg, count, buf);
- pm860x_write_device(i2c, 0xFE, 0, &zero);
- pm860x_write_device(i2c, 0xFC, 0, &zero);
- mutex_unlock(&chip->io_lock);
+ i2c_lock_adapter(i2c->adapter);
+ read_device(i2c, 0xfa, 0, &zero);
+ read_device(i2c, 0xfb, 0, &zero);
+ read_device(i2c, 0xff, 0, &zero);
+ ret = read_device(i2c, reg, count, buf);
+ read_device(i2c, 0xFE, 0, &zero);
+ read_device(i2c, 0xFC, 0, &zero);
+ i2c_unlock_adapter(i2c->adapter);
return ret;
}
EXPORT_SYMBOL(pm860x_page_bulk_read);
@@ -188,18 +191,18 @@ EXPORT_SYMBOL(pm860x_page_bulk_read);
int pm860x_page_bulk_write(struct i2c_client *i2c, int reg,
int count, unsigned char *buf)
{
- struct pm860x_chip *chip = i2c_get_clientdata(i2c);
unsigned char zero = 0;
int ret;
- mutex_lock(&chip->io_lock);
- pm860x_write_device(i2c, 0xFA, 0, &zero);
- pm860x_write_device(i2c, 0xFB, 0, &zero);
- pm860x_write_device(i2c, 0xFF, 0, &zero);
- ret = pm860x_write_device(i2c, reg, count, buf);
- pm860x_write_device(i2c, 0xFE, 0, &zero);
- pm860x_write_device(i2c, 0xFC, 0, &zero);
- mutex_unlock(&chip->io_lock);
+ i2c_lock_adapter(i2c->adapter);
+ read_device(i2c, 0xFA, 0, &zero);
+ read_device(i2c, 0xFB, 0, &zero);
+ read_device(i2c, 0xFF, 0, &zero);
+ ret = write_device(i2c, reg, count, buf);
+ read_device(i2c, 0xFE, 0, &zero);
+ read_device(i2c, 0xFC, 0, &zero);
+ i2c_unlock_adapter(i2c->adapter);
+ i2c_unlock_adapter(i2c->adapter);
return ret;
}
EXPORT_SYMBOL(pm860x_page_bulk_write);
@@ -207,25 +210,24 @@ EXPORT_SYMBOL(pm860x_page_bulk_write);
int pm860x_page_set_bits(struct i2c_client *i2c, int reg,
unsigned char mask, unsigned char data)
{
- struct pm860x_chip *chip = i2c_get_clientdata(i2c);
unsigned char zero;
unsigned char value;
int ret;
- mutex_lock(&chip->io_lock);
- pm860x_write_device(i2c, 0xFA, 0, &zero);
- pm860x_write_device(i2c, 0xFB, 0, &zero);
- pm860x_write_device(i2c, 0xFF, 0, &zero);
- ret = pm860x_read_device(i2c, reg, 1, &value);
+ i2c_lock_adapter(i2c->adapter);
+ read_device(i2c, 0xFA, 0, &zero);
+ read_device(i2c, 0xFB, 0, &zero);
+ read_device(i2c, 0xFF, 0, &zero);
+ ret = read_device(i2c, reg, 1, &value);
if (ret < 0)
goto out;
value &= ~mask;
value |= data;
- ret = pm860x_write_device(i2c, reg, 1, &value);
+ ret = write_device(i2c, reg, 1, &value);
out:
- pm860x_write_device(i2c, 0xFE, 0, &zero);
- pm860x_write_device(i2c, 0xFC, 0, &zero);
- mutex_unlock(&chip->io_lock);
+ read_device(i2c, 0xFE, 0, &zero);
+ read_device(i2c, 0xFC, 0, &zero);
+ i2c_unlock_adapter(i2c->adapter);
return ret;
}
EXPORT_SYMBOL(pm860x_page_set_bits);
@@ -257,11 +259,17 @@ static int verify_addr(struct i2c_client *i2c)
return 0;
}
+static struct regmap_config pm860x_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
static int __devinit pm860x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct pm860x_platform_data *pdata = client->dev.platform_data;
struct pm860x_chip *chip;
+ int ret;
if (!pdata) {
pr_info("No platform data in %s!\n", __func__);
@@ -273,10 +281,17 @@ static int __devinit pm860x_probe(struct i2c_client *client,
return -ENOMEM;
chip->id = verify_addr(client);
+ chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
+ if (IS_ERR(chip->regmap)) {
+ ret = PTR_ERR(chip->regmap);
+ dev_err(&client->dev, "Failed to allocate register map: %d\n",
+ ret);
+ kfree(chip);
+ return ret;
+ }
chip->client = client;
i2c_set_clientdata(client, chip);
chip->dev = &client->dev;
- mutex_init(&chip->io_lock);
dev_set_drvdata(chip->dev, chip);
/*
@@ -290,6 +305,14 @@ static int __devinit pm860x_probe(struct i2c_client *client,
chip->companion_addr = pdata->companion_addr;
chip->companion = i2c_new_dummy(chip->client->adapter,
chip->companion_addr);
+ chip->regmap_companion = regmap_init_i2c(chip->companion,
+ &pm860x_regmap_config);
+ if (IS_ERR(chip->regmap_companion)) {
+ ret = PTR_ERR(chip->regmap_companion);
+ dev_err(&chip->companion->dev,
+ "Failed to allocate register map: %d\n", ret);
+ return ret;
+ }
i2c_set_clientdata(chip->companion, chip);
}
@@ -302,7 +325,11 @@ static int __devexit pm860x_remove(struct i2c_client *client)
struct pm860x_chip *chip = i2c_get_clientdata(client);
pm860x_device_exit(chip);
- i2c_unregister_device(chip->companion);
+ if (chip->companion) {
+ regmap_exit(chip->regmap_companion);
+ i2c_unregister_device(chip->companion);
+ }
+ regmap_exit(chip->regmap);
kfree(chip);
return 0;
}
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 053208d31fb9..cd13e9f2f5e6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -12,6 +12,7 @@ config MFD_CORE
config MFD_88PM860X
bool "Support Marvell 88PM8606/88PM8607"
depends on I2C=y && GENERIC_HARDIRQS
+ select REGMAP_I2C
select MFD_CORE
help
This supports for Marvell 88PM8606/88PM8607 Power Management IC.
@@ -199,7 +200,7 @@ config MENELAUS
config TWL4030_CORE
bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support"
- depends on I2C=y && GENERIC_HARDIRQS
+ depends on I2C=y && GENERIC_HARDIRQS && 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
@@ -257,7 +258,7 @@ config TWL6040_CORE
config MFD_STMPE
bool "Support STMicroelectronics STMPE"
- depends on I2C=y && GENERIC_HARDIRQS
+ depends on (I2C=y || SPI_MASTER=y) && GENERIC_HARDIRQS
select MFD_CORE
help
Support for the STMPE family of I/O Expanders from
@@ -278,6 +279,23 @@ config MFD_STMPE
Keypad: stmpe-keypad
Touchscreen: stmpe-ts
+menu "STMPE Interface Drivers"
+depends on MFD_STMPE
+
+config STMPE_I2C
+ bool "STMPE I2C Inteface"
+ depends on I2C=y
+ default y
+ help
+ This is used to enable I2C interface of STMPE
+
+config STMPE_SPI
+ bool "STMPE SPI Inteface"
+ depends on SPI_MASTER
+ help
+ This is used to enable SPI interface of STMPE
+endmenu
+
config MFD_TC3589X
bool "Support Toshiba TC35892 and variants"
depends on I2C=y && GENERIC_HARDIRQS
@@ -311,7 +329,7 @@ config MFD_TC6387XB
config MFD_TC6393XB
bool "Support Toshiba TC6393XB"
- depends on GPIOLIB && ARM
+ depends on GPIOLIB && ARM && HAVE_CLK
select MFD_CORE
select MFD_TMIO
help
@@ -399,6 +417,17 @@ config MFD_MAX8998
additional drivers must be enabled in order to use the functionality
of the device.
+config MFD_S5M_CORE
+ bool "SAMSUNG S5M Series Support"
+ depends on I2C=y && GENERIC_HARDIRQS
+ select MFD_CORE
+ select REGMAP_I2C
+ help
+ Support for the Samsung Electronics S5M MFD series.
+ This driver provies common support for accessing the device,
+ additional drivers must be enabled in order to use the functionality
+ of the device
+
config MFD_WM8400
tristate "Support Wolfson Microelectronics WM8400"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 47591fc7d0d2..b953bab934f7 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -16,6 +16,8 @@ obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o
obj-$(CONFIG_MFD_STMPE) += stmpe.o
+obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o
+obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o
obj-$(CONFIG_MFD_TC3589X) += tc3589x.o
obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o
obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o
@@ -109,3 +111,4 @@ obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
+obj-$(CONFIG_MFD_S5M_CORE) += s5m-core.o s5m-irq.o
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c
index 02c42015ba51..3aa36eb5c79b 100644
--- a/drivers/mfd/aat2870-core.c
+++ b/drivers/mfd/aat2870-core.c
@@ -407,13 +407,13 @@ static int aat2870_i2c_probe(struct i2c_client *client,
aat2870->init(aat2870);
if (aat2870->en_pin >= 0) {
- ret = gpio_request(aat2870->en_pin, "aat2870-en");
+ ret = gpio_request_one(aat2870->en_pin, GPIOF_OUT_INIT_HIGH,
+ "aat2870-en");
if (ret < 0) {
dev_err(&client->dev,
"Failed to request GPIO %d\n", aat2870->en_pin);
goto out_kfree;
}
- gpio_direction_output(aat2870->en_pin, 1);
}
aat2870_enable(aat2870);
@@ -468,9 +468,10 @@ static int aat2870_i2c_remove(struct i2c_client *client)
return 0;
}
-#ifdef CONFIG_PM
-static int aat2870_i2c_suspend(struct i2c_client *client, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int aat2870_i2c_suspend(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct aat2870_data *aat2870 = i2c_get_clientdata(client);
aat2870_disable(aat2870);
@@ -478,8 +479,9 @@ static int aat2870_i2c_suspend(struct i2c_client *client, pm_message_t state)
return 0;
}
-static int aat2870_i2c_resume(struct i2c_client *client)
+static int aat2870_i2c_resume(struct device *dev)
{
+ struct i2c_client *client = to_i2c_client(dev);
struct aat2870_data *aat2870 = i2c_get_clientdata(client);
struct aat2870_register *reg = NULL;
int i;
@@ -495,12 +497,12 @@ static int aat2870_i2c_resume(struct i2c_client *client)
return 0;
}
-#else
-#define aat2870_i2c_suspend NULL
-#define aat2870_i2c_resume NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(aat2870_pm_ops, aat2870_i2c_suspend,
+ aat2870_i2c_resume);
-static struct i2c_device_id aat2870_i2c_id_table[] = {
+static const struct i2c_device_id aat2870_i2c_id_table[] = {
{ "aat2870", 0 },
{ }
};
@@ -510,11 +512,10 @@ static struct i2c_driver aat2870_i2c_driver = {
.driver = {
.name = "aat2870",
.owner = THIS_MODULE,
+ .pm = &aat2870_pm_ops,
},
.probe = aat2870_i2c_probe,
.remove = aat2870_i2c_remove,
- .suspend = aat2870_i2c_suspend,
- .resume = aat2870_i2c_resume,
.id_table = aat2870_i2c_id_table,
};
diff --git a/drivers/mfd/ab5500-core.c b/drivers/mfd/ab5500-core.c
index ec10629a0b0b..bd56a764dea1 100644
--- a/drivers/mfd/ab5500-core.c
+++ b/drivers/mfd/ab5500-core.c
@@ -22,8 +22,8 @@
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/random.h>
-#include <linux/mfd/ab5500/ab5500.h>
#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab5500.h>
#include <linux/list.h>
#include <linux/bitops.h>
#include <linux/spinlock.h>
diff --git a/drivers/mfd/ab5500-debugfs.c b/drivers/mfd/ab5500-debugfs.c
index b7b2d3483fd4..72006940937a 100644
--- a/drivers/mfd/ab5500-debugfs.c
+++ b/drivers/mfd/ab5500-debugfs.c
@@ -7,8 +7,8 @@
#include <linux/module.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
-#include <linux/mfd/ab5500/ab5500.h>
#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab5500.h>
#include <linux/uaccess.h>
#include "ab5500-core.h"
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index d3d572b2317b..53e2a80f42fa 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -17,7 +17,7 @@
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/abx500.h>
-#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <linux/regulator/ab8500.h>
/*
diff --git a/drivers/mfd/ab8500-debugfs.c b/drivers/mfd/ab8500-debugfs.c
index dedb7f65cea6..9a0211aa8897 100644
--- a/drivers/mfd/ab8500-debugfs.c
+++ b/drivers/mfd/ab8500-debugfs.c
@@ -13,7 +13,7 @@
#include <linux/platform_device.h>
#include <linux/mfd/abx500.h>
-#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500/ab8500.h>
static u32 debug_bank;
static u32 debug_address;
diff --git a/drivers/mfd/ab8500-gpadc.c b/drivers/mfd/ab8500-gpadc.c
index e985d1701a83..c39fc716e1dc 100644
--- a/drivers/mfd/ab8500-gpadc.c
+++ b/drivers/mfd/ab8500-gpadc.c
@@ -18,9 +18,9 @@
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/list.h>
-#include <linux/mfd/ab8500.h>
#include <linux/mfd/abx500.h>
-#include <linux/mfd/ab8500/gpadc.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-gpadc.h>
/*
* GPADC register offsets
diff --git a/drivers/mfd/ab8500-i2c.c b/drivers/mfd/ab8500-i2c.c
index 9be541c6b004..087fecd71ce0 100644
--- a/drivers/mfd/ab8500-i2c.c
+++ b/drivers/mfd/ab8500-i2c.c
@@ -10,7 +10,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/db8500-prcmu.h>
static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
diff --git a/drivers/mfd/ab8500-sysctrl.c b/drivers/mfd/ab8500-sysctrl.c
index f20feefac190..c28d4eb1eff0 100644
--- a/drivers/mfd/ab8500-sysctrl.c
+++ b/drivers/mfd/ab8500-sysctrl.c
@@ -7,9 +7,9 @@
#include <linux/err.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/mfd/ab8500.h>
#include <linux/mfd/abx500.h>
-#include <linux/mfd/ab8500/sysctrl.h>
+#include <linux/mfd/abx500/ab8500.h>
+#include <linux/mfd/abx500/ab8500-sysctrl.h>
static struct device *sysctrl_dev;
diff --git a/drivers/mfd/cs5535-mfd.c b/drivers/mfd/cs5535-mfd.c
index 155fa0407882..315fef5d466a 100644
--- a/drivers/mfd/cs5535-mfd.c
+++ b/drivers/mfd/cs5535-mfd.c
@@ -172,14 +172,14 @@ static void __devexit cs5535_mfd_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-static struct pci_device_id cs5535_mfd_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(cs5535_mfd_pci_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, cs5535_mfd_pci_tbl);
-static struct pci_driver cs5535_mfd_drv = {
+static struct pci_driver cs5535_mfd_driver = {
.name = DRV_NAME,
.id_table = cs5535_mfd_pci_tbl,
.probe = cs5535_mfd_probe,
@@ -188,12 +188,12 @@ static struct pci_driver cs5535_mfd_drv = {
static int __init cs5535_mfd_init(void)
{
- return pci_register_driver(&cs5535_mfd_drv);
+ return pci_register_driver(&cs5535_mfd_driver);
}
static void __exit cs5535_mfd_exit(void)
{
- pci_unregister_driver(&cs5535_mfd_drv);
+ pci_unregister_driver(&cs5535_mfd_driver);
}
module_init(cs5535_mfd_init);
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 8ad88da647b9..7710227d284e 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -308,8 +308,7 @@ static int add_children(struct i2c_client *client)
for (i = 0; i < ARRAY_SIZE(config_inputs); i++) {
int gpio = dm355evm_msp_gpio.base + config_inputs[i].offset;
- gpio_request(gpio, config_inputs[i].label);
- gpio_direction_input(gpio);
+ gpio_request_one(gpio, GPIOF_IN, config_inputs[i].label);
/* make it easy for userspace to see these */
gpio_export(gpio, false);
diff --git a/drivers/mfd/intel_msic.c b/drivers/mfd/intel_msic.c
index 97c27762174f..b76657eb0c51 100644
--- a/drivers/mfd/intel_msic.c
+++ b/drivers/mfd/intel_msic.c
@@ -485,17 +485,7 @@ static struct platform_driver intel_msic_driver = {
},
};
-static int __init intel_msic_init(void)
-{
- return platform_driver_register(&intel_msic_driver);
-}
-module_init(intel_msic_init);
-
-static void __exit intel_msic_exit(void)
-{
- platform_driver_unregister(&intel_msic_driver);
-}
-module_exit(intel_msic_exit);
+module_platform_driver(intel_msic_driver);
MODULE_DESCRIPTION("Driver for Intel MSIC");
MODULE_AUTHOR("Mika Westerberg <mika.westerberg@linux.intel.com>");
diff --git a/drivers/mfd/janz-cmodio.c b/drivers/mfd/janz-cmodio.c
index 5c2a06acb77f..a9223ed1b7c5 100644
--- a/drivers/mfd/janz-cmodio.c
+++ b/drivers/mfd/janz-cmodio.c
@@ -33,7 +33,7 @@
/* Module Parameters */
static unsigned int num_modules = CMODIO_MAX_MODULES;
-static unsigned char *modules[CMODIO_MAX_MODULES] = {
+static char *modules[CMODIO_MAX_MODULES] = {
"empty", "empty", "empty", "empty",
};
diff --git a/drivers/mfd/jz4740-adc.c b/drivers/mfd/jz4740-adc.c
index ef39528088f2..87662a17dec6 100644
--- a/drivers/mfd/jz4740-adc.c
+++ b/drivers/mfd/jz4740-adc.c
@@ -181,7 +181,7 @@ static struct resource jz4740_battery_resources[] = {
},
};
-const struct mfd_cell jz4740_adc_cells[] = {
+static struct mfd_cell jz4740_adc_cells[] = {
{
.id = 0,
.name = "jz4740-hwmon",
@@ -338,17 +338,7 @@ static struct platform_driver jz4740_adc_driver = {
},
};
-static int __init jz4740_adc_init(void)
-{
- return platform_driver_register(&jz4740_adc_driver);
-}
-module_init(jz4740_adc_init);
-
-static void __exit jz4740_adc_exit(void)
-{
- platform_driver_unregister(&jz4740_adc_driver);
-}
-module_exit(jz4740_adc_exit);
+module_platform_driver(jz4740_adc_driver);
MODULE_DESCRIPTION("JZ4740 SoC ADC driver");
MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
diff --git a/drivers/mfd/lpc_sch.c b/drivers/mfd/lpc_sch.c
index ea1169b04779..abc421364a45 100644
--- a/drivers/mfd/lpc_sch.c
+++ b/drivers/mfd/lpc_sch.c
@@ -74,7 +74,7 @@ static struct mfd_cell tunnelcreek_cells[] = {
},
};
-static struct pci_device_id lpc_sch_ids[] = {
+static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) },
{ 0, }
diff --git a/drivers/mfd/max8925-i2c.c b/drivers/mfd/max8925-i2c.c
index 0219115e00c7..d9e4b36edee9 100644
--- a/drivers/mfd/max8925-i2c.c
+++ b/drivers/mfd/max8925-i2c.c
@@ -161,6 +161,8 @@ static int __devinit max8925_probe(struct i2c_client *client,
chip->adc = i2c_new_dummy(chip->i2c->adapter, ADC_I2C_ADDR);
i2c_set_clientdata(chip->adc, chip);
+ device_init_wakeup(&client->dev, 1);
+
max8925_device_init(chip, pdata);
return 0;
@@ -177,10 +179,35 @@ static int __devexit max8925_remove(struct i2c_client *client)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int max8925_suspend(struct device *dev)
+{
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ struct max8925_chip *chip = i2c_get_clientdata(client);
+
+ if (device_may_wakeup(dev) && chip->wakeup_flag)
+ enable_irq_wake(chip->core_irq);
+ return 0;
+}
+
+static int max8925_resume(struct device *dev)
+{
+ struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+ struct max8925_chip *chip = i2c_get_clientdata(client);
+
+ if (device_may_wakeup(dev) && chip->wakeup_flag)
+ disable_irq_wake(chip->core_irq);
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(max8925_pm_ops, max8925_suspend, max8925_resume);
+
static struct i2c_driver max8925_driver = {
.driver = {
.name = "max8925",
.owner = THIS_MODULE,
+ .pm = &max8925_pm_ops,
},
.probe = max8925_probe,
.remove = __devexit_p(max8925_remove),
diff --git a/drivers/mfd/max8997.c b/drivers/mfd/max8997.c
index 5be53ae9b61c..cb83a7ab53e7 100644
--- a/drivers/mfd/max8997.c
+++ b/drivers/mfd/max8997.c
@@ -43,7 +43,8 @@ static struct mfd_cell max8997_devs[] = {
{ .name = "max8997-battery", },
{ .name = "max8997-haptic", },
{ .name = "max8997-muic", },
- { .name = "max8997-flash", },
+ { .name = "max8997-led", .id = 1 },
+ { .name = "max8997-led", .id = 2 },
};
int max8997_read_reg(struct i2c_client *i2c, u8 reg, u8 *dest)
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c
index de4096aee248..6ef56d28c056 100644
--- a/drivers/mfd/max8998.c
+++ b/drivers/mfd/max8998.c
@@ -176,6 +176,8 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
if (ret < 0)
goto err;
+ device_init_wakeup(max8998->dev, max8998->wakeup);
+
return ret;
err:
@@ -210,7 +212,7 @@ static int max8998_suspend(struct device *dev)
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
- if (max8998->wakeup)
+ if (device_may_wakeup(dev))
irq_set_irq_wake(max8998->irq, 1);
return 0;
}
@@ -220,7 +222,7 @@ static int max8998_resume(struct device *dev)
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
- if (max8998->wakeup)
+ if (device_may_wakeup(dev))
irq_set_irq_wake(max8998->irq, 0);
/*
* In LP3974, if IRQ registers are not "read & clear"
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index e9619acc0237..7122386b4e3c 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -18,11 +18,15 @@
#include <linux/spi/spi.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mc13xxx.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/of_gpio.h>
struct mc13xxx {
struct spi_device *spidev;
struct mutex lock;
int irq;
+ int flags;
irq_handler_t irqhandler[MC13XXX_NUM_IRQ];
void *irqdata[MC13XXX_NUM_IRQ];
@@ -550,10 +554,7 @@ static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx)
int mc13xxx_get_flags(struct mc13xxx *mc13xxx)
{
- struct mc13xxx_platform_data *pdata =
- dev_get_platdata(&mc13xxx->spidev->dev);
-
- return pdata->flags;
+ return mc13xxx->flags;
}
EXPORT_SYMBOL(mc13xxx_get_flags);
@@ -615,13 +616,13 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode,
break;
case MC13XXX_ADC_MODE_SINGLE_CHAN:
- adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK;
+ adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK;
adc1 |= (channel & 0x7) << MC13XXX_ADC1_CHAN0_SHIFT;
adc1 |= MC13XXX_ADC1_RAND;
break;
case MC13XXX_ADC_MODE_MULT_CHAN:
- adc0 |= old_adc0 & MC13XXX_ADC0_TSMOD_MASK;
+ adc0 |= old_adc0 & MC13XXX_ADC0_CONFIG_MASK;
adc1 |= 4 << MC13XXX_ADC1_CHAN1_SHIFT;
break;
@@ -696,17 +697,67 @@ static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format)
return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0);
}
+#ifdef CONFIG_OF
+static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx)
+{
+ struct device_node *np = mc13xxx->spidev->dev.of_node;
+
+ if (!np)
+ return -ENODEV;
+
+ if (of_get_property(np, "fsl,mc13xxx-uses-adc", NULL))
+ mc13xxx->flags |= MC13XXX_USE_ADC;
+
+ if (of_get_property(np, "fsl,mc13xxx-uses-codec", NULL))
+ mc13xxx->flags |= MC13XXX_USE_CODEC;
+
+ if (of_get_property(np, "fsl,mc13xxx-uses-rtc", NULL))
+ mc13xxx->flags |= MC13XXX_USE_RTC;
+
+ if (of_get_property(np, "fsl,mc13xxx-uses-touch", NULL))
+ mc13xxx->flags |= MC13XXX_USE_TOUCHSCREEN;
+
+ return 0;
+}
+#else
+static inline int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx)
+{
+ return -ENODEV;
+}
+#endif
+
+static const struct spi_device_id mc13xxx_device_id[] = {
+ {
+ .name = "mc13783",
+ .driver_data = MC13XXX_ID_MC13783,
+ }, {
+ .name = "mc13892",
+ .driver_data = MC13XXX_ID_MC13892,
+ }, {
+ /* sentinel */
+ }
+};
+MODULE_DEVICE_TABLE(spi, mc13xxx_device_id);
+
+static const struct of_device_id mc13xxx_dt_ids[] = {
+ { .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, },
+ { .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, },
+ { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids);
+
static int mc13xxx_probe(struct spi_device *spi)
{
+ const struct of_device_id *of_id;
+ struct spi_driver *sdrv = to_spi_driver(spi->dev.driver);
struct mc13xxx *mc13xxx;
struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev);
enum mc13xxx_id id;
int ret;
- if (!pdata) {
- dev_err(&spi->dev, "invalid platform data\n");
- return -EINVAL;
- }
+ of_id = of_match_device(mc13xxx_dt_ids, &spi->dev);
+ if (of_id)
+ sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data];
mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL);
if (!mc13xxx)
@@ -749,28 +800,33 @@ err_revision:
mc13xxx_unlock(mc13xxx);
- if (pdata->flags & MC13XXX_USE_ADC)
+ if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata)
+ mc13xxx->flags = pdata->flags;
+
+ if (mc13xxx->flags & MC13XXX_USE_ADC)
mc13xxx_add_subdevice(mc13xxx, "%s-adc");
- if (pdata->flags & MC13XXX_USE_CODEC)
+ if (mc13xxx->flags & MC13XXX_USE_CODEC)
mc13xxx_add_subdevice(mc13xxx, "%s-codec");
- mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
- &pdata->regulators, sizeof(pdata->regulators));
-
- if (pdata->flags & MC13XXX_USE_RTC)
+ if (mc13xxx->flags & MC13XXX_USE_RTC)
mc13xxx_add_subdevice(mc13xxx, "%s-rtc");
- if (pdata->flags & MC13XXX_USE_TOUCHSCREEN)
+ if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN)
mc13xxx_add_subdevice(mc13xxx, "%s-ts");
- if (pdata->leds)
+ if (pdata) {
+ mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator",
+ &pdata->regulators, sizeof(pdata->regulators));
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led",
pdata->leds, sizeof(*pdata->leds));
-
- if (pdata->buttons)
mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton",
pdata->buttons, sizeof(*pdata->buttons));
+ } else {
+ mc13xxx_add_subdevice(mc13xxx, "%s-regulator");
+ mc13xxx_add_subdevice(mc13xxx, "%s-led");
+ mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton");
+ }
return 0;
}
@@ -788,25 +844,12 @@ static int __devexit mc13xxx_remove(struct spi_device *spi)
return 0;
}
-static const struct spi_device_id mc13xxx_device_id[] = {
- {
- .name = "mc13783",
- .driver_data = MC13XXX_ID_MC13783,
- }, {
- .name = "mc13892",
- .driver_data = MC13XXX_ID_MC13892,
- }, {
- /* sentinel */
- }
-};
-MODULE_DEVICE_TABLE(spi, mc13xxx_device_id);
-
static struct spi_driver mc13xxx_driver = {
.id_table = mc13xxx_device_id,
.driver = {
.name = "mc13xxx",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
+ .of_match_table = mc13xxx_dt_ids,
},
.probe = mc13xxx_probe,
.remove = __devexit_p(mc13xxx_remove),
diff --git a/drivers/mfd/mcp-core.c b/drivers/mfd/mcp-core.c
index 84815f9ef636..63be60bc3455 100644
--- a/drivers/mfd/mcp-core.c
+++ b/drivers/mfd/mcp-core.c
@@ -26,9 +26,35 @@
#define to_mcp(d) container_of(d, struct mcp, attached_device)
#define to_mcp_driver(d) container_of(d, struct mcp_driver, drv)
+static const struct mcp_device_id *mcp_match_id(const struct mcp_device_id *id,
+ const char *codec)
+{
+ while (id->name[0]) {
+ if (strcmp(codec, id->name) == 0)
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
+const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp)
+{
+ const struct mcp_driver *driver =
+ to_mcp_driver(mcp->attached_device.driver);
+
+ return mcp_match_id(driver->id_table, mcp->codec);
+}
+EXPORT_SYMBOL(mcp_get_device_id);
+
static int mcp_bus_match(struct device *dev, struct device_driver *drv)
{
- return 1;
+ const struct mcp *mcp = to_mcp(dev);
+ const struct mcp_driver *driver = to_mcp_driver(drv);
+
+ if (driver->id_table)
+ return !!mcp_match_id(driver->id_table, mcp->codec);
+
+ return 0;
}
static int mcp_bus_probe(struct device *dev)
@@ -74,9 +100,18 @@ static int mcp_bus_resume(struct device *dev)
return ret;
}
+static int mcp_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+ struct mcp *mcp = to_mcp(dev);
+
+ add_uevent_var(env, "MODALIAS=%s%s", MCP_MODULE_PREFIX, mcp->codec);
+ return 0;
+}
+
static struct bus_type mcp_bus_type = {
.name = "mcp",
.match = mcp_bus_match,
+ .uevent = mcp_bus_uevent,
.probe = mcp_bus_probe,
.remove = mcp_bus_remove,
.suspend = mcp_bus_suspend,
@@ -212,9 +247,14 @@ struct mcp *mcp_host_alloc(struct device *parent, size_t size)
}
EXPORT_SYMBOL(mcp_host_alloc);
-int mcp_host_register(struct mcp *mcp)
+int mcp_host_register(struct mcp *mcp, void *pdata)
{
+ if (!mcp->codec)
+ return -EINVAL;
+
+ mcp->attached_device.platform_data = pdata;
dev_set_name(&mcp->attached_device, "mcp0");
+ request_module("%s%s", MCP_MODULE_PREFIX, mcp->codec);
return device_register(&mcp->attached_device);
}
EXPORT_SYMBOL(mcp_host_register);
diff --git a/drivers/mfd/mcp-sa11x0.c b/drivers/mfd/mcp-sa11x0.c
index 2dab02d9ac8b..9adc2eb69492 100644
--- a/drivers/mfd/mcp-sa11x0.c
+++ b/drivers/mfd/mcp-sa11x0.c
@@ -19,6 +19,7 @@
#include <linux/spinlock.h>
#include <linux/platform_device.h>
#include <linux/mfd/mcp.h>
+#include <linux/io.h>
#include <mach/dma.h>
#include <mach/hardware.h>
@@ -26,12 +27,19 @@
#include <asm/system.h>
#include <mach/mcp.h>
-#include <mach/assabet.h>
-
+/* Register offsets */
+#define MCCR0 0x00
+#define MCDR0 0x08
+#define MCDR1 0x0C
+#define MCDR2 0x10
+#define MCSR 0x18
+#define MCCR1 0x00
struct mcp_sa11x0 {
- u32 mccr0;
- u32 mccr1;
+ u32 mccr0;
+ u32 mccr1;
+ unsigned char *mccr0_base;
+ unsigned char *mccr1_base;
};
#define priv(mcp) ((struct mcp_sa11x0 *)mcp_priv(mcp))
@@ -39,25 +47,25 @@ struct mcp_sa11x0 {
static void
mcp_sa11x0_set_telecom_divisor(struct mcp *mcp, unsigned int divisor)
{
- unsigned int mccr0;
+ struct mcp_sa11x0 *priv = priv(mcp);
divisor /= 32;
- mccr0 = Ser4MCCR0 & ~0x00007f00;
- mccr0 |= divisor << 8;
- Ser4MCCR0 = mccr0;
+ priv->mccr0 &= ~0x00007f00;
+ priv->mccr0 |= divisor << 8;
+ __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
}
static void
mcp_sa11x0_set_audio_divisor(struct mcp *mcp, unsigned int divisor)
{
- unsigned int mccr0;
+ struct mcp_sa11x0 *priv = priv(mcp);
divisor /= 32;
- mccr0 = Ser4MCCR0 & ~0x0000007f;
- mccr0 |= divisor;
- Ser4MCCR0 = mccr0;
+ priv->mccr0 &= ~0x0000007f;
+ priv->mccr0 |= divisor;
+ __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
}
/*
@@ -71,12 +79,16 @@ mcp_sa11x0_write(struct mcp *mcp, unsigned int reg, unsigned int val)
{
int ret = -ETIME;
int i;
+ u32 mcpreg;
+ struct mcp_sa11x0 *priv = priv(mcp);
- Ser4MCDR2 = reg << 17 | MCDR2_Wr | (val & 0xffff);
+ mcpreg = reg << 17 | MCDR2_Wr | (val & 0xffff);
+ __raw_writel(mcpreg, priv->mccr0_base + MCDR2);
for (i = 0; i < 2; i++) {
udelay(mcp->rw_timeout);
- if (Ser4MCSR & MCSR_CWC) {
+ mcpreg = __raw_readl(priv->mccr0_base + MCSR);
+ if (mcpreg & MCSR_CWC) {
ret = 0;
break;
}
@@ -97,13 +109,18 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
{
int ret = -ETIME;
int i;
+ u32 mcpreg;
+ struct mcp_sa11x0 *priv = priv(mcp);
- Ser4MCDR2 = reg << 17 | MCDR2_Rd;
+ mcpreg = reg << 17 | MCDR2_Rd;
+ __raw_writel(mcpreg, priv->mccr0_base + MCDR2);
for (i = 0; i < 2; i++) {
udelay(mcp->rw_timeout);
- if (Ser4MCSR & MCSR_CRC) {
- ret = Ser4MCDR2 & 0xffff;
+ mcpreg = __raw_readl(priv->mccr0_base + MCSR);
+ if (mcpreg & MCSR_CRC) {
+ ret = __raw_readl(priv->mccr0_base + MCDR2)
+ & 0xffff;
break;
}
}
@@ -116,13 +133,19 @@ mcp_sa11x0_read(struct mcp *mcp, unsigned int reg)
static void mcp_sa11x0_enable(struct mcp *mcp)
{
- Ser4MCSR = -1;
- Ser4MCCR0 |= MCCR0_MCE;
+ struct mcp_sa11x0 *priv = priv(mcp);
+
+ __raw_writel(-1, priv->mccr0_base + MCSR);
+ priv->mccr0 |= MCCR0_MCE;
+ __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
}
static void mcp_sa11x0_disable(struct mcp *mcp)
{
- Ser4MCCR0 &= ~MCCR0_MCE;
+ struct mcp_sa11x0 *priv = priv(mcp);
+
+ priv->mccr0 &= ~MCCR0_MCE;
+ __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
}
/*
@@ -142,50 +165,69 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
struct mcp_plat_data *data = pdev->dev.platform_data;
struct mcp *mcp;
int ret;
+ struct mcp_sa11x0 *priv;
+ struct resource *res_mem0, *res_mem1;
+ u32 size0, size1;
if (!data)
return -ENODEV;
- if (!request_mem_region(0x80060000, 0x60, "sa11x0-mcp"))
+ if (!data->codec)
+ return -ENODEV;
+
+ res_mem0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res_mem0)
+ return -ENODEV;
+ size0 = res_mem0->end - res_mem0->start + 1;
+
+ res_mem1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!res_mem1)
+ return -ENODEV;
+ size1 = res_mem1->end - res_mem1->start + 1;
+
+ if (!request_mem_region(res_mem0->start, size0, "sa11x0-mcp"))
return -EBUSY;
+ if (!request_mem_region(res_mem1->start, size1, "sa11x0-mcp")) {
+ ret = -EBUSY;
+ goto release;
+ }
+
mcp = mcp_host_alloc(&pdev->dev, sizeof(struct mcp_sa11x0));
if (!mcp) {
ret = -ENOMEM;
- goto release;
+ goto release2;
}
+ priv = priv(mcp);
+
mcp->owner = THIS_MODULE;
mcp->ops = &mcp_sa11x0;
mcp->sclk_rate = data->sclk_rate;
- mcp->dma_audio_rd = DMA_Ser4MCP0Rd;
- mcp->dma_audio_wr = DMA_Ser4MCP0Wr;
- mcp->dma_telco_rd = DMA_Ser4MCP1Rd;
- mcp->dma_telco_wr = DMA_Ser4MCP1Wr;
- mcp->gpio_base = data->gpio_base;
+ mcp->dma_audio_rd = DDAR_DevAdd(res_mem0->start + MCDR0)
+ + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev;
+ mcp->dma_audio_wr = DDAR_DevAdd(res_mem0->start + MCDR0)
+ + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev;
+ mcp->dma_telco_rd = DDAR_DevAdd(res_mem0->start + MCDR1)
+ + DDAR_DevRd + DDAR_Brst4 + DDAR_8BitDev;
+ mcp->dma_telco_wr = DDAR_DevAdd(res_mem0->start + MCDR1)
+ + DDAR_DevWr + DDAR_Brst4 + DDAR_8BitDev;
+ mcp->codec = data->codec;
platform_set_drvdata(pdev, mcp);
- if (machine_is_assabet()) {
- ASSABET_BCR_set(ASSABET_BCR_CODEC_RST);
- }
-
- /*
- * Setup the PPC unit correctly.
- */
- PPDR &= ~PPC_RXD4;
- PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
- PSDR |= PPC_RXD4;
- PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
- PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
-
/*
* Initialise device. Note that we initially
* set the sampling rate to minimum.
*/
- Ser4MCSR = -1;
- Ser4MCCR1 = data->mccr1;
- Ser4MCCR0 = data->mccr0 | 0x7f7f;
+ priv->mccr0_base = ioremap(res_mem0->start, size0);
+ priv->mccr1_base = ioremap(res_mem1->start, size1);
+
+ __raw_writel(-1, priv->mccr0_base + MCSR);
+ priv->mccr1 = data->mccr1;
+ priv->mccr0 = data->mccr0 | 0x7f7f;
+ __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
+ __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1);
/*
* Calculate the read/write timeout (us) from the bit clock
@@ -195,36 +237,53 @@ static int mcp_sa11x0_probe(struct platform_device *pdev)
mcp->rw_timeout = (64 * 3 * 1000000 + mcp->sclk_rate - 1) /
mcp->sclk_rate;
- ret = mcp_host_register(mcp);
+ ret = mcp_host_register(mcp, data->codec_pdata);
if (ret == 0)
goto out;
+ release2:
+ release_mem_region(res_mem1->start, size1);
release:
- release_mem_region(0x80060000, 0x60);
+ release_mem_region(res_mem0->start, size0);
platform_set_drvdata(pdev, NULL);
out:
return ret;
}
-static int mcp_sa11x0_remove(struct platform_device *dev)
+static int mcp_sa11x0_remove(struct platform_device *pdev)
{
- struct mcp *mcp = platform_get_drvdata(dev);
+ struct mcp *mcp = platform_get_drvdata(pdev);
+ struct mcp_sa11x0 *priv = priv(mcp);
+ struct resource *res_mem;
+ u32 size;
- platform_set_drvdata(dev, NULL);
+ platform_set_drvdata(pdev, NULL);
mcp_host_unregister(mcp);
- release_mem_region(0x80060000, 0x60);
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res_mem) {
+ size = res_mem->end - res_mem->start + 1;
+ release_mem_region(res_mem->start, size);
+ }
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res_mem) {
+ size = res_mem->end - res_mem->start + 1;
+ release_mem_region(res_mem->start, size);
+ }
+ iounmap(priv->mccr0_base);
+ iounmap(priv->mccr1_base);
return 0;
}
static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
{
struct mcp *mcp = platform_get_drvdata(dev);
+ struct mcp_sa11x0 *priv = priv(mcp);
+ u32 mccr0;
- priv(mcp)->mccr0 = Ser4MCCR0;
- priv(mcp)->mccr1 = Ser4MCCR1;
- Ser4MCCR0 &= ~MCCR0_MCE;
+ mccr0 = priv->mccr0 & ~MCCR0_MCE;
+ __raw_writel(mccr0, priv->mccr0_base + MCCR0);
return 0;
}
@@ -232,9 +291,10 @@ static int mcp_sa11x0_suspend(struct platform_device *dev, pm_message_t state)
static int mcp_sa11x0_resume(struct platform_device *dev)
{
struct mcp *mcp = platform_get_drvdata(dev);
+ struct mcp_sa11x0 *priv = priv(mcp);
- Ser4MCCR1 = priv(mcp)->mccr1;
- Ser4MCCR0 = priv(mcp)->mccr0;
+ __raw_writel(priv->mccr0, priv->mccr0_base + MCCR0);
+ __raw_writel(priv->mccr1, priv->mccr1_base + MCCR1);
return 0;
}
@@ -251,24 +311,14 @@ static struct platform_driver mcp_sa11x0_driver = {
.resume = mcp_sa11x0_resume,
.driver = {
.name = "sa11x0-mcp",
+ .owner = THIS_MODULE,
},
};
/*
* This needs re-working
*/
-static int __init mcp_sa11x0_init(void)
-{
- return platform_driver_register(&mcp_sa11x0_driver);
-}
-
-static void __exit mcp_sa11x0_exit(void)
-{
- platform_driver_unregister(&mcp_sa11x0_driver);
-}
-
-module_init(mcp_sa11x0_init);
-module_exit(mcp_sa11x0_exit);
+module_platform_driver(mcp_sa11x0_driver);
MODULE_AUTHOR("Russell King <rmk@arm.linux.org.uk>");
MODULE_DESCRIPTION("SA11x0 multimedia communications port driver");
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 3f565ef3e149..68ac2c55d5ae 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -503,19 +503,13 @@ static void omap_usbhs_init(struct device *dev)
spin_lock_irqsave(&omap->lock, flags);
if (pdata->ehci_data->phy_reset) {
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) {
- gpio_request(pdata->ehci_data->reset_gpio_port[0],
- "USB1 PHY reset");
- gpio_direction_output
- (pdata->ehci_data->reset_gpio_port[0], 0);
- }
+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
+ gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
+ GPIOF_OUT_INIT_LOW, "USB1 PHY reset");
- if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) {
- gpio_request(pdata->ehci_data->reset_gpio_port[1],
- "USB2 PHY reset");
- gpio_direction_output
- (pdata->ehci_data->reset_gpio_port[1], 0);
- }
+ if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1]))
+ gpio_request_one(pdata->ehci_data->reset_gpio_port[1],
+ GPIOF_OUT_INIT_LOW, "USB2 PHY reset");
/* Hold the PHY in RESET for enough time till DIR is high */
udelay(10);
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
index aed0d2a9b032..3927c17e4175 100644
--- a/drivers/mfd/pcf50633-adc.c
+++ b/drivers/mfd/pcf50633-adc.c
@@ -249,17 +249,7 @@ static struct platform_driver pcf50633_adc_driver = {
.remove = __devexit_p(pcf50633_adc_remove),
};
-static int __init pcf50633_adc_init(void)
-{
- return platform_driver_register(&pcf50633_adc_driver);
-}
-module_init(pcf50633_adc_init);
-
-static void __exit pcf50633_adc_exit(void)
-{
- platform_driver_unregister(&pcf50633_adc_driver);
-}
-module_exit(pcf50633_adc_exit);
+module_platform_driver(pcf50633_adc_driver);
MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
MODULE_DESCRIPTION("PCF50633 adc driver");
diff --git a/drivers/mfd/s5m-core.c b/drivers/mfd/s5m-core.c
new file mode 100644
index 000000000000..e075c113eec6
--- /dev/null
+++ b/drivers/mfd/s5m-core.c
@@ -0,0 +1,176 @@
+/*
+ * s5m87xx.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/pm_runtime.h>
+#include <linux/mutex.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+#include <linux/mfd/s5m87xx/s5m-pmic.h>
+#include <linux/mfd/s5m87xx/s5m-rtc.h>
+#include <linux/regmap.h>
+
+static struct mfd_cell s5m87xx_devs[] = {
+ {
+ .name = "s5m8767-pmic",
+ }, {
+ .name = "s5m-rtc",
+ },
+};
+
+int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, void *dest)
+{
+ return regmap_read(s5m87xx->regmap, reg, dest);
+}
+EXPORT_SYMBOL_GPL(s5m_reg_read);
+
+int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf)
+{
+ return regmap_bulk_read(s5m87xx->regmap, reg, buf, count);;
+}
+EXPORT_SYMBOL_GPL(s5m_bulk_read);
+
+int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value)
+{
+ return regmap_write(s5m87xx->regmap, reg, value);
+}
+EXPORT_SYMBOL_GPL(s5m_reg_write);
+
+int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf)
+{
+ return regmap_raw_write(s5m87xx->regmap, reg, buf, count * sizeof(u16));
+}
+EXPORT_SYMBOL_GPL(s5m_bulk_write);
+
+int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask)
+{
+ return regmap_update_bits(s5m87xx->regmap, reg, mask, val);
+}
+EXPORT_SYMBOL_GPL(s5m_reg_update);
+
+static struct regmap_config s5m_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 8,
+};
+
+static int s5m87xx_i2c_probe(struct i2c_client *i2c,
+ const struct i2c_device_id *id)
+{
+ struct s5m_platform_data *pdata = i2c->dev.platform_data;
+ struct s5m87xx_dev *s5m87xx;
+ int ret = 0;
+ int error;
+
+ s5m87xx = kzalloc(sizeof(struct s5m87xx_dev), GFP_KERNEL);
+ if (s5m87xx == NULL)
+ return -ENOMEM;
+
+ i2c_set_clientdata(i2c, s5m87xx);
+ s5m87xx->dev = &i2c->dev;
+ s5m87xx->i2c = i2c;
+ s5m87xx->irq = i2c->irq;
+ s5m87xx->type = id->driver_data;
+
+ if (pdata) {
+ s5m87xx->device_type = pdata->device_type;
+ s5m87xx->ono = pdata->ono;
+ s5m87xx->irq_base = pdata->irq_base;
+ s5m87xx->wakeup = pdata->wakeup;
+ }
+
+ s5m87xx->regmap = regmap_init_i2c(i2c, &s5m_regmap_config);
+ if (IS_ERR(s5m87xx->regmap)) {
+ error = PTR_ERR(s5m87xx->regmap);
+ dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+ error);
+ goto err;
+ }
+
+ s5m87xx->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR);
+ i2c_set_clientdata(s5m87xx->rtc, s5m87xx);
+
+ if (pdata->cfg_pmic_irq)
+ pdata->cfg_pmic_irq();
+
+ s5m_irq_init(s5m87xx);
+
+ pm_runtime_set_active(s5m87xx->dev);
+
+ ret = mfd_add_devices(s5m87xx->dev, -1,
+ s5m87xx_devs, ARRAY_SIZE(s5m87xx_devs),
+ NULL, 0);
+
+ if (ret < 0)
+ goto err;
+
+ return ret;
+
+err:
+ mfd_remove_devices(s5m87xx->dev);
+ s5m_irq_exit(s5m87xx);
+ i2c_unregister_device(s5m87xx->rtc);
+ regmap_exit(s5m87xx->regmap);
+ kfree(s5m87xx);
+ return ret;
+}
+
+static int s5m87xx_i2c_remove(struct i2c_client *i2c)
+{
+ struct s5m87xx_dev *s5m87xx = i2c_get_clientdata(i2c);
+
+ mfd_remove_devices(s5m87xx->dev);
+ s5m_irq_exit(s5m87xx);
+ i2c_unregister_device(s5m87xx->rtc);
+ regmap_exit(s5m87xx->regmap);
+ kfree(s5m87xx);
+ return 0;
+}
+
+static const struct i2c_device_id s5m87xx_i2c_id[] = {
+ { "s5m87xx", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, s5m87xx_i2c_id);
+
+static struct i2c_driver s5m87xx_i2c_driver = {
+ .driver = {
+ .name = "s5m87xx",
+ .owner = THIS_MODULE,
+ },
+ .probe = s5m87xx_i2c_probe,
+ .remove = s5m87xx_i2c_remove,
+ .id_table = s5m87xx_i2c_id,
+};
+
+static int __init s5m87xx_i2c_init(void)
+{
+ return i2c_add_driver(&s5m87xx_i2c_driver);
+}
+
+subsys_initcall(s5m87xx_i2c_init);
+
+static void __exit s5m87xx_i2c_exit(void)
+{
+ i2c_del_driver(&s5m87xx_i2c_driver);
+}
+module_exit(s5m87xx_i2c_exit);
+
+MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
+MODULE_DESCRIPTION("Core support for the S5M MFD");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/s5m-irq.c b/drivers/mfd/s5m-irq.c
new file mode 100644
index 000000000000..de76dfb6f0ad
--- /dev/null
+++ b/drivers/mfd/s5m-irq.c
@@ -0,0 +1,487 @@
+/*
+ * s5m-irq.c
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/s5m87xx/s5m-core.h>
+
+struct s5m_irq_data {
+ int reg;
+ int mask;
+};
+
+static struct s5m_irq_data s5m8767_irqs[] = {
+ [S5M8767_IRQ_PWRR] = {
+ .reg = 1,
+ .mask = S5M8767_IRQ_PWRR_MASK,
+ },
+ [S5M8767_IRQ_PWRF] = {
+ .reg = 1,
+ .mask = S5M8767_IRQ_PWRF_MASK,
+ },
+ [S5M8767_IRQ_PWR1S] = {
+ .reg = 1,
+ .mask = S5M8767_IRQ_PWR1S_MASK,
+ },
+ [S5M8767_IRQ_JIGR] = {
+ .reg = 1,
+ .mask = S5M8767_IRQ_JIGR_MASK,
+ },
+ [S5M8767_IRQ_JIGF] = {
+ .reg = 1,
+ .mask = S5M8767_IRQ_JIGF_MASK,
+ },
+ [S5M8767_IRQ_LOWBAT2] = {
+ .reg = 1,
+ .mask = S5M8767_IRQ_LOWBAT2_MASK,
+ },
+ [S5M8767_IRQ_LOWBAT1] = {
+ .reg = 1,
+ .mask = S5M8767_IRQ_LOWBAT1_MASK,
+ },
+ [S5M8767_IRQ_MRB] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_MRB_MASK,
+ },
+ [S5M8767_IRQ_DVSOK2] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_DVSOK2_MASK,
+ },
+ [S5M8767_IRQ_DVSOK3] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_DVSOK3_MASK,
+ },
+ [S5M8767_IRQ_DVSOK4] = {
+ .reg = 2,
+ .mask = S5M8767_IRQ_DVSOK4_MASK,
+ },
+ [S5M8767_IRQ_RTC60S] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_RTC60S_MASK,
+ },
+ [S5M8767_IRQ_RTCA1] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_RTCA1_MASK,
+ },
+ [S5M8767_IRQ_RTCA2] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_RTCA2_MASK,
+ },
+ [S5M8767_IRQ_SMPL] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_SMPL_MASK,
+ },
+ [S5M8767_IRQ_RTC1S] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_RTC1S_MASK,
+ },
+ [S5M8767_IRQ_WTSR] = {
+ .reg = 3,
+ .mask = S5M8767_IRQ_WTSR_MASK,
+ },
+};
+
+static struct s5m_irq_data s5m8763_irqs[] = {
+ [S5M8763_IRQ_DCINF] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_DCINF_MASK,
+ },
+ [S5M8763_IRQ_DCINR] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_DCINR_MASK,
+ },
+ [S5M8763_IRQ_JIGF] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_JIGF_MASK,
+ },
+ [S5M8763_IRQ_JIGR] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_JIGR_MASK,
+ },
+ [S5M8763_IRQ_PWRONF] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_PWRONF_MASK,
+ },
+ [S5M8763_IRQ_PWRONR] = {
+ .reg = 1,
+ .mask = S5M8763_IRQ_PWRONR_MASK,
+ },
+ [S5M8763_IRQ_WTSREVNT] = {
+ .reg = 2,
+ .mask = S5M8763_IRQ_WTSREVNT_MASK,
+ },
+ [S5M8763_IRQ_SMPLEVNT] = {
+ .reg = 2,
+ .mask = S5M8763_IRQ_SMPLEVNT_MASK,
+ },
+ [S5M8763_IRQ_ALARM1] = {
+ .reg = 2,
+ .mask = S5M8763_IRQ_ALARM1_MASK,
+ },
+ [S5M8763_IRQ_ALARM0] = {
+ .reg = 2,
+ .mask = S5M8763_IRQ_ALARM0_MASK,
+ },
+ [S5M8763_IRQ_ONKEY1S] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_ONKEY1S_MASK,
+ },
+ [S5M8763_IRQ_TOPOFFR] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_TOPOFFR_MASK,
+ },
+ [S5M8763_IRQ_DCINOVPR] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_DCINOVPR_MASK,
+ },
+ [S5M8763_IRQ_CHGRSTF] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_CHGRSTF_MASK,
+ },
+ [S5M8763_IRQ_DONER] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_DONER_MASK,
+ },
+ [S5M8763_IRQ_CHGFAULT] = {
+ .reg = 3,
+ .mask = S5M8763_IRQ_CHGFAULT_MASK,
+ },
+ [S5M8763_IRQ_LOBAT1] = {
+ .reg = 4,
+ .mask = S5M8763_IRQ_LOBAT1_MASK,
+ },
+ [S5M8763_IRQ_LOBAT2] = {
+ .reg = 4,
+ .mask = S5M8763_IRQ_LOBAT2_MASK,
+ },
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8767_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+ return &s5m8767_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8767_irq_lock(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_sync_unlock(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+ if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) {
+ s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i];
+ s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+ s5m87xx->irq_masks_cur[i]);
+ }
+ }
+
+ mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8767_irq_unmask(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+ data->irq);
+
+ s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8767_irq_mask(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ struct s5m_irq_data *irq_data = irq_to_s5m8767_irq(s5m87xx,
+ data->irq);
+
+ s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8767_irq_chip = {
+ .name = "s5m8767",
+ .irq_bus_lock = s5m8767_irq_lock,
+ .irq_bus_sync_unlock = s5m8767_irq_sync_unlock,
+ .irq_mask = s5m8767_irq_mask,
+ .irq_unmask = s5m8767_irq_unmask,
+};
+
+static inline struct s5m_irq_data *
+irq_to_s5m8763_irq(struct s5m87xx_dev *s5m87xx, int irq)
+{
+ return &s5m8763_irqs[irq - s5m87xx->irq_base];
+}
+
+static void s5m8763_irq_lock(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+
+ mutex_lock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_sync_unlock(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(s5m87xx->irq_masks_cur); i++) {
+ if (s5m87xx->irq_masks_cur[i] != s5m87xx->irq_masks_cache[i]) {
+ s5m87xx->irq_masks_cache[i] = s5m87xx->irq_masks_cur[i];
+ s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+ s5m87xx->irq_masks_cur[i]);
+ }
+ }
+
+ mutex_unlock(&s5m87xx->irqlock);
+}
+
+static void s5m8763_irq_unmask(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+ data->irq);
+
+ s5m87xx->irq_masks_cur[irq_data->reg - 1] &= ~irq_data->mask;
+}
+
+static void s5m8763_irq_mask(struct irq_data *data)
+{
+ struct s5m87xx_dev *s5m87xx = irq_data_get_irq_chip_data(data);
+ struct s5m_irq_data *irq_data = irq_to_s5m8763_irq(s5m87xx,
+ data->irq);
+
+ s5m87xx->irq_masks_cur[irq_data->reg - 1] |= irq_data->mask;
+}
+
+static struct irq_chip s5m8763_irq_chip = {
+ .name = "s5m8763",
+ .irq_bus_lock = s5m8763_irq_lock,
+ .irq_bus_sync_unlock = s5m8763_irq_sync_unlock,
+ .irq_mask = s5m8763_irq_mask,
+ .irq_unmask = s5m8763_irq_unmask,
+};
+
+
+static irqreturn_t s5m8767_irq_thread(int irq, void *data)
+{
+ struct s5m87xx_dev *s5m87xx = data;
+ u8 irq_reg[NUM_IRQ_REGS-1];
+ int ret;
+ int i;
+
+
+ ret = s5m_bulk_read(s5m87xx, S5M8767_REG_INT1,
+ NUM_IRQ_REGS - 1, irq_reg);
+ if (ret < 0) {
+ dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n",
+ ret);
+ return IRQ_NONE;
+ }
+
+ for (i = 0; i < NUM_IRQ_REGS - 1; i++)
+ irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+ for (i = 0; i < S5M8767_IRQ_NR; i++) {
+ if (irq_reg[s5m8767_irqs[i].reg - 1] & s5m8767_irqs[i].mask)
+ handle_nested_irq(s5m87xx->irq_base + i);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t s5m8763_irq_thread(int irq, void *data)
+{
+ struct s5m87xx_dev *s5m87xx = data;
+ u8 irq_reg[NUM_IRQ_REGS];
+ int ret;
+ int i;
+
+ ret = s5m_bulk_read(s5m87xx, S5M8763_REG_IRQ1,
+ NUM_IRQ_REGS, irq_reg);
+ if (ret < 0) {
+ dev_err(s5m87xx->dev, "Failed to read interrupt register: %d\n",
+ ret);
+ return IRQ_NONE;
+ }
+
+ for (i = 0; i < NUM_IRQ_REGS; i++)
+ irq_reg[i] &= ~s5m87xx->irq_masks_cur[i];
+
+ for (i = 0; i < S5M8763_IRQ_NR; i++) {
+ if (irq_reg[s5m8763_irqs[i].reg - 1] & s5m8763_irqs[i].mask)
+ handle_nested_irq(s5m87xx->irq_base + i);
+ }
+
+ return IRQ_HANDLED;
+}
+
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx)
+{
+ if (s5m87xx->irq && s5m87xx->irq_base){
+ switch (s5m87xx->device_type) {
+ case S5M8763X:
+ s5m8763_irq_thread(s5m87xx->irq_base, s5m87xx);
+ break;
+ case S5M8767X:
+ s5m8767_irq_thread(s5m87xx->irq_base, s5m87xx);
+ break;
+ default:
+ break;
+
+ }
+ }
+ return 0;
+}
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx)
+{
+ int i;
+ int cur_irq;
+ int ret = 0;
+ int type = s5m87xx->device_type;
+
+ if (!s5m87xx->irq) {
+ dev_warn(s5m87xx->dev,
+ "No interrupt specified, no interrupts\n");
+ s5m87xx->irq_base = 0;
+ return 0;
+ }
+
+ if (!s5m87xx->irq_base) {
+ dev_err(s5m87xx->dev,
+ "No interrupt base specified, no interrupts\n");
+ return 0;
+ }
+
+ mutex_init(&s5m87xx->irqlock);
+
+ switch (type) {
+ case S5M8763X:
+ for (i = 0; i < NUM_IRQ_REGS; i++) {
+ s5m87xx->irq_masks_cur[i] = 0xff;
+ s5m87xx->irq_masks_cache[i] = 0xff;
+ s5m_reg_write(s5m87xx, S5M8763_REG_IRQM1 + i,
+ 0xff);
+ }
+
+ s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM1, 0xff);
+ s5m_reg_write(s5m87xx, S5M8763_REG_STATUSM2, 0xff);
+
+ for (i = 0; i < S5M8763_IRQ_NR; i++) {
+ cur_irq = i + s5m87xx->irq_base;
+ irq_set_chip_data(cur_irq, s5m87xx);
+ irq_set_chip_and_handler(cur_irq, &s5m8763_irq_chip,
+ handle_edge_irq);
+ irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(cur_irq, IRQF_VALID);
+#else
+ irq_set_noprobe(cur_irq);
+#endif
+ }
+
+ ret = request_threaded_irq(s5m87xx->irq, NULL,
+ s5m8763_irq_thread,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "s5m87xx-irq", s5m87xx);
+ if (ret) {
+ dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+ s5m87xx->irq, ret);
+ return ret;
+ }
+ break;
+ case S5M8767X:
+ for (i = 0; i < NUM_IRQ_REGS - 1; i++) {
+ s5m87xx->irq_masks_cur[i] = 0xff;
+ s5m87xx->irq_masks_cache[i] = 0xff;
+ s5m_reg_write(s5m87xx, S5M8767_REG_INT1M + i,
+ 0xff);
+ }
+ for (i = 0; i < S5M8767_IRQ_NR; i++) {
+ cur_irq = i + s5m87xx->irq_base;
+ irq_set_chip_data(cur_irq, s5m87xx);
+ if (ret) {
+ dev_err(s5m87xx->dev,
+ "Failed to irq_set_chip_data %d: %d\n",
+ s5m87xx->irq, ret);
+ return ret;
+ }
+
+ irq_set_chip_and_handler(cur_irq, &s5m8767_irq_chip,
+ handle_edge_irq);
+ irq_set_nested_thread(cur_irq, 1);
+#ifdef CONFIG_ARM
+ set_irq_flags(cur_irq, IRQF_VALID);
+#else
+ irq_set_noprobe(cur_irq);
+#endif
+ }
+
+ ret = request_threaded_irq(s5m87xx->irq, NULL,
+ s5m8767_irq_thread,
+ IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ "s5m87xx-irq", s5m87xx);
+ if (ret) {
+ dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+ s5m87xx->irq, ret);
+ return ret;
+ }
+ break;
+ default:
+ break;
+ }
+
+ if (!s5m87xx->ono)
+ return 0;
+
+ switch (type) {
+ case S5M8763X:
+ ret = request_threaded_irq(s5m87xx->ono, NULL,
+ s5m8763_irq_thread,
+ IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT, "s5m87xx-ono",
+ s5m87xx);
+ break;
+ case S5M8767X:
+ ret = request_threaded_irq(s5m87xx->ono, NULL,
+ s5m8767_irq_thread,
+ IRQF_TRIGGER_FALLING |
+ IRQF_TRIGGER_RISING |
+ IRQF_ONESHOT, "s5m87xx-ono", s5m87xx);
+ break;
+ default:
+ break;
+ }
+
+ if (ret)
+ dev_err(s5m87xx->dev, "Failed to request IRQ %d: %d\n",
+ s5m87xx->ono, ret);
+
+ return 0;
+}
+
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx)
+{
+ if (s5m87xx->ono)
+ free_irq(s5m87xx->ono, s5m87xx);
+
+ if (s5m87xx->irq)
+ free_irq(s5m87xx->irq, s5m87xx);
+}
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index df3702c1756d..f4d86117f44a 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -1720,7 +1720,7 @@ static int sm501_plat_remove(struct platform_device *dev)
return 0;
}
-static struct pci_device_id sm501_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(sm501_pci_tbl) = {
{ 0x126f, 0x0501, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0, },
};
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
new file mode 100644
index 000000000000..373f423b1181
--- /dev/null
+++ b/drivers/mfd/stmpe-i2c.c
@@ -0,0 +1,109 @@
+/*
+ * ST Microelectronics MFD: stmpe's i2c client specific driver
+ *
+ * Copyright (C) ST-Ericsson SA 2010
+ * Copyright (C) ST Microelectronics SA 2011
+ *
+ * License Terms: GNU General Public License, version 2
+ * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
+ * Author: Viresh Kumar <viresh.kumar@st.com> for ST Microelectronics
+ */
+
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include "stmpe.h"
+
+static int i2c_reg_read(struct stmpe *stmpe, u8 reg)
+{
+ struct i2c_client *i2c = stmpe->client;
+
+ return i2c_smbus_read_byte_data(i2c, reg);
+}
+
+static int i2c_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
+{
+ struct i2c_client *i2c = stmpe->client;
+
+ return i2c_smbus_write_byte_data(i2c, reg, val);
+}
+
+static int i2c_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
+{
+ struct i2c_client *i2c = stmpe->client;
+
+ return i2c_smbus_read_i2c_block_data(i2c, reg, length, values);
+}
+
+static int i2c_block_write(struct stmpe *stmpe, u8 reg, u8 length,
+ const u8 *values)
+{
+ struct i2c_client *i2c = stmpe->client;
+
+ return i2c_smbus_write_i2c_block_data(i2c, reg, length, values);
+}
+
+static struct stmpe_client_info i2c_ci = {
+ .read_byte = i2c_reg_read,
+ .write_byte = i2c_reg_write,
+ .read_block = i2c_block_read,
+ .write_block = i2c_block_write,
+};
+
+static int __devinit
+stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+ i2c_ci.data = (void *)id;
+ i2c_ci.irq = i2c->irq;
+ i2c_ci.client = i2c;
+ i2c_ci.dev = &i2c->dev;
+
+ return stmpe_probe(&i2c_ci, id->driver_data);
+}
+
+static int __devexit stmpe_i2c_remove(struct i2c_client *i2c)
+{
+ struct stmpe *stmpe = dev_get_drvdata(&i2c->dev);
+
+ return stmpe_remove(stmpe);
+}
+
+static const struct i2c_device_id stmpe_i2c_id[] = {
+ { "stmpe610", STMPE610 },
+ { "stmpe801", STMPE801 },
+ { "stmpe811", STMPE811 },
+ { "stmpe1601", STMPE1601 },
+ { "stmpe2401", STMPE2401 },
+ { "stmpe2403", STMPE2403 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, stmpe_id);
+
+static struct i2c_driver stmpe_i2c_driver = {
+ .driver.name = "stmpe-i2c",
+ .driver.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .driver.pm = &stmpe_dev_pm_ops,
+#endif
+ .probe = stmpe_i2c_probe,
+ .remove = __devexit_p(stmpe_i2c_remove),
+ .id_table = stmpe_i2c_id,
+};
+
+static int __init stmpe_init(void)
+{
+ return i2c_add_driver(&stmpe_i2c_driver);
+}
+subsys_initcall(stmpe_init);
+
+static void __exit stmpe_exit(void)
+{
+ i2c_del_driver(&stmpe_i2c_driver);
+}
+module_exit(stmpe_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver");
+MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>");
diff --git a/drivers/mfd/stmpe-spi.c b/drivers/mfd/stmpe-spi.c
new file mode 100644
index 000000000000..b58c43c7ea93
--- /dev/null
+++ b/drivers/mfd/stmpe-spi.c
@@ -0,0 +1,150 @@
+/*
+ * ST Microelectronics MFD: stmpe's spi client specific driver
+ *
+ * Copyright (C) ST Microelectronics SA 2011
+ *
+ * License Terms: GNU General Public License, version 2
+ * Author: Viresh Kumar <viresh.kumar@st.com> for ST Microelectronics
+ */
+
+#include <linux/spi/spi.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include "stmpe.h"
+
+#define READ_CMD (1 << 7)
+
+static int spi_reg_read(struct stmpe *stmpe, u8 reg)
+{
+ struct spi_device *spi = stmpe->client;
+ int status = spi_w8r16(spi, reg | READ_CMD);
+
+ return (status < 0) ? status : status >> 8;
+}
+
+static int spi_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
+{
+ struct spi_device *spi = stmpe->client;
+ u16 cmd = (val << 8) | reg;
+
+ return spi_write(spi, (const u8 *)&cmd, 2);
+}
+
+static int spi_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
+{
+ int ret, i;
+
+ for (i = 0; i < length; i++) {
+ ret = spi_reg_read(stmpe, reg + i);
+ if (ret < 0)
+ return ret;
+ *(values + i) = ret;
+ }
+
+ return 0;
+}
+
+static int spi_block_write(struct stmpe *stmpe, u8 reg, u8 length,
+ const u8 *values)
+{
+ int ret = 0, i;
+
+ for (i = length; i > 0; i--, reg++) {
+ ret = spi_reg_write(stmpe, reg, *(values + i - 1));
+ if (ret < 0)
+ return ret;
+ }
+
+ return ret;
+}
+
+static void spi_init(struct stmpe *stmpe)
+{
+ struct spi_device *spi = stmpe->client;
+
+ spi->bits_per_word = 8;
+
+ /* This register is only present for stmpe811 */
+ if (stmpe->variant->id_val == 0x0811)
+ spi_reg_write(stmpe, STMPE811_REG_SPI_CFG, spi->mode);
+
+ if (spi_setup(spi) < 0)
+ dev_dbg(&spi->dev, "spi_setup failed\n");
+}
+
+static struct stmpe_client_info spi_ci = {
+ .read_byte = spi_reg_read,
+ .write_byte = spi_reg_write,
+ .read_block = spi_block_read,
+ .write_block = spi_block_write,
+ .init = spi_init,
+};
+
+static int __devinit
+stmpe_spi_probe(struct spi_device *spi)
+{
+ const struct spi_device_id *id = spi_get_device_id(spi);
+
+ /* don't exceed max specified rate - 1MHz - Limitation of STMPE */
+ if (spi->max_speed_hz > 1000000) {
+ dev_dbg(&spi->dev, "f(sample) %d KHz?\n",
+ (spi->max_speed_hz/1000));
+ return -EINVAL;
+ }
+
+ spi_ci.irq = spi->irq;
+ spi_ci.client = spi;
+ spi_ci.dev = &spi->dev;
+
+ return stmpe_probe(&spi_ci, id->driver_data);
+}
+
+static int __devexit stmpe_spi_remove(struct spi_device *spi)
+{
+ struct stmpe *stmpe = dev_get_drvdata(&spi->dev);
+
+ return stmpe_remove(stmpe);
+}
+
+static const struct spi_device_id stmpe_spi_id[] = {
+ { "stmpe610", STMPE610 },
+ { "stmpe801", STMPE801 },
+ { "stmpe811", STMPE811 },
+ { "stmpe1601", STMPE1601 },
+ { "stmpe2401", STMPE2401 },
+ { "stmpe2403", STMPE2403 },
+ { }
+};
+MODULE_DEVICE_TABLE(spi, stmpe_id);
+
+static struct spi_driver stmpe_spi_driver = {
+ .driver = {
+ .name = "stmpe-spi",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &stmpe_dev_pm_ops,
+#endif
+ },
+ .probe = stmpe_spi_probe,
+ .remove = __devexit_p(stmpe_spi_remove),
+ .id_table = stmpe_spi_id,
+};
+
+static int __init stmpe_init(void)
+{
+ return spi_register_driver(&stmpe_spi_driver);
+}
+subsys_initcall(stmpe_init);
+
+static void __exit stmpe_exit(void)
+{
+ spi_unregister_driver(&stmpe_spi_driver);
+}
+module_exit(stmpe_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("STMPE MFD SPI Interface Driver");
+MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 2963689cf45c..e07947e56b2a 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -1,18 +1,20 @@
/*
+ * ST Microelectronics MFD: stmpe's driver
+ *
* Copyright (C) ST-Ericsson SA 2010
*
* License Terms: GNU General Public License, version 2
* Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
*/
+#include <linux/gpio.h>
+#include <linux/export.h>
#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/pm.h>
#include <linux/slab.h>
-#include <linux/i2c.h>
#include <linux/mfd/core.h>
-#include <linux/mfd/stmpe.h>
#include "stmpe.h"
static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
@@ -29,10 +31,9 @@ static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg)
{
int ret;
- ret = i2c_smbus_read_byte_data(stmpe->i2c, reg);
+ ret = stmpe->ci->read_byte(stmpe, reg);
if (ret < 0)
- dev_err(stmpe->dev, "failed to read reg %#x: %d\n",
- reg, ret);
+ dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret);
dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret);
@@ -45,10 +46,9 @@ static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val);
- ret = i2c_smbus_write_byte_data(stmpe->i2c, reg, val);
+ ret = stmpe->ci->write_byte(stmpe, reg, val);
if (ret < 0)
- dev_err(stmpe->dev, "failed to write reg %#x: %d\n",
- reg, ret);
+ dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret);
return ret;
}
@@ -72,10 +72,9 @@ static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
{
int ret;
- ret = i2c_smbus_read_i2c_block_data(stmpe->i2c, reg, length, values);
+ ret = stmpe->ci->read_block(stmpe, reg, length, values);
if (ret < 0)
- dev_err(stmpe->dev, "failed to read regs %#x: %d\n",
- reg, ret);
+ dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret);
dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret);
stmpe_dump_bytes("stmpe rd: ", values, length);
@@ -91,11 +90,9 @@ static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length);
stmpe_dump_bytes("stmpe wr: ", values, length);
- ret = i2c_smbus_write_i2c_block_data(stmpe->i2c, reg, length,
- values);
+ ret = stmpe->ci->write_block(stmpe, reg, length, values);
if (ret < 0)
- dev_err(stmpe->dev, "failed to write regs %#x: %d\n",
- reg, ret);
+ dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret);
return ret;
}
@@ -245,12 +242,14 @@ int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, enum stmpe_block block)
u8 regaddr = stmpe->regs[STMPE_IDX_GPAFR_U_MSB];
int af_bits = variant->af_bits;
int numregs = DIV_ROUND_UP(stmpe->num_gpios * af_bits, 8);
- int afperreg = 8 / af_bits;
int mask = (1 << af_bits) - 1;
u8 regs[numregs];
- int af;
- int ret;
+ int af, afperreg, ret;
+
+ if (!variant->get_altfunc)
+ return 0;
+ afperreg = 8 / af_bits;
mutex_lock(&stmpe->lock);
ret = __stmpe_enable(stmpe, STMPE_BLOCK_GPIO);
@@ -325,7 +324,51 @@ static struct mfd_cell stmpe_keypad_cell = {
};
/*
- * Touchscreen (STMPE811)
+ * STMPE801
+ */
+static const u8 stmpe801_regs[] = {
+ [STMPE_IDX_CHIP_ID] = STMPE801_REG_CHIP_ID,
+ [STMPE_IDX_ICR_LSB] = STMPE801_REG_SYS_CTRL,
+ [STMPE_IDX_GPMR_LSB] = STMPE801_REG_GPIO_MP_STA,
+ [STMPE_IDX_GPSR_LSB] = STMPE801_REG_GPIO_SET_PIN,
+ [STMPE_IDX_GPCR_LSB] = STMPE801_REG_GPIO_SET_PIN,
+ [STMPE_IDX_GPDR_LSB] = STMPE801_REG_GPIO_DIR,
+ [STMPE_IDX_IEGPIOR_LSB] = STMPE801_REG_GPIO_INT_EN,
+ [STMPE_IDX_ISGPIOR_MSB] = STMPE801_REG_GPIO_INT_STA,
+
+};
+
+static struct stmpe_variant_block stmpe801_blocks[] = {
+ {
+ .cell = &stmpe_gpio_cell,
+ .irq = 0,
+ .block = STMPE_BLOCK_GPIO,
+ },
+};
+
+static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
+ bool enable)
+{
+ if (blocks & STMPE_BLOCK_GPIO)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+static struct stmpe_variant_info stmpe801 = {
+ .name = "stmpe801",
+ .id_val = STMPE801_ID,
+ .id_mask = 0xffff,
+ .num_gpios = 8,
+ .regs = stmpe801_regs,
+ .blocks = stmpe801_blocks,
+ .num_blocks = ARRAY_SIZE(stmpe801_blocks),
+ .num_irqs = STMPE801_NR_INTERNAL_IRQS,
+ .enable = stmpe801_enable,
+};
+
+/*
+ * Touchscreen (STMPE811 or STMPE610)
*/
static struct resource stmpe_ts_resources[] = {
@@ -350,7 +393,7 @@ static struct mfd_cell stmpe_ts_cell = {
};
/*
- * STMPE811
+ * STMPE811 or STMPE610
*/
static const u8 stmpe811_regs[] = {
@@ -421,6 +464,21 @@ static struct stmpe_variant_info stmpe811 = {
.get_altfunc = stmpe811_get_altfunc,
};
+/* Similar to 811, except number of gpios */
+static struct stmpe_variant_info stmpe610 = {
+ .name = "stmpe610",
+ .id_val = 0x0811,
+ .id_mask = 0xffff,
+ .num_gpios = 6,
+ .af_bits = 1,
+ .regs = stmpe811_regs,
+ .blocks = stmpe811_blocks,
+ .num_blocks = ARRAY_SIZE(stmpe811_blocks),
+ .num_irqs = STMPE811_NR_INTERNAL_IRQS,
+ .enable = stmpe811_enable,
+ .get_altfunc = stmpe811_get_altfunc,
+};
+
/*
* STMPE1601
*/
@@ -655,6 +713,8 @@ static struct stmpe_variant_info stmpe2403 = {
};
static struct stmpe_variant_info *stmpe_variant_info[] = {
+ [STMPE610] = &stmpe610,
+ [STMPE801] = &stmpe801,
[STMPE811] = &stmpe811,
[STMPE1601] = &stmpe1601,
[STMPE2401] = &stmpe2401,
@@ -671,6 +731,11 @@ static irqreturn_t stmpe_irq(int irq, void *data)
int ret;
int i;
+ if (variant->id_val == STMPE801_ID) {
+ handle_nested_irq(stmpe->irq_base);
+ return IRQ_HANDLED;
+ }
+
ret = stmpe_block_read(stmpe, israddr, num, isr);
if (ret < 0)
return IRQ_NONE;
@@ -757,14 +822,17 @@ static struct irq_chip stmpe_irq_chip = {
static int __devinit stmpe_irq_init(struct stmpe *stmpe)
{
+ struct irq_chip *chip = NULL;
int num_irqs = stmpe->variant->num_irqs;
int base = stmpe->irq_base;
int irq;
+ if (stmpe->variant->id_val != STMPE801_ID)
+ chip = &stmpe_irq_chip;
+
for (irq = base; irq < base + num_irqs; irq++) {
irq_set_chip_data(irq, stmpe);
- irq_set_chip_and_handler(irq, &stmpe_irq_chip,
- handle_edge_irq);
+ irq_set_chip_and_handler(irq, chip, handle_edge_irq);
irq_set_nested_thread(irq, 1);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
@@ -796,7 +864,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
unsigned int irq_trigger = stmpe->pdata->irq_trigger;
int autosleep_timeout = stmpe->pdata->autosleep_timeout;
struct stmpe_variant_info *variant = stmpe->variant;
- u8 icr = STMPE_ICR_LSB_GIM;
+ u8 icr;
unsigned int id;
u8 data[2];
int ret;
@@ -819,16 +887,32 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
if (ret)
return ret;
- if (irq_trigger == IRQF_TRIGGER_FALLING ||
- irq_trigger == IRQF_TRIGGER_RISING)
- icr |= STMPE_ICR_LSB_EDGE;
+ if (id == STMPE801_ID)
+ icr = STMPE801_REG_SYS_CTRL_INT_EN;
+ else
+ icr = STMPE_ICR_LSB_GIM;
+
+ /* STMPE801 doesn't support Edge interrupts */
+ if (id != STMPE801_ID) {
+ if (irq_trigger == IRQF_TRIGGER_FALLING ||
+ irq_trigger == IRQF_TRIGGER_RISING)
+ icr |= STMPE_ICR_LSB_EDGE;
+ }
if (irq_trigger == IRQF_TRIGGER_RISING ||
- irq_trigger == IRQF_TRIGGER_HIGH)
- icr |= STMPE_ICR_LSB_HIGH;
+ irq_trigger == IRQF_TRIGGER_HIGH) {
+ if (id == STMPE801_ID)
+ icr |= STMPE801_REG_SYS_CTRL_INT_HI;
+ else
+ icr |= STMPE_ICR_LSB_HIGH;
+ }
- if (stmpe->pdata->irq_invert_polarity)
- icr ^= STMPE_ICR_LSB_HIGH;
+ if (stmpe->pdata->irq_invert_polarity) {
+ if (id == STMPE801_ID)
+ icr ^= STMPE801_REG_SYS_CTRL_INT_HI;
+ else
+ icr ^= STMPE_ICR_LSB_HIGH;
+ }
if (stmpe->pdata->autosleep) {
ret = stmpe_autosleep(stmpe, autosleep_timeout);
@@ -873,32 +957,10 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe)
return ret;
}
-#ifdef CONFIG_PM
-static int stmpe_suspend(struct device *dev)
-{
- struct i2c_client *i2c = to_i2c_client(dev);
-
- if (device_may_wakeup(&i2c->dev))
- enable_irq_wake(i2c->irq);
-
- return 0;
-}
-
-static int stmpe_resume(struct device *dev)
-{
- struct i2c_client *i2c = to_i2c_client(dev);
-
- if (device_may_wakeup(&i2c->dev))
- disable_irq_wake(i2c->irq);
-
- return 0;
-}
-#endif
-
-static int __devinit stmpe_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+/* Called from client specific probe routines */
+int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
{
- struct stmpe_platform_data *pdata = i2c->dev.platform_data;
+ struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev);
struct stmpe *stmpe;
int ret;
@@ -912,30 +974,43 @@ static int __devinit stmpe_probe(struct i2c_client *i2c,
mutex_init(&stmpe->irq_lock);
mutex_init(&stmpe->lock);
- stmpe->dev = &i2c->dev;
- stmpe->i2c = i2c;
-
+ stmpe->dev = ci->dev;
+ stmpe->client = ci->client;
stmpe->pdata = pdata;
stmpe->irq_base = pdata->irq_base;
-
- stmpe->partnum = id->driver_data;
- stmpe->variant = stmpe_variant_info[stmpe->partnum];
+ stmpe->ci = ci;
+ stmpe->partnum = partnum;
+ stmpe->variant = stmpe_variant_info[partnum];
stmpe->regs = stmpe->variant->regs;
stmpe->num_gpios = stmpe->variant->num_gpios;
+ dev_set_drvdata(stmpe->dev, stmpe);
- i2c_set_clientdata(i2c, stmpe);
+ if (ci->init)
+ ci->init(stmpe);
+
+ if (pdata->irq_over_gpio) {
+ ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe");
+ if (ret) {
+ dev_err(stmpe->dev, "failed to request IRQ GPIO: %d\n",
+ ret);
+ goto out_free;
+ }
+
+ stmpe->irq = gpio_to_irq(pdata->irq_gpio);
+ } else {
+ stmpe->irq = ci->irq;
+ }
ret = stmpe_chip_init(stmpe);
if (ret)
- goto out_free;
+ goto free_gpio;
ret = stmpe_irq_init(stmpe);
if (ret)
- goto out_free;
+ goto free_gpio;
- ret = request_threaded_irq(stmpe->i2c->irq, NULL, stmpe_irq,
- pdata->irq_trigger | IRQF_ONESHOT,
- "stmpe", stmpe);
+ ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq,
+ pdata->irq_trigger | IRQF_ONESHOT, "stmpe", stmpe);
if (ret) {
dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret);
goto out_removeirq;
@@ -951,67 +1026,55 @@ static int __devinit stmpe_probe(struct i2c_client *i2c,
out_removedevs:
mfd_remove_devices(stmpe->dev);
- free_irq(stmpe->i2c->irq, stmpe);
+ free_irq(stmpe->irq, stmpe);
out_removeirq:
stmpe_irq_remove(stmpe);
+free_gpio:
+ if (pdata->irq_over_gpio)
+ gpio_free(pdata->irq_gpio);
out_free:
kfree(stmpe);
return ret;
}
-static int __devexit stmpe_remove(struct i2c_client *client)
+int stmpe_remove(struct stmpe *stmpe)
{
- struct stmpe *stmpe = i2c_get_clientdata(client);
-
mfd_remove_devices(stmpe->dev);
- free_irq(stmpe->i2c->irq, stmpe);
+ free_irq(stmpe->irq, stmpe);
stmpe_irq_remove(stmpe);
+ if (stmpe->pdata->irq_over_gpio)
+ gpio_free(stmpe->pdata->irq_gpio);
+
kfree(stmpe);
return 0;
}
-static const struct i2c_device_id stmpe_id[] = {
- { "stmpe811", STMPE811 },
- { "stmpe1601", STMPE1601 },
- { "stmpe2401", STMPE2401 },
- { "stmpe2403", STMPE2403 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, stmpe_id);
-
#ifdef CONFIG_PM
-static const struct dev_pm_ops stmpe_dev_pm_ops = {
- .suspend = stmpe_suspend,
- .resume = stmpe_resume,
-};
-#endif
+static int stmpe_suspend(struct device *dev)
+{
+ struct stmpe *stmpe = dev_get_drvdata(dev);
-static struct i2c_driver stmpe_driver = {
- .driver.name = "stmpe",
- .driver.owner = THIS_MODULE,
-#ifdef CONFIG_PM
- .driver.pm = &stmpe_dev_pm_ops,
-#endif
- .probe = stmpe_probe,
- .remove = __devexit_p(stmpe_remove),
- .id_table = stmpe_id,
-};
+ if (device_may_wakeup(dev))
+ enable_irq_wake(stmpe->irq);
-static int __init stmpe_init(void)
-{
- return i2c_add_driver(&stmpe_driver);
+ return 0;
}
-subsys_initcall(stmpe_init);
-static void __exit stmpe_exit(void)
+static int stmpe_resume(struct device *dev)
{
- i2c_del_driver(&stmpe_driver);
+ struct stmpe *stmpe = dev_get_drvdata(dev);
+
+ if (device_may_wakeup(dev))
+ disable_irq_wake(stmpe->irq);
+
+ return 0;
}
-module_exit(stmpe_exit);
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("STMPE MFD core driver");
-MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>");
+const struct dev_pm_ops stmpe_dev_pm_ops = {
+ .suspend = stmpe_suspend,
+ .resume = stmpe_resume,
+};
+#endif
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index e4ee38956583..7b8e13f5b764 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -8,6 +8,14 @@
#ifndef __STMPE_H
#define __STMPE_H
+#include <linux/device.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/stmpe.h>
+#include <linux/printk.h>
+#include <linux/types.h>
+
+extern const struct dev_pm_ops stmpe_dev_pm_ops;
+
#ifdef STMPE_DUMP_BYTES
static inline void stmpe_dump_bytes(const char *str, const void *buf,
size_t len)
@@ -67,11 +75,55 @@ struct stmpe_variant_info {
int (*enable_autosleep)(struct stmpe *stmpe, int autosleep_timeout);
};
+/**
+ * struct stmpe_client_info - i2c or spi specific routines/info
+ * @data: client specific data
+ * @read_byte: read single byte
+ * @write_byte: write single byte
+ * @read_block: read block or multiple bytes
+ * @write_block: write block or multiple bytes
+ * @init: client init routine, called during probe
+ */
+struct stmpe_client_info {
+ void *data;
+ int irq;
+ void *client;
+ struct device *dev;
+ int (*read_byte)(struct stmpe *stmpe, u8 reg);
+ int (*write_byte)(struct stmpe *stmpe, u8 reg, u8 val);
+ int (*read_block)(struct stmpe *stmpe, u8 reg, u8 len, u8 *values);
+ int (*write_block)(struct stmpe *stmpe, u8 reg, u8 len,
+ const u8 *values);
+ void (*init)(struct stmpe *stmpe);
+};
+
+int stmpe_probe(struct stmpe_client_info *ci, int partnum);
+int stmpe_remove(struct stmpe *stmpe);
+
#define STMPE_ICR_LSB_HIGH (1 << 2)
#define STMPE_ICR_LSB_EDGE (1 << 1)
#define STMPE_ICR_LSB_GIM (1 << 0)
/*
+ * STMPE801
+ */
+#define STMPE801_ID 0x0108
+#define STMPE801_NR_INTERNAL_IRQS 1
+
+#define STMPE801_REG_CHIP_ID 0x00
+#define STMPE801_REG_VERSION_ID 0x02
+#define STMPE801_REG_SYS_CTRL 0x04
+#define STMPE801_REG_GPIO_INT_EN 0x08
+#define STMPE801_REG_GPIO_INT_STA 0x09
+#define STMPE801_REG_GPIO_MP_STA 0x10
+#define STMPE801_REG_GPIO_SET_PIN 0x11
+#define STMPE801_REG_GPIO_DIR 0x12
+
+#define STMPE801_REG_SYS_CTRL_RESET (1 << 7)
+#define STMPE801_REG_SYS_CTRL_INT_EN (1 << 2)
+#define STMPE801_REG_SYS_CTRL_INT_HI (1 << 0)
+
+/*
* STMPE811
*/
@@ -87,6 +139,7 @@ struct stmpe_variant_info {
#define STMPE811_REG_CHIP_ID 0x00
#define STMPE811_REG_SYS_CTRL2 0x04
+#define STMPE811_REG_SPI_CFG 0x08
#define STMPE811_REG_INT_CTRL 0x09
#define STMPE811_REG_INT_EN 0x0A
#define STMPE811_REG_INT_STA 0x0B
diff --git a/drivers/mfd/t7l66xb.c b/drivers/mfd/t7l66xb.c
index 91ad21ef7721..2d9e8799e733 100644
--- a/drivers/mfd/t7l66xb.c
+++ b/drivers/mfd/t7l66xb.c
@@ -442,21 +442,7 @@ static struct platform_driver t7l66xb_platform_driver = {
/*--------------------------------------------------------------------------*/
-static int __init t7l66xb_init(void)
-{
- int retval = 0;
-
- retval = platform_driver_register(&t7l66xb_platform_driver);
- return retval;
-}
-
-static void __exit t7l66xb_exit(void)
-{
- platform_driver_unregister(&t7l66xb_platform_driver);
-}
-
-module_init(t7l66xb_init);
-module_exit(t7l66xb_exit);
+module_platform_driver(t7l66xb_platform_driver);
MODULE_DESCRIPTION("Toshiba T7L66XB core driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tc6387xb.c b/drivers/mfd/tc6387xb.c
index 71bc835324d8..d20a284ad4ba 100644
--- a/drivers/mfd/tc6387xb.c
+++ b/drivers/mfd/tc6387xb.c
@@ -234,19 +234,7 @@ static struct platform_driver tc6387xb_platform_driver = {
.resume = tc6387xb_resume,
};
-
-static int __init tc6387xb_init(void)
-{
- return platform_driver_register(&tc6387xb_platform_driver);
-}
-
-static void __exit tc6387xb_exit(void)
-{
- platform_driver_unregister(&tc6387xb_platform_driver);
-}
-
-module_init(tc6387xb_init);
-module_exit(tc6387xb_exit);
+module_platform_driver(tc6387xb_platform_driver);
MODULE_DESCRIPTION("Toshiba TC6387XB core driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/ti-ssp.c b/drivers/mfd/ti-ssp.c
index af9ab0e5ca64..4fb0e6c8e8fe 100644
--- a/drivers/mfd/ti-ssp.c
+++ b/drivers/mfd/ti-ssp.c
@@ -458,17 +458,7 @@ static struct platform_driver ti_ssp_driver = {
}
};
-static int __init ti_ssp_init(void)
-{
- return platform_driver_register(&ti_ssp_driver);
-}
-module_init(ti_ssp_init);
-
-static void __exit ti_ssp_exit(void)
-{
- platform_driver_unregister(&ti_ssp_driver);
-}
-module_exit(ti_ssp_exit);
+module_platform_driver(ti_ssp_driver);
MODULE_DESCRIPTION("Sequencer Serial Port (SSP) Driver");
MODULE_AUTHOR("Cyril Chemparathy");
diff --git a/drivers/mfd/timberdale.c b/drivers/mfd/timberdale.c
index 02d65692ceb4..0ba26fb12cf5 100644
--- a/drivers/mfd/timberdale.c
+++ b/drivers/mfd/timberdale.c
@@ -857,7 +857,7 @@ static void __devexit timb_remove(struct pci_dev *dev)
kfree(priv);
}
-static struct pci_device_id timberdale_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(timberdale_pci_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_TIMB, PCI_DEVICE_ID_TIMB) },
{ 0 }
};
diff --git a/drivers/mfd/tps65910-irq.c b/drivers/mfd/tps65910-irq.c
index a56be931551c..95c0d7978bec 100644
--- a/drivers/mfd/tps65910-irq.c
+++ b/drivers/mfd/tps65910-irq.c
@@ -215,6 +215,7 @@ int tps65910_irq_init(struct tps65910 *tps65910, int irq,
int tps65910_irq_exit(struct tps65910 *tps65910)
{
- free_irq(tps65910->chip_irq, tps65910);
+ if (tps65910->chip_irq)
+ free_irq(tps65910->chip_irq, tps65910);
return 0;
}
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index c1da84bc1573..01cf5012a08f 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -172,15 +172,12 @@ static int tps65910_i2c_probe(struct i2c_client *i2c,
tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base);
- ret = tps65910_irq_init(tps65910, init_data->irq, init_data);
- if (ret < 0)
- goto err;
+ tps65910_irq_init(tps65910, init_data->irq, init_data);
kfree(init_data);
return ret;
err:
- mfd_remove_devices(tps65910->dev);
kfree(tps65910);
kfree(init_data);
return ret;
@@ -190,8 +187,8 @@ static int tps65910_i2c_remove(struct i2c_client *i2c)
{
struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
- mfd_remove_devices(tps65910->dev);
tps65910_irq_exit(tps65910);
+ mfd_remove_devices(tps65910->dev);
kfree(tps65910);
return 0;
diff --git a/drivers/mfd/tps65912-spi.c b/drivers/mfd/tps65912-spi.c
index 6d71e0d25744..27d3302d56b8 100644
--- a/drivers/mfd/tps65912-spi.c
+++ b/drivers/mfd/tps65912-spi.c
@@ -111,7 +111,6 @@ static int __devexit tps65912_spi_remove(struct spi_device *spi)
static struct spi_driver tps65912_spi_driver = {
.driver = {
.name = "tps65912",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = tps65912_spi_probe,
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 61e70cfaa774..e04e04ddc15e 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -34,6 +34,11 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <linux/device.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/irqdomain.h>
#include <linux/regulator/machine.h>
@@ -144,6 +149,9 @@
#define TWL_MODULE_LAST TWL4030_MODULE_LAST
+#define TWL4030_NR_IRQS 8
+#define TWL6030_NR_IRQS 20
+
/* Base Address defns for twl4030_map[] */
/* subchip/slave 0 - USB ID */
@@ -255,6 +263,7 @@ struct twl_client {
static struct twl_client twl_modules[TWL_NUM_SLAVES];
+static struct irq_domain domain;
/* mapping the module id to slave id and base address */
struct twl_mapping {
@@ -1183,14 +1192,48 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
int status;
unsigned i;
struct twl4030_platform_data *pdata = client->dev.platform_data;
+ struct device_node *node = client->dev.of_node;
u8 temp;
int ret = 0;
+ int nr_irqs = TWL4030_NR_IRQS;
+
+ if ((id->driver_data) & TWL6030_CLASS)
+ nr_irqs = TWL6030_NR_IRQS;
+
+ if (node && !pdata) {
+ /*
+ * XXX: Temporary pdata until the information is correctly
+ * retrieved by every TWL modules from DT.
+ */
+ pdata = devm_kzalloc(&client->dev,
+ sizeof(struct twl4030_platform_data),
+ GFP_KERNEL);
+ if (!pdata)
+ return -ENOMEM;
+ }
if (!pdata) {
dev_dbg(&client->dev, "no platform data?\n");
return -EINVAL;
}
+ status = irq_alloc_descs(-1, pdata->irq_base, nr_irqs, 0);
+ if (IS_ERR_VALUE(status)) {
+ dev_err(&client->dev, "Fail to allocate IRQ descs\n");
+ return status;
+ }
+
+ pdata->irq_base = status;
+ pdata->irq_end = pdata->irq_base + nr_irqs;
+
+ domain.irq_base = pdata->irq_base;
+ domain.nr_irq = nr_irqs;
+#ifdef CONFIG_OF_IRQ
+ domain.of_node = of_node_get(node);
+ domain.ops = &irq_domain_simple_ops;
+#endif
+ irq_domain_add(&domain);
+
if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
dev_dbg(&client->dev, "can't talk I2C?\n");
return -EIO;
@@ -1270,7 +1313,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1);
}
- status = add_children(pdata, id->driver_data);
+#ifdef CONFIG_OF_DEVICE
+ if (node)
+ status = of_platform_populate(node, NULL, NULL, &client->dev);
+ else
+#endif
+ status = add_children(pdata, id->driver_data);
+
fail:
if (status < 0)
twl_remove(client);
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index ae51ab5d0e5d..838ce4eb444e 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -261,17 +261,7 @@ static struct platform_driver twl4030_audio_driver = {
},
};
-static int __devinit twl4030_audio_init(void)
-{
- return platform_driver_register(&twl4030_audio_driver);
-}
-module_init(twl4030_audio_init);
-
-static void __devexit twl4030_audio_exit(void)
-{
- platform_driver_unregister(&twl4030_audio_driver);
-}
-module_exit(twl4030_audio_exit);
+module_platform_driver(twl4030_audio_driver);
MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl4030-irq.c b/drivers/mfd/twl4030-irq.c
index 29f11e0765fe..b69bb517b102 100644
--- a/drivers/mfd/twl4030-irq.c
+++ b/drivers/mfd/twl4030-irq.c
@@ -492,7 +492,7 @@ static void twl4030_sih_bus_sync_unlock(struct irq_data *data)
u8 bytes[4];
} imr;
- /* byte[0] gets overwriten as we write ... */
+ /* byte[0] gets overwritten as we write ... */
imr.word = cpu_to_le32(agent->imr << 8);
agent->imr_change_pending = false;
@@ -667,6 +667,7 @@ int twl4030_sih_setup(int module)
irq_set_chip_data(irq, agent);
irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip,
handle_edge_irq);
+ irq_set_nested_thread(irq, 1);
activate_irq(irq);
}
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
index 834f824d3c11..456ecb5ac4fe 100644
--- a/drivers/mfd/twl4030-madc.c
+++ b/drivers/mfd/twl4030-madc.c
@@ -807,19 +807,7 @@ static struct platform_driver twl4030_madc_driver = {
},
};
-static int __init twl4030_madc_init(void)
-{
- return platform_driver_register(&twl4030_madc_driver);
-}
-
-module_init(twl4030_madc_init);
-
-static void __exit twl4030_madc_exit(void)
-{
- platform_driver_unregister(&twl4030_madc_driver);
-}
-
-module_exit(twl4030_madc_exit);
+module_platform_driver(twl4030_madc_driver);
MODULE_DESCRIPTION("TWL4030 ADC driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c
index a764676f0922..d905f5171153 100644
--- a/drivers/mfd/twl4030-power.c
+++ b/drivers/mfd/twl4030-power.c
@@ -34,7 +34,8 @@
static u8 twl4030_start_script_address = 0x2b;
#define PWR_P1_SW_EVENTS 0x10
-#define PWR_DEVOFF (1<<0)
+#define PWR_DEVOFF (1 << 0)
+#define SEQ_OFFSYNC (1 << 0)
#define PHY_TO_OFF_PM_MASTER(p) (p - 0x36)
#define PHY_TO_OFF_PM_RECEIVER(p) (p - 0x5b)
@@ -511,12 +512,27 @@ int twl4030_remove_script(u8 flags)
return err;
}
+/*
+ * In master mode, start the power off sequence.
+ * After a successful execution, TWL shuts down the power to the SoC
+ * and all peripherals connected to it.
+ */
+void twl4030_power_off(void)
+{
+ int err;
+
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, PWR_DEVOFF,
+ TWL4030_PM_MASTER_P1_SW_EVENTS);
+ if (err)
+ pr_err("TWL4030 Unable to power off\n");
+}
+
void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
{
int err = 0;
int i;
struct twl4030_resconfig *resconfig;
- u8 address = twl4030_start_script_address;
+ u8 val, address = twl4030_start_script_address;
err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER,
TWL4030_PM_MASTER_KEY_CFG1,
@@ -548,6 +564,28 @@ void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts)
}
}
+ /* Board has to be wired properly to use this feature */
+ if (twl4030_scripts->use_poweroff && !pm_power_off) {
+ /* Default for SEQ_OFFSYNC is set, lets ensure this */
+ err = twl_i2c_read_u8(TWL4030_MODULE_PM_MASTER, &val,
+ TWL4030_PM_MASTER_CFG_P123_TRANSITION);
+ if (err) {
+ pr_warning("TWL4030 Unable to read registers\n");
+
+ } else if (!(val & SEQ_OFFSYNC)) {
+ val |= SEQ_OFFSYNC;
+ err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, val,
+ TWL4030_PM_MASTER_CFG_P123_TRANSITION);
+ if (err) {
+ pr_err("TWL4030 Unable to setup SEQ_OFFSYNC\n");
+ goto relock;
+ }
+ }
+
+ pm_power_off = twl4030_power_off;
+ }
+
+relock:
err = twl_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0,
TWL4030_PM_MASTER_PROTECT_KEY);
if (err)
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index 268f80fd0439..dda86293dc9f 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -509,13 +509,10 @@ static int __devinit twl6040_probe(struct platform_device *pdev)
twl6040->audpwron = -EINVAL;
if (gpio_is_valid(twl6040->audpwron)) {
- ret = gpio_request(twl6040->audpwron, "audpwron");
+ ret = gpio_request_one(twl6040->audpwron, GPIOF_OUT_INIT_LOW,
+ "audpwron");
if (ret)
goto gpio1_err;
-
- ret = gpio_direction_output(twl6040->audpwron, 0);
- if (ret)
- goto gpio2_err;
}
/* codec interrupt */
@@ -619,18 +616,7 @@ static struct platform_driver twl6040_driver = {
},
};
-static int __devinit twl6040_init(void)
-{
- return platform_driver_register(&twl6040_driver);
-}
-module_init(twl6040_init);
-
-static void __devexit twl6040_exit(void)
-{
- platform_driver_unregister(&twl6040_driver);
-}
-
-module_exit(twl6040_exit);
+module_platform_driver(twl6040_driver);
MODULE_DESCRIPTION("TWL6040 MFD");
MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
diff --git a/drivers/mfd/ucb1x00-core.c b/drivers/mfd/ucb1x00-core.c
index b281217334eb..91c4f25e0e55 100644
--- a/drivers/mfd/ucb1x00-core.c
+++ b/drivers/mfd/ucb1x00-core.c
@@ -36,6 +36,15 @@ static DEFINE_MUTEX(ucb1x00_mutex);
static LIST_HEAD(ucb1x00_drivers);
static LIST_HEAD(ucb1x00_devices);
+static struct mcp_device_id ucb1x00_id[] = {
+ { "ucb1x00", 0 }, /* auto-detection */
+ { "ucb1200", UCB_ID_1200 },
+ { "ucb1300", UCB_ID_1300 },
+ { "tc35143", UCB_ID_TC35143 },
+ { }
+};
+MODULE_DEVICE_TABLE(mcp, ucb1x00_id);
+
/**
* ucb1x00_io_set_dir - set IO direction
* @ucb: UCB1x00 structure describing chip
@@ -527,17 +536,33 @@ static struct class ucb1x00_class = {
static int ucb1x00_probe(struct mcp *mcp)
{
+ const struct mcp_device_id *mid;
struct ucb1x00 *ucb;
struct ucb1x00_driver *drv;
+ struct ucb1x00_plat_data *pdata;
unsigned int id;
int ret = -ENODEV;
int temp;
mcp_enable(mcp);
id = mcp_reg_read(mcp, UCB_ID);
+ mid = mcp_get_device_id(mcp);
- if (id != UCB_ID_1200 && id != UCB_ID_1300 && id != UCB_ID_TC35143) {
- printk(KERN_WARNING "UCB1x00 ID not found: %04x\n", id);
+ if (mid && mid->driver_data) {
+ if (id != mid->driver_data) {
+ printk(KERN_WARNING "%s wrong ID %04x found: %04x\n",
+ mid->name, (unsigned int) mid->driver_data, id);
+ goto err_disable;
+ }
+ } else {
+ mid = &ucb1x00_id[1];
+ while (mid->driver_data) {
+ if (id == mid->driver_data)
+ break;
+ mid++;
+ }
+ printk(KERN_WARNING "%s ID not found: %04x\n",
+ ucb1x00_id[0].name, id);
goto err_disable;
}
@@ -546,28 +571,28 @@ static int ucb1x00_probe(struct mcp *mcp)
if (!ucb)
goto err_disable;
-
+ pdata = mcp->attached_device.platform_data;
ucb->dev.class = &ucb1x00_class;
ucb->dev.parent = &mcp->attached_device;
- dev_set_name(&ucb->dev, "ucb1x00");
+ dev_set_name(&ucb->dev, mid->name);
spin_lock_init(&ucb->lock);
spin_lock_init(&ucb->io_lock);
sema_init(&ucb->adc_sem, 1);
- ucb->id = id;
+ ucb->id = mid;
ucb->mcp = mcp;
ucb->irq = ucb1x00_detect_irq(ucb);
if (ucb->irq == NO_IRQ) {
- printk(KERN_ERR "UCB1x00: IRQ probe failed\n");
+ printk(KERN_ERR "%s: IRQ probe failed\n", mid->name);
ret = -ENODEV;
goto err_free;
}
ucb->gpio.base = -1;
- if (mcp->gpio_base != 0) {
+ if (pdata && (pdata->gpio_base >= 0)) {
ucb->gpio.label = dev_name(&ucb->dev);
- ucb->gpio.base = mcp->gpio_base;
+ ucb->gpio.base = pdata->gpio_base;
ucb->gpio.ngpio = 10;
ucb->gpio.set = ucb1x00_gpio_set;
ucb->gpio.get = ucb1x00_gpio_get;
@@ -580,10 +605,10 @@ static int ucb1x00_probe(struct mcp *mcp)
dev_info(&ucb->dev, "gpio_base not set so no gpiolib support");
ret = request_irq(ucb->irq, ucb1x00_irq, IRQF_TRIGGER_RISING,
- "UCB1x00", ucb);
+ mid->name, ucb);
if (ret) {
- printk(KERN_ERR "ucb1x00: unable to grab irq%d: %d\n",
- ucb->irq, ret);
+ printk(KERN_ERR "%s: unable to grab irq%d: %d\n",
+ mid->name, ucb->irq, ret);
goto err_gpio;
}
@@ -705,6 +730,7 @@ static struct mcp_driver ucb1x00_driver = {
.remove = ucb1x00_remove,
.suspend = ucb1x00_suspend,
.resume = ucb1x00_resume,
+ .id_table = ucb1x00_id,
};
static int __init ucb1x00_init(void)
diff --git a/drivers/mfd/ucb1x00-ts.c b/drivers/mfd/ucb1x00-ts.c
index 38ffbd50a0d2..40ec3c118868 100644
--- a/drivers/mfd/ucb1x00-ts.c
+++ b/drivers/mfd/ucb1x00-ts.c
@@ -382,7 +382,7 @@ static int ucb1x00_ts_add(struct ucb1x00_dev *dev)
ts->adcsync = adcsync ? UCB_SYNC : UCB_NOSYNC;
idev->name = "Touchscreen panel";
- idev->id.product = ts->ucb->id;
+ idev->id.product = ts->ucb->id->driver_data;
idev->open = ucb1x00_ts_open;
idev->close = ucb1x00_ts_close;
diff --git a/drivers/mfd/vx855.c b/drivers/mfd/vx855.c
index d698703dbd46..b73cc15e0081 100644
--- a/drivers/mfd/vx855.c
+++ b/drivers/mfd/vx855.c
@@ -118,7 +118,7 @@ static void __devexit vx855_remove(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-static struct pci_device_id vx855_pci_tbl[] = {
+static DEFINE_PCI_DEVICE_TABLE(vx855_pci_tbl) = {
{ PCI_DEVICE(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VX855) },
{ 0, }
};
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 0a2b8d41a702..f5e54fae8ada 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -559,6 +559,8 @@ static int wm831x_write(struct wm831x *wm831x, unsigned short reg,
dev_vdbg(wm831x->dev, "Write %04x to R%d(0x%x)\n",
buf[i], reg + i, reg + i);
ret = regmap_write(wm831x->regmap, reg + i, buf[i]);
+ if (ret != 0)
+ return ret;
}
return 0;
@@ -1875,7 +1877,6 @@ err_irq:
err_regmap:
mfd_remove_devices(wm831x->dev);
regmap_exit(wm831x->regmap);
- kfree(wm831x);
return ret;
}
@@ -1887,7 +1888,6 @@ void wm831x_device_exit(struct wm831x *wm831x)
free_irq(wm831x->irq_base + WM831X_IRQ_AUXADC_DATA, wm831x);
wm831x_irq_exit(wm831x);
regmap_exit(wm831x->regmap);
- kfree(wm831x);
}
int wm831x_device_suspend(struct wm831x *wm831x)
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c
index ac8da1d439da..cb15609b0a48 100644
--- a/drivers/mfd/wm831x-i2c.c
+++ b/drivers/mfd/wm831x-i2c.c
@@ -30,7 +30,7 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
struct wm831x *wm831x;
int ret;
- wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
+ wm831x = devm_kzalloc(&i2c->dev, sizeof(struct wm831x), GFP_KERNEL);
if (wm831x == NULL)
return -ENOMEM;
@@ -42,7 +42,6 @@ static int wm831x_i2c_probe(struct i2c_client *i2c,
ret = PTR_ERR(wm831x->regmap);
dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
ret);
- kfree(wm831x);
return ret;
}
diff --git a/drivers/mfd/wm831x-irq.c b/drivers/mfd/wm831x-irq.c
index f4747a4a9a93..bec4d0539160 100644
--- a/drivers/mfd/wm831x-irq.c
+++ b/drivers/mfd/wm831x-irq.c
@@ -325,11 +325,6 @@ static inline int irq_data_to_status_reg(struct wm831x_irq_data *irq_data)
return WM831X_INTERRUPT_STATUS_1 - 1 + irq_data->reg;
}
-static inline int irq_data_to_mask_reg(struct wm831x_irq_data *irq_data)
-{
- return WM831X_INTERRUPT_STATUS_1_MASK - 1 + irq_data->reg;
-}
-
static inline struct wm831x_irq_data *irq_to_wm831x_irq(struct wm831x *wm831x,
int irq)
{
@@ -477,8 +472,7 @@ static irqreturn_t wm831x_irq_thread(int irq, void *data)
handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHPD);
if (primary & WM831X_TCHDATA_INT)
handle_nested_irq(wm831x->irq_base + WM831X_IRQ_TCHDATA);
- if (primary & (WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT))
- goto out;
+ primary &= ~(WM831X_TCHDATA_EINT | WM831X_TCHPD_EINT);
for (i = 0; i < ARRAY_SIZE(wm831x_irqs); i++) {
int offset = wm831x_irqs[i].reg - 1;
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c
index 8d6a9a969dbc..62ef3254105f 100644
--- a/drivers/mfd/wm831x-spi.c
+++ b/drivers/mfd/wm831x-spi.c
@@ -30,7 +30,7 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
type = (enum wm831x_parent)id->driver_data;
- wm831x = kzalloc(sizeof(struct wm831x), GFP_KERNEL);
+ wm831x = devm_kzalloc(&spi->dev, sizeof(struct wm831x), GFP_KERNEL);
if (wm831x == NULL)
return -ENOMEM;
@@ -45,7 +45,6 @@ static int __devinit wm831x_spi_probe(struct spi_device *spi)
ret = PTR_ERR(wm831x->regmap);
dev_err(wm831x->dev, "Failed to allocate register map: %d\n",
ret);
- kfree(wm831x);
return ret;
}
@@ -95,7 +94,6 @@ MODULE_DEVICE_TABLE(spi, wm831x_spi_id);
static struct spi_driver wm831x_spi_driver = {
.driver = {
.name = "wm831x",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
.pm = &wm831x_spi_pm,
},
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c
index e81cc31e4202..dd1caaac55e4 100644
--- a/drivers/mfd/wm8350-core.c
+++ b/drivers/mfd/wm8350-core.c
@@ -573,6 +573,8 @@ int wm8350_device_init(struct wm8350 *wm8350, int irq,
u16 id1, id2, mask_rev;
u16 cust_id, mode, chip_rev;
+ dev_set_drvdata(wm8350->dev, wm8350);
+
/* get WM8350 revision and config mode */
ret = wm8350->read_dev(wm8350, WM8350_RESET_ID, sizeof(id1), &id1);
if (ret != 0) {
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c
index 5fe5de166adb..d955faaf27c4 100644
--- a/drivers/mfd/wm8350-i2c.c
+++ b/drivers/mfd/wm8350-i2c.c
@@ -63,7 +63,7 @@ static int wm8350_i2c_probe(struct i2c_client *i2c,
struct wm8350 *wm8350;
int ret = 0;
- wm8350 = kzalloc(sizeof(struct wm8350), GFP_KERNEL);
+ wm8350 = devm_kzalloc(&i2c->dev, sizeof(struct wm8350), GFP_KERNEL);
if (wm8350 == NULL)
return -ENOMEM;
@@ -80,7 +80,6 @@ static int wm8350_i2c_probe(struct i2c_client *i2c,
return ret;
err:
- kfree(wm8350);
return ret;
}
@@ -89,7 +88,6 @@ static int wm8350_i2c_remove(struct i2c_client *i2c)
struct wm8350 *wm8350 = i2c_get_clientdata(i2c);
wm8350_device_exit(wm8350);
- kfree(wm8350);
return 0;
}
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c
index 62b4626f4561..2204893444a6 100644
--- a/drivers/mfd/wm8400-core.c
+++ b/drivers/mfd/wm8400-core.c
@@ -344,7 +344,7 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
struct wm8400 *wm8400;
int ret;
- wm8400 = kzalloc(sizeof(struct wm8400), GFP_KERNEL);
+ wm8400 = devm_kzalloc(&i2c->dev, sizeof(struct wm8400), GFP_KERNEL);
if (wm8400 == NULL) {
ret = -ENOMEM;
goto err;
@@ -353,7 +353,7 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
wm8400->regmap = regmap_init_i2c(i2c, &wm8400_regmap_config);
if (IS_ERR(wm8400->regmap)) {
ret = PTR_ERR(wm8400->regmap);
- goto struct_err;
+ goto err;
}
wm8400->dev = &i2c->dev;
@@ -367,8 +367,6 @@ static int wm8400_i2c_probe(struct i2c_client *i2c,
map_err:
regmap_exit(wm8400->regmap);
-struct_err:
- kfree(wm8400);
err:
return ret;
}
@@ -379,7 +377,6 @@ static int wm8400_i2c_remove(struct i2c_client *i2c)
wm8400_release(wm8400);
regmap_exit(wm8400->regmap);
- kfree(wm8400);
return 0;
}
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 5664696f2d3a..6a1a092db146 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -500,6 +500,14 @@ config USB_SWITCH_FSA9480
stereo and mono audio, video, microphone and UART data to use
a common connector port.
+config MAX8997_MUIC
+ tristate "MAX8997 MUIC Support"
+ depends on MFD_MAX8997
+ help
+ If you say yes here you get support for the MUIC device of
+ Maxim MAX8997 PMIC.
+ The MAX8997 MUIC is a USB port accessory detector and switch.
+
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b26495a02554..3e1d80106f04 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -48,3 +48,4 @@ obj-y += lis3lv02d/
obj-y += carma/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
+obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o
diff --git a/drivers/misc/ab8500-pwm.c b/drivers/misc/ab8500-pwm.c
index 2208a9d52622..d7a9aa14e5d5 100644
--- a/drivers/misc/ab8500-pwm.c
+++ b/drivers/misc/ab8500-pwm.c
@@ -8,8 +8,8 @@
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/pwm.h>
-#include <linux/mfd/ab8500.h>
#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <linux/module.h>
/*
diff --git a/drivers/misc/iwmc3200top/main.c b/drivers/misc/iwmc3200top/main.c
index b1f4563be9ae..701eb600b127 100644
--- a/drivers/misc/iwmc3200top/main.c
+++ b/drivers/misc/iwmc3200top/main.c
@@ -376,20 +376,20 @@ static int blocks;
module_param(blocks, int, 0604);
MODULE_PARM_DESC(blocks, "max_blocks_to_send");
-static int dump;
+static bool dump;
module_param(dump, bool, 0604);
MODULE_PARM_DESC(dump, "dump_hex_content");
-static int jump = 1;
+static bool jump = 1;
module_param(jump, bool, 0604);
-static int direct = 1;
+static bool direct = 1;
module_param(direct, bool, 0604);
-static int checksum = 1;
+static bool checksum = 1;
module_param(checksum, bool, 0604);
-static int fw_download = 1;
+static bool fw_download = 1;
module_param(fw_download, bool, 0604);
static int block_size = IWMC_SDIO_BLK_SIZE;
@@ -398,7 +398,7 @@ module_param(block_size, int, 0404);
static int download_trans_blks = IWMC_DEFAULT_TR_BLK;
module_param(download_trans_blks, int, 0604);
-static int rubbish_barker;
+static bool rubbish_barker;
module_param(rubbish_barker, bool, 0604);
#ifdef CONFIG_IWMC3200TOP_DEBUG
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index 29d12a70eb1b..a981e2a42f92 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -111,6 +111,8 @@ static struct kernel_param_ops param_ops_axis = {
.get = param_get_int,
};
+#define param_check_axis(name, p) param_check_int(name, p)
+
module_param_array_named(axes, lis3_dev.ac.as_array, axis, NULL, 0644);
MODULE_PARM_DESC(axes, "Axis-mapping for x,y,z directions");
diff --git a/drivers/misc/max8997-muic.c b/drivers/misc/max8997-muic.c
new file mode 100644
index 000000000000..d74ef41aabd5
--- /dev/null
+++ b/drivers/misc/max8997-muic.c
@@ -0,0 +1,505 @@
+/*
+ * max8997-muic.c - MAX8997 muic driver for the Maxim 8997
+ *
+ * Copyright (C) 2011 Samsung Electrnoics
+ * Donggeun Kim <dg77.kim@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/i2c.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/kobject.h>
+#include <linux/mfd/max8997.h>
+#include <linux/mfd/max8997-private.h>
+
+/* MAX8997-MUIC STATUS1 register */
+#define STATUS1_ADC_SHIFT 0
+#define STATUS1_ADCLOW_SHIFT 5
+#define STATUS1_ADCERR_SHIFT 6
+#define STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT)
+#define STATUS1_ADCLOW_MASK (0x1 << STATUS1_ADCLOW_SHIFT)
+#define STATUS1_ADCERR_MASK (0x1 << STATUS1_ADCERR_SHIFT)
+
+/* MAX8997-MUIC STATUS2 register */
+#define STATUS2_CHGTYP_SHIFT 0
+#define STATUS2_CHGDETRUN_SHIFT 3
+#define STATUS2_DCDTMR_SHIFT 4
+#define STATUS2_DBCHG_SHIFT 5
+#define STATUS2_VBVOLT_SHIFT 6
+#define STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT)
+#define STATUS2_CHGDETRUN_MASK (0x1 << STATUS2_CHGDETRUN_SHIFT)
+#define STATUS2_DCDTMR_MASK (0x1 << STATUS2_DCDTMR_SHIFT)
+#define STATUS2_DBCHG_MASK (0x1 << STATUS2_DBCHG_SHIFT)
+#define STATUS2_VBVOLT_MASK (0x1 << STATUS2_VBVOLT_SHIFT)
+
+/* MAX8997-MUIC STATUS3 register */
+#define STATUS3_OVP_SHIFT 2
+#define STATUS3_OVP_MASK (0x1 << STATUS3_OVP_SHIFT)
+
+/* MAX8997-MUIC CONTROL1 register */
+#define COMN1SW_SHIFT 0
+#define COMP2SW_SHIFT 3
+#define COMN1SW_MASK (0x7 << COMN1SW_SHIFT)
+#define COMP2SW_MASK (0x7 << COMP2SW_SHIFT)
+#define SW_MASK (COMP2SW_MASK | COMN1SW_MASK)
+
+#define MAX8997_SW_USB ((1 << COMP2SW_SHIFT) | (1 << COMN1SW_SHIFT))
+#define MAX8997_SW_AUDIO ((2 << COMP2SW_SHIFT) | (2 << COMN1SW_SHIFT))
+#define MAX8997_SW_UART ((3 << COMP2SW_SHIFT) | (3 << COMN1SW_SHIFT))
+#define MAX8997_SW_OPEN ((0 << COMP2SW_SHIFT) | (0 << COMN1SW_SHIFT))
+
+#define MAX8997_ADC_GROUND 0x00
+#define MAX8997_ADC_MHL 0x01
+#define MAX8997_ADC_JIG_USB_1 0x18
+#define MAX8997_ADC_JIG_USB_2 0x19
+#define MAX8997_ADC_DESKDOCK 0x1a
+#define MAX8997_ADC_JIG_UART 0x1c
+#define MAX8997_ADC_CARDOCK 0x1d
+#define MAX8997_ADC_OPEN 0x1f
+
+struct max8997_muic_irq {
+ unsigned int irq;
+ const char *name;
+};
+
+static struct max8997_muic_irq muic_irqs[] = {
+ { MAX8997_MUICIRQ_ADCError, "muic-ADC_error" },
+ { MAX8997_MUICIRQ_ADCLow, "muic-ADC_low" },
+ { MAX8997_MUICIRQ_ADC, "muic-ADC" },
+ { MAX8997_MUICIRQ_VBVolt, "muic-VB_voltage" },
+ { MAX8997_MUICIRQ_DBChg, "muic-DB_charger" },
+ { MAX8997_MUICIRQ_DCDTmr, "muic-DCD_timer" },
+ { MAX8997_MUICIRQ_ChgDetRun, "muic-CDR_status" },
+ { MAX8997_MUICIRQ_ChgTyp, "muic-charger_type" },
+ { MAX8997_MUICIRQ_OVP, "muic-over_voltage" },
+};
+
+struct max8997_muic_info {
+ struct device *dev;
+ struct max8997_dev *iodev;
+ struct i2c_client *muic;
+ struct max8997_muic_platform_data *muic_pdata;
+
+ int irq;
+ struct work_struct irq_work;
+
+ enum max8997_muic_charger_type pre_charger_type;
+ int pre_adc;
+
+ struct mutex mutex;
+};
+
+static int max8997_muic_handle_usb(struct max8997_muic_info *info,
+ enum max8997_muic_usb_type usb_type, bool attached)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ int ret = 0;
+
+ if (usb_type == MAX8997_USB_HOST) {
+ /* switch to USB */
+ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
+ attached ? MAX8997_SW_USB : MAX8997_SW_OPEN,
+ SW_MASK);
+ if (ret) {
+ dev_err(info->dev, "failed to update muic register\n");
+ goto out;
+ }
+ }
+
+ if (mdata->usb_callback)
+ mdata->usb_callback(usb_type, attached);
+out:
+ return ret;
+}
+
+static void max8997_muic_handle_mhl(struct max8997_muic_info *info,
+ bool attached)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+
+ if (mdata->mhl_callback)
+ mdata->mhl_callback(attached);
+}
+
+static int max8997_muic_handle_dock(struct max8997_muic_info *info,
+ int adc, bool attached)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ int ret = 0;
+
+ /* switch to AUDIO */
+ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
+ attached ? MAX8997_SW_AUDIO : MAX8997_SW_OPEN,
+ SW_MASK);
+ if (ret) {
+ dev_err(info->dev, "failed to update muic register\n");
+ goto out;
+ }
+
+ switch (adc) {
+ case MAX8997_ADC_DESKDOCK:
+ if (mdata->deskdock_callback)
+ mdata->deskdock_callback(attached);
+ break;
+ case MAX8997_ADC_CARDOCK:
+ if (mdata->cardock_callback)
+ mdata->cardock_callback(attached);
+ break;
+ default:
+ break;
+ }
+out:
+ return ret;
+}
+
+static int max8997_muic_handle_jig_uart(struct max8997_muic_info *info,
+ bool attached)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ int ret = 0;
+
+ /* switch to UART */
+ ret = max8997_update_reg(info->muic, MAX8997_MUIC_REG_CONTROL1,
+ attached ? MAX8997_SW_UART : MAX8997_SW_OPEN,
+ SW_MASK);
+ if (ret) {
+ dev_err(info->dev, "failed to update muic register\n");
+ goto out;
+ }
+
+ if (mdata->uart_callback)
+ mdata->uart_callback(attached);
+out:
+ return ret;
+}
+
+static int max8997_muic_handle_adc_detach(struct max8997_muic_info *info)
+{
+ int ret = 0;
+
+ switch (info->pre_adc) {
+ case MAX8997_ADC_GROUND:
+ ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, false);
+ break;
+ case MAX8997_ADC_MHL:
+ max8997_muic_handle_mhl(info, false);
+ break;
+ case MAX8997_ADC_JIG_USB_1:
+ case MAX8997_ADC_JIG_USB_2:
+ ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, false);
+ break;
+ case MAX8997_ADC_DESKDOCK:
+ case MAX8997_ADC_CARDOCK:
+ ret = max8997_muic_handle_dock(info, info->pre_adc, false);
+ break;
+ case MAX8997_ADC_JIG_UART:
+ ret = max8997_muic_handle_jig_uart(info, false);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+static int max8997_muic_handle_adc(struct max8997_muic_info *info, int adc)
+{
+ int ret = 0;
+
+ switch (adc) {
+ case MAX8997_ADC_GROUND:
+ ret = max8997_muic_handle_usb(info, MAX8997_USB_HOST, true);
+ break;
+ case MAX8997_ADC_MHL:
+ max8997_muic_handle_mhl(info, true);
+ break;
+ case MAX8997_ADC_JIG_USB_1:
+ case MAX8997_ADC_JIG_USB_2:
+ ret = max8997_muic_handle_usb(info, MAX8997_USB_DEVICE, true);
+ break;
+ case MAX8997_ADC_DESKDOCK:
+ case MAX8997_ADC_CARDOCK:
+ ret = max8997_muic_handle_dock(info, adc, true);
+ break;
+ case MAX8997_ADC_JIG_UART:
+ ret = max8997_muic_handle_jig_uart(info, true);
+ break;
+ case MAX8997_ADC_OPEN:
+ ret = max8997_muic_handle_adc_detach(info);
+ break;
+ default:
+ break;
+ }
+
+ info->pre_adc = adc;
+
+ return ret;
+}
+
+static int max8997_muic_handle_charger_type(struct max8997_muic_info *info,
+ enum max8997_muic_charger_type charger_type)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ u8 adc;
+ int ret;
+
+ ret = max8997_read_reg(info->muic, MAX8997_MUIC_REG_STATUS1, &adc);
+ if (ret) {
+ dev_err(info->dev, "failed to read muic register\n");
+ goto out;
+ }
+
+ switch (charger_type) {
+ case MAX8997_CHARGER_TYPE_NONE:
+ if (mdata->charger_callback)
+ mdata->charger_callback(false, charger_type);
+ if (info->pre_charger_type == MAX8997_CHARGER_TYPE_USB) {
+ max8997_muic_handle_usb(info,
+ MAX8997_USB_DEVICE, false);
+ }
+ break;
+ case MAX8997_CHARGER_TYPE_USB:
+ if ((adc & STATUS1_ADC_MASK) == MAX8997_ADC_OPEN) {
+ max8997_muic_handle_usb(info,
+ MAX8997_USB_DEVICE, true);
+ }
+ if (mdata->charger_callback)
+ mdata->charger_callback(true, charger_type);
+ break;
+ case MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT:
+ case MAX8997_CHARGER_TYPE_DEDICATED_CHG:
+ case MAX8997_CHARGER_TYPE_500MA:
+ case MAX8997_CHARGER_TYPE_1A:
+ if (mdata->charger_callback)
+ mdata->charger_callback(true, charger_type);
+ break;
+ default:
+ break;
+ }
+
+ info->pre_charger_type = charger_type;
+out:
+ return ret;
+}
+
+static void max8997_muic_irq_work(struct work_struct *work)
+{
+ struct max8997_muic_info *info = container_of(work,
+ struct max8997_muic_info, irq_work);
+ struct max8997_platform_data *pdata =
+ dev_get_platdata(info->iodev->dev);
+ u8 status[3];
+ u8 adc, chg_type;
+
+ int irq_type = info->irq - pdata->irq_base;
+ int ret;
+
+ mutex_lock(&info->mutex);
+
+ ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
+ 3, status);
+ if (ret) {
+ dev_err(info->dev, "failed to read muic register\n");
+ mutex_unlock(&info->mutex);
+ return;
+ }
+
+ dev_dbg(info->dev, "%s: STATUS1:0x%x, 2:0x%x\n", __func__,
+ status[0], status[1]);
+
+ switch (irq_type) {
+ case MAX8997_MUICIRQ_ADC:
+ adc = status[0] & STATUS1_ADC_MASK;
+ adc >>= STATUS1_ADC_SHIFT;
+
+ max8997_muic_handle_adc(info, adc);
+ break;
+ case MAX8997_MUICIRQ_ChgTyp:
+ chg_type = status[1] & STATUS2_CHGTYP_MASK;
+ chg_type >>= STATUS2_CHGTYP_SHIFT;
+
+ max8997_muic_handle_charger_type(info, chg_type);
+ break;
+ default:
+ dev_info(info->dev, "misc interrupt: %s occurred\n",
+ muic_irqs[irq_type].name);
+ break;
+ }
+
+ mutex_unlock(&info->mutex);
+
+ return;
+}
+
+static irqreturn_t max8997_muic_irq_handler(int irq, void *data)
+{
+ struct max8997_muic_info *info = data;
+
+ dev_dbg(info->dev, "irq:%d\n", irq);
+ info->irq = irq;
+
+ schedule_work(&info->irq_work);
+
+ return IRQ_HANDLED;
+}
+
+static void max8997_muic_detect_dev(struct max8997_muic_info *info)
+{
+ int ret;
+ u8 status[2], adc, chg_type;
+
+ ret = max8997_bulk_read(info->muic, MAX8997_MUIC_REG_STATUS1,
+ 2, status);
+ if (ret) {
+ dev_err(info->dev, "failed to read muic register\n");
+ return;
+ }
+
+ dev_info(info->dev, "STATUS1:0x%x, STATUS2:0x%x\n",
+ status[0], status[1]);
+
+ adc = status[0] & STATUS1_ADC_MASK;
+ adc >>= STATUS1_ADC_SHIFT;
+
+ chg_type = status[1] & STATUS2_CHGTYP_MASK;
+ chg_type >>= STATUS2_CHGTYP_SHIFT;
+
+ max8997_muic_handle_adc(info, adc);
+ max8997_muic_handle_charger_type(info, chg_type);
+}
+
+static void max8997_initialize_device(struct max8997_muic_info *info)
+{
+ struct max8997_muic_platform_data *mdata = info->muic_pdata;
+ int i;
+
+ for (i = 0; i < mdata->num_init_data; i++) {
+ max8997_write_reg(info->muic, mdata->init_data[i].addr,
+ mdata->init_data[i].data);
+ }
+}
+
+static int __devinit max8997_muic_probe(struct platform_device *pdev)
+{
+ struct max8997_dev *iodev = dev_get_drvdata(pdev->dev.parent);
+ struct max8997_platform_data *pdata = dev_get_platdata(iodev->dev);
+ struct max8997_muic_info *info;
+ int ret, i;
+
+ info = kzalloc(sizeof(struct max8997_muic_info), GFP_KERNEL);
+ if (!info) {
+ dev_err(&pdev->dev, "failed to allocate memory\n");
+ ret = -ENOMEM;
+ goto err_kfree;
+ }
+
+ if (!pdata->muic_pdata) {
+ dev_err(&pdev->dev, "failed to get platform_data\n");
+ ret = -EINVAL;
+ goto err_pdata;
+ }
+ info->muic_pdata = pdata->muic_pdata;
+
+ info->dev = &pdev->dev;
+ info->iodev = iodev;
+ info->muic = iodev->muic;
+
+ platform_set_drvdata(pdev, info);
+ mutex_init(&info->mutex);
+
+ INIT_WORK(&info->irq_work, max8997_muic_irq_work);
+
+ for (i = 0; i < ARRAY_SIZE(muic_irqs); i++) {
+ struct max8997_muic_irq *muic_irq = &muic_irqs[i];
+
+ ret = request_threaded_irq(pdata->irq_base + muic_irq->irq,
+ NULL, max8997_muic_irq_handler,
+ 0, muic_irq->name,
+ info);
+ if (ret) {
+ dev_err(&pdev->dev,
+ "failed: irq request (IRQ: %d,"
+ " error :%d)\n",
+ muic_irq->irq, ret);
+
+ for (i = i - 1; i >= 0; i--)
+ free_irq(muic_irq->irq, info);
+
+ goto err_irq;
+ }
+ }
+
+ /* Initialize registers according to platform data */
+ max8997_initialize_device(info);
+
+ /* Initial device detection */
+ max8997_muic_detect_dev(info);
+
+ return ret;
+
+err_irq:
+err_pdata:
+ kfree(info);
+err_kfree:
+ return ret;
+}
+
+static int __devexit max8997_muic_remove(struct platform_device *pdev)
+{
+ struct max8997_muic_info *info = platform_get_drvdata(pdev);
+ struct max8997_platform_data *pdata =
+ dev_get_platdata(info->iodev->dev);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(muic_irqs); i++)
+ free_irq(pdata->irq_base + muic_irqs[i].irq, info);
+ cancel_work_sync(&info->irq_work);
+
+ kfree(info);
+
+ return 0;
+}
+
+static struct platform_driver max8997_muic_driver = {
+ .driver = {
+ .name = "max8997-muic",
+ .owner = THIS_MODULE,
+ },
+ .probe = max8997_muic_probe,
+ .remove = __devexit_p(max8997_muic_remove),
+};
+
+static int __init max8997_muic_init(void)
+{
+ return platform_driver_register(&max8997_muic_driver);
+}
+module_init(max8997_muic_init);
+
+static void __exit max8997_muic_exit(void)
+{
+ platform_driver_unregister(&max8997_muic_driver);
+}
+module_exit(max8997_muic_exit);
+
+MODULE_DESCRIPTION("Maxim MAX8997 MUIC driver");
+MODULE_AUTHOR("Donggeun Kim <dg77.kim@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 12eef393e216..400756ec7c49 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -6,5 +6,4 @@ subdir-ccflags-$(CONFIG_MMC_DEBUG) := -DDEBUG
obj-$(CONFIG_MMC) += core/
obj-$(CONFIG_MMC) += card/
-obj-$(CONFIG_MMC) += host/
-
+obj-$(subst m,y,$(CONFIG_MMC)) += host/
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 1e0e27cbe987..0cad48a284a8 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -107,6 +107,8 @@ struct mmc_blk_data {
*/
unsigned int part_curr;
struct device_attribute force_ro;
+ struct device_attribute power_ro_lock;
+ int area_type;
};
static DEFINE_MUTEX(open_lock);
@@ -119,6 +121,7 @@ enum mmc_blk_status {
MMC_BLK_ABORT,
MMC_BLK_DATA_ERR,
MMC_BLK_ECC_ERR,
+ MMC_BLK_NOMEDIUM,
};
module_param(perdev_minors, int, 0444);
@@ -165,6 +168,70 @@ static void mmc_blk_put(struct mmc_blk_data *md)
mutex_unlock(&open_lock);
}
+static ssize_t power_ro_lock_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int ret;
+ struct mmc_blk_data *md = mmc_blk_get(dev_to_disk(dev));
+ struct mmc_card *card = md->queue.card;
+ int locked = 0;
+
+ if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PERM_WP_EN)
+ locked = 2;
+ else if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_EN)
+ locked = 1;
+
+ ret = snprintf(buf, PAGE_SIZE, "%d\n", locked);
+
+ return ret;
+}
+
+static ssize_t power_ro_lock_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int ret;
+ struct mmc_blk_data *md, *part_md;
+ struct mmc_card *card;
+ unsigned long set;
+
+ if (kstrtoul(buf, 0, &set))
+ return -EINVAL;
+
+ if (set != 1)
+ return count;
+
+ md = mmc_blk_get(dev_to_disk(dev));
+ card = md->queue.card;
+
+ mmc_claim_host(card->host);
+
+ ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP,
+ card->ext_csd.boot_ro_lock |
+ EXT_CSD_BOOT_WP_B_PWR_WP_EN,
+ card->ext_csd.part_time);
+ if (ret)
+ pr_err("%s: Locking boot partition ro until next power on failed: %d\n", md->disk->disk_name, ret);
+ else
+ card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN;
+
+ mmc_release_host(card->host);
+
+ if (!ret) {
+ pr_info("%s: Locking boot partition ro until next power on\n",
+ md->disk->disk_name);
+ set_disk_ro(md->disk, 1);
+
+ list_for_each_entry(part_md, &md->part, part)
+ if (part_md->area_type == MMC_BLK_DATA_AREA_BOOT) {
+ pr_info("%s: Locking boot partition ro until next power on\n", part_md->disk->disk_name);
+ set_disk_ro(part_md->disk, 1);
+ }
+ }
+
+ mmc_blk_put(md);
+ return count;
+}
+
static ssize_t force_ro_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -266,6 +333,9 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
goto idata_err;
}
+ if (!idata->buf_bytes)
+ return idata;
+
idata->buf = kzalloc(idata->buf_bytes, GFP_KERNEL);
if (!idata->buf) {
err = -ENOMEM;
@@ -312,25 +382,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
if (IS_ERR(idata))
return PTR_ERR(idata);
- cmd.opcode = idata->ic.opcode;
- cmd.arg = idata->ic.arg;
- cmd.flags = idata->ic.flags;
-
- data.sg = &sg;
- data.sg_len = 1;
- data.blksz = idata->ic.blksz;
- data.blocks = idata->ic.blocks;
-
- sg_init_one(data.sg, idata->buf, idata->buf_bytes);
-
- if (idata->ic.write_flag)
- data.flags = MMC_DATA_WRITE;
- else
- data.flags = MMC_DATA_READ;
-
- mrq.cmd = &cmd;
- mrq.data = &data;
-
md = mmc_blk_get(bdev->bd_disk);
if (!md) {
err = -EINVAL;
@@ -343,6 +394,48 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
goto cmd_done;
}
+ cmd.opcode = idata->ic.opcode;
+ cmd.arg = idata->ic.arg;
+ cmd.flags = idata->ic.flags;
+
+ if (idata->buf_bytes) {
+ data.sg = &sg;
+ data.sg_len = 1;
+ data.blksz = idata->ic.blksz;
+ data.blocks = idata->ic.blocks;
+
+ sg_init_one(data.sg, idata->buf, idata->buf_bytes);
+
+ if (idata->ic.write_flag)
+ data.flags = MMC_DATA_WRITE;
+ else
+ data.flags = MMC_DATA_READ;
+
+ /* data.flags must already be set before doing this. */
+ mmc_set_data_timeout(&data, card);
+
+ /* Allow overriding the timeout_ns for empirical tuning. */
+ if (idata->ic.data_timeout_ns)
+ data.timeout_ns = idata->ic.data_timeout_ns;
+
+ if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
+ /*
+ * Pretend this is a data transfer and rely on the
+ * host driver to compute timeout. When all host
+ * drivers support cmd.cmd_timeout for R1B, this
+ * can be changed to:
+ *
+ * mrq.data = NULL;
+ * cmd.cmd_timeout = idata->ic.cmd_timeout_ms;
+ */
+ data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000;
+ }
+
+ mrq.data = &data;
+ }
+
+ mrq.cmd = &cmd;
+
mmc_claim_host(card->host);
if (idata->ic.is_acmd) {
@@ -351,24 +444,6 @@ static int mmc_blk_ioctl_cmd(struct block_device *bdev,
goto cmd_rel_host;
}
- /* data.flags must already be set before doing this. */
- mmc_set_data_timeout(&data, card);
- /* Allow overriding the timeout_ns for empirical tuning. */
- if (idata->ic.data_timeout_ns)
- data.timeout_ns = idata->ic.data_timeout_ns;
-
- if ((cmd.flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
- /*
- * Pretend this is a data transfer and rely on the host driver
- * to compute timeout. When all host drivers support
- * cmd.cmd_timeout for R1B, this can be changed to:
- *
- * mrq.data = NULL;
- * cmd.cmd_timeout = idata->ic.cmd_timeout_ms;
- */
- data.timeout_ns = idata->ic.cmd_timeout_ms * 1000000;
- }
-
mmc_wait_for_req(card->host, &mrq);
if (cmd.error) {
@@ -565,6 +640,7 @@ static int get_card_status(struct mmc_card *card, u32 *status, int retries)
return err;
}
+#define ERR_NOMEDIUM 3
#define ERR_RETRY 2
#define ERR_ABORT 1
#define ERR_CONTINUE 0
@@ -632,6 +708,9 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
u32 status, stop_status = 0;
int err, retry;
+ if (mmc_card_removed(card))
+ return ERR_NOMEDIUM;
+
/*
* Try to get card status which indicates both the card state
* and why there was no response. If the first attempt fails,
@@ -648,8 +727,12 @@ static int mmc_blk_cmd_recovery(struct mmc_card *card, struct request *req,
}
/* We couldn't get a response from the card. Give up. */
- if (err)
+ if (err) {
+ /* Check if the card is removed */
+ if (mmc_detect_card_removed(card->host))
+ return ERR_NOMEDIUM;
return ERR_ABORT;
+ }
/* Flag ECC errors */
if ((status & R1_CARD_ECC_FAILED) ||
@@ -922,6 +1005,8 @@ static int mmc_blk_err_check(struct mmc_card *card,
return MMC_BLK_RETRY;
case ERR_ABORT:
return MMC_BLK_ABORT;
+ case ERR_NOMEDIUM:
+ return MMC_BLK_NOMEDIUM;
case ERR_CONTINUE:
break;
}
@@ -1255,6 +1340,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
if (!ret)
goto start_new_req;
break;
+ case MMC_BLK_NOMEDIUM:
+ goto cmd_abort;
}
if (ret) {
@@ -1271,6 +1358,8 @@ static int mmc_blk_issue_rw_rq(struct mmc_queue *mq, struct request *rqc)
cmd_abort:
spin_lock_irq(&md->lock);
+ if (mmc_card_removed(card))
+ req->cmd_flags |= REQ_QUIET;
while (ret)
ret = __blk_end_request(req, -EIO, blk_rq_cur_bytes(req));
spin_unlock_irq(&md->lock);
@@ -1339,7 +1428,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
struct device *parent,
sector_t size,
bool default_ro,
- const char *subname)
+ const char *subname,
+ int area_type)
{
struct mmc_blk_data *md;
int devidx, ret;
@@ -1364,11 +1454,12 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
if (!subname) {
md->name_idx = find_first_zero_bit(name_use, max_devices);
__set_bit(md->name_idx, name_use);
- }
- else
+ } else
md->name_idx = ((struct mmc_blk_data *)
dev_to_disk(parent)->private_data)->name_idx;
+ md->area_type = area_type;
+
/*
* Set the read-only status based on the supported commands
* and the write protect switch.
@@ -1462,7 +1553,8 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
size = card->csd.capacity << (card->csd.read_blkbits - 9);
}
- md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL);
+ md = mmc_blk_alloc_req(card, &card->dev, size, false, NULL,
+ MMC_BLK_DATA_AREA_MAIN);
return md;
}
@@ -1471,13 +1563,14 @@ static int mmc_blk_alloc_part(struct mmc_card *card,
unsigned int part_type,
sector_t size,
bool default_ro,
- const char *subname)
+ const char *subname,
+ int area_type)
{
char cap_str[10];
struct mmc_blk_data *part_md;
part_md = mmc_blk_alloc_req(card, disk_to_dev(md->disk), size, default_ro,
- subname);
+ subname, area_type);
if (IS_ERR(part_md))
return PTR_ERR(part_md);
part_md->part_type = part_type;
@@ -1510,7 +1603,8 @@ static int mmc_blk_alloc_parts(struct mmc_card *card, struct mmc_blk_data *md)
card->part[idx].part_cfg,
card->part[idx].size >> 9,
card->part[idx].force_ro,
- card->part[idx].name);
+ card->part[idx].name,
+ card->part[idx].area_type);
if (ret)
return ret;
}
@@ -1539,9 +1633,16 @@ mmc_blk_set_blksize(struct mmc_blk_data *md, struct mmc_card *card)
static void mmc_blk_remove_req(struct mmc_blk_data *md)
{
+ struct mmc_card *card;
+
if (md) {
+ card = md->queue.card;
if (md->disk->flags & GENHD_FL_UP) {
device_remove_file(disk_to_dev(md->disk), &md->force_ro);
+ if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&
+ card->ext_csd.boot_ro_lockable)
+ device_remove_file(disk_to_dev(md->disk),
+ &md->power_ro_lock);
/* Stop new requests from getting into the queue */
del_gendisk(md->disk);
@@ -1570,6 +1671,7 @@ static void mmc_blk_remove_parts(struct mmc_card *card,
static int mmc_add_disk(struct mmc_blk_data *md)
{
int ret;
+ struct mmc_card *card = md->queue.card;
add_disk(md->disk);
md->force_ro.show = force_ro_show;
@@ -1579,18 +1681,53 @@ static int mmc_add_disk(struct mmc_blk_data *md)
md->force_ro.attr.mode = S_IRUGO | S_IWUSR;
ret = device_create_file(disk_to_dev(md->disk), &md->force_ro);
if (ret)
- del_gendisk(md->disk);
+ goto force_ro_fail;
+
+ if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&
+ card->ext_csd.boot_ro_lockable) {
+ mode_t mode;
+
+ if (card->ext_csd.boot_ro_lock & EXT_CSD_BOOT_WP_B_PWR_WP_DIS)
+ mode = S_IRUGO;
+ else
+ mode = S_IRUGO | S_IWUSR;
+
+ md->power_ro_lock.show = power_ro_lock_show;
+ md->power_ro_lock.store = power_ro_lock_store;
+ md->power_ro_lock.attr.mode = mode;
+ md->power_ro_lock.attr.name =
+ "ro_lock_until_next_power_on";
+ ret = device_create_file(disk_to_dev(md->disk),
+ &md->power_ro_lock);
+ if (ret)
+ goto power_ro_lock_fail;
+ }
+ return ret;
+
+power_ro_lock_fail:
+ device_remove_file(disk_to_dev(md->disk), &md->force_ro);
+force_ro_fail:
+ del_gendisk(md->disk);
return ret;
}
+#define CID_MANFID_SANDISK 0x2
+#define CID_MANFID_TOSHIBA 0x11
+#define CID_MANFID_MICRON 0x13
+
static const struct mmc_fixup blk_fixups[] =
{
- MMC_FIXUP("SEM02G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
- MMC_FIXUP("SEM04G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
- MMC_FIXUP("SEM08G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
- MMC_FIXUP("SEM16G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
- MMC_FIXUP("SEM32G", 0x2, 0x100, add_quirk, MMC_QUIRK_INAND_CMD38),
+ MMC_FIXUP("SEM02G", CID_MANFID_SANDISK, 0x100, add_quirk,
+ MMC_QUIRK_INAND_CMD38),
+ MMC_FIXUP("SEM04G", CID_MANFID_SANDISK, 0x100, add_quirk,
+ MMC_QUIRK_INAND_CMD38),
+ MMC_FIXUP("SEM08G", CID_MANFID_SANDISK, 0x100, add_quirk,
+ MMC_QUIRK_INAND_CMD38),
+ MMC_FIXUP("SEM16G", CID_MANFID_SANDISK, 0x100, add_quirk,
+ MMC_QUIRK_INAND_CMD38),
+ MMC_FIXUP("SEM32G", CID_MANFID_SANDISK, 0x100, add_quirk,
+ MMC_QUIRK_INAND_CMD38),
/*
* Some MMC cards experience performance degradation with CMD23
@@ -1600,18 +1737,18 @@ static const struct mmc_fixup blk_fixups[] =
*
* N.B. This doesn't affect SD cards.
*/
- MMC_FIXUP("MMC08G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_FIXUP("MMC08G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_BLK_NO_CMD23),
- MMC_FIXUP("MMC16G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_FIXUP("MMC16G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_BLK_NO_CMD23),
- MMC_FIXUP("MMC32G", 0x11, CID_OEMID_ANY, add_quirk_mmc,
+ MMC_FIXUP("MMC32G", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_BLK_NO_CMD23),
/*
* Some Micron MMC cards needs longer data read timeout than
* indicated in CSD.
*/
- MMC_FIXUP(CID_NAME_ANY, 0x13, 0x200, add_quirk_mmc,
+ MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,
MMC_QUIRK_LONG_READ_TIME),
END_FIXUP
diff --git a/drivers/mmc/card/mmc_test.c b/drivers/mmc/card/mmc_test.c
index e99bdc18002d..759714ed6bee 100644
--- a/drivers/mmc/card/mmc_test.c
+++ b/drivers/mmc/card/mmc_test.c
@@ -1581,6 +1581,7 @@ static int mmc_test_area_init(struct mmc_test_card *test, int erase, int fill)
t->max_segs = test->card->host->max_segs;
t->max_seg_sz = test->card->host->max_seg_size;
+ t->max_seg_sz -= t->max_seg_sz % 512;
t->max_tfr = t->max_sz;
if (t->max_tfr >> 9 > test->card->host->max_blk_count)
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index dcad59cbfef1..2517547b4366 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -29,6 +29,8 @@
*/
static int mmc_prep_request(struct request_queue *q, struct request *req)
{
+ struct mmc_queue *mq = q->queuedata;
+
/*
* We only like normal block requests and discards.
*/
@@ -37,6 +39,9 @@ static int mmc_prep_request(struct request_queue *q, struct request *req)
return BLKPREP_KILL;
}
+ if (mq && mmc_card_removed(mq->card))
+ return BLKPREP_KILL;
+
req->cmd_flags |= REQ_DONTPREP;
return BLKPREP_OK;
diff --git a/drivers/mmc/core/Makefile b/drivers/mmc/core/Makefile
index 639501970b41..dca4428380f1 100644
--- a/drivers/mmc/core/Makefile
+++ b/drivers/mmc/core/Makefile
@@ -7,6 +7,6 @@ mmc_core-y := core.o bus.o host.o \
mmc.o mmc_ops.o sd.o sd_ops.o \
sdio.o sdio_ops.o sdio_bus.o \
sdio_cis.o sdio_io.o sdio_irq.o \
- quirks.o
+ quirks.o cd-gpio.o
mmc_core-$(CONFIG_DEBUG_FS) += debugfs.o
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index 6be49249895a..5d011a39dfff 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -303,10 +303,11 @@ int mmc_add_card(struct mmc_card *card)
mmc_card_ddr_mode(card) ? "DDR " : "",
type);
} else {
- printk(KERN_INFO "%s: new %s%s%s card at address %04x\n",
+ pr_info("%s: new %s%s%s%s card at address %04x\n",
mmc_hostname(card->host),
- mmc_sd_card_uhs(card) ? "ultra high speed " :
+ mmc_card_uhs(card) ? "ultra high speed " :
(mmc_card_highspeed(card) ? "high speed " : ""),
+ (mmc_card_hs200(card) ? "HS200 " : ""),
mmc_card_ddr_mode(card) ? "DDR " : "",
type, card->rca);
}
diff --git a/drivers/mmc/core/cd-gpio.c b/drivers/mmc/core/cd-gpio.c
new file mode 100644
index 000000000000..082202ae4a03
--- /dev/null
+++ b/drivers/mmc/core/cd-gpio.c
@@ -0,0 +1,74 @@
+/*
+ * Generic GPIO card-detect helper
+ *
+ * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/mmc/host.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+struct mmc_cd_gpio {
+ unsigned int gpio;
+ char label[0];
+};
+
+static irqreturn_t mmc_cd_gpio_irqt(int irq, void *dev_id)
+{
+ /* Schedule a card detection after a debounce timeout */
+ mmc_detect_change(dev_id, msecs_to_jiffies(100));
+ return IRQ_HANDLED;
+}
+
+int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio,
+ unsigned int irq, unsigned long flags)
+{
+ size_t len = strlen(dev_name(host->parent)) + 4;
+ struct mmc_cd_gpio *cd = kmalloc(sizeof(*cd) + len, GFP_KERNEL);
+ int ret;
+
+ if (!cd)
+ return -ENOMEM;
+
+ snprintf(cd->label, len, "%s cd", dev_name(host->parent));
+
+ ret = gpio_request_one(gpio, GPIOF_DIR_IN, cd->label);
+ if (ret < 0)
+ goto egpioreq;
+
+ ret = request_threaded_irq(irq, NULL, mmc_cd_gpio_irqt,
+ flags, cd->label, host);
+ if (ret < 0)
+ goto eirqreq;
+
+ cd->gpio = gpio;
+ host->hotplug.irq = irq;
+ host->hotplug.handler_priv = cd;
+
+ return 0;
+
+eirqreq:
+ gpio_free(gpio);
+egpioreq:
+ kfree(cd);
+ return ret;
+}
+EXPORT_SYMBOL(mmc_cd_gpio_request);
+
+void mmc_cd_gpio_free(struct mmc_host *host)
+{
+ struct mmc_cd_gpio *cd = host->hotplug.handler_priv;
+
+ free_irq(host->hotplug.irq, host);
+ gpio_free(cd->gpio);
+ kfree(cd);
+}
+EXPORT_SYMBOL(mmc_cd_gpio_free);
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
index 950b97d7412a..f545a3e6eb80 100644
--- a/drivers/mmc/core/core.c
+++ b/drivers/mmc/core/core.c
@@ -48,7 +48,7 @@ static struct workqueue_struct *workqueue;
* performance cost, and for other reasons may not always be desired.
* So we allow it it to be disabled.
*/
-int use_spi_crc = 1;
+bool use_spi_crc = 1;
module_param(use_spi_crc, bool, 0);
/*
@@ -58,9 +58,9 @@ module_param(use_spi_crc, bool, 0);
* overridden if necessary.
*/
#ifdef CONFIG_MMC_UNSAFE_RESUME
-int mmc_assume_removable;
+bool mmc_assume_removable;
#else
-int mmc_assume_removable = 1;
+bool mmc_assume_removable = 1;
#endif
EXPORT_SYMBOL(mmc_assume_removable);
module_param_named(removable, mmc_assume_removable, bool, 0644);
@@ -140,7 +140,7 @@ void mmc_request_done(struct mmc_host *host, struct mmc_request *mrq)
cmd->retries = 0;
}
- if (err && cmd->retries) {
+ if (err && cmd->retries && !mmc_card_removed(host->card)) {
/*
* Request starter must handle retries - see
* mmc_wait_for_req_done().
@@ -247,6 +247,11 @@ static void __mmc_start_req(struct mmc_host *host, struct mmc_request *mrq)
{
init_completion(&mrq->completion);
mrq->done = mmc_wait_done;
+ if (mmc_card_removed(host->card)) {
+ mrq->cmd->error = -ENOMEDIUM;
+ complete(&mrq->completion);
+ return;
+ }
mmc_start_request(host, mrq);
}
@@ -259,7 +264,8 @@ static void mmc_wait_for_req_done(struct mmc_host *host,
wait_for_completion(&mrq->completion);
cmd = mrq->cmd;
- if (!cmd->error || !cmd->retries)
+ if (!cmd->error || !cmd->retries ||
+ mmc_card_removed(host->card))
break;
pr_debug("%s: req failed (CMD%u): %d, retrying...\n",
@@ -1456,7 +1462,7 @@ void mmc_detect_change(struct mmc_host *host, unsigned long delay)
WARN_ON(host->removed);
spin_unlock_irqrestore(&host->lock, flags);
#endif
-
+ host->detect_change = 1;
mmc_schedule_delayed_work(&host->detect, delay);
}
@@ -2049,6 +2055,43 @@ static int mmc_rescan_try_freq(struct mmc_host *host, unsigned freq)
return -EIO;
}
+int _mmc_detect_card_removed(struct mmc_host *host)
+{
+ int ret;
+
+ if ((host->caps & MMC_CAP_NONREMOVABLE) || !host->bus_ops->alive)
+ return 0;
+
+ if (!host->card || mmc_card_removed(host->card))
+ return 1;
+
+ ret = host->bus_ops->alive(host);
+ if (ret) {
+ mmc_card_set_removed(host->card);
+ pr_debug("%s: card remove detected\n", mmc_hostname(host));
+ }
+
+ return ret;
+}
+
+int mmc_detect_card_removed(struct mmc_host *host)
+{
+ struct mmc_card *card = host->card;
+
+ WARN_ON(!host->claimed);
+ /*
+ * The card will be considered unchanged unless we have been asked to
+ * detect a change or host requires polling to provide card detection.
+ */
+ if (card && !host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL))
+ return mmc_card_removed(card);
+
+ host->detect_change = 0;
+
+ return _mmc_detect_card_removed(host);
+}
+EXPORT_SYMBOL(mmc_detect_card_removed);
+
void mmc_rescan(struct work_struct *work)
{
static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
@@ -2069,6 +2112,8 @@ void mmc_rescan(struct work_struct *work)
&& !(host->caps & MMC_CAP_NONREMOVABLE))
host->bus_ops->detect(host);
+ host->detect_change = 0;
+
/*
* Let mmc_bus_put() free the bus/bus_ops if we've found that
* the card is no longer present.
@@ -2130,6 +2175,7 @@ void mmc_stop_host(struct mmc_host *host)
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
+ /* Calling bus_ops->remove() with a claimed host can deadlock */
if (host->bus_ops->remove)
host->bus_ops->remove(host);
@@ -2201,6 +2247,9 @@ int mmc_card_awake(struct mmc_host *host)
{
int err = -ENOSYS;
+ if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
+ return 0;
+
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
@@ -2216,6 +2265,9 @@ int mmc_card_sleep(struct mmc_host *host)
{
int err = -ENOSYS;
+ if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
+ return 0;
+
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
@@ -2270,6 +2322,7 @@ EXPORT_SYMBOL(mmc_flush_cache);
int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
{
struct mmc_card *card = host->card;
+ unsigned int timeout;
int err = 0;
if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
@@ -2280,16 +2333,18 @@ int mmc_cache_ctrl(struct mmc_host *host, u8 enable)
(card->ext_csd.cache_size > 0)) {
enable = !!enable;
- if (card->ext_csd.cache_ctrl ^ enable)
+ if (card->ext_csd.cache_ctrl ^ enable) {
+ timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_CACHE_CTRL, enable, 0);
- if (err)
- pr_err("%s: cache %s error %d\n",
- mmc_hostname(card->host),
- enable ? "on" : "off",
- err);
- else
- card->ext_csd.cache_ctrl = enable;
+ EXT_CSD_CACHE_CTRL, enable, timeout);
+ if (err)
+ pr_err("%s: cache %s error %d\n",
+ mmc_hostname(card->host),
+ enable ? "on" : "off",
+ err);
+ else
+ card->ext_csd.cache_ctrl = enable;
+ }
}
return err;
@@ -2310,7 +2365,13 @@ int mmc_suspend_host(struct mmc_host *host)
cancel_delayed_work(&host->disable);
cancel_delayed_work(&host->detect);
mmc_flush_scheduled_work();
- err = mmc_cache_ctrl(host, 0);
+ if (mmc_try_claim_host(host)) {
+ err = mmc_cache_ctrl(host, 0);
+ mmc_do_release_host(host);
+ } else {
+ err = -EBUSY;
+ }
+
if (err)
goto out;
@@ -2338,7 +2399,9 @@ int mmc_suspend_host(struct mmc_host *host)
if (err == -ENOSYS || !host->bus_ops->resume) {
/*
* We simply "remove" the card in this case.
- * It will be redetected on resume.
+ * It will be redetected on resume. (Calling
+ * bus_ops->remove() with a claimed host can
+ * deadlock.)
*/
if (host->bus_ops->remove)
host->bus_ops->remove(host);
@@ -2431,11 +2494,11 @@ int mmc_pm_notify(struct notifier_block *notify_block,
if (!host->bus_ops || host->bus_ops->suspend)
break;
- mmc_claim_host(host);
-
+ /* Calling bus_ops->remove() with a claimed host can deadlock */
if (host->bus_ops->remove)
host->bus_ops->remove(host);
+ mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
mmc_release_host(host);
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h
index 14664f1fb16f..3bdafbca354f 100644
--- a/drivers/mmc/core/core.h
+++ b/drivers/mmc/core/core.h
@@ -24,6 +24,7 @@ struct mmc_bus_ops {
int (*resume)(struct mmc_host *);
int (*power_save)(struct mmc_host *);
int (*power_restore)(struct mmc_host *);
+ int (*alive)(struct mmc_host *);
};
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
@@ -59,12 +60,14 @@ void mmc_rescan(struct work_struct *work);
void mmc_start_host(struct mmc_host *host);
void mmc_stop_host(struct mmc_host *host);
+int _mmc_detect_card_removed(struct mmc_host *host);
+
int mmc_attach_mmc(struct mmc_host *host);
int mmc_attach_sd(struct mmc_host *host);
int mmc_attach_sdio(struct mmc_host *host);
/* Module parameters */
-extern int use_spi_crc;
+extern bool use_spi_crc;
/* Debugfs information for hosts and cards */
void mmc_add_host_debugfs(struct mmc_host *host);
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
index 3923880118b6..9ab5b17d488a 100644
--- a/drivers/mmc/core/debugfs.c
+++ b/drivers/mmc/core/debugfs.c
@@ -57,6 +57,8 @@ static int mmc_ios_show(struct seq_file *s, void *data)
const char *str;
seq_printf(s, "clock:\t\t%u Hz\n", ios->clock);
+ if (host->actual_clock)
+ seq_printf(s, "actual clock:\t%u Hz\n", host->actual_clock);
seq_printf(s, "vdd:\t\t%u ", ios->vdd);
if ((1 << ios->vdd) & MMC_VDD_165_195)
seq_printf(s, "(1.65 - 1.95 V)\n");
@@ -133,6 +135,9 @@ static int mmc_ios_show(struct seq_file *s, void *data)
case MMC_TIMING_UHS_DDR50:
str = "sd uhs DDR50";
break;
+ case MMC_TIMING_MMC_HS200:
+ str = "mmc high-speed SDR200";
+ break;
default:
str = "invalid";
break;
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index d31c78b72b0f..30055f2b0d44 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -54,6 +54,27 @@ static DEFINE_IDR(mmc_host_idr);
static DEFINE_SPINLOCK(mmc_host_lock);
#ifdef CONFIG_MMC_CLKGATE
+static ssize_t clkgate_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct mmc_host *host = cls_dev_to_mmc_host(dev);
+ return snprintf(buf, PAGE_SIZE, "%lu\n", host->clkgate_delay);
+}
+
+static ssize_t clkgate_delay_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct mmc_host *host = cls_dev_to_mmc_host(dev);
+ unsigned long flags, value;
+
+ if (kstrtoul(buf, 0, &value))
+ return -EINVAL;
+
+ spin_lock_irqsave(&host->clk_lock, flags);
+ host->clkgate_delay = value;
+ spin_unlock_irqrestore(&host->clk_lock, flags);
+ return count;
+}
/*
* Enabling clock gating will make the core call out to the host
@@ -114,7 +135,7 @@ static void mmc_host_clk_gate_delayed(struct mmc_host *host)
static void mmc_host_clk_gate_work(struct work_struct *work)
{
struct mmc_host *host = container_of(work, struct mmc_host,
- clk_gate_work);
+ clk_gate_work.work);
mmc_host_clk_gate_delayed(host);
}
@@ -131,6 +152,8 @@ void mmc_host_clk_hold(struct mmc_host *host)
{
unsigned long flags;
+ /* cancel any clock gating work scheduled by mmc_host_clk_release() */
+ cancel_delayed_work_sync(&host->clk_gate_work);
mutex_lock(&host->clk_gate_mutex);
spin_lock_irqsave(&host->clk_lock, flags);
if (host->clk_gated) {
@@ -180,7 +203,8 @@ void mmc_host_clk_release(struct mmc_host *host)
host->clk_requests--;
if (mmc_host_may_gate_card(host->card) &&
!host->clk_requests)
- queue_work(system_nrt_wq, &host->clk_gate_work);
+ queue_delayed_work(system_nrt_wq, &host->clk_gate_work,
+ msecs_to_jiffies(host->clkgate_delay));
spin_unlock_irqrestore(&host->clk_lock, flags);
}
@@ -213,8 +237,13 @@ static inline void mmc_host_clk_init(struct mmc_host *host)
host->clk_requests = 0;
/* Hold MCI clock for 8 cycles by default */
host->clk_delay = 8;
+ /*
+ * Default clock gating delay is 200ms.
+ * This value can be tuned by writing into sysfs entry.
+ */
+ host->clkgate_delay = 200;
host->clk_gated = false;
- INIT_WORK(&host->clk_gate_work, mmc_host_clk_gate_work);
+ INIT_DELAYED_WORK(&host->clk_gate_work, mmc_host_clk_gate_work);
spin_lock_init(&host->clk_lock);
mutex_init(&host->clk_gate_mutex);
}
@@ -229,7 +258,7 @@ static inline void mmc_host_clk_exit(struct mmc_host *host)
* Wait for any outstanding gate and then make sure we're
* ungated before exiting.
*/
- if (cancel_work_sync(&host->clk_gate_work))
+ if (cancel_delayed_work_sync(&host->clk_gate_work))
mmc_host_clk_gate_delayed(host);
if (host->clk_gated)
mmc_host_clk_hold(host);
@@ -237,6 +266,17 @@ static inline void mmc_host_clk_exit(struct mmc_host *host)
WARN_ON(host->clk_requests > 1);
}
+static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
+{
+ host->clkgate_delay_attr.show = clkgate_delay_show;
+ host->clkgate_delay_attr.store = clkgate_delay_store;
+ sysfs_attr_init(&host->clkgate_delay_attr.attr);
+ host->clkgate_delay_attr.attr.name = "clkgate_delay";
+ host->clkgate_delay_attr.attr.mode = S_IRUGO | S_IWUSR;
+ if (device_create_file(&host->class_dev, &host->clkgate_delay_attr))
+ pr_err("%s: Failed to create clkgate_delay sysfs entry\n",
+ mmc_hostname(host));
+}
#else
static inline void mmc_host_clk_init(struct mmc_host *host)
@@ -247,6 +287,10 @@ static inline void mmc_host_clk_exit(struct mmc_host *host)
{
}
+static inline void mmc_host_clk_sysfs_init(struct mmc_host *host)
+{
+}
+
#endif
/**
@@ -335,6 +379,7 @@ int mmc_add_host(struct mmc_host *host)
#ifdef CONFIG_DEBUG_FS
mmc_add_host_debugfs(host);
#endif
+ mmc_host_clk_sysfs_init(host);
mmc_start_host(host);
register_pm_notifier(&host->pm_notify);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index d240427c1246..59b9ba52e66a 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -286,6 +286,27 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
}
card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE];
switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) {
+ case EXT_CSD_CARD_TYPE_SDR_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_200;
+ break;
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_2V;
+ break;
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_ALL:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V:
+ case EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52:
+ card->ext_csd.hs_max_dtr = 200000000;
+ card->ext_csd.card_type = EXT_CSD_CARD_TYPE_SDR_1_8V;
+ break;
case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 |
EXT_CSD_CARD_TYPE_26:
card->ext_csd.hs_max_dtr = 52000000;
@@ -348,7 +369,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
part_size = ext_csd[EXT_CSD_BOOT_MULT] << 17;
mmc_part_add(card, part_size,
EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx,
- "boot%d", idx, true);
+ "boot%d", idx, true,
+ MMC_BLK_DATA_AREA_BOOT);
}
}
}
@@ -435,7 +457,8 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
hc_wp_grp_sz);
mmc_part_add(card, part_size << 19,
EXT_CSD_PART_CONFIG_ACC_GP0 + idx,
- "gp%d", idx, false);
+ "gp%d", idx, false,
+ MMC_BLK_DATA_AREA_GP);
}
}
card->ext_csd.sec_trim_mult =
@@ -446,6 +469,14 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd)
ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT];
card->ext_csd.trim_timeout = 300 *
ext_csd[EXT_CSD_TRIM_MULT];
+
+ /*
+ * Note that the call to mmc_part_add above defaults to read
+ * only. If this default assumption is changed, the call must
+ * take into account the value of boot_locked below.
+ */
+ card->ext_csd.boot_ro_lock = ext_csd[EXT_CSD_BOOT_WP];
+ card->ext_csd.boot_ro_lockable = true;
}
if (card->ext_csd.rev >= 5) {
@@ -690,6 +721,79 @@ static int mmc_select_powerclass(struct mmc_card *card,
}
/*
+ * Selects the desired buswidth and switch to the HS200 mode
+ * if bus width set without error
+ */
+static int mmc_select_hs200(struct mmc_card *card)
+{
+ int idx, err = 0;
+ struct mmc_host *host;
+ static unsigned ext_csd_bits[] = {
+ EXT_CSD_BUS_WIDTH_4,
+ EXT_CSD_BUS_WIDTH_8,
+ };
+ static unsigned bus_widths[] = {
+ MMC_BUS_WIDTH_4,
+ MMC_BUS_WIDTH_8,
+ };
+
+ BUG_ON(!card);
+
+ host = card->host;
+
+ if (card->ext_csd.card_type & EXT_CSD_CARD_TYPE_SDR_1_2V &&
+ host->caps2 & MMC_CAP2_HS200_1_2V_SDR)
+ if (mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120, 0))
+ err = mmc_set_signal_voltage(host,
+ MMC_SIGNAL_VOLTAGE_180, 0);
+
+ /* If fails try again during next card power cycle */
+ if (err)
+ goto err;
+
+ idx = (host->caps & MMC_CAP_8_BIT_DATA) ? 1 : 0;
+
+ /*
+ * Unlike SD, MMC cards dont have a configuration register to notify
+ * supported bus width. So bus test command should be run to identify
+ * the supported bus width or compare the ext csd values of current
+ * bus width and ext csd values of 1 bit mode read earlier.
+ */
+ for (; idx >= 0; idx--) {
+
+ /*
+ * Host is capable of 8bit transfer, then switch
+ * the device to work in 8bit transfer mode. If the
+ * mmc switch command returns error then switch to
+ * 4bit transfer mode. On success set the corresponding
+ * bus width on the host.
+ */
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_BUS_WIDTH,
+ ext_csd_bits[idx],
+ card->ext_csd.generic_cmd6_time);
+ if (err)
+ continue;
+
+ mmc_set_bus_width(card->host, bus_widths[idx]);
+
+ if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST))
+ err = mmc_compare_ext_csds(card, bus_widths[idx]);
+ else
+ err = mmc_bus_test(card, bus_widths[idx]);
+ if (!err)
+ break;
+ }
+
+ /* switch to HS200 mode if bus width set successfully */
+ if (!err)
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HS_TIMING, 2, 0);
+err:
+ return err;
+}
+
+/*
* Handle the detection and initialisation of a card.
*
* In the case of a resume, "oldcard" will contain the card
@@ -895,11 +999,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
/*
* Activate high speed (if supported)
*/
- if ((card->ext_csd.hs_max_dtr != 0) &&
- (host->caps & MMC_CAP_MMC_HIGHSPEED)) {
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_HS_TIMING, 1,
- card->ext_csd.generic_cmd6_time);
+ if (card->ext_csd.hs_max_dtr != 0) {
+ err = 0;
+ if (card->ext_csd.hs_max_dtr > 52000000 &&
+ host->caps2 & MMC_CAP2_HS200)
+ err = mmc_select_hs200(card);
+ else if (host->caps & MMC_CAP_MMC_HIGHSPEED)
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_HS_TIMING, 1, 0);
+
if (err && err != -EBADMSG)
goto free_card;
@@ -908,8 +1016,15 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
mmc_hostname(card->host));
err = 0;
} else {
- mmc_card_set_highspeed(card);
- mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+ if (card->ext_csd.hs_max_dtr > 52000000 &&
+ host->caps2 & MMC_CAP2_HS200) {
+ mmc_card_set_hs200(card);
+ mmc_set_timing(card->host,
+ MMC_TIMING_MMC_HS200);
+ } else {
+ mmc_card_set_highspeed(card);
+ mmc_set_timing(card->host, MMC_TIMING_MMC_HS);
+ }
}
}
@@ -934,7 +1049,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
*/
max_dtr = (unsigned int)-1;
- if (mmc_card_highspeed(card)) {
+ if (mmc_card_highspeed(card) || mmc_card_hs200(card)) {
if (max_dtr > card->ext_csd.hs_max_dtr)
max_dtr = card->ext_csd.hs_max_dtr;
} else if (max_dtr > card->csd.max_dtr) {
@@ -960,9 +1075,48 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
}
/*
+ * Indicate HS200 SDR mode (if supported).
+ */
+ if (mmc_card_hs200(card)) {
+ u32 ext_csd_bits;
+ u32 bus_width = card->host->ios.bus_width;
+
+ /*
+ * For devices supporting HS200 mode, the bus width has
+ * to be set before executing the tuning function. If
+ * set before tuning, then device will respond with CRC
+ * errors for responses on CMD line. So for HS200 the
+ * sequence will be
+ * 1. set bus width 4bit / 8 bit (1 bit not supported)
+ * 2. switch to HS200 mode
+ * 3. set the clock to > 52Mhz <=200MHz and
+ * 4. execute tuning for HS200
+ */
+ if ((host->caps2 & MMC_CAP2_HS200) &&
+ card->host->ops->execute_tuning)
+ err = card->host->ops->execute_tuning(card->host,
+ MMC_SEND_TUNING_BLOCK_HS200);
+ if (err) {
+ pr_warning("%s: tuning execution failed\n",
+ mmc_hostname(card->host));
+ goto err;
+ }
+
+ ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
+ EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
+ err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
+ if (err) {
+ pr_err("%s: power class selection to bus width %d failed\n",
+ mmc_hostname(card->host), 1 << bus_width);
+ goto err;
+ }
+ }
+
+ /*
* Activate wide bus and DDR (if supported).
*/
- if ((card->csd.mmca_vsn >= CSD_SPEC_VER_4) &&
+ if (!mmc_card_hs200(card) &&
+ (card->csd.mmca_vsn >= CSD_SPEC_VER_3) &&
(host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) {
static unsigned ext_csd_bits[][2] = {
{ EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 },
@@ -1048,7 +1202,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
*
* WARNING: eMMC rules are NOT the same as SD DDR
*/
- if (ddr == EXT_CSD_CARD_TYPE_DDR_1_2V) {
+ if (ddr == MMC_1_2V_DDR_MODE) {
err = mmc_set_signal_voltage(host,
MMC_SIGNAL_VOLTAGE_120, 0);
if (err)
@@ -1067,14 +1221,23 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
if ((host->caps2 & MMC_CAP2_CACHE_CTRL) &&
card->ext_csd.cache_size > 0) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_CACHE_CTRL, 1, 0);
+ EXT_CSD_CACHE_CTRL, 1,
+ card->ext_csd.generic_cmd6_time);
if (err && err != -EBADMSG)
goto free_card;
/*
* Only if no error, cache is turned on successfully.
*/
- card->ext_csd.cache_ctrl = err ? 0 : 1;
+ if (err) {
+ pr_warning("%s: Cache is supported, "
+ "but failed to turn on (%d)\n",
+ mmc_hostname(card->host), err);
+ card->ext_csd.cache_ctrl = 0;
+ err = 0;
+ } else {
+ card->ext_csd.cache_ctrl = 1;
+ }
}
if (!oldcard)
@@ -1105,6 +1268,14 @@ static void mmc_remove(struct mmc_host *host)
}
/*
+ * Card detection - card is alive.
+ */
+static int mmc_alive(struct mmc_host *host)
+{
+ return mmc_send_status(host->card, NULL);
+}
+
+/*
* Card detection callback from host.
*/
static void mmc_detect(struct mmc_host *host)
@@ -1119,7 +1290,7 @@ static void mmc_detect(struct mmc_host *host)
/*
* Just check if our card has been removed.
*/
- err = mmc_send_status(host->card, NULL);
+ err = _mmc_detect_card_removed(host);
mmc_release_host(host);
@@ -1224,6 +1395,7 @@ static const struct mmc_bus_ops mmc_ops = {
.suspend = NULL,
.resume = NULL,
.power_restore = mmc_power_restore,
+ .alive = mmc_alive,
};
static const struct mmc_bus_ops mmc_ops_unsafe = {
@@ -1234,6 +1406,7 @@ static const struct mmc_bus_ops mmc_ops_unsafe = {
.suspend = mmc_suspend,
.resume = mmc_resume,
.power_restore = mmc_power_restore,
+ .alive = mmc_alive,
};
static void mmc_attach_bus_ops(struct mmc_host *host)
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index f2a05ea40f2a..c63ad03c29c7 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -307,8 +307,8 @@ static int mmc_read_switch(struct mmc_card *card)
goto out;
}
- if (status[13] & UHS_SDR50_BUS_SPEED)
- card->sw_caps.hs_max_dtr = 50000000;
+ if (status[13] & SD_MODE_HIGH_SPEED)
+ card->sw_caps.hs_max_dtr = HIGH_SPEED_MAX_DTR;
if (card->scr.sda_spec3) {
card->sw_caps.sd3_bus_mode = status[13];
@@ -661,7 +661,8 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card)
/* SPI mode doesn't define CMD19 */
if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
- err = card->host->ops->execute_tuning(card->host);
+ err = card->host->ops->execute_tuning(card->host,
+ MMC_SEND_TUNING_BLOCK);
out:
kfree(status);
@@ -960,7 +961,7 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr,
goto free_card;
/* Card is an ultra-high-speed card */
- mmc_sd_card_set_uhs(card);
+ mmc_card_set_uhs(card);
/*
* Since initialization is now complete, enable preset
@@ -1019,6 +1020,14 @@ static void mmc_sd_remove(struct mmc_host *host)
}
/*
+ * Card detection - card is alive.
+ */
+static int mmc_sd_alive(struct mmc_host *host)
+{
+ return mmc_send_status(host->card, NULL);
+}
+
+/*
* Card detection callback from host.
*/
static void mmc_sd_detect(struct mmc_host *host)
@@ -1033,7 +1042,7 @@ static void mmc_sd_detect(struct mmc_host *host)
/*
* Just check if our card has been removed.
*/
- err = mmc_send_status(host->card, NULL);
+ err = _mmc_detect_card_removed(host);
mmc_release_host(host);
@@ -1102,6 +1111,7 @@ static const struct mmc_bus_ops mmc_sd_ops = {
.suspend = NULL,
.resume = NULL,
.power_restore = mmc_sd_power_restore,
+ .alive = mmc_sd_alive,
};
static const struct mmc_bus_ops mmc_sd_ops_unsafe = {
@@ -1110,6 +1120,7 @@ static const struct mmc_bus_ops mmc_sd_ops_unsafe = {
.suspend = mmc_sd_suspend,
.resume = mmc_sd_resume,
.power_restore = mmc_sd_power_restore,
+ .alive = mmc_sd_alive,
};
static void mmc_sd_attach_bus_ops(struct mmc_host *host)
diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
index 3ab565e32a6a..bd7bacc950dc 100644
--- a/drivers/mmc/core/sdio.c
+++ b/drivers/mmc/core/sdio.c
@@ -14,6 +14,7 @@
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
@@ -102,6 +103,7 @@ static int sdio_read_cccr(struct mmc_card *card)
int ret;
int cccr_vsn;
unsigned char data;
+ unsigned char speed;
memset(&card->cccr, 0, sizeof(struct sdio_cccr));
@@ -140,12 +142,60 @@ static int sdio_read_cccr(struct mmc_card *card)
}
if (cccr_vsn >= SDIO_CCCR_REV_1_20) {
- ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &data);
+ ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
if (ret)
goto out;
- if (data & SDIO_SPEED_SHS)
- card->cccr.high_speed = 1;
+ card->scr.sda_spec3 = 0;
+ card->sw_caps.sd3_bus_mode = 0;
+ card->sw_caps.sd3_drv_type = 0;
+ if (cccr_vsn >= SDIO_CCCR_REV_3_00) {
+ card->scr.sda_spec3 = 1;
+ ret = mmc_io_rw_direct(card, 0, 0,
+ SDIO_CCCR_UHS, 0, &data);
+ if (ret)
+ goto out;
+
+ if (card->host->caps &
+ (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
+ MMC_CAP_UHS_DDR50)) {
+ if (data & SDIO_UHS_DDR50)
+ card->sw_caps.sd3_bus_mode
+ |= SD_MODE_UHS_DDR50;
+
+ if (data & SDIO_UHS_SDR50)
+ card->sw_caps.sd3_bus_mode
+ |= SD_MODE_UHS_SDR50;
+
+ if (data & SDIO_UHS_SDR104)
+ card->sw_caps.sd3_bus_mode
+ |= SD_MODE_UHS_SDR104;
+ }
+
+ ret = mmc_io_rw_direct(card, 0, 0,
+ SDIO_CCCR_DRIVE_STRENGTH, 0, &data);
+ if (ret)
+ goto out;
+
+ if (data & SDIO_DRIVE_SDTA)
+ card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_A;
+ if (data & SDIO_DRIVE_SDTC)
+ card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_C;
+ if (data & SDIO_DRIVE_SDTD)
+ card->sw_caps.sd3_drv_type |= SD_DRIVER_TYPE_D;
+ }
+
+ /* if no uhs mode ensure we check for high speed */
+ if (!card->sw_caps.sd3_bus_mode) {
+ if (speed & SDIO_SPEED_SHS) {
+ card->cccr.high_speed = 1;
+ card->sw_caps.hs_max_dtr = 50000000;
+ } else {
+ card->cccr.high_speed = 0;
+ card->sw_caps.hs_max_dtr = 25000000;
+ }
+ }
}
out:
@@ -327,6 +377,194 @@ static unsigned mmc_sdio_get_max_clock(struct mmc_card *card)
return max_dtr;
}
+static unsigned char host_drive_to_sdio_drive(int host_strength)
+{
+ switch (host_strength) {
+ case MMC_SET_DRIVER_TYPE_A:
+ return SDIO_DTSx_SET_TYPE_A;
+ case MMC_SET_DRIVER_TYPE_B:
+ return SDIO_DTSx_SET_TYPE_B;
+ case MMC_SET_DRIVER_TYPE_C:
+ return SDIO_DTSx_SET_TYPE_C;
+ case MMC_SET_DRIVER_TYPE_D:
+ return SDIO_DTSx_SET_TYPE_D;
+ default:
+ return SDIO_DTSx_SET_TYPE_B;
+ }
+}
+
+static void sdio_select_driver_type(struct mmc_card *card)
+{
+ int host_drv_type = SD_DRIVER_TYPE_B;
+ int card_drv_type = SD_DRIVER_TYPE_B;
+ int drive_strength;
+ unsigned char card_strength;
+ int err;
+
+ /*
+ * If the host doesn't support any of the Driver Types A,C or D,
+ * or there is no board specific handler then default Driver
+ * Type B is used.
+ */
+ if (!(card->host->caps &
+ (MMC_CAP_DRIVER_TYPE_A |
+ MMC_CAP_DRIVER_TYPE_C |
+ MMC_CAP_DRIVER_TYPE_D)))
+ return;
+
+ if (!card->host->ops->select_drive_strength)
+ return;
+
+ if (card->host->caps & MMC_CAP_DRIVER_TYPE_A)
+ host_drv_type |= SD_DRIVER_TYPE_A;
+
+ if (card->host->caps & MMC_CAP_DRIVER_TYPE_C)
+ host_drv_type |= SD_DRIVER_TYPE_C;
+
+ if (card->host->caps & MMC_CAP_DRIVER_TYPE_D)
+ host_drv_type |= SD_DRIVER_TYPE_D;
+
+ if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_A)
+ card_drv_type |= SD_DRIVER_TYPE_A;
+
+ if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_C)
+ card_drv_type |= SD_DRIVER_TYPE_C;
+
+ if (card->sw_caps.sd3_drv_type & SD_DRIVER_TYPE_D)
+ card_drv_type |= SD_DRIVER_TYPE_D;
+
+ /*
+ * The drive strength that the hardware can support
+ * depends on the board design. Pass the appropriate
+ * information and let the hardware specific code
+ * return what is possible given the options
+ */
+ drive_strength = card->host->ops->select_drive_strength(
+ card->sw_caps.uhs_max_dtr,
+ host_drv_type, card_drv_type);
+
+ /* if error just use default for drive strength B */
+ err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_DRIVE_STRENGTH, 0,
+ &card_strength);
+ if (err)
+ return;
+
+ card_strength &= ~(SDIO_DRIVE_DTSx_MASK<<SDIO_DRIVE_DTSx_SHIFT);
+ card_strength |= host_drive_to_sdio_drive(drive_strength);
+
+ err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_DRIVE_STRENGTH,
+ card_strength, NULL);
+
+ /* if error default to drive strength B */
+ if (!err)
+ mmc_set_driver_type(card->host, drive_strength);
+}
+
+
+static int sdio_set_bus_speed_mode(struct mmc_card *card)
+{
+ unsigned int bus_speed, timing;
+ int err;
+ unsigned char speed;
+
+ /*
+ * If the host doesn't support any of the UHS-I modes, fallback on
+ * default speed.
+ */
+ if (!(card->host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50)))
+ return 0;
+
+ bus_speed = SDIO_SPEED_SDR12;
+ timing = MMC_TIMING_UHS_SDR12;
+ if ((card->host->caps & MMC_CAP_UHS_SDR104) &&
+ (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104)) {
+ bus_speed = SDIO_SPEED_SDR104;
+ timing = MMC_TIMING_UHS_SDR104;
+ card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
+ } else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
+ (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
+ bus_speed = SDIO_SPEED_DDR50;
+ timing = MMC_TIMING_UHS_DDR50;
+ card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
+ } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+ MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
+ SD_MODE_UHS_SDR50)) {
+ bus_speed = SDIO_SPEED_SDR50;
+ timing = MMC_TIMING_UHS_SDR50;
+ card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+ } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
+ (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
+ bus_speed = SDIO_SPEED_SDR25;
+ timing = MMC_TIMING_UHS_SDR25;
+ card->sw_caps.uhs_max_dtr = UHS_SDR25_MAX_DTR;
+ } else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25 |
+ MMC_CAP_UHS_SDR12)) && (card->sw_caps.sd3_bus_mode &
+ SD_MODE_UHS_SDR12)) {
+ bus_speed = SDIO_SPEED_SDR12;
+ timing = MMC_TIMING_UHS_SDR12;
+ card->sw_caps.uhs_max_dtr = UHS_SDR12_MAX_DTR;
+ }
+
+ err = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_SPEED, 0, &speed);
+ if (err)
+ return err;
+
+ speed &= ~SDIO_SPEED_BSS_MASK;
+ speed |= bus_speed;
+ err = mmc_io_rw_direct(card, 1, 0, SDIO_CCCR_SPEED, speed, NULL);
+ if (err)
+ return err;
+
+ if (bus_speed) {
+ mmc_set_timing(card->host, timing);
+ mmc_set_clock(card->host, card->sw_caps.uhs_max_dtr);
+ }
+
+ return 0;
+}
+
+/*
+ * UHS-I specific initialization procedure
+ */
+static int mmc_sdio_init_uhs_card(struct mmc_card *card)
+{
+ int err;
+
+ if (!card->scr.sda_spec3)
+ return 0;
+
+ /*
+ * Switch to wider bus (if supported).
+ */
+ if (card->host->caps & MMC_CAP_4_BIT_DATA) {
+ err = sdio_enable_4bit_bus(card);
+ if (err > 0) {
+ mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
+ err = 0;
+ }
+ }
+
+ /* Set the driver strength for the card */
+ sdio_select_driver_type(card);
+
+ /* Set bus speed mode of the card */
+ err = sdio_set_bus_speed_mode(card);
+ if (err)
+ goto out;
+
+ /* Initialize and start re-tuning timer */
+ if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
+ err = card->host->ops->execute_tuning(card->host,
+ MMC_SEND_TUNING_BLOCK);
+
+out:
+
+ return err;
+}
+
/*
* Handle the detection and initialisation of a card.
*
@@ -394,6 +632,30 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
host->ops->init_card(host, card);
/*
+ * If the host and card support UHS-I mode request the card
+ * to switch to 1.8V signaling level. No 1.8v signalling if
+ * UHS mode is not enabled to maintain compatibilty and some
+ * systems that claim 1.8v signalling in fact do not support
+ * it.
+ */
+ if ((ocr & R4_18V_PRESENT) &&
+ (host->caps &
+ (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 |
+ MMC_CAP_UHS_DDR50))) {
+ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
+ true);
+ if (err) {
+ ocr &= ~R4_18V_PRESENT;
+ host->ocr &= ~R4_18V_PRESENT;
+ }
+ err = 0;
+ } else {
+ ocr &= ~R4_18V_PRESENT;
+ host->ocr &= ~R4_18V_PRESENT;
+ }
+
+ /*
* For native busses: set card RCA and quit open drain mode.
*/
if (!powered_resume && !mmc_host_is_spi(host)) {
@@ -492,29 +754,39 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
if (err)
goto remove;
- /*
- * Switch to high-speed (if supported).
- */
- err = sdio_enable_hs(card);
- if (err > 0)
- mmc_sd_go_highspeed(card);
- else if (err)
- goto remove;
+ /* Initialization sequence for UHS-I cards */
+ /* Only if card supports 1.8v and UHS signaling */
+ if ((ocr & R4_18V_PRESENT) && card->sw_caps.sd3_bus_mode) {
+ err = mmc_sdio_init_uhs_card(card);
+ if (err)
+ goto remove;
- /*
- * Change to the card's maximum speed.
- */
- mmc_set_clock(host, mmc_sdio_get_max_clock(card));
+ /* Card is an ultra-high-speed card */
+ mmc_card_set_uhs(card);
+ } else {
+ /*
+ * Switch to high-speed (if supported).
+ */
+ err = sdio_enable_hs(card);
+ if (err > 0)
+ mmc_sd_go_highspeed(card);
+ else if (err)
+ goto remove;
- /*
- * Switch to wider bus (if supported).
- */
- err = sdio_enable_4bit_bus(card);
- if (err > 0)
- mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
- else if (err)
- goto remove;
+ /*
+ * Change to the card's maximum speed.
+ */
+ mmc_set_clock(host, mmc_sdio_get_max_clock(card));
+ /*
+ * Switch to wider bus (if supported).
+ */
+ err = sdio_enable_4bit_bus(card);
+ if (err > 0)
+ mmc_set_bus_width(card->host, MMC_BUS_WIDTH_4);
+ else if (err)
+ goto remove;
+ }
finish:
if (!oldcard)
host->card = card;
@@ -550,6 +822,14 @@ static void mmc_sdio_remove(struct mmc_host *host)
}
/*
+ * Card detection - card is alive.
+ */
+static int mmc_sdio_alive(struct mmc_host *host)
+{
+ return mmc_select_card(host->card);
+}
+
+/*
* Card detection callback from host.
*/
static void mmc_sdio_detect(struct mmc_host *host)
@@ -571,7 +851,7 @@ static void mmc_sdio_detect(struct mmc_host *host)
/*
* Just check if our card has been removed.
*/
- err = mmc_select_card(host->card);
+ err = _mmc_detect_card_removed(host);
mmc_release_host(host);
@@ -749,6 +1029,7 @@ static const struct mmc_bus_ops mmc_sdio_ops = {
.suspend = mmc_sdio_suspend,
.resume = mmc_sdio_resume,
.power_restore = mmc_sdio_power_restore,
+ .alive = mmc_sdio_alive,
};
@@ -797,8 +1078,17 @@ int mmc_attach_sdio(struct mmc_host *host)
* Detect and init the card.
*/
err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
- if (err)
- goto err;
+ if (err) {
+ if (err == -EAGAIN) {
+ /*
+ * Retry initialization with S18R set to 0.
+ */
+ host->ocr &= ~R4_18V_PRESENT;
+ err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
+ }
+ if (err)
+ goto err;
+ }
card = host->card;
/*
diff --git a/drivers/mmc/core/sdio_io.c b/drivers/mmc/core/sdio_io.c
index b1f3168f791b..8f6f5ac131fc 100644
--- a/drivers/mmc/core/sdio_io.c
+++ b/drivers/mmc/core/sdio_io.c
@@ -196,6 +196,9 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
else
mval = min(mval, func->max_blksize);
+ if (mmc_card_broken_byte_mode_512(func->card))
+ return min(mval, 511u);
+
return min(mval, 512u); /* maximum size for byte mode */
}
@@ -314,7 +317,7 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
func->card->host->max_seg_size / func->cur_blksize);
max_blocks = min(max_blocks, 511u);
- while (remainder > func->cur_blksize) {
+ while (remainder >= func->cur_blksize) {
unsigned blocks;
blocks = remainder / func->cur_blksize;
@@ -339,8 +342,9 @@ static int sdio_io_rw_ext_helper(struct sdio_func *func, int write,
while (remainder > 0) {
size = min(remainder, sdio_max_byte_size(func));
+ /* Indicate byte mode by setting "blocks" = 0 */
ret = mmc_io_rw_extended(func->card, write, func->num, addr,
- incr_addr, buf, 1, size);
+ incr_addr, buf, 0, size);
if (ret)
return ret;
diff --git a/drivers/mmc/core/sdio_ops.c b/drivers/mmc/core/sdio_ops.c
index b0517cc06200..d29e20630eed 100644
--- a/drivers/mmc/core/sdio_ops.c
+++ b/drivers/mmc/core/sdio_ops.c
@@ -128,8 +128,6 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
BUG_ON(!card);
BUG_ON(fn > 7);
- BUG_ON(blocks == 1 && blksz > 512);
- WARN_ON(blocks == 0);
WARN_ON(blksz == 0);
/* sanity check */
@@ -144,22 +142,20 @@ int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
cmd.arg |= fn << 28;
cmd.arg |= incr_addr ? 0x04000000 : 0x00000000;
cmd.arg |= addr << 9;
- if (blocks == 1 && blksz < 512)
- cmd.arg |= blksz; /* byte mode */
- else if (blocks == 1 && blksz == 512 &&
- !(mmc_card_broken_byte_mode_512(card)))
- cmd.arg |= 0; /* byte mode, 0==512 */
+ if (blocks == 0)
+ cmd.arg |= (blksz == 512) ? 0 : blksz; /* byte mode */
else
cmd.arg |= 0x08000000 | blocks; /* block mode */
cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
data.blksz = blksz;
- data.blocks = blocks;
+ /* Code in host drivers/fwk assumes that "blocks" always is >=1 */
+ data.blocks = blocks ? blocks : 1;
data.flags = write ? MMC_DATA_WRITE : MMC_DATA_READ;
data.sg = &sg;
data.sg_len = 1;
- sg_init_one(&sg, buf, blksz * blocks);
+ sg_init_one(&sg, buf, data.blksz * data.blocks);
mmc_set_data_timeout(&data, card);
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
index b4b83f302e32..745f8fce2519 100644
--- a/drivers/mmc/host/Makefile
+++ b/drivers/mmc/host/Makefile
@@ -9,6 +9,7 @@ obj-$(CONFIG_MMC_MXC) += mxcmmc.o
obj-$(CONFIG_MMC_MXS) += mxs-mmc.o
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
obj-$(CONFIG_MMC_SDHCI_PCI) += sdhci-pci.o
+obj-$(subst m,y,$(CONFIG_MMC_SDHCI_PCI)) += sdhci-pci-data.o
obj-$(CONFIG_MMC_SDHCI_PXAV3) += sdhci-pxav3.o
obj-$(CONFIG_MMC_SDHCI_PXAV2) += sdhci-pxav2.o
obj-$(CONFIG_MMC_SDHCI_S3C) += sdhci-s3c.o
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c
index f437c3e6f3aa..947faa5d2ce4 100644
--- a/drivers/mmc/host/at91_mci.c
+++ b/drivers/mmc/host/at91_mci.c
@@ -236,7 +236,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
sg = &data->sg[i];
- sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+ sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset;
amount = min(size, sg->length);
size -= amount;
@@ -252,7 +252,7 @@ static inline void at91_mci_sg_to_dma(struct at91mci_host *host, struct mmc_data
dmabuf = (unsigned *)tmpv;
}
- kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
+ kunmap_atomic(sgbuffer);
if (size == 0)
break;
@@ -302,7 +302,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
sg = &data->sg[i];
- sgbuffer = kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+ sgbuffer = kmap_atomic(sg_page(sg)) + sg->offset;
amount = min(size, sg->length);
size -= amount;
@@ -318,7 +318,7 @@ static void at91_mci_post_dma_read(struct at91mci_host *host)
}
flush_kernel_dcache_page(sg_page(sg));
- kunmap_atomic(sgbuffer, KM_BIO_SRC_IRQ);
+ kunmap_atomic(sgbuffer);
data->bytes_xfered += amount;
if (size == 0)
break;
diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c
index 5d3b9ae64523..dbd0c8a4e98a 100644
--- a/drivers/mmc/host/au1xmmc.c
+++ b/drivers/mmc/host/au1xmmc.c
@@ -153,6 +153,7 @@ static inline int has_dbdma(void)
{
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1200:
+ case ALCHEMY_CPU_AU1300:
return 1;
default:
return 0;
@@ -768,11 +769,15 @@ static void au1xmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
config2 = au_readl(HOST_CONFIG2(host));
switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_8:
+ config2 |= SD_CONFIG2_BB;
+ break;
case MMC_BUS_WIDTH_4:
+ config2 &= ~SD_CONFIG2_BB;
config2 |= SD_CONFIG2_WB;
break;
case MMC_BUS_WIDTH_1:
- config2 &= ~SD_CONFIG2_WB;
+ config2 &= ~(SD_CONFIG2_WB | SD_CONFIG2_BB);
break;
}
au_writel(config2, HOST_CONFIG2(host));
@@ -943,7 +948,7 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
struct mmc_host *mmc;
struct au1xmmc_host *host;
struct resource *r;
- int ret;
+ int ret, iflag;
mmc = mmc_alloc_host(sizeof(struct au1xmmc_host), &pdev->dev);
if (!mmc) {
@@ -982,37 +987,43 @@ static int __devinit au1xmmc_probe(struct platform_device *pdev)
dev_err(&pdev->dev, "no IRQ defined\n");
goto out3;
}
-
host->irq = r->start;
- /* IRQ is shared among both SD controllers */
- ret = request_irq(host->irq, au1xmmc_irq, IRQF_SHARED,
- DRIVER_NAME, host);
- if (ret) {
- dev_err(&pdev->dev, "cannot grab IRQ\n");
- goto out3;
- }
mmc->ops = &au1xmmc_ops;
mmc->f_min = 450000;
mmc->f_max = 24000000;
+ mmc->max_blk_size = 2048;
+ mmc->max_blk_count = 512;
+
+ mmc->ocr_avail = AU1XMMC_OCR;
+ mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+ mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT;
+
+ iflag = IRQF_SHARED; /* Au1100/Au1200: one int for both ctrls */
+
switch (alchemy_get_cputype()) {
case ALCHEMY_CPU_AU1100:
mmc->max_seg_size = AU1100_MMC_DESCRIPTOR_SIZE;
- mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT;
break;
case ALCHEMY_CPU_AU1200:
mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE;
- mmc->max_segs = AU1XMMC_DESCRIPTOR_COUNT;
+ break;
+ case ALCHEMY_CPU_AU1300:
+ iflag = 0; /* nothing is shared */
+ mmc->max_seg_size = AU1200_MMC_DESCRIPTOR_SIZE;
+ mmc->f_max = 52000000;
+ if (host->ioarea->start == AU1100_SD0_PHYS_ADDR)
+ mmc->caps |= MMC_CAP_8_BIT_DATA;
break;
}
- mmc->max_blk_size = 2048;
- mmc->max_blk_count = 512;
-
- mmc->ocr_avail = AU1XMMC_OCR;
- mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
+ ret = request_irq(host->irq, au1xmmc_irq, iflag, DRIVER_NAME, host);
+ if (ret) {
+ dev_err(&pdev->dev, "cannot grab IRQ\n");
+ goto out3;
+ }
host->status = HOST_S_IDLE;
diff --git a/drivers/mmc/host/bfin_sdh.c b/drivers/mmc/host/bfin_sdh.c
index 0371bf502249..03666174ca48 100644
--- a/drivers/mmc/host/bfin_sdh.c
+++ b/drivers/mmc/host/bfin_sdh.c
@@ -627,17 +627,7 @@ static struct platform_driver sdh_driver = {
},
};
-static int __init sdh_init(void)
-{
- return platform_driver_register(&sdh_driver);
-}
-module_init(sdh_init);
-
-static void __exit sdh_exit(void)
-{
- platform_driver_unregister(&sdh_driver);
-}
-module_exit(sdh_exit);
+module_platform_driver(sdh_driver);
MODULE_DESCRIPTION("Blackfin Secure Digital Host Driver");
MODULE_AUTHOR("Cliff Cai, Roy Huang");
diff --git a/drivers/mmc/host/cb710-mmc.c b/drivers/mmc/host/cb710-mmc.c
index ce2a47b71dd6..83693fd7c6b3 100644
--- a/drivers/mmc/host/cb710-mmc.c
+++ b/drivers/mmc/host/cb710-mmc.c
@@ -780,18 +780,7 @@ static struct platform_driver cb710_mmc_driver = {
#endif
};
-static int __init cb710_mmc_init_module(void)
-{
- return platform_driver_register(&cb710_mmc_driver);
-}
-
-static void __exit cb710_mmc_cleanup_module(void)
-{
- platform_driver_unregister(&cb710_mmc_driver);
-}
-
-module_init(cb710_mmc_init_module);
-module_exit(cb710_mmc_cleanup_module);
+module_platform_driver(cb710_mmc_driver);
MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>");
MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part");
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 3aaeb0841914..0e342793ff14 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -588,11 +588,11 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot)
mci_writel(host, CTYPE, (slot->ctype << slot->id));
}
-static void dw_mci_start_request(struct dw_mci *host,
- struct dw_mci_slot *slot)
+static void __dw_mci_start_request(struct dw_mci *host,
+ struct dw_mci_slot *slot,
+ struct mmc_command *cmd)
{
struct mmc_request *mrq;
- struct mmc_command *cmd;
struct mmc_data *data;
u32 cmdflags;
@@ -610,14 +610,13 @@ static void dw_mci_start_request(struct dw_mci *host,
host->completed_events = 0;
host->data_status = 0;
- data = mrq->data;
+ data = cmd->data;
if (data) {
dw_mci_set_timeout(host);
mci_writel(host, BYTCNT, data->blksz*data->blocks);
mci_writel(host, BLKSIZ, data->blksz);
}
- cmd = mrq->cmd;
cmdflags = dw_mci_prepare_command(slot->mmc, cmd);
/* this is the first command, send the initialization clock */
@@ -635,6 +634,16 @@ static void dw_mci_start_request(struct dw_mci *host,
host->stop_cmdr = dw_mci_prepare_command(slot->mmc, mrq->stop);
}
+static void dw_mci_start_request(struct dw_mci *host,
+ struct dw_mci_slot *slot)
+{
+ struct mmc_request *mrq = slot->mrq;
+ struct mmc_command *cmd;
+
+ cmd = mrq->sbc ? mrq->sbc : mrq->cmd;
+ __dw_mci_start_request(host, slot, cmd);
+}
+
/* must be called with host->lock held */
static void dw_mci_queue_request(struct dw_mci *host, struct dw_mci_slot *slot,
struct mmc_request *mrq)
@@ -698,12 +707,15 @@ static void dw_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
break;
}
+ regs = mci_readl(slot->host, UHS_REG);
+
/* DDR mode set */
- if (ios->timing == MMC_TIMING_UHS_DDR50) {
- regs = mci_readl(slot->host, UHS_REG);
+ if (ios->timing == MMC_TIMING_UHS_DDR50)
regs |= (0x1 << slot->id) << 16;
- mci_writel(slot->host, UHS_REG, regs);
- }
+ else
+ regs &= ~(0x1 << slot->id) << 16;
+
+ mci_writel(slot->host, UHS_REG, regs);
if (ios->clock) {
/*
@@ -889,7 +901,14 @@ static void dw_mci_tasklet_func(unsigned long priv)
cmd = host->cmd;
host->cmd = NULL;
set_bit(EVENT_CMD_COMPLETE, &host->completed_events);
- dw_mci_command_complete(host, host->mrq->cmd);
+ dw_mci_command_complete(host, cmd);
+ if (cmd == host->mrq->sbc && !cmd->error) {
+ prev_state = state = STATE_SENDING_CMD;
+ __dw_mci_start_request(host, host->cur_slot,
+ host->mrq->cmd);
+ goto unlock;
+ }
+
if (!host->mrq->data || cmd->error) {
dw_mci_request_end(host, host->mrq);
goto unlock;
@@ -967,6 +986,12 @@ static void dw_mci_tasklet_func(unsigned long priv)
goto unlock;
}
+ if (host->mrq->sbc && !data->error) {
+ data->stop->error = 0;
+ dw_mci_request_end(host, host->mrq);
+ goto unlock;
+ }
+
prev_state = state = STATE_SENDING_STOP;
if (!data->error)
send_stop_cmd(host, data);
@@ -1678,8 +1703,9 @@ static int __init dw_mci_init_slot(struct dw_mci *host, unsigned int id)
if (host->pdata->caps)
mmc->caps = host->pdata->caps;
- else
- mmc->caps = 0;
+
+ if (host->pdata->caps2)
+ mmc->caps2 = host->pdata->caps2;
if (host->pdata->get_bus_wd)
if (host->pdata->get_bus_wd(slot->id) >= 4)
@@ -1923,7 +1949,7 @@ static int dw_mci_probe(struct platform_device *pdev)
* should put it in the platform data.
*/
fifo_size = mci_readl(host, FIFOTH);
- fifo_size = 1 + ((fifo_size >> 16) & 0x7ff);
+ fifo_size = 1 + ((fifo_size >> 16) & 0xfff);
} else {
fifo_size = host->pdata->fifo_depth;
}
@@ -2062,14 +2088,14 @@ static int __exit dw_mci_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
/*
* TODO: we should probably disable the clock to the card in the suspend path.
*/
-static int dw_mci_suspend(struct platform_device *pdev, pm_message_t mesg)
+static int dw_mci_suspend(struct device *dev)
{
int i, ret;
- struct dw_mci *host = platform_get_drvdata(pdev);
+ struct dw_mci *host = dev_get_drvdata(dev);
for (i = 0; i < host->num_slots; i++) {
struct dw_mci_slot *slot = host->slot[i];
@@ -2092,10 +2118,10 @@ static int dw_mci_suspend(struct platform_device *pdev, pm_message_t mesg)
return 0;
}
-static int dw_mci_resume(struct platform_device *pdev)
+static int dw_mci_resume(struct device *dev)
{
int i, ret;
- struct dw_mci *host = platform_get_drvdata(pdev);
+ struct dw_mci *host = dev_get_drvdata(dev);
if (host->vmmc)
regulator_enable(host->vmmc);
@@ -2103,7 +2129,7 @@ static int dw_mci_resume(struct platform_device *pdev)
if (host->dma_ops->init)
host->dma_ops->init(host);
- if (!mci_wait_reset(&pdev->dev, host)) {
+ if (!mci_wait_reset(dev, host)) {
ret = -ENODEV;
return ret;
}
@@ -2131,14 +2157,15 @@ static int dw_mci_resume(struct platform_device *pdev)
#else
#define dw_mci_suspend NULL
#define dw_mci_resume NULL
-#endif /* CONFIG_PM */
+#endif /* CONFIG_PM_SLEEP */
+
+static SIMPLE_DEV_PM_OPS(dw_mci_pmops, dw_mci_suspend, dw_mci_resume);
static struct platform_driver dw_mci_driver = {
.remove = __exit_p(dw_mci_remove),
- .suspend = dw_mci_suspend,
- .resume = dw_mci_resume,
.driver = {
.name = "dw_mmc",
+ .pm = &dw_mci_pmops,
},
};
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 72c071f6e001..df392a1143f2 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -126,7 +126,7 @@
#define SDMMC_CMD_RESP_EXP BIT(6)
#define SDMMC_CMD_INDX(n) ((n) & 0x1F)
/* Status register defines */
-#define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FF)
+#define SDMMC_GET_FCNT(x) (((x)>>17) & 0x1FFF)
/* Internal DMAC interrupt defines */
#define SDMMC_IDMAC_INT_AI BIT(9)
#define SDMMC_IDMAC_INT_NI BIT(8)
diff --git a/drivers/mmc/host/jz4740_mmc.c b/drivers/mmc/host/jz4740_mmc.c
index 74218ad677e4..c8852a8128a9 100644
--- a/drivers/mmc/host/jz4740_mmc.c
+++ b/drivers/mmc/host/jz4740_mmc.c
@@ -1012,17 +1012,7 @@ static struct platform_driver jz4740_mmc_driver = {
},
};
-static int __init jz4740_mmc_init(void)
-{
- return platform_driver_register(&jz4740_mmc_driver);
-}
-module_init(jz4740_mmc_init);
-
-static void __exit jz4740_mmc_exit(void)
-{
- platform_driver_unregister(&jz4740_mmc_driver);
-}
-module_exit(jz4740_mmc_exit);
+module_platform_driver(jz4740_mmc_driver);
MODULE_DESCRIPTION("JZ4740 SD/MMC controller driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 92946b84e9fa..273306c68d58 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1525,7 +1525,6 @@ static struct of_device_id mmc_spi_of_match_table[] __devinitdata = {
static struct spi_driver mmc_spi_driver = {
.driver = {
.name = "mmc_spi",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
.of_match_table = mmc_spi_of_match_table,
},
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c
index fa8dd2fda4b2..ece03b491c7d 100644
--- a/drivers/mmc/host/mmci.c
+++ b/drivers/mmc/host/mmci.c
@@ -1245,6 +1245,7 @@ static int __devinit mmci_probe(struct amba_device *dev,
if (host->vcc == NULL)
mmc->ocr_avail = plat->ocr_mask;
mmc->caps = plat->capabilities;
+ mmc->caps2 = plat->capabilities2;
/*
* We can do SGIO
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 80d8eb143b48..1d14cda95e56 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -689,8 +689,8 @@ msmsdcc_pio_irq(int irq, void *dev_id)
/* Map the current scatter buffer */
local_irq_save(flags);
- buffer = kmap_atomic(sg_page(host->pio.sg),
- KM_BIO_SRC_IRQ) + host->pio.sg->offset;
+ buffer = kmap_atomic(sg_page(host->pio.sg))
+ + host->pio.sg->offset;
buffer += host->pio.sg_off;
remain = host->pio.sg->length - host->pio.sg_off;
len = 0;
@@ -700,7 +700,7 @@ msmsdcc_pio_irq(int irq, void *dev_id)
len = msmsdcc_pio_write(host, buffer, remain, status);
/* Unmap the buffer */
- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+ kunmap_atomic(buffer);
local_irq_restore(flags);
host->pio.sg_off += len;
@@ -1480,18 +1480,7 @@ static struct platform_driver msmsdcc_driver = {
},
};
-static int __init msmsdcc_init(void)
-{
- return platform_driver_register(&msmsdcc_driver);
-}
-
-static void __exit msmsdcc_exit(void)
-{
- platform_driver_unregister(&msmsdcc_driver);
-}
-
-module_init(msmsdcc_init);
-module_exit(msmsdcc_exit);
+module_platform_driver(msmsdcc_driver);
MODULE_DESCRIPTION("Qualcomm MSM 7X00A Multimedia Card Interface driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c
index 8e0fbe994047..7088b40f9579 100644
--- a/drivers/mmc/host/mxcmmc.c
+++ b/drivers/mmc/host/mxcmmc.c
@@ -1047,18 +1047,7 @@ static struct platform_driver mxcmci_driver = {
}
};
-static int __init mxcmci_init(void)
-{
- return platform_driver_register(&mxcmci_driver);
-}
-
-static void __exit mxcmci_exit(void)
-{
- platform_driver_unregister(&mxcmci_driver);
-}
-
-module_init(mxcmci_init);
-module_exit(mxcmci_exit);
+module_platform_driver(mxcmci_driver);
MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
index 973011f9a298..4e2e019dd5c9 100644
--- a/drivers/mmc/host/mxs-mmc.c
+++ b/drivers/mmc/host/mxs-mmc.c
@@ -855,18 +855,7 @@ static struct platform_driver mxs_mmc_driver = {
},
};
-static int __init mxs_mmc_init(void)
-{
- return platform_driver_register(&mxs_mmc_driver);
-}
-
-static void __exit mxs_mmc_exit(void)
-{
- platform_driver_unregister(&mxs_mmc_driver);
-}
-
-module_init(mxs_mmc_init);
-module_exit(mxs_mmc_exit);
+module_platform_driver(mxs_mmc_driver);
MODULE_DESCRIPTION("FREESCALE MXS MMC peripheral");
MODULE_AUTHOR("Freescale Semiconductor");
diff --git a/drivers/mmc/host/omap_hsmmc.c b/drivers/mmc/host/omap_hsmmc.c
index d1fb561e089d..fd0c661bbad3 100644
--- a/drivers/mmc/host/omap_hsmmc.c
+++ b/drivers/mmc/host/omap_hsmmc.c
@@ -24,7 +24,6 @@
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
-#include <linux/workqueue.h>
#include <linux/timer.h>
#include <linux/clk.h>
#include <linux/mmc/host.h>
@@ -120,7 +119,6 @@
#define MMC_AUTOSUSPEND_DELAY 100
#define MMC_TIMEOUT_MS 20
-#define OMAP_MMC_MASTER_CLOCK 96000000
#define OMAP_MMC_MIN_CLOCK 400000
#define OMAP_MMC_MAX_CLOCK 52000000
#define DRIVER_NAME "omap_hsmmc"
@@ -163,7 +161,6 @@ struct omap_hsmmc_host {
*/
struct regulator *vcc;
struct regulator *vcc_aux;
- struct work_struct mmc_carddetect_work;
void __iomem *base;
resource_size_t mapbase;
spinlock_t irq_lock; /* Prevent races with irq handler */
@@ -598,12 +595,12 @@ static void omap_hsmmc_disable_irq(struct omap_hsmmc_host *host)
}
/* Calculate divisor for the given clock frequency */
-static u16 calc_divisor(struct mmc_ios *ios)
+static u16 calc_divisor(struct omap_hsmmc_host *host, struct mmc_ios *ios)
{
u16 dsor = 0;
if (ios->clock) {
- dsor = DIV_ROUND_UP(OMAP_MMC_MASTER_CLOCK, ios->clock);
+ dsor = DIV_ROUND_UP(clk_get_rate(host->fclk), ios->clock);
if (dsor > 250)
dsor = 250;
}
@@ -623,7 +620,7 @@ static void omap_hsmmc_set_clock(struct omap_hsmmc_host *host)
regval = OMAP_HSMMC_READ(host->base, SYSCTL);
regval = regval & ~(CLKD_MASK | DTO_MASK);
- regval = regval | (calc_divisor(ios) << 6) | (DTO << 16);
+ regval = regval | (calc_divisor(host, ios) << 6) | (DTO << 16);
OMAP_HSMMC_WRITE(host->base, SYSCTL, regval);
OMAP_HSMMC_WRITE(host->base, SYSCTL,
OMAP_HSMMC_READ(host->base, SYSCTL) | ICE);
@@ -1280,17 +1277,16 @@ static void omap_hsmmc_protect_card(struct omap_hsmmc_host *host)
}
/*
- * Work Item to notify the core about card insertion/removal
+ * irq handler to notify the core about card insertion/removal
*/
-static void omap_hsmmc_detect(struct work_struct *work)
+static irqreturn_t omap_hsmmc_detect(int irq, void *dev_id)
{
- struct omap_hsmmc_host *host =
- container_of(work, struct omap_hsmmc_host, mmc_carddetect_work);
+ struct omap_hsmmc_host *host = dev_id;
struct omap_mmc_slot_data *slot = &mmc_slot(host);
int carddetect;
if (host->suspended)
- return;
+ return IRQ_HANDLED;
sysfs_notify(&host->mmc->class_dev.kobj, NULL, "cover_switch");
@@ -1305,19 +1301,6 @@ static void omap_hsmmc_detect(struct work_struct *work)
mmc_detect_change(host->mmc, (HZ * 200) / 1000);
else
mmc_detect_change(host->mmc, (HZ * 50) / 1000);
-}
-
-/*
- * ISR for handling card insertion and removal
- */
-static irqreturn_t omap_hsmmc_cd_handler(int irq, void *dev_id)
-{
- struct omap_hsmmc_host *host = (struct omap_hsmmc_host *)dev_id;
-
- if (host->suspended)
- return IRQ_HANDLED;
- schedule_work(&host->mmc_carddetect_work);
-
return IRQ_HANDLED;
}
@@ -1919,7 +1902,6 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
host->next_data.cookie = 1;
platform_set_drvdata(pdev, host);
- INIT_WORK(&host->mmc_carddetect_work, omap_hsmmc_detect);
mmc->ops = &omap_hsmmc_ops;
@@ -2049,10 +2031,11 @@ static int __init omap_hsmmc_probe(struct platform_device *pdev)
/* Request IRQ for card detect */
if ((mmc_slot(host).card_detect_irq)) {
- ret = request_irq(mmc_slot(host).card_detect_irq,
- omap_hsmmc_cd_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
- mmc_hostname(mmc), host);
+ ret = request_threaded_irq(mmc_slot(host).card_detect_irq,
+ NULL,
+ omap_hsmmc_detect,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ mmc_hostname(mmc), host);
if (ret) {
dev_dbg(mmc_dev(host->mmc),
"Unable to grab MMC CD IRQ\n");
@@ -2131,7 +2114,6 @@ static int omap_hsmmc_remove(struct platform_device *pdev)
free_irq(host->irq, host);
if (mmc_slot(host).card_detect_irq)
free_irq(mmc_slot(host).card_detect_irq, host);
- flush_work_sync(&host->mmc_carddetect_work);
pm_runtime_put_sync(host->dev);
pm_runtime_disable(host->dev);
@@ -2178,7 +2160,6 @@ static int omap_hsmmc_suspend(struct device *dev)
return ret;
}
}
- cancel_work_sync(&host->mmc_carddetect_work);
ret = mmc_suspend_host(host->mmc);
if (ret) {
diff --git a/drivers/mmc/host/pxamci.c b/drivers/mmc/host/pxamci.c
index fc4356e00d46..cb2dc0e75ba7 100644
--- a/drivers/mmc/host/pxamci.c
+++ b/drivers/mmc/host/pxamci.c
@@ -872,18 +872,7 @@ static struct platform_driver pxamci_driver = {
},
};
-static int __init pxamci_init(void)
-{
- return platform_driver_register(&pxamci_driver);
-}
-
-static void __exit pxamci_exit(void)
-{
- platform_driver_unregister(&pxamci_driver);
-}
-
-module_init(pxamci_init);
-module_exit(pxamci_exit);
+module_platform_driver(pxamci_driver);
MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
index 720f99334a7f..1bcfd6dbb5cc 100644
--- a/drivers/mmc/host/s3cmci.c
+++ b/drivers/mmc/host/s3cmci.c
@@ -1914,18 +1914,7 @@ static struct platform_driver s3cmci_driver = {
.shutdown = s3cmci_shutdown,
};
-static int __init s3cmci_init(void)
-{
- return platform_driver_register(&s3cmci_driver);
-}
-
-static void __exit s3cmci_exit(void)
-{
- platform_driver_unregister(&s3cmci_driver);
-}
-
-module_init(s3cmci_init);
-module_exit(s3cmci_exit);
+module_platform_driver(s3cmci_driver);
MODULE_DESCRIPTION("Samsung S3C MMC/SD Card Interface driver");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/mmc/host/sdhci-cns3xxx.c b/drivers/mmc/host/sdhci-cns3xxx.c
index b4257e700617..28a870804f60 100644
--- a/drivers/mmc/host/sdhci-cns3xxx.c
+++ b/drivers/mmc/host/sdhci-cns3xxx.c
@@ -115,17 +115,7 @@ static struct platform_driver sdhci_cns3xxx_driver = {
.remove = __devexit_p(sdhci_cns3xxx_remove),
};
-static int __init sdhci_cns3xxx_init(void)
-{
- return platform_driver_register(&sdhci_cns3xxx_driver);
-}
-module_init(sdhci_cns3xxx_init);
-
-static void __exit sdhci_cns3xxx_exit(void)
-{
- platform_driver_unregister(&sdhci_cns3xxx_driver);
-}
-module_exit(sdhci_cns3xxx_exit);
+module_platform_driver(sdhci_cns3xxx_driver);
MODULE_DESCRIPTION("SDHCI driver for CNS3xxx");
MODULE_AUTHOR("Scott Shu, "
diff --git a/drivers/mmc/host/sdhci-dove.c b/drivers/mmc/host/sdhci-dove.c
index a81312c91f70..46fd1fd1b605 100644
--- a/drivers/mmc/host/sdhci-dove.c
+++ b/drivers/mmc/host/sdhci-dove.c
@@ -88,17 +88,7 @@ static struct platform_driver sdhci_dove_driver = {
.remove = __devexit_p(sdhci_dove_remove),
};
-static int __init sdhci_dove_init(void)
-{
- return platform_driver_register(&sdhci_dove_driver);
-}
-module_init(sdhci_dove_init);
-
-static void __exit sdhci_dove_exit(void)
-{
- platform_driver_unregister(&sdhci_dove_driver);
-}
-module_exit(sdhci_dove_exit);
+module_platform_driver(sdhci_dove_driver);
MODULE_DESCRIPTION("SDHCI driver for Dove");
MODULE_AUTHOR("Saeed Bishara <saeed@marvell.com>, "
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 38ebc4ea259f..d601e41af282 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -606,17 +606,7 @@ static struct platform_driver sdhci_esdhc_imx_driver = {
.remove = __devexit_p(sdhci_esdhc_imx_remove),
};
-static int __init sdhci_esdhc_imx_init(void)
-{
- return platform_driver_register(&sdhci_esdhc_imx_driver);
-}
-module_init(sdhci_esdhc_imx_init);
-
-static void __exit sdhci_esdhc_imx_exit(void)
-{
- platform_driver_unregister(&sdhci_esdhc_imx_driver);
-}
-module_exit(sdhci_esdhc_imx_exit);
+module_platform_driver(sdhci_esdhc_imx_driver);
MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC");
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index c3b08f111942..b97b2f5dafdb 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -73,7 +73,7 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
| (div << ESDHC_DIVIDER_SHIFT)
| (pre_div << ESDHC_PREDIV_SHIFT));
sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
- mdelay(100);
+ mdelay(1);
out:
host->clock = clock;
}
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
index 01e5f627e0f0..ff4adc018041 100644
--- a/drivers/mmc/host/sdhci-of-esdhc.c
+++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -131,17 +131,7 @@ static struct platform_driver sdhci_esdhc_driver = {
.remove = __devexit_p(sdhci_esdhc_remove),
};
-static int __init sdhci_esdhc_init(void)
-{
- return platform_driver_register(&sdhci_esdhc_driver);
-}
-module_init(sdhci_esdhc_init);
-
-static void __exit sdhci_esdhc_exit(void)
-{
- platform_driver_unregister(&sdhci_esdhc_driver);
-}
-module_exit(sdhci_esdhc_exit);
+module_platform_driver(sdhci_esdhc_driver);
MODULE_DESCRIPTION("SDHCI OF driver for Freescale MPC eSDHC");
MODULE_AUTHOR("Xiaobo Xie <X.Xie@freescale.com>, "
diff --git a/drivers/mmc/host/sdhci-of-hlwd.c b/drivers/mmc/host/sdhci-of-hlwd.c
index 3619adc7d9fc..0ce088ae0228 100644
--- a/drivers/mmc/host/sdhci-of-hlwd.c
+++ b/drivers/mmc/host/sdhci-of-hlwd.c
@@ -93,17 +93,7 @@ static struct platform_driver sdhci_hlwd_driver = {
.remove = __devexit_p(sdhci_hlwd_remove),
};
-static int __init sdhci_hlwd_init(void)
-{
- return platform_driver_register(&sdhci_hlwd_driver);
-}
-module_init(sdhci_hlwd_init);
-
-static void __exit sdhci_hlwd_exit(void)
-{
- platform_driver_unregister(&sdhci_hlwd_driver);
-}
-module_exit(sdhci_hlwd_exit);
+module_platform_driver(sdhci_hlwd_driver);
MODULE_DESCRIPTION("Nintendo Wii SDHCI OF driver");
MODULE_AUTHOR("The GameCube Linux Team, Albert Herranz");
diff --git a/drivers/mmc/host/sdhci-pci-data.c b/drivers/mmc/host/sdhci-pci-data.c
new file mode 100644
index 000000000000..a611217769f5
--- /dev/null
+++ b/drivers/mmc/host/sdhci-pci-data.c
@@ -0,0 +1,5 @@
+#include <linux/module.h>
+#include <linux/mmc/sdhci-pci-data.h>
+
+struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev, int slotno);
+EXPORT_SYMBOL_GPL(sdhci_pci_get_data);
diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c
index 6878a94626bc..7165e6a09274 100644
--- a/drivers/mmc/host/sdhci-pci.c
+++ b/drivers/mmc/host/sdhci-pci.c
@@ -23,8 +23,8 @@
#include <linux/scatterlist.h>
#include <linux/io.h>
#include <linux/gpio.h>
-#include <linux/sfi.h>
#include <linux/pm_runtime.h>
+#include <linux/mmc/sdhci-pci-data.h>
#include "sdhci.h"
@@ -61,6 +61,7 @@ struct sdhci_pci_fixes {
struct sdhci_pci_slot {
struct sdhci_pci_chip *chip;
struct sdhci_host *host;
+ struct sdhci_pci_data *data;
int pci_bar;
int rst_n_gpio;
@@ -171,32 +172,9 @@ static int mrst_hc_probe(struct sdhci_pci_chip *chip)
return 0;
}
-/* Medfield eMMC hardware reset GPIOs */
-static int mfd_emmc0_rst_gpio = -EINVAL;
-static int mfd_emmc1_rst_gpio = -EINVAL;
-
-static int mfd_emmc_gpio_parse(struct sfi_table_header *table)
-{
- struct sfi_table_simple *sb = (struct sfi_table_simple *)table;
- struct sfi_gpio_table_entry *entry;
- int i, num;
-
- num = SFI_GET_NUM_ENTRIES(sb, struct sfi_gpio_table_entry);
- entry = (struct sfi_gpio_table_entry *)sb->pentry;
-
- for (i = 0; i < num; i++, entry++) {
- if (!strncmp(entry->pin_name, "emmc0_rst", SFI_NAME_LEN))
- mfd_emmc0_rst_gpio = entry->pin_no;
- else if (!strncmp(entry->pin_name, "emmc1_rst", SFI_NAME_LEN))
- mfd_emmc1_rst_gpio = entry->pin_no;
- }
-
- return 0;
-}
-
#ifdef CONFIG_PM_RUNTIME
-static irqreturn_t mfd_sd_cd(int irq, void *dev_id)
+static irqreturn_t sdhci_pci_sd_cd(int irq, void *dev_id)
{
struct sdhci_pci_slot *slot = dev_id;
struct sdhci_host *host = slot->host;
@@ -205,15 +183,16 @@ static irqreturn_t mfd_sd_cd(int irq, void *dev_id)
return IRQ_HANDLED;
}
-#define MFLD_SD_CD_PIN 69
-
-static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
+static void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
{
- int err, irq, gpio = MFLD_SD_CD_PIN;
+ int err, irq, gpio = slot->cd_gpio;
slot->cd_gpio = -EINVAL;
slot->cd_irq = -EINVAL;
+ if (!gpio_is_valid(gpio))
+ return;
+
err = gpio_request(gpio, "sd_cd");
if (err < 0)
goto out;
@@ -226,72 +205,53 @@ static int mfd_sd_probe_slot(struct sdhci_pci_slot *slot)
if (irq < 0)
goto out_free;
- err = request_irq(irq, mfd_sd_cd, IRQF_TRIGGER_RISING |
+ err = request_irq(irq, sdhci_pci_sd_cd, IRQF_TRIGGER_RISING |
IRQF_TRIGGER_FALLING, "sd_cd", slot);
if (err)
goto out_free;
slot->cd_gpio = gpio;
slot->cd_irq = irq;
- slot->host->quirks2 |= SDHCI_QUIRK2_OWN_CARD_DETECTION;
- return 0;
+ return;
out_free:
gpio_free(gpio);
out:
dev_warn(&slot->chip->pdev->dev, "failed to setup card detect wake up\n");
- return 0;
}
-static void mfd_sd_remove_slot(struct sdhci_pci_slot *slot, int dead)
+static void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
{
if (slot->cd_irq >= 0)
free_irq(slot->cd_irq, slot);
- gpio_free(slot->cd_gpio);
+ if (gpio_is_valid(slot->cd_gpio))
+ gpio_free(slot->cd_gpio);
}
#else
-#define mfd_sd_probe_slot NULL
-#define mfd_sd_remove_slot NULL
+static inline void sdhci_pci_add_own_cd(struct sdhci_pci_slot *slot)
+{
+}
+
+static inline void sdhci_pci_remove_own_cd(struct sdhci_pci_slot *slot)
+{
+}
#endif
static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot)
{
- const char *name = NULL;
- int gpio = -EINVAL;
-
- sfi_table_parse(SFI_SIG_GPIO, NULL, NULL, mfd_emmc_gpio_parse);
-
- switch (slot->chip->pdev->device) {
- case PCI_DEVICE_ID_INTEL_MFD_EMMC0:
- gpio = mfd_emmc0_rst_gpio;
- name = "eMMC0_reset";
- break;
- case PCI_DEVICE_ID_INTEL_MFD_EMMC1:
- gpio = mfd_emmc1_rst_gpio;
- name = "eMMC1_reset";
- break;
- }
-
- if (!gpio_request(gpio, name)) {
- gpio_direction_output(gpio, 1);
- slot->rst_n_gpio = gpio;
- slot->host->mmc->caps |= MMC_CAP_HW_RESET;
- }
-
slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE;
-
slot->host->mmc->caps2 = MMC_CAP2_BOOTPART_NOACC;
-
return 0;
}
-static void mfd_emmc_remove_slot(struct sdhci_pci_slot *slot, int dead)
+static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot)
{
- gpio_free(slot->rst_n_gpio);
+ slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD;
+ return 0;
}
static const struct sdhci_pci_fixes sdhci_intel_mrst_hc0 = {
@@ -307,20 +267,18 @@ static const struct sdhci_pci_fixes sdhci_intel_mrst_hc1_hc2 = {
static const struct sdhci_pci_fixes sdhci_intel_mfd_sd = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.allow_runtime_pm = true,
- .probe_slot = mfd_sd_probe_slot,
- .remove_slot = mfd_sd_remove_slot,
};
static const struct sdhci_pci_fixes sdhci_intel_mfd_sdio = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.allow_runtime_pm = true,
+ .probe_slot = mfd_sdio_probe_slot,
};
static const struct sdhci_pci_fixes sdhci_intel_mfd_emmc = {
.quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
.allow_runtime_pm = true,
.probe_slot = mfd_emmc_probe_slot,
- .remove_slot = mfd_emmc_remove_slot,
};
/* O2Micro extra registers */
@@ -1012,11 +970,8 @@ static int sdhci_pci_suspend(struct device *dev)
ret = sdhci_suspend_host(slot->host);
- if (ret) {
- for (i--; i >= 0; i--)
- sdhci_resume_host(chip->slots[i]->host);
- return ret;
- }
+ if (ret)
+ goto err_pci_suspend;
slot_pm_flags = slot->host->mmc->pm_flags;
if (slot_pm_flags & MMC_PM_WAKE_SDIO_IRQ)
@@ -1027,11 +982,8 @@ static int sdhci_pci_suspend(struct device *dev)
if (chip->fixes && chip->fixes->suspend) {
ret = chip->fixes->suspend(chip);
- if (ret) {
- for (i = chip->num_slots - 1; i >= 0; i--)
- sdhci_resume_host(chip->slots[i]->host);
- return ret;
- }
+ if (ret)
+ goto err_pci_suspend;
}
pci_save_state(pdev);
@@ -1048,6 +1000,11 @@ static int sdhci_pci_suspend(struct device *dev)
}
return 0;
+
+err_pci_suspend:
+ while (--i >= 0)
+ sdhci_resume_host(chip->slots[i]->host);
+ return ret;
}
static int sdhci_pci_resume(struct device *dev)
@@ -1113,23 +1070,22 @@ static int sdhci_pci_runtime_suspend(struct device *dev)
ret = sdhci_runtime_suspend_host(slot->host);
- if (ret) {
- for (i--; i >= 0; i--)
- sdhci_runtime_resume_host(chip->slots[i]->host);
- return ret;
- }
+ if (ret)
+ goto err_pci_runtime_suspend;
}
if (chip->fixes && chip->fixes->suspend) {
ret = chip->fixes->suspend(chip);
- if (ret) {
- for (i = chip->num_slots - 1; i >= 0; i--)
- sdhci_runtime_resume_host(chip->slots[i]->host);
- return ret;
- }
+ if (ret)
+ goto err_pci_runtime_suspend;
}
return 0;
+
+err_pci_runtime_suspend:
+ while (--i >= 0)
+ sdhci_runtime_resume_host(chip->slots[i]->host);
+ return ret;
}
static int sdhci_pci_runtime_resume(struct device *dev)
@@ -1190,11 +1146,12 @@ static const struct dev_pm_ops sdhci_pci_pm_ops = {
\*****************************************************************************/
static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
- struct pci_dev *pdev, struct sdhci_pci_chip *chip, int bar)
+ struct pci_dev *pdev, struct sdhci_pci_chip *chip, int first_bar,
+ int slotno)
{
struct sdhci_pci_slot *slot;
struct sdhci_host *host;
- int ret;
+ int ret, bar = first_bar + slotno;
if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) {
dev_err(&pdev->dev, "BAR %d is not iomem. Aborting.\n", bar);
@@ -1228,6 +1185,23 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
slot->host = host;
slot->pci_bar = bar;
slot->rst_n_gpio = -EINVAL;
+ slot->cd_gpio = -EINVAL;
+
+ /* Retrieve platform data if there is any */
+ if (*sdhci_pci_get_data)
+ slot->data = sdhci_pci_get_data(pdev, slotno);
+
+ if (slot->data) {
+ if (slot->data->setup) {
+ ret = slot->data->setup(slot->data);
+ if (ret) {
+ dev_err(&pdev->dev, "platform setup failed\n");
+ goto free;
+ }
+ }
+ slot->rst_n_gpio = slot->data->rst_n_gpio;
+ slot->cd_gpio = slot->data->cd_gpio;
+ }
host->hw_name = "PCI";
host->ops = &sdhci_pci_ops;
@@ -1238,7 +1212,7 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
ret = pci_request_region(pdev, bar, mmc_hostname(host->mmc));
if (ret) {
dev_err(&pdev->dev, "cannot request region\n");
- goto free;
+ goto cleanup;
}
host->ioaddr = pci_ioremap_bar(pdev, bar);
@@ -1254,15 +1228,30 @@ static struct sdhci_pci_slot * __devinit sdhci_pci_probe_slot(
goto unmap;
}
+ if (gpio_is_valid(slot->rst_n_gpio)) {
+ if (!gpio_request(slot->rst_n_gpio, "eMMC_reset")) {
+ gpio_direction_output(slot->rst_n_gpio, 1);
+ slot->host->mmc->caps |= MMC_CAP_HW_RESET;
+ } else {
+ dev_warn(&pdev->dev, "failed to request rst_n_gpio\n");
+ slot->rst_n_gpio = -EINVAL;
+ }
+ }
+
host->mmc->pm_caps = MMC_PM_KEEP_POWER | MMC_PM_WAKE_SDIO_IRQ;
ret = sdhci_add_host(host);
if (ret)
goto remove;
+ sdhci_pci_add_own_cd(slot);
+
return slot;
remove:
+ if (gpio_is_valid(slot->rst_n_gpio))
+ gpio_free(slot->rst_n_gpio);
+
if (chip->fixes && chip->fixes->remove_slot)
chip->fixes->remove_slot(slot, 0);
@@ -1272,6 +1261,10 @@ unmap:
release:
pci_release_region(pdev, bar);
+cleanup:
+ if (slot->data && slot->data->cleanup)
+ slot->data->cleanup(slot->data);
+
free:
sdhci_free_host(host);
@@ -1283,6 +1276,8 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
int dead;
u32 scratch;
+ sdhci_pci_remove_own_cd(slot);
+
dead = 0;
scratch = readl(slot->host->ioaddr + SDHCI_INT_STATUS);
if (scratch == (u32)-1)
@@ -1290,9 +1285,15 @@ static void sdhci_pci_remove_slot(struct sdhci_pci_slot *slot)
sdhci_remove_host(slot->host, dead);
+ if (gpio_is_valid(slot->rst_n_gpio))
+ gpio_free(slot->rst_n_gpio);
+
if (slot->chip->fixes && slot->chip->fixes->remove_slot)
slot->chip->fixes->remove_slot(slot, dead);
+ if (slot->data && slot->data->cleanup)
+ slot->data->cleanup(slot->data);
+
pci_release_region(slot->chip->pdev, slot->pci_bar);
sdhci_free_host(slot->host);
@@ -1379,7 +1380,7 @@ static int __devinit sdhci_pci_probe(struct pci_dev *pdev,
slots = chip->num_slots; /* Quirk may have changed this */
for (i = 0; i < slots; i++) {
- slot = sdhci_pci_probe_slot(pdev, chip, first_bar + i);
+ slot = sdhci_pci_probe_slot(pdev, chip, first_bar, i);
if (IS_ERR(slot)) {
for (i--; i >= 0; i--)
sdhci_pci_remove_slot(chip->slots[i]);
diff --git a/drivers/mmc/host/sdhci-pxav2.c b/drivers/mmc/host/sdhci-pxav2.c
index 7a039c3cb1f1..dbb75bfbcffb 100644
--- a/drivers/mmc/host/sdhci-pxav2.c
+++ b/drivers/mmc/host/sdhci-pxav2.c
@@ -223,18 +223,8 @@ static struct platform_driver sdhci_pxav2_driver = {
.probe = sdhci_pxav2_probe,
.remove = __devexit_p(sdhci_pxav2_remove),
};
-static int __init sdhci_pxav2_init(void)
-{
- return platform_driver_register(&sdhci_pxav2_driver);
-}
-
-static void __exit sdhci_pxav2_exit(void)
-{
- platform_driver_unregister(&sdhci_pxav2_driver);
-}
-module_init(sdhci_pxav2_init);
-module_exit(sdhci_pxav2_exit);
+module_platform_driver(sdhci_pxav2_driver);
MODULE_DESCRIPTION("SDHCI driver for pxav2");
MODULE_AUTHOR("Marvell International Ltd.");
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c
index 15673a7ee6a5..f29695683556 100644
--- a/drivers/mmc/host/sdhci-pxav3.c
+++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -269,18 +269,8 @@ static struct platform_driver sdhci_pxav3_driver = {
.probe = sdhci_pxav3_probe,
.remove = __devexit_p(sdhci_pxav3_remove),
};
-static int __init sdhci_pxav3_init(void)
-{
- return platform_driver_register(&sdhci_pxav3_driver);
-}
-
-static void __exit sdhci_pxav3_exit(void)
-{
- platform_driver_unregister(&sdhci_pxav3_driver);
-}
-module_init(sdhci_pxav3_init);
-module_exit(sdhci_pxav3_exit);
+module_platform_driver(sdhci_pxav3_driver);
MODULE_DESCRIPTION("SDHCI driver for pxav3");
MODULE_AUTHOR("Marvell International Ltd.");
diff --git a/drivers/mmc/host/sdhci-s3c.c b/drivers/mmc/host/sdhci-s3c.c
index 9a20d1f55bb7..1af756ee0f9a 100644
--- a/drivers/mmc/host/sdhci-s3c.c
+++ b/drivers/mmc/host/sdhci-s3c.c
@@ -80,7 +80,7 @@ static void sdhci_s3c_check_sclk(struct sdhci_host *host)
tmp &= ~S3C_SDHCI_CTRL2_SELBASECLK_MASK;
tmp |= ourhost->cur_clk << S3C_SDHCI_CTRL2_SELBASECLK_SHIFT;
- writel(tmp, host->ioaddr + 0x80);
+ writel(tmp, host->ioaddr + S3C_SDHCI_CONTROL2);
}
}
@@ -521,6 +521,9 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
if (pdata->host_caps)
host->mmc->caps |= pdata->host_caps;
+ if (pdata->pm_caps)
+ host->mmc->pm_caps |= pdata->pm_caps;
+
host->quirks |= (SDHCI_QUIRK_32BIT_DMA_ADDR |
SDHCI_QUIRK_32BIT_DMA_SIZE);
@@ -654,18 +657,7 @@ static struct platform_driver sdhci_s3c_driver = {
},
};
-static int __init sdhci_s3c_init(void)
-{
- return platform_driver_register(&sdhci_s3c_driver);
-}
-
-static void __exit sdhci_s3c_exit(void)
-{
- platform_driver_unregister(&sdhci_s3c_driver);
-}
-
-module_init(sdhci_s3c_init);
-module_exit(sdhci_s3c_exit);
+module_platform_driver(sdhci_s3c_driver);
MODULE_DESCRIPTION("Samsung SDHCI (HSMMC) glue");
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
diff --git a/drivers/mmc/host/sdhci-spear.c b/drivers/mmc/host/sdhci-spear.c
index 63cc8b6a1c9e..b7f8b33c5f19 100644
--- a/drivers/mmc/host/sdhci-spear.c
+++ b/drivers/mmc/host/sdhci-spear.c
@@ -21,6 +21,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
+#include <linux/pm.h>
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/sdhci-spear.h>
@@ -271,26 +272,54 @@ static int __devexit sdhci_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM
+static int sdhci_suspend(struct device *dev)
+{
+ struct sdhci_host *host = dev_get_drvdata(dev);
+ struct spear_sdhci *sdhci = dev_get_platdata(dev);
+ int ret;
+
+ ret = sdhci_suspend_host(host);
+ if (!ret)
+ clk_disable(sdhci->clk);
+
+ return ret;
+}
+
+static int sdhci_resume(struct device *dev)
+{
+ struct sdhci_host *host = dev_get_drvdata(dev);
+ struct spear_sdhci *sdhci = dev_get_platdata(dev);
+ int ret;
+
+ ret = clk_enable(sdhci->clk);
+ if (ret) {
+ dev_dbg(dev, "Resume: Error enabling clock\n");
+ return ret;
+ }
+
+ return sdhci_resume_host(host);
+}
+
+const struct dev_pm_ops sdhci_pm_ops = {
+ .suspend = sdhci_suspend,
+ .resume = sdhci_resume,
+};
+#endif
+
static struct platform_driver sdhci_driver = {
.driver = {
.name = "sdhci",
.owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &sdhci_pm_ops,
+#endif
},
.probe = sdhci_probe,
.remove = __devexit_p(sdhci_remove),
};
-static int __init sdhci_init(void)
-{
- return platform_driver_register(&sdhci_driver);
-}
-module_init(sdhci_init);
-
-static void __exit sdhci_exit(void)
-{
- platform_driver_unregister(&sdhci_driver);
-}
-module_exit(sdhci_exit);
+module_platform_driver(sdhci_driver);
MODULE_DESCRIPTION("SPEAr Secure Digital Host Controller Interface driver");
MODULE_AUTHOR("Viresh Kumar <viresh.kumar@st.com>");
diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c
index e2e18d3f949c..78a36eba4df0 100644
--- a/drivers/mmc/host/sdhci-tegra.c
+++ b/drivers/mmc/host/sdhci-tegra.c
@@ -324,17 +324,7 @@ static struct platform_driver sdhci_tegra_driver = {
.remove = __devexit_p(sdhci_tegra_remove),
};
-static int __init sdhci_tegra_init(void)
-{
- return platform_driver_register(&sdhci_tegra_driver);
-}
-module_init(sdhci_tegra_init);
-
-static void __exit sdhci_tegra_exit(void)
-{
- platform_driver_unregister(&sdhci_tegra_driver);
-}
-module_exit(sdhci_tegra_exit);
+module_platform_driver(sdhci_tegra_driver);
MODULE_DESCRIPTION("SDHCI driver for Tegra");
MODULE_AUTHOR(" Google, Inc.");
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index 19ed580f2cab..8d66706824a6 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -49,7 +49,7 @@ static void sdhci_finish_data(struct sdhci_host *);
static void sdhci_send_command(struct sdhci_host *, struct mmc_command *);
static void sdhci_finish_command(struct sdhci_host *);
-static int sdhci_execute_tuning(struct mmc_host *mmc);
+static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode);
static void sdhci_tuning_timer(unsigned long data);
#ifdef CONFIG_PM_RUNTIME
@@ -146,10 +146,8 @@ static void sdhci_set_card_detection(struct sdhci_host *host, bool enable)
{
u32 present, irqs;
- if (host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION)
- return;
-
- if (host->quirks2 & SDHCI_QUIRK2_OWN_CARD_DETECTION)
+ if ((host->quirks & SDHCI_QUIRK_BROKEN_CARD_DETECTION) ||
+ !mmc_card_is_removable(host->mmc))
return;
present = sdhci_readl(host, SDHCI_PRESENT_STATE) &
@@ -214,6 +212,11 @@ static void sdhci_reset(struct sdhci_host *host, u8 mask)
if (host->quirks & SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET)
sdhci_clear_set_irqs(host, SDHCI_INT_ALL_MASK, ier);
+
+ if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
+ if ((host->ops->enable_dma) && (mask & SDHCI_RESET_ALL))
+ host->ops->enable_dma(host);
+ }
}
static void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios);
@@ -423,12 +426,12 @@ static void sdhci_transfer_pio(struct sdhci_host *host)
static char *sdhci_kmap_atomic(struct scatterlist *sg, unsigned long *flags)
{
local_irq_save(*flags);
- return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+ return kmap_atomic(sg_page(sg)) + sg->offset;
}
static void sdhci_kunmap_atomic(void *buffer, unsigned long *flags)
{
- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
+ kunmap_atomic(buffer);
local_irq_restore(*flags);
}
@@ -1016,7 +1019,8 @@ static void sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
flags |= SDHCI_CMD_INDEX;
/* CMD19 is special in that the Data Present Select should be set */
- if (cmd->data || (cmd->opcode == MMC_SEND_TUNING_BLOCK))
+ if (cmd->data || cmd->opcode == MMC_SEND_TUNING_BLOCK ||
+ cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200)
flags |= SDHCI_CMD_DATA;
sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
@@ -1066,12 +1070,15 @@ static void sdhci_finish_command(struct sdhci_host *host)
static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
{
int div = 0; /* Initialized for compiler warning */
+ int real_div = div, clk_mul = 1;
u16 clk = 0;
unsigned long timeout;
- if (clock == host->clock)
+ if (clock && clock == host->clock)
return;
+ host->mmc->actual_clock = 0;
+
if (host->ops->set_clock) {
host->ops->set_clock(host, clock);
if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK)
@@ -1109,6 +1116,8 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
* Control register.
*/
clk = SDHCI_PROG_CLOCK_MODE;
+ real_div = div;
+ clk_mul = host->clk_mul;
div--;
}
} else {
@@ -1122,6 +1131,7 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
break;
}
}
+ real_div = div;
div >>= 1;
}
} else {
@@ -1130,9 +1140,13 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
if ((host->max_clk / div) <= clock)
break;
}
+ real_div = div;
div >>= 1;
}
+ if (real_div)
+ host->mmc->actual_clock = (host->max_clk * clk_mul) / real_div;
+
clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
<< SDHCI_DIVIDER_HI_SHIFT;
@@ -1160,7 +1174,7 @@ out:
host->clock = clock;
}
-static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
+static int sdhci_set_power(struct sdhci_host *host, unsigned short power)
{
u8 pwr = 0;
@@ -1183,13 +1197,13 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
}
if (host->pwr == pwr)
- return;
+ return -1;
host->pwr = pwr;
if (pwr == 0) {
sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
- return;
+ return 0;
}
/*
@@ -1216,6 +1230,8 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
*/
if (host->quirks & SDHCI_QUIRK_DELAY_AFTER_POWER)
mdelay(10);
+
+ return power;
}
/*****************************************************************************\
@@ -1277,7 +1293,7 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
if ((host->flags & SDHCI_NEEDS_RETUNING) &&
!(present_state & (SDHCI_DOING_WRITE | SDHCI_DOING_READ))) {
spin_unlock_irqrestore(&host->lock, flags);
- sdhci_execute_tuning(mmc);
+ sdhci_execute_tuning(mmc, mrq->cmd->opcode);
spin_lock_irqsave(&host->lock, flags);
/* Restore original mmc_request structure */
@@ -1297,12 +1313,17 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
{
unsigned long flags;
+ int vdd_bit = -1;
u8 ctrl;
spin_lock_irqsave(&host->lock, flags);
- if (host->flags & SDHCI_DEVICE_DEAD)
- goto out;
+ if (host->flags & SDHCI_DEVICE_DEAD) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ if (host->vmmc && ios->power_mode == MMC_POWER_OFF)
+ mmc_regulator_set_ocr(host->mmc, host->vmmc, 0);
+ return;
+ }
/*
* Reset the chip on each power off.
@@ -1316,9 +1337,15 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
sdhci_set_clock(host, ios->clock);
if (ios->power_mode == MMC_POWER_OFF)
- sdhci_set_power(host, -1);
+ vdd_bit = sdhci_set_power(host, -1);
else
- sdhci_set_power(host, ios->vdd);
+ vdd_bit = sdhci_set_power(host, ios->vdd);
+
+ if (host->vmmc && vdd_bit != -1) {
+ spin_unlock_irqrestore(&host->lock, flags);
+ mmc_regulator_set_ocr(host->mmc, host->vmmc, vdd_bit);
+ spin_lock_irqsave(&host->lock, flags);
+ }
if (host->ops->platform_send_init_74_clocks)
host->ops->platform_send_init_74_clocks(host, ios->power_mode);
@@ -1361,11 +1388,11 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
unsigned int clock;
/* In case of UHS-I modes, set High Speed Enable */
- if ((ios->timing == MMC_TIMING_UHS_SDR50) ||
+ if ((ios->timing == MMC_TIMING_MMC_HS200) ||
+ (ios->timing == MMC_TIMING_UHS_SDR50) ||
(ios->timing == MMC_TIMING_UHS_SDR104) ||
(ios->timing == MMC_TIMING_UHS_DDR50) ||
- (ios->timing == MMC_TIMING_UHS_SDR25) ||
- (ios->timing == MMC_TIMING_UHS_SDR12))
+ (ios->timing == MMC_TIMING_UHS_SDR25))
ctrl |= SDHCI_CTRL_HISPD;
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
@@ -1415,7 +1442,9 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
/* Select Bus Speed Mode for host */
ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
- if (ios->timing == MMC_TIMING_UHS_SDR12)
+ if (ios->timing == MMC_TIMING_MMC_HS200)
+ ctrl_2 |= SDHCI_CTRL_HS_SDR200;
+ else if (ios->timing == MMC_TIMING_UHS_SDR12)
ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
else if (ios->timing == MMC_TIMING_UHS_SDR25)
ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
@@ -1443,7 +1472,6 @@ static void sdhci_do_set_ios(struct sdhci_host *host, struct mmc_ios *ios)
if(host->quirks & SDHCI_QUIRK_RESET_CMD_DATA_ON_IOS)
sdhci_reset(host, SDHCI_RESET_CMD | SDHCI_RESET_DATA);
-out:
mmiowb();
spin_unlock_irqrestore(&host->lock, flags);
}
@@ -1663,7 +1691,7 @@ static int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
return err;
}
-static int sdhci_execute_tuning(struct mmc_host *mmc)
+static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
{
struct sdhci_host *host;
u16 ctrl;
@@ -1671,6 +1699,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
int tuning_loop_counter = MAX_TUNING_LOOP;
unsigned long timeout;
int err = 0;
+ bool requires_tuning_nonuhs = false;
host = mmc_priv(mmc);
@@ -1681,13 +1710,19 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
/*
- * Host Controller needs tuning only in case of SDR104 mode
- * and for SDR50 mode when Use Tuning for SDR50 is set in
+ * The Host Controller needs tuning only in case of SDR104 mode
+ * and for SDR50 mode when Use Tuning for SDR50 is set in the
* Capabilities register.
+ * If the Host Controller supports the HS200 mode then the
+ * tuning function has to be executed.
*/
+ if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
+ (host->flags & SDHCI_SDR50_NEEDS_TUNING ||
+ host->flags & SDHCI_HS200_NEEDS_TUNING))
+ requires_tuning_nonuhs = true;
+
if (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR104) ||
- (((ctrl & SDHCI_CTRL_UHS_MASK) == SDHCI_CTRL_UHS_SDR50) &&
- (host->flags & SDHCI_SDR50_NEEDS_TUNING)))
+ requires_tuning_nonuhs)
ctrl |= SDHCI_CTRL_EXEC_TUNING;
else {
spin_unlock(&host->lock);
@@ -1723,7 +1758,7 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
if (!tuning_loop_counter && !timeout)
break;
- cmd.opcode = MMC_SEND_TUNING_BLOCK;
+ cmd.opcode = opcode;
cmd.arg = 0;
cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
cmd.retries = 0;
@@ -1738,7 +1773,17 @@ static int sdhci_execute_tuning(struct mmc_host *mmc)
* block to the Host Controller. So we set the block size
* to 64 here.
*/
- sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE);
+ if (cmd.opcode == MMC_SEND_TUNING_BLOCK_HS200) {
+ if (mmc->ios.bus_width == MMC_BUS_WIDTH_8)
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128),
+ SDHCI_BLOCK_SIZE);
+ else if (mmc->ios.bus_width == MMC_BUS_WIDTH_4)
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64),
+ SDHCI_BLOCK_SIZE);
+ } else {
+ sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64),
+ SDHCI_BLOCK_SIZE);
+ }
/*
* The tuning block is sent by the card to the host controller.
@@ -2121,12 +2166,14 @@ static void sdhci_show_adma_error(struct sdhci_host *host) { }
static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
{
+ u32 command;
BUG_ON(intmask == 0);
/* CMD19 generates _only_ Buffer Read Ready interrupt */
if (intmask & SDHCI_INT_DATA_AVAIL) {
- if (SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND)) ==
- MMC_SEND_TUNING_BLOCK) {
+ command = SDHCI_GET_CMD(sdhci_readw(host, SDHCI_COMMAND));
+ if (command == MMC_SEND_TUNING_BLOCK ||
+ command == MMC_SEND_TUNING_BLOCK_HS200) {
host->tuning_done = 1;
wake_up(&host->buf_ready_int);
return;
@@ -2330,26 +2377,33 @@ out:
int sdhci_suspend_host(struct sdhci_host *host)
{
int ret;
+ bool has_tuning_timer;
sdhci_disable_card_detection(host);
/* Disable tuning since we are suspending */
- if (host->version >= SDHCI_SPEC_300 && host->tuning_count &&
- host->tuning_mode == SDHCI_TUNING_MODE_1) {
+ has_tuning_timer = host->version >= SDHCI_SPEC_300 &&
+ host->tuning_count && host->tuning_mode == SDHCI_TUNING_MODE_1;
+ if (has_tuning_timer) {
+ del_timer_sync(&host->tuning_timer);
host->flags &= ~SDHCI_NEEDS_RETUNING;
- mod_timer(&host->tuning_timer, jiffies +
- host->tuning_count * HZ);
}
ret = mmc_suspend_host(host->mmc);
- if (ret)
+ if (ret) {
+ if (has_tuning_timer) {
+ host->flags |= SDHCI_NEEDS_RETUNING;
+ mod_timer(&host->tuning_timer, jiffies +
+ host->tuning_count * HZ);
+ }
+
+ sdhci_enable_card_detection(host);
+
return ret;
+ }
free_irq(host->irq, host);
- if (host->vmmc)
- ret = regulator_disable(host->vmmc);
-
return ret;
}
@@ -2359,12 +2413,6 @@ int sdhci_resume_host(struct sdhci_host *host)
{
int ret;
- if (host->vmmc) {
- int ret = regulator_enable(host->vmmc);
- if (ret)
- return ret;
- }
-
if (host->flags & (SDHCI_USE_SDMA | SDHCI_USE_ADMA)) {
if (host->ops->enable_dma)
host->ops->enable_dma(host);
@@ -2727,10 +2775,14 @@ int sdhci_add_host(struct sdhci_host *host)
if (caps[1] & SDHCI_SUPPORT_DDR50)
mmc->caps |= MMC_CAP_UHS_DDR50;
- /* Does the host needs tuning for SDR50? */
+ /* Does the host need tuning for SDR50? */
if (caps[1] & SDHCI_USE_SDR50_TUNING)
host->flags |= SDHCI_SDR50_NEEDS_TUNING;
+ /* Does the host need tuning for HS200? */
+ if (mmc->caps2 & MMC_CAP2_HS200)
+ host->flags |= SDHCI_HS200_NEEDS_TUNING;
+
/* Driver Type(s) (A, C, D) supported by the host */
if (caps[1] & SDHCI_DRIVER_TYPE_A)
mmc->caps |= MMC_CAP_DRIVER_TYPE_A;
@@ -2926,8 +2978,6 @@ int sdhci_add_host(struct sdhci_host *host)
if (IS_ERR(host->vmmc)) {
pr_info("%s: no vmmc regulator found\n", mmc_hostname(mmc));
host->vmmc = NULL;
- } else {
- regulator_enable(host->vmmc);
}
sdhci_init(host, 0);
@@ -3016,10 +3066,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
tasklet_kill(&host->card_tasklet);
tasklet_kill(&host->finish_tasklet);
- if (host->vmmc) {
- regulator_disable(host->vmmc);
+ if (host->vmmc)
regulator_put(host->vmmc);
- }
kfree(host->adma_desc);
kfree(host->align_buffer);
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index a04d4d0c6fd2..ad265b96b75b 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -158,6 +158,7 @@
#define SDHCI_CTRL_UHS_SDR50 0x0002
#define SDHCI_CTRL_UHS_SDR104 0x0003
#define SDHCI_CTRL_UHS_DDR50 0x0004
+#define SDHCI_CTRL_HS_SDR200 0x0005 /* reserved value in SDIO spec */
#define SDHCI_CTRL_VDD_180 0x0008
#define SDHCI_CTRL_DRV_TYPE_MASK 0x0030
#define SDHCI_CTRL_DRV_TYPE_B 0x0000
diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c
index d5505f3fe2a1..4a2c5b2355f2 100644
--- a/drivers/mmc/host/sh_mmcif.c
+++ b/drivers/mmc/host/sh_mmcif.c
@@ -16,6 +16,33 @@
*
*/
+/*
+ * The MMCIF driver is now processing MMC requests asynchronously, according
+ * to the Linux MMC API requirement.
+ *
+ * The MMCIF driver processes MMC requests in up to 3 stages: command, optional
+ * data, and optional stop. To achieve asynchronous processing each of these
+ * stages is split into two halves: a top and a bottom half. The top half
+ * initialises the hardware, installs a timeout handler to handle completion
+ * timeouts, and returns. In case of the command stage this immediately returns
+ * control to the caller, leaving all further processing to run asynchronously.
+ * All further request processing is performed by the bottom halves.
+ *
+ * The bottom half further consists of a "hard" IRQ handler, an IRQ handler
+ * thread, a DMA completion callback, if DMA is used, a timeout work, and
+ * request- and stage-specific handler methods.
+ *
+ * Each bottom half run begins with either a hardware interrupt, a DMA callback
+ * invocation, or a timeout work run. In case of an error or a successful
+ * processing completion, the MMC core is informed and the request processing is
+ * finished. In case processing has to continue, i.e., if data has to be read
+ * from or written to the card, or if a stop command has to be sent, the next
+ * top half is called, which performs the necessary hardware handling and
+ * reschedules the timeout work. This returns the driver state machine into the
+ * bottom half waiting state.
+ */
+
+#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
@@ -123,6 +150,11 @@
#define MASK_MRBSYTO (1 << 1)
#define MASK_MRSPTO (1 << 0)
+#define MASK_START_CMD (MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR | \
+ MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR | \
+ MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO | \
+ MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO)
+
/* CE_HOST_STS1 */
#define STS1_CMDSEQ (1 << 31)
@@ -162,9 +194,21 @@ enum mmcif_state {
STATE_IOS,
};
+enum mmcif_wait_for {
+ MMCIF_WAIT_FOR_REQUEST,
+ MMCIF_WAIT_FOR_CMD,
+ MMCIF_WAIT_FOR_MREAD,
+ MMCIF_WAIT_FOR_MWRITE,
+ MMCIF_WAIT_FOR_READ,
+ MMCIF_WAIT_FOR_WRITE,
+ MMCIF_WAIT_FOR_READ_END,
+ MMCIF_WAIT_FOR_WRITE_END,
+ MMCIF_WAIT_FOR_STOP,
+};
+
struct sh_mmcif_host {
struct mmc_host *mmc;
- struct mmc_data *data;
+ struct mmc_request *mrq;
struct platform_device *pd;
struct sh_dmae_slave dma_slave_tx;
struct sh_dmae_slave dma_slave_rx;
@@ -172,11 +216,17 @@ struct sh_mmcif_host {
unsigned int clk;
int bus_width;
bool sd_error;
+ bool dying;
long timeout;
void __iomem *addr;
- struct completion intr_wait;
+ u32 *pio_ptr;
+ spinlock_t lock; /* protect sh_mmcif_host::state */
enum mmcif_state state;
- spinlock_t lock;
+ enum mmcif_wait_for wait_for;
+ struct delayed_work timeout_work;
+ size_t blocksize;
+ int sg_idx;
+ int sg_blkidx;
bool power;
bool card_present;
@@ -202,19 +252,21 @@ static inline void sh_mmcif_bitclr(struct sh_mmcif_host *host,
static void mmcif_dma_complete(void *arg)
{
struct sh_mmcif_host *host = arg;
+ struct mmc_data *data = host->mrq->data;
+
dev_dbg(&host->pd->dev, "Command completed\n");
- if (WARN(!host->data, "%s: NULL data in DMA completion!\n",
+ if (WARN(!data, "%s: NULL data in DMA completion!\n",
dev_name(&host->pd->dev)))
return;
- if (host->data->flags & MMC_DATA_READ)
+ if (data->flags & MMC_DATA_READ)
dma_unmap_sg(host->chan_rx->device->dev,
- host->data->sg, host->data->sg_len,
+ data->sg, data->sg_len,
DMA_FROM_DEVICE);
else
dma_unmap_sg(host->chan_tx->device->dev,
- host->data->sg, host->data->sg_len,
+ data->sg, data->sg_len,
DMA_TO_DEVICE);
complete(&host->dma_complete);
@@ -222,13 +274,14 @@ static void mmcif_dma_complete(void *arg)
static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
{
- struct scatterlist *sg = host->data->sg;
+ struct mmc_data *data = host->mrq->data;
+ struct scatterlist *sg = data->sg;
struct dma_async_tx_descriptor *desc = NULL;
struct dma_chan *chan = host->chan_rx;
dma_cookie_t cookie = -EINVAL;
int ret;
- ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len,
+ ret = dma_map_sg(chan->device->dev, sg, data->sg_len,
DMA_FROM_DEVICE);
if (ret > 0) {
host->dma_active = true;
@@ -244,7 +297,7 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
dma_async_issue_pending(chan);
}
dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
- __func__, host->data->sg_len, ret, cookie);
+ __func__, data->sg_len, ret, cookie);
if (!desc) {
/* DMA failed, fall back to PIO */
@@ -265,18 +318,19 @@ static void sh_mmcif_start_dma_rx(struct sh_mmcif_host *host)
}
dev_dbg(&host->pd->dev, "%s(): desc %p, cookie %d, sg[%d]\n", __func__,
- desc, cookie, host->data->sg_len);
+ desc, cookie, data->sg_len);
}
static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
{
- struct scatterlist *sg = host->data->sg;
+ struct mmc_data *data = host->mrq->data;
+ struct scatterlist *sg = data->sg;
struct dma_async_tx_descriptor *desc = NULL;
struct dma_chan *chan = host->chan_tx;
dma_cookie_t cookie = -EINVAL;
int ret;
- ret = dma_map_sg(chan->device->dev, sg, host->data->sg_len,
+ ret = dma_map_sg(chan->device->dev, sg, data->sg_len,
DMA_TO_DEVICE);
if (ret > 0) {
host->dma_active = true;
@@ -292,7 +346,7 @@ static void sh_mmcif_start_dma_tx(struct sh_mmcif_host *host)
dma_async_issue_pending(chan);
}
dev_dbg(&host->pd->dev, "%s(): mapped %d -> %d, cookie %d\n",
- __func__, host->data->sg_len, ret, cookie);
+ __func__, data->sg_len, ret, cookie);
if (!desc) {
/* DMA failed, fall back to PIO */
@@ -399,7 +453,7 @@ static void sh_mmcif_clock_control(struct sh_mmcif_host *host, unsigned int clk)
sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_SUP_PCLK);
else
sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_CLEAR &
- (ilog2(__rounddown_pow_of_two(host->clk / clk)) << 16));
+ ((fls(host->clk / clk) - 1) << 16));
sh_mmcif_bitset(host, MMCIF_CE_CLK_CTRL, CLK_ENABLE);
}
@@ -421,7 +475,7 @@ static void sh_mmcif_sync_reset(struct sh_mmcif_host *host)
static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
{
u32 state1, state2;
- int ret, timeout = 10000000;
+ int ret, timeout;
host->sd_error = false;
@@ -433,155 +487,212 @@ static int sh_mmcif_error_manage(struct sh_mmcif_host *host)
if (state1 & STS1_CMDSEQ) {
sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, CMD_CTRL_BREAK);
sh_mmcif_bitset(host, MMCIF_CE_CMD_CTRL, ~CMD_CTRL_BREAK);
- while (1) {
- timeout--;
- if (timeout < 0) {
- dev_err(&host->pd->dev,
- "Forceed end of command sequence timeout err\n");
- return -EIO;
- }
+ for (timeout = 10000000; timeout; timeout--) {
if (!(sh_mmcif_readl(host->addr, MMCIF_CE_HOST_STS1)
- & STS1_CMDSEQ))
+ & STS1_CMDSEQ))
break;
mdelay(1);
}
+ if (!timeout) {
+ dev_err(&host->pd->dev,
+ "Forced end of command sequence timeout err\n");
+ return -EIO;
+ }
sh_mmcif_sync_reset(host);
dev_dbg(&host->pd->dev, "Forced end of command sequence\n");
return -EIO;
}
if (state2 & STS2_CRC_ERR) {
- dev_dbg(&host->pd->dev, ": Happened CRC error\n");
+ dev_dbg(&host->pd->dev, ": CRC error\n");
ret = -EIO;
} else if (state2 & STS2_TIMEOUT_ERR) {
- dev_dbg(&host->pd->dev, ": Happened Timeout error\n");
+ dev_dbg(&host->pd->dev, ": Timeout\n");
ret = -ETIMEDOUT;
} else {
- dev_dbg(&host->pd->dev, ": Happened End/Index error\n");
+ dev_dbg(&host->pd->dev, ": End/Index error\n");
ret = -EIO;
}
return ret;
}
-static int sh_mmcif_single_read(struct sh_mmcif_host *host,
- struct mmc_request *mrq)
+static bool sh_mmcif_next_block(struct sh_mmcif_host *host, u32 *p)
{
- struct mmc_data *data = mrq->data;
- long time;
- u32 blocksize, i, *p = sg_virt(data->sg);
+ struct mmc_data *data = host->mrq->data;
+
+ host->sg_blkidx += host->blocksize;
+
+ /* data->sg->length must be a multiple of host->blocksize? */
+ BUG_ON(host->sg_blkidx > data->sg->length);
+
+ if (host->sg_blkidx == data->sg->length) {
+ host->sg_blkidx = 0;
+ if (++host->sg_idx < data->sg_len)
+ host->pio_ptr = sg_virt(++data->sg);
+ } else {
+ host->pio_ptr = p;
+ }
+
+ if (host->sg_idx == data->sg_len)
+ return false;
+
+ return true;
+}
+
+static void sh_mmcif_single_read(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
+{
+ host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
+ BLOCK_SIZE_MASK) + 3;
+
+ host->wait_for = MMCIF_WAIT_FOR_READ;
+ schedule_delayed_work(&host->timeout_work, host->timeout);
/* buf read enable */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
-
- blocksize = (BLOCK_SIZE_MASK &
- sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
- for (i = 0; i < blocksize / 4; i++)
+}
+
+static bool sh_mmcif_read_block(struct sh_mmcif_host *host)
+{
+ struct mmc_data *data = host->mrq->data;
+ u32 *p = sg_virt(data->sg);
+ int i;
+
+ if (host->sd_error) {
+ data->error = sh_mmcif_error_manage(host);
+ return false;
+ }
+
+ for (i = 0; i < host->blocksize / 4; i++)
*p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
/* buffer read end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFRE);
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
+ host->wait_for = MMCIF_WAIT_FOR_READ_END;
- return 0;
+ return true;
}
-static int sh_mmcif_multi_read(struct sh_mmcif_host *host,
- struct mmc_request *mrq)
+static void sh_mmcif_multi_read(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
{
struct mmc_data *data = mrq->data;
- long time;
- u32 blocksize, i, j, sec, *p;
-
- blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
- MMCIF_CE_BLOCK_SET);
- for (j = 0; j < data->sg_len; j++) {
- p = sg_virt(data->sg);
- for (sec = 0; sec < data->sg->length / blocksize; sec++) {
- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
- /* buf read enable */
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
-
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
-
- for (i = 0; i < blocksize / 4; i++)
- *p++ = sh_mmcif_readl(host->addr,
- MMCIF_CE_DATA);
- }
- if (j < data->sg_len - 1)
- data->sg++;
+
+ if (!data->sg_len || !data->sg->length)
+ return;
+
+ host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
+ BLOCK_SIZE_MASK;
+
+ host->wait_for = MMCIF_WAIT_FOR_MREAD;
+ host->sg_idx = 0;
+ host->sg_blkidx = 0;
+ host->pio_ptr = sg_virt(data->sg);
+ schedule_delayed_work(&host->timeout_work, host->timeout);
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
+}
+
+static bool sh_mmcif_mread_block(struct sh_mmcif_host *host)
+{
+ struct mmc_data *data = host->mrq->data;
+ u32 *p = host->pio_ptr;
+ int i;
+
+ if (host->sd_error) {
+ data->error = sh_mmcif_error_manage(host);
+ return false;
}
- return 0;
+
+ BUG_ON(!data->sg->length);
+
+ for (i = 0; i < host->blocksize / 4; i++)
+ *p++ = sh_mmcif_readl(host->addr, MMCIF_CE_DATA);
+
+ if (!sh_mmcif_next_block(host, p))
+ return false;
+
+ schedule_delayed_work(&host->timeout_work, host->timeout);
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFREN);
+
+ return true;
}
-static int sh_mmcif_single_write(struct sh_mmcif_host *host,
+static void sh_mmcif_single_write(struct sh_mmcif_host *host,
struct mmc_request *mrq)
{
- struct mmc_data *data = mrq->data;
- long time;
- u32 blocksize, i, *p = sg_virt(data->sg);
+ host->blocksize = (sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
+ BLOCK_SIZE_MASK) + 3;
- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+ host->wait_for = MMCIF_WAIT_FOR_WRITE;
+ schedule_delayed_work(&host->timeout_work, host->timeout);
/* buf write enable */
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
-
- blocksize = (BLOCK_SIZE_MASK &
- sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET)) + 3;
- for (i = 0; i < blocksize / 4; i++)
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+}
+
+static bool sh_mmcif_write_block(struct sh_mmcif_host *host)
+{
+ struct mmc_data *data = host->mrq->data;
+ u32 *p = sg_virt(data->sg);
+ int i;
+
+ if (host->sd_error) {
+ data->error = sh_mmcif_error_manage(host);
+ return false;
+ }
+
+ for (i = 0; i < host->blocksize / 4; i++)
sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
/* buffer write end */
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MDTRANE);
+ host->wait_for = MMCIF_WAIT_FOR_WRITE_END;
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
-
- return 0;
+ return true;
}
-static int sh_mmcif_multi_write(struct sh_mmcif_host *host,
- struct mmc_request *mrq)
+static void sh_mmcif_multi_write(struct sh_mmcif_host *host,
+ struct mmc_request *mrq)
{
struct mmc_data *data = mrq->data;
- long time;
- u32 i, sec, j, blocksize, *p;
- blocksize = BLOCK_SIZE_MASK & sh_mmcif_readl(host->addr,
- MMCIF_CE_BLOCK_SET);
+ if (!data->sg_len || !data->sg->length)
+ return;
- for (j = 0; j < data->sg_len; j++) {
- p = sg_virt(data->sg);
- for (sec = 0; sec < data->sg->length / blocksize; sec++) {
- sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
- /* buf write enable*/
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
+ host->blocksize = sh_mmcif_readl(host->addr, MMCIF_CE_BLOCK_SET) &
+ BLOCK_SIZE_MASK;
- if (time <= 0 || host->sd_error)
- return sh_mmcif_error_manage(host);
+ host->wait_for = MMCIF_WAIT_FOR_MWRITE;
+ host->sg_idx = 0;
+ host->sg_blkidx = 0;
+ host->pio_ptr = sg_virt(data->sg);
+ schedule_delayed_work(&host->timeout_work, host->timeout);
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+}
- for (i = 0; i < blocksize / 4; i++)
- sh_mmcif_writel(host->addr,
- MMCIF_CE_DATA, *p++);
- }
- if (j < data->sg_len - 1)
- data->sg++;
+static bool sh_mmcif_mwrite_block(struct sh_mmcif_host *host)
+{
+ struct mmc_data *data = host->mrq->data;
+ u32 *p = host->pio_ptr;
+ int i;
+
+ if (host->sd_error) {
+ data->error = sh_mmcif_error_manage(host);
+ return false;
}
- return 0;
+
+ BUG_ON(!data->sg->length);
+
+ for (i = 0; i < host->blocksize / 4; i++)
+ sh_mmcif_writel(host->addr, MMCIF_CE_DATA, *p++);
+
+ if (!sh_mmcif_next_block(host, p))
+ return false;
+
+ schedule_delayed_work(&host->timeout_work, host->timeout);
+ sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MBUFWEN);
+
+ return true;
}
static void sh_mmcif_get_response(struct sh_mmcif_host *host,
@@ -603,8 +714,11 @@ static void sh_mmcif_get_cmd12response(struct sh_mmcif_host *host,
}
static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
- struct mmc_request *mrq, struct mmc_command *cmd, u32 opc)
+ struct mmc_request *mrq)
{
+ struct mmc_data *data = mrq->data;
+ struct mmc_command *cmd = mrq->cmd;
+ u32 opc = cmd->opcode;
u32 tmp = 0;
/* Response Type check */
@@ -636,7 +750,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
break;
}
/* WDAT / DATW */
- if (host->data) {
+ if (data) {
tmp |= CMD_SET_WDAT;
switch (host->bus_width) {
case MMC_BUS_WIDTH_1:
@@ -660,7 +774,7 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
if (opc == MMC_READ_MULTIPLE_BLOCK || opc == MMC_WRITE_MULTIPLE_BLOCK) {
tmp |= CMD_SET_CMLTE | CMD_SET_CMD12EN;
sh_mmcif_bitset(host, MMCIF_CE_BLOCK_SET,
- mrq->data->blocks << 16);
+ data->blocks << 16);
}
/* RIDXC[1:0] check bits */
if (opc == MMC_SEND_OP_COND || opc == MMC_ALL_SEND_CID ||
@@ -674,68 +788,60 @@ static u32 sh_mmcif_set_cmd(struct sh_mmcif_host *host,
opc == MMC_SEND_CSD || opc == MMC_SEND_CID)
tmp |= CMD_SET_CRC7C_INTERNAL;
- return opc = ((opc << 24) | tmp);
+ return (opc << 24) | tmp;
}
static int sh_mmcif_data_trans(struct sh_mmcif_host *host,
- struct mmc_request *mrq, u32 opc)
+ struct mmc_request *mrq, u32 opc)
{
- int ret;
-
switch (opc) {
case MMC_READ_MULTIPLE_BLOCK:
- ret = sh_mmcif_multi_read(host, mrq);
- break;
+ sh_mmcif_multi_read(host, mrq);
+ return 0;
case MMC_WRITE_MULTIPLE_BLOCK:
- ret = sh_mmcif_multi_write(host, mrq);
- break;
+ sh_mmcif_multi_write(host, mrq);
+ return 0;
case MMC_WRITE_BLOCK:
- ret = sh_mmcif_single_write(host, mrq);
- break;
+ sh_mmcif_single_write(host, mrq);
+ return 0;
case MMC_READ_SINGLE_BLOCK:
case MMC_SEND_EXT_CSD:
- ret = sh_mmcif_single_read(host, mrq);
- break;
+ sh_mmcif_single_read(host, mrq);
+ return 0;
default:
dev_err(&host->pd->dev, "UNSUPPORTED CMD = d'%08d\n", opc);
- ret = -EINVAL;
- break;
+ return -EINVAL;
}
- return ret;
}
static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
- struct mmc_request *mrq, struct mmc_command *cmd)
+ struct mmc_request *mrq)
{
- long time;
- int ret = 0, mask = 0;
+ struct mmc_command *cmd = mrq->cmd;
u32 opc = cmd->opcode;
+ u32 mask;
switch (opc) {
- /* respons busy check */
+ /* response busy check */
case MMC_SWITCH:
case MMC_STOP_TRANSMISSION:
case MMC_SET_WRITE_PROT:
case MMC_CLR_WRITE_PROT:
case MMC_ERASE:
case MMC_GEN_CMD:
- mask = MASK_MRBSYE;
+ mask = MASK_START_CMD | MASK_MRBSYE;
break;
default:
- mask = MASK_MCRSPE;
+ mask = MASK_START_CMD | MASK_MCRSPE;
break;
}
- mask |= MASK_MCMDVIO | MASK_MBUFVIO | MASK_MWDATERR |
- MASK_MRDATERR | MASK_MRIDXERR | MASK_MRSPERR |
- MASK_MCCSTO | MASK_MCRCSTO | MASK_MWDATTO |
- MASK_MRDATTO | MASK_MRBSYTO | MASK_MRSPTO;
- if (host->data) {
+ if (mrq->data) {
sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET, 0);
sh_mmcif_writel(host->addr, MMCIF_CE_BLOCK_SET,
mrq->data->blksz);
}
- opc = sh_mmcif_set_cmd(host, mrq, cmd, opc);
+ opc = sh_mmcif_set_cmd(host, mrq);
sh_mmcif_writel(host->addr, MMCIF_CE_INT, 0xD80430C0);
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, mask);
@@ -744,80 +850,28 @@ static void sh_mmcif_start_cmd(struct sh_mmcif_host *host,
/* set cmd */
sh_mmcif_writel(host->addr, MMCIF_CE_CMD_SET, opc);
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0) {
- cmd->error = sh_mmcif_error_manage(host);
- return;
- }
- if (host->sd_error) {
- switch (cmd->opcode) {
- case MMC_ALL_SEND_CID:
- case MMC_SELECT_CARD:
- case MMC_APP_CMD:
- cmd->error = -ETIMEDOUT;
- break;
- default:
- dev_dbg(&host->pd->dev, "Cmd(d'%d) err\n",
- cmd->opcode);
- cmd->error = sh_mmcif_error_manage(host);
- break;
- }
- host->sd_error = false;
- return;
- }
- if (!(cmd->flags & MMC_RSP_PRESENT)) {
- cmd->error = 0;
- return;
- }
- sh_mmcif_get_response(host, cmd);
- if (host->data) {
- if (!host->dma_active) {
- ret = sh_mmcif_data_trans(host, mrq, cmd->opcode);
- } else {
- long time =
- wait_for_completion_interruptible_timeout(&host->dma_complete,
- host->timeout);
- if (!time)
- ret = -ETIMEDOUT;
- else if (time < 0)
- ret = time;
- sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
- BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
- host->dma_active = false;
- }
- if (ret < 0)
- mrq->data->bytes_xfered = 0;
- else
- mrq->data->bytes_xfered =
- mrq->data->blocks * mrq->data->blksz;
- }
- cmd->error = ret;
+ host->wait_for = MMCIF_WAIT_FOR_CMD;
+ schedule_delayed_work(&host->timeout_work, host->timeout);
}
static void sh_mmcif_stop_cmd(struct sh_mmcif_host *host,
- struct mmc_request *mrq, struct mmc_command *cmd)
+ struct mmc_request *mrq)
{
- long time;
-
- if (mrq->cmd->opcode == MMC_READ_MULTIPLE_BLOCK)
+ switch (mrq->cmd->opcode) {
+ case MMC_READ_MULTIPLE_BLOCK:
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12DRE);
- else if (mrq->cmd->opcode == MMC_WRITE_MULTIPLE_BLOCK)
+ break;
+ case MMC_WRITE_MULTIPLE_BLOCK:
sh_mmcif_bitset(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
- else {
+ break;
+ default:
dev_err(&host->pd->dev, "unsupported stop cmd\n");
- cmd->error = sh_mmcif_error_manage(host);
+ mrq->stop->error = sh_mmcif_error_manage(host);
return;
}
- time = wait_for_completion_interruptible_timeout(&host->intr_wait,
- host->timeout);
- if (time <= 0 || host->sd_error) {
- cmd->error = sh_mmcif_error_manage(host);
- return;
- }
- sh_mmcif_get_cmd12response(host, cmd);
- cmd->error = 0;
+ host->wait_for = MMCIF_WAIT_FOR_STOP;
+ schedule_delayed_work(&host->timeout_work, host->timeout);
}
static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -856,23 +910,10 @@ static void sh_mmcif_request(struct mmc_host *mmc, struct mmc_request *mrq)
default:
break;
}
- host->data = mrq->data;
- if (mrq->data) {
- if (mrq->data->flags & MMC_DATA_READ) {
- if (host->chan_rx)
- sh_mmcif_start_dma_rx(host);
- } else {
- if (host->chan_tx)
- sh_mmcif_start_dma_tx(host);
- }
- }
- sh_mmcif_start_cmd(host, mrq, mrq->cmd);
- host->data = NULL;
- if (!mrq->cmd->error && mrq->stop)
- sh_mmcif_stop_cmd(host, mrq, mrq->stop);
- host->state = STATE_IDLE;
- mmc_request_done(mmc, mrq);
+ host->mrq = mrq;
+
+ sh_mmcif_start_cmd(host, mrq);
}
static void sh_mmcif_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
@@ -947,9 +988,156 @@ static struct mmc_host_ops sh_mmcif_ops = {
.get_cd = sh_mmcif_get_cd,
};
-static void sh_mmcif_detect(struct mmc_host *mmc)
+static bool sh_mmcif_end_cmd(struct sh_mmcif_host *host)
{
- mmc_detect_change(mmc, 0);
+ struct mmc_command *cmd = host->mrq->cmd;
+ struct mmc_data *data = host->mrq->data;
+ long time;
+
+ if (host->sd_error) {
+ switch (cmd->opcode) {
+ case MMC_ALL_SEND_CID:
+ case MMC_SELECT_CARD:
+ case MMC_APP_CMD:
+ cmd->error = -ETIMEDOUT;
+ host->sd_error = false;
+ break;
+ default:
+ cmd->error = sh_mmcif_error_manage(host);
+ dev_dbg(&host->pd->dev, "Cmd(d'%d) error %d\n",
+ cmd->opcode, cmd->error);
+ break;
+ }
+ return false;
+ }
+ if (!(cmd->flags & MMC_RSP_PRESENT)) {
+ cmd->error = 0;
+ return false;
+ }
+
+ sh_mmcif_get_response(host, cmd);
+
+ if (!data)
+ return false;
+
+ if (data->flags & MMC_DATA_READ) {
+ if (host->chan_rx)
+ sh_mmcif_start_dma_rx(host);
+ } else {
+ if (host->chan_tx)
+ sh_mmcif_start_dma_tx(host);
+ }
+
+ if (!host->dma_active) {
+ data->error = sh_mmcif_data_trans(host, host->mrq, cmd->opcode);
+ if (!data->error)
+ return true;
+ return false;
+ }
+
+ /* Running in the IRQ thread, can sleep */
+ time = wait_for_completion_interruptible_timeout(&host->dma_complete,
+ host->timeout);
+ if (host->sd_error) {
+ dev_err(host->mmc->parent,
+ "Error IRQ while waiting for DMA completion!\n");
+ /* Woken up by an error IRQ: abort DMA */
+ if (data->flags & MMC_DATA_READ)
+ dmaengine_terminate_all(host->chan_rx);
+ else
+ dmaengine_terminate_all(host->chan_tx);
+ data->error = sh_mmcif_error_manage(host);
+ } else if (!time) {
+ data->error = -ETIMEDOUT;
+ } else if (time < 0) {
+ data->error = time;
+ }
+ sh_mmcif_bitclr(host, MMCIF_CE_BUF_ACC,
+ BUF_ACC_DMAREN | BUF_ACC_DMAWEN);
+ host->dma_active = false;
+
+ if (data->error)
+ data->bytes_xfered = 0;
+
+ return false;
+}
+
+static irqreturn_t sh_mmcif_irqt(int irq, void *dev_id)
+{
+ struct sh_mmcif_host *host = dev_id;
+ struct mmc_request *mrq = host->mrq;
+ struct mmc_data *data = mrq->data;
+
+ cancel_delayed_work_sync(&host->timeout_work);
+
+ /*
+ * All handlers return true, if processing continues, and false, if the
+ * request has to be completed - successfully or not
+ */
+ switch (host->wait_for) {
+ case MMCIF_WAIT_FOR_REQUEST:
+ /* We're too late, the timeout has already kicked in */
+ return IRQ_HANDLED;
+ case MMCIF_WAIT_FOR_CMD:
+ if (sh_mmcif_end_cmd(host))
+ /* Wait for data */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_MREAD:
+ if (sh_mmcif_mread_block(host))
+ /* Wait for more data */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_READ:
+ if (sh_mmcif_read_block(host))
+ /* Wait for data end */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_MWRITE:
+ if (sh_mmcif_mwrite_block(host))
+ /* Wait data to write */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_WRITE:
+ if (sh_mmcif_write_block(host))
+ /* Wait for data end */
+ return IRQ_HANDLED;
+ break;
+ case MMCIF_WAIT_FOR_STOP:
+ if (host->sd_error) {
+ mrq->stop->error = sh_mmcif_error_manage(host);
+ break;
+ }
+ sh_mmcif_get_cmd12response(host, mrq->stop);
+ mrq->stop->error = 0;
+ break;
+ case MMCIF_WAIT_FOR_READ_END:
+ case MMCIF_WAIT_FOR_WRITE_END:
+ if (host->sd_error)
+ data->error = sh_mmcif_error_manage(host);
+ break;
+ default:
+ BUG();
+ }
+
+ if (host->wait_for != MMCIF_WAIT_FOR_STOP) {
+ if (!mrq->cmd->error && data && !data->error)
+ data->bytes_xfered =
+ data->blocks * data->blksz;
+
+ if (mrq->stop && !mrq->cmd->error && (!data || !data->error)) {
+ sh_mmcif_stop_cmd(host, mrq);
+ if (!mrq->stop->error)
+ return IRQ_HANDLED;
+ }
+ }
+
+ host->wait_for = MMCIF_WAIT_FOR_REQUEST;
+ host->state = STATE_IDLE;
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, mrq);
+
+ return IRQ_HANDLED;
}
static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
@@ -960,7 +1148,12 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
state = sh_mmcif_readl(host->addr, MMCIF_CE_INT);
- if (state & INT_RBSYE) {
+ if (state & INT_ERR_STS) {
+ /* error interrupts - process first */
+ sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
+ sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
+ err = 1;
+ } else if (state & INT_RBSYE) {
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
~(INT_RBSYE | INT_CRSPE));
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MRBSYE);
@@ -988,11 +1181,6 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
sh_mmcif_writel(host->addr, MMCIF_CE_INT,
~(INT_CMD12RBE | INT_CMD12CRE));
sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, MASK_MCMD12RBE);
- } else if (state & INT_ERR_STS) {
- /* err interrupts */
- sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
- sh_mmcif_bitclr(host, MMCIF_CE_INT_MASK, state);
- err = 1;
} else {
dev_dbg(&host->pd->dev, "Unsupported interrupt: 0x%x\n", state);
sh_mmcif_writel(host->addr, MMCIF_CE_INT, ~state);
@@ -1003,14 +1191,57 @@ static irqreturn_t sh_mmcif_intr(int irq, void *dev_id)
host->sd_error = true;
dev_dbg(&host->pd->dev, "int err state = %08x\n", state);
}
- if (state & ~(INT_CMD12RBE | INT_CMD12CRE))
- complete(&host->intr_wait);
- else
+ if (state & ~(INT_CMD12RBE | INT_CMD12CRE)) {
+ if (!host->dma_active)
+ return IRQ_WAKE_THREAD;
+ else if (host->sd_error)
+ mmcif_dma_complete(host);
+ } else {
dev_dbg(&host->pd->dev, "Unexpected IRQ 0x%x\n", state);
+ }
return IRQ_HANDLED;
}
+static void mmcif_timeout_work(struct work_struct *work)
+{
+ struct delayed_work *d = container_of(work, struct delayed_work, work);
+ struct sh_mmcif_host *host = container_of(d, struct sh_mmcif_host, timeout_work);
+ struct mmc_request *mrq = host->mrq;
+
+ if (host->dying)
+ /* Don't run after mmc_remove_host() */
+ return;
+
+ /*
+ * Handle races with cancel_delayed_work(), unless
+ * cancel_delayed_work_sync() is used
+ */
+ switch (host->wait_for) {
+ case MMCIF_WAIT_FOR_CMD:
+ mrq->cmd->error = sh_mmcif_error_manage(host);
+ break;
+ case MMCIF_WAIT_FOR_STOP:
+ mrq->stop->error = sh_mmcif_error_manage(host);
+ break;
+ case MMCIF_WAIT_FOR_MREAD:
+ case MMCIF_WAIT_FOR_MWRITE:
+ case MMCIF_WAIT_FOR_READ:
+ case MMCIF_WAIT_FOR_WRITE:
+ case MMCIF_WAIT_FOR_READ_END:
+ case MMCIF_WAIT_FOR_WRITE_END:
+ mrq->data->error = sh_mmcif_error_manage(host);
+ break;
+ default:
+ BUG();
+ }
+
+ host->state = STATE_IDLE;
+ host->wait_for = MMCIF_WAIT_FOR_REQUEST;
+ host->mrq = NULL;
+ mmc_request_done(host->mmc, mrq);
+}
+
static int __devinit sh_mmcif_probe(struct platform_device *pdev)
{
int ret = 0, irq[2];
@@ -1064,7 +1295,6 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
host->clk = clk_get_rate(host->hclk);
host->pd = pdev;
- init_completion(&host->intr_wait);
spin_lock_init(&host->lock);
mmc->ops = &sh_mmcif_ops;
@@ -1101,19 +1331,21 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev)
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
- ret = request_irq(irq[0], sh_mmcif_intr, 0, "sh_mmc:error", host);
+ ret = request_threaded_irq(irq[0], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:error", host);
if (ret) {
dev_err(&pdev->dev, "request_irq error (sh_mmc:error)\n");
goto clean_up3;
}
- ret = request_irq(irq[1], sh_mmcif_intr, 0, "sh_mmc:int", host);
+ ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host);
if (ret) {
free_irq(irq[0], host);
dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n");
goto clean_up3;
}
- sh_mmcif_detect(host->mmc);
+ INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work);
+
+ mmc_detect_change(host->mmc, 0);
dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION);
dev_dbg(&pdev->dev, "chip ver H'%04x\n",
@@ -1139,11 +1371,19 @@ static int __devexit sh_mmcif_remove(struct platform_device *pdev)
struct sh_mmcif_host *host = platform_get_drvdata(pdev);
int irq[2];
+ host->dying = true;
pm_runtime_get_sync(&pdev->dev);
mmc_remove_host(host->mmc);
sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL);
+ /*
+ * FIXME: cancel_delayed_work(_sync)() and free_irq() race with the
+ * mmc_remove_host() call above. But swapping order doesn't help either
+ * (a query on the linux-mmc mailing list didn't bring any replies).
+ */
+ cancel_delayed_work_sync(&host->timeout_work);
+
if (host->addr)
iounmap(host->addr);
@@ -1206,19 +1446,7 @@ static struct platform_driver sh_mmcif_driver = {
},
};
-static int __init sh_mmcif_init(void)
-{
- return platform_driver_register(&sh_mmcif_driver);
-}
-
-static void __exit sh_mmcif_exit(void)
-{
- platform_driver_unregister(&sh_mmcif_driver);
-}
-
-module_init(sh_mmcif_init);
-module_exit(sh_mmcif_exit);
-
+module_platform_driver(sh_mmcif_driver);
MODULE_DESCRIPTION("SuperH on-chip MMC/eMMC interface driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c
index 41ae6466bd83..58da3c44acc5 100644
--- a/drivers/mmc/host/sh_mobile_sdhi.c
+++ b/drivers/mmc/host/sh_mobile_sdhi.c
@@ -282,18 +282,7 @@ static struct platform_driver sh_mobile_sdhi_driver = {
.remove = __devexit_p(sh_mobile_sdhi_remove),
};
-static int __init sh_mobile_sdhi_init(void)
-{
- return platform_driver_register(&sh_mobile_sdhi_driver);
-}
-
-static void __exit sh_mobile_sdhi_exit(void)
-{
- platform_driver_unregister(&sh_mobile_sdhi_driver);
-}
-
-module_init(sh_mobile_sdhi_init);
-module_exit(sh_mobile_sdhi_exit);
+module_platform_driver(sh_mobile_sdhi_driver);
MODULE_DESCRIPTION("SuperH Mobile SDHI driver");
MODULE_AUTHOR("Magnus Damm");
diff --git a/drivers/mmc/host/tifm_sd.c b/drivers/mmc/host/tifm_sd.c
index f70d04664cac..43d962829f8e 100644
--- a/drivers/mmc/host/tifm_sd.c
+++ b/drivers/mmc/host/tifm_sd.c
@@ -22,8 +22,8 @@
#define DRIVER_NAME "tifm_sd"
#define DRIVER_VERSION "0.8"
-static int no_dma = 0;
-static int fixed_timeout = 0;
+static bool no_dma = 0;
+static bool fixed_timeout = 0;
module_param(no_dma, bool, 0644);
module_param(fixed_timeout, bool, 0644);
@@ -118,7 +118,7 @@ static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg,
unsigned char *buf;
unsigned int pos = 0, val;
- buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + off;
+ buf = kmap_atomic(pg) + off;
if (host->cmd_flags & DATA_CARRY) {
buf[pos++] = host->bounce_buf_data[0];
host->cmd_flags &= ~DATA_CARRY;
@@ -134,7 +134,7 @@ static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg,
}
buf[pos++] = (val >> 8) & 0xff;
}
- kunmap_atomic(buf - off, KM_BIO_DST_IRQ);
+ kunmap_atomic(buf - off);
}
static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg,
@@ -144,7 +144,7 @@ static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg,
unsigned char *buf;
unsigned int pos = 0, val;
- buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + off;
+ buf = kmap_atomic(pg) + off;
if (host->cmd_flags & DATA_CARRY) {
val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00);
writel(val, sock->addr + SOCK_MMCSD_DATA);
@@ -161,7 +161,7 @@ static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg,
val |= (buf[pos++] << 8) & 0xff00;
writel(val, sock->addr + SOCK_MMCSD_DATA);
}
- kunmap_atomic(buf - off, KM_BIO_SRC_IRQ);
+ kunmap_atomic(buf - off);
}
static void tifm_sd_transfer_data(struct tifm_sd *host)
@@ -212,13 +212,13 @@ static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off,
struct page *src, unsigned int src_off,
unsigned int count)
{
- unsigned char *src_buf = kmap_atomic(src, KM_BIO_SRC_IRQ) + src_off;
- unsigned char *dst_buf = kmap_atomic(dst, KM_BIO_DST_IRQ) + dst_off;
+ unsigned char *src_buf = kmap_atomic(src) + src_off;
+ unsigned char *dst_buf = kmap_atomic(dst) + dst_off;
memcpy(dst_buf, src_buf, count);
- kunmap_atomic(dst_buf - dst_off, KM_BIO_DST_IRQ);
- kunmap_atomic(src_buf - src_off, KM_BIO_SRC_IRQ);
+ kunmap_atomic(dst_buf - dst_off);
+ kunmap_atomic(src_buf - src_off);
}
static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
diff --git a/drivers/mmc/host/tmio_mmc.c b/drivers/mmc/host/tmio_mmc.c
index a4ea10242787..113ce6c9cf32 100644
--- a/drivers/mmc/host/tmio_mmc.c
+++ b/drivers/mmc/host/tmio_mmc.c
@@ -138,19 +138,7 @@ static struct platform_driver tmio_mmc_driver = {
.resume = tmio_mmc_resume,
};
-
-static int __init tmio_mmc_init(void)
-{
- return platform_driver_register(&tmio_mmc_driver);
-}
-
-static void __exit tmio_mmc_exit(void)
-{
- platform_driver_unregister(&tmio_mmc_driver);
-}
-
-module_init(tmio_mmc_init);
-module_exit(tmio_mmc_exit);
+module_platform_driver(tmio_mmc_driver);
MODULE_DESCRIPTION("Toshiba TMIO SD/MMC driver");
MODULE_AUTHOR("Ian Molton <spyro@f2s.com>");
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 3020f98218f0..a95e6d901726 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -105,13 +105,13 @@ static inline char *tmio_mmc_kmap_atomic(struct scatterlist *sg,
unsigned long *flags)
{
local_irq_save(*flags);
- return kmap_atomic(sg_page(sg), KM_BIO_SRC_IRQ) + sg->offset;
+ return kmap_atomic(sg_page(sg)) + sg->offset;
}
static inline void tmio_mmc_kunmap_atomic(struct scatterlist *sg,
unsigned long *flags, void *virt)
{
- kunmap_atomic(virt - sg->offset, KM_BIO_SRC_IRQ);
+ kunmap_atomic(virt - sg->offset);
local_irq_restore(*flags);
}
diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c
index 4208b3958069..abad01b37cfb 100644
--- a/drivers/mmc/host/tmio_mmc_pio.c
+++ b/drivers/mmc/host/tmio_mmc_pio.c
@@ -800,8 +800,7 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
} else if (ios->power_mode != MMC_POWER_UP) {
if (host->set_pwr && ios->power_mode == MMC_POWER_OFF)
host->set_pwr(host->pdev, 0);
- if ((pdata->flags & TMIO_MMC_HAS_COLD_CD) &&
- pdata->power) {
+ if (pdata->power) {
pdata->power = false;
pm_runtime_put(&host->pdev->dev);
}
@@ -915,6 +914,23 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
if (ret < 0)
goto pm_disable;
+ /*
+ * There are 4 different scenarios for the card detection:
+ * 1) an external gpio irq handles the cd (best for power savings)
+ * 2) internal sdhi irq handles the cd
+ * 3) a worker thread polls the sdhi - indicated by MMC_CAP_NEEDS_POLL
+ * 4) the medium is non-removable - indicated by MMC_CAP_NONREMOVABLE
+ *
+ * While we increment the rtpm counter for all scenarios when the mmc
+ * core activates us by calling an appropriate set_ios(), we must
+ * additionally ensure that in case 2) the tmio mmc hardware stays
+ * powered on during runtime for the card detection to work.
+ */
+ if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD
+ || mmc->caps & MMC_CAP_NEEDS_POLL
+ || mmc->caps & MMC_CAP_NONREMOVABLE))
+ pm_runtime_get_noresume(&pdev->dev);
+
tmio_mmc_clk_stop(_host);
tmio_mmc_reset(_host);
@@ -933,12 +949,6 @@ int __devinit tmio_mmc_host_probe(struct tmio_mmc_host **host,
/* See if we also get DMA */
tmio_mmc_request_dma(_host, pdata);
- /* We have to keep the device powered for its card detection to work */
- if (!(pdata->flags & TMIO_MMC_HAS_COLD_CD)) {
- pdata->power = true;
- pm_runtime_get_noresume(&pdev->dev);
- }
-
mmc_add_host(mmc);
/* Unmask the IRQs we want to know about */
@@ -974,7 +984,9 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
* the controller, the runtime PM is suspended and pdata->power == false,
* so, our .runtime_resume() will not try to detect a card in the slot.
*/
- if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD)
+ if (host->pdata->flags & TMIO_MMC_HAS_COLD_CD
+ || host->mmc->caps & MMC_CAP_NEEDS_POLL
+ || host->mmc->caps & MMC_CAP_NONREMOVABLE)
pm_runtime_get_sync(&pdev->dev);
mmc_remove_host(host->mmc);
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c
index 2ec978bc32ba..3135a1a5d75d 100644
--- a/drivers/mmc/host/vub300.c
+++ b/drivers/mmc/host/vub300.c
@@ -223,25 +223,25 @@ enum SD_RESPONSE_TYPE {
#define FUN(c) (0x000007 & (c->arg>>28))
#define REG(c) (0x01FFFF & (c->arg>>9))
-static int limit_speed_to_24_MHz;
+static bool limit_speed_to_24_MHz;
module_param(limit_speed_to_24_MHz, bool, 0644);
MODULE_PARM_DESC(limit_speed_to_24_MHz, "Limit Max SDIO Clock Speed to 24 MHz");
-static int pad_input_to_usb_pkt;
+static bool pad_input_to_usb_pkt;
module_param(pad_input_to_usb_pkt, bool, 0644);
MODULE_PARM_DESC(pad_input_to_usb_pkt,
"Pad USB data input transfers to whole USB Packet");
-static int disable_offload_processing;
+static bool disable_offload_processing;
module_param(disable_offload_processing, bool, 0644);
MODULE_PARM_DESC(disable_offload_processing, "Disable Offload Processing");
-static int force_1_bit_data_xfers;
+static bool force_1_bit_data_xfers;
module_param(force_1_bit_data_xfers, bool, 0644);
MODULE_PARM_DESC(force_1_bit_data_xfers,
"Force SDIO Data Transfers to 1-bit Mode");
-static int force_polling_for_irqs;
+static bool force_polling_for_irqs;
module_param(force_polling_for_irqs, bool, 0644);
MODULE_PARM_DESC(force_polling_for_irqs, "Force Polling for SDIO interrupts");
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c
index 7dd3700f2303..73abbc3e093e 100644
--- a/drivers/mtd/nand/au1550nd.c
+++ b/drivers/mtd/nand/au1550nd.c
@@ -17,35 +17,19 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#include <linux/platform_device.h>
#include <asm/io.h>
+#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1550nd.h>
-#ifdef CONFIG_MIPS_PB1550
-#include <asm/mach-pb1x00/pb1550.h>
-#elif defined(CONFIG_MIPS_DB1550)
-#include <asm/mach-db1x00/db1x00.h>
-#endif
-#include <asm/mach-db1x00/bcsr.h>
-/*
- * MTD structure for NAND controller
- */
-static struct mtd_info *au1550_mtd = NULL;
-static void __iomem *p_nand;
-static int nand_width = 1; /* default x8 */
-static void (*au1550_write_byte)(struct mtd_info *, u_char);
+struct au1550nd_ctx {
+ struct mtd_info info;
+ struct nand_chip chip;
-/*
- * Define partitions for flash device
- */
-static const struct mtd_partition partition_info[] = {
- {
- .name = "NAND FS 0",
- .offset = 0,
- .size = 8 * 1024 * 1024},
- {
- .name = "NAND FS 1",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL}
+ int cs;
+ void __iomem *base;
+ void (*write_byte)(struct mtd_info *, u_char);
};
/**
@@ -259,24 +243,25 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
{
- register struct nand_chip *this = mtd->priv;
+ struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info);
+ struct nand_chip *this = mtd->priv;
switch (cmd) {
case NAND_CTL_SETCLE:
- this->IO_ADDR_W = p_nand + MEM_STNAND_CMD;
+ this->IO_ADDR_W = ctx->base + MEM_STNAND_CMD;
break;
case NAND_CTL_CLRCLE:
- this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
+ this->IO_ADDR_W = ctx->base + MEM_STNAND_DATA;
break;
case NAND_CTL_SETALE:
- this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR;
+ this->IO_ADDR_W = ctx->base + MEM_STNAND_ADDR;
break;
case NAND_CTL_CLRALE:
- this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
+ this->IO_ADDR_W = ctx->base + MEM_STNAND_DATA;
/* FIXME: Nobody knows why this is necessary,
* but it works only that way */
udelay(1);
@@ -284,7 +269,7 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
case NAND_CTL_SETNCE:
/* assert (force assert) chip enable */
- au_writel((1 << (4 + NAND_CS)), MEM_STNDCTL);
+ au_writel((1 << (4 + ctx->cs)), MEM_STNDCTL);
break;
case NAND_CTL_CLRNCE:
@@ -331,9 +316,10 @@ static void au1550_select_chip(struct mtd_info *mtd, int chip)
*/
static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr)
{
- register struct nand_chip *this = mtd->priv;
+ struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info);
+ struct nand_chip *this = mtd->priv;
int ce_override = 0, i;
- ulong flags;
+ unsigned long flags = 0;
/* Begin command latch cycle */
au1550_hwcontrol(mtd, NAND_CTL_SETCLE);
@@ -354,9 +340,9 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
column -= 256;
readcmd = NAND_CMD_READ1;
}
- au1550_write_byte(mtd, readcmd);
+ ctx->write_byte(mtd, readcmd);
}
- au1550_write_byte(mtd, command);
+ ctx->write_byte(mtd, command);
/* Set ALE and clear CLE to start address cycle */
au1550_hwcontrol(mtd, NAND_CTL_CLRCLE);
@@ -369,10 +355,10 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
/* Adjust columns for 16 bit buswidth */
if (this->options & NAND_BUSWIDTH_16)
column >>= 1;
- au1550_write_byte(mtd, column);
+ ctx->write_byte(mtd, column);
}
if (page_addr != -1) {
- au1550_write_byte(mtd, (u8)(page_addr & 0xff));
+ ctx->write_byte(mtd, (u8)(page_addr & 0xff));
if (command == NAND_CMD_READ0 ||
command == NAND_CMD_READ1 ||
@@ -390,11 +376,12 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
au1550_hwcontrol(mtd, NAND_CTL_SETNCE);
}
- au1550_write_byte(mtd, (u8)(page_addr >> 8));
+ ctx->write_byte(mtd, (u8)(page_addr >> 8));
/* One more address cycle for devices > 32MiB */
if (this->chipsize > (32 << 20))
- au1550_write_byte(mtd, (u8)((page_addr >> 16) & 0x0f));
+ ctx->write_byte(mtd,
+ ((page_addr >> 16) & 0x0f));
}
/* Latch in address */
au1550_hwcontrol(mtd, NAND_CTL_CLRALE);
@@ -440,121 +427,79 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i
while(!this->dev_ready(mtd));
}
-
-/*
- * Main initialization routine
- */
-static int __init au1xxx_nand_init(void)
+static int __devinit find_nand_cs(unsigned long nand_base)
{
- struct nand_chip *this;
- u16 boot_swapboot = 0; /* default value */
- int retval;
- u32 mem_staddr;
- u32 nand_phys;
-
- /* Allocate memory for MTD device structure and private data */
- au1550_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL);
- if (!au1550_mtd) {
- printk("Unable to allocate NAND MTD dev structure.\n");
- return -ENOMEM;
- }
-
- /* Get pointer to private data */
- this = (struct nand_chip *)(&au1550_mtd[1]);
-
- /* Link the private data with the MTD structure */
- au1550_mtd->priv = this;
- au1550_mtd->owner = THIS_MODULE;
-
+ void __iomem *base =
+ (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR);
+ unsigned long addr, staddr, start, mask, end;
+ int i;
- /* MEM_STNDCTL: disable ints, disable nand boot */
- au_writel(0, MEM_STNDCTL);
+ for (i = 0; i < 4; i++) {
+ addr = 0x1000 + (i * 0x10); /* CSx */
+ staddr = __raw_readl(base + addr + 0x08); /* STADDRx */
+ /* figure out the decoded range of this CS */
+ start = (staddr << 4) & 0xfffc0000;
+ mask = (staddr << 18) & 0xfffc0000;
+ end = (start | (start - 1)) & ~(start ^ mask);
+ if ((nand_base >= start) && (nand_base < end))
+ return i;
+ }
-#ifdef CONFIG_MIPS_PB1550
- /* set gpio206 high */
- gpio_direction_input(206);
+ return -ENODEV;
+}
- boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1);
+static int __devinit au1550nd_probe(struct platform_device *pdev)
+{
+ struct au1550nd_platdata *pd;
+ struct au1550nd_ctx *ctx;
+ struct nand_chip *this;
+ struct resource *r;
+ int ret, cs;
- switch (boot_swapboot) {
- case 0:
- case 2:
- case 8:
- case 0xC:
- case 0xD:
- /* x16 NAND Flash */
- nand_width = 0;
- break;
- case 1:
- case 9:
- case 3:
- case 0xE:
- case 0xF:
- /* x8 NAND Flash */
- nand_width = 1;
- break;
- default:
- printk("Pb1550 NAND: bad boot:swap\n");
- retval = -EINVAL;
- goto outmem;
+ pd = pdev->dev.platform_data;
+ if (!pd) {
+ dev_err(&pdev->dev, "missing platform data\n");
+ return -ENODEV;
}
-#endif
-
- /* Configure chip-select; normally done by boot code, e.g. YAMON */
-#ifdef NAND_STCFG
- if (NAND_CS == 0) {
- au_writel(NAND_STCFG, MEM_STCFG0);
- au_writel(NAND_STTIME, MEM_STTIME0);
- au_writel(NAND_STADDR, MEM_STADDR0);
- }
- if (NAND_CS == 1) {
- au_writel(NAND_STCFG, MEM_STCFG1);
- au_writel(NAND_STTIME, MEM_STTIME1);
- au_writel(NAND_STADDR, MEM_STADDR1);
+
+ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+ if (!ctx) {
+ dev_err(&pdev->dev, "no memory for NAND context\n");
+ return -ENOMEM;
}
- if (NAND_CS == 2) {
- au_writel(NAND_STCFG, MEM_STCFG2);
- au_writel(NAND_STTIME, MEM_STTIME2);
- au_writel(NAND_STADDR, MEM_STADDR2);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ dev_err(&pdev->dev, "no NAND memory resource\n");
+ ret = -ENODEV;
+ goto out1;
}
- if (NAND_CS == 3) {
- au_writel(NAND_STCFG, MEM_STCFG3);
- au_writel(NAND_STTIME, MEM_STTIME3);
- au_writel(NAND_STADDR, MEM_STADDR3);
+ if (request_mem_region(r->start, resource_size(r), "au1550-nand")) {
+ dev_err(&pdev->dev, "cannot claim NAND memory area\n");
+ ret = -ENOMEM;
+ goto out1;
}
-#endif
-
- /* Locate NAND chip-select in order to determine NAND phys address */
- mem_staddr = 0x00000000;
- if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))
- mem_staddr = au_readl(MEM_STADDR0);
- else if (((au_readl(MEM_STCFG1) & 0x7) == 0x5) && (NAND_CS == 1))
- mem_staddr = au_readl(MEM_STADDR1);
- else if (((au_readl(MEM_STCFG2) & 0x7) == 0x5) && (NAND_CS == 2))
- mem_staddr = au_readl(MEM_STADDR2);
- else if (((au_readl(MEM_STCFG3) & 0x7) == 0x5) && (NAND_CS == 3))
- mem_staddr = au_readl(MEM_STADDR3);
-
- if (mem_staddr == 0x00000000) {
- printk("Au1xxx NAND: ERROR WITH NAND CHIP-SELECT\n");
- kfree(au1550_mtd);
- return 1;
+
+ ctx->base = ioremap_nocache(r->start, 0x1000);
+ if (!ctx->base) {
+ dev_err(&pdev->dev, "cannot remap NAND memory area\n");
+ ret = -ENODEV;
+ goto out2;
}
- nand_phys = (mem_staddr << 4) & 0xFFFC0000;
- p_nand = ioremap(nand_phys, 0x1000);
+ this = &ctx->chip;
+ ctx->info.priv = this;
+ ctx->info.owner = THIS_MODULE;
- /* make controller and MTD agree */
- if (NAND_CS == 0)
- nand_width = au_readl(MEM_STCFG0) & (1 << 22);
- if (NAND_CS == 1)
- nand_width = au_readl(MEM_STCFG1) & (1 << 22);
- if (NAND_CS == 2)
- nand_width = au_readl(MEM_STCFG2) & (1 << 22);
- if (NAND_CS == 3)
- nand_width = au_readl(MEM_STCFG3) & (1 << 22);
+ /* figure out which CS# r->start belongs to */
+ cs = find_nand_cs(r->start);
+ if (cs < 0) {
+ dev_err(&pdev->dev, "cannot detect NAND chipselect\n");
+ ret = -ENODEV;
+ goto out3;
+ }
+ ctx->cs = cs;
- /* Set address of hardware control function */
this->dev_ready = au1550_device_ready;
this->select_chip = au1550_select_chip;
this->cmdfunc = au1550_command;
@@ -565,54 +510,57 @@ static int __init au1xxx_nand_init(void)
this->options = NAND_NO_AUTOINCR;
- if (!nand_width)
+ if (pd->devwidth)
this->options |= NAND_BUSWIDTH_16;
- this->read_byte = (!nand_width) ? au_read_byte16 : au_read_byte;
- au1550_write_byte = (!nand_width) ? au_write_byte16 : au_write_byte;
+ this->read_byte = (pd->devwidth) ? au_read_byte16 : au_read_byte;
+ ctx->write_byte = (pd->devwidth) ? au_write_byte16 : au_write_byte;
this->read_word = au_read_word;
- this->write_buf = (!nand_width) ? au_write_buf16 : au_write_buf;
- this->read_buf = (!nand_width) ? au_read_buf16 : au_read_buf;
- this->verify_buf = (!nand_width) ? au_verify_buf16 : au_verify_buf;
-
- /* Scan to find existence of the device */
- if (nand_scan(au1550_mtd, 1)) {
- retval = -ENXIO;
- goto outio;
+ this->write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf;
+ this->read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf;
+ this->verify_buf = (pd->devwidth) ? au_verify_buf16 : au_verify_buf;
+
+ ret = nand_scan(&ctx->info, 1);
+ if (ret) {
+ dev_err(&pdev->dev, "NAND scan failed with %d\n", ret);
+ goto out3;
}
- /* Register the partitions */
- mtd_device_register(au1550_mtd, partition_info,
- ARRAY_SIZE(partition_info));
+ mtd_device_register(&ctx->info, pd->parts, pd->num_parts);
return 0;
- outio:
- iounmap(p_nand);
-
- outmem:
- kfree(au1550_mtd);
- return retval;
+out3:
+ iounmap(ctx->base);
+out2:
+ release_mem_region(r->start, resource_size(r));
+out1:
+ kfree(ctx);
+ return ret;
}
-module_init(au1xxx_nand_init);
-
-/*
- * Clean up routine
- */
-static void __exit au1550_cleanup(void)
+static int __devexit au1550nd_remove(struct platform_device *pdev)
{
- /* Release resources, unregister device */
- nand_release(au1550_mtd);
+ struct au1550nd_ctx *ctx = platform_get_drvdata(pdev);
+ struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- /* Free the MTD device structure */
- kfree(au1550_mtd);
-
- /* Unmap */
- iounmap(p_nand);
+ nand_release(&ctx->info);
+ iounmap(ctx->base);
+ release_mem_region(r->start, 0x1000);
+ kfree(ctx);
+ return 0;
}
-module_exit(au1550_cleanup);
+static struct platform_driver au1550nd_driver = {
+ .driver = {
+ .name = "au1550-nand",
+ .owner = THIS_MODULE,
+ },
+ .probe = au1550nd_probe,
+ .remove = __devexit_p(au1550nd_remove),
+};
+
+module_platform_driver(au1550nd_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Embedded Edge, LLC");
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 8544d6bf50a0..5c3d719c37e6 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -185,7 +185,7 @@ struct pxa3xx_nand_info {
uint32_t ndcb2;
};
-static int use_dma = 1;
+static bool use_dma = 1;
module_param(use_dma, bool, 0444);
MODULE_PARM_DESC(use_dma, "enable DMA for data transferring to/from NAND HW");
diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c
index f20f393bfda6..769a4e096b3c 100644
--- a/drivers/mtd/nand/r852.c
+++ b/drivers/mtd/nand/r852.c
@@ -22,7 +22,7 @@
#include "r852.h"
-static int r852_enable_dma = 1;
+static bool r852_enable_dma = 1;
module_param(r852_enable_dma, bool, S_IRUGO);
MODULE_PARM_DESC(r852_enable_dma, "Enable usage of the DMA (default)");
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index d423d18b4ad6..e535137eb2d0 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -313,8 +313,12 @@ config TOSHIBA_FIR
donauboe.
config AU1000_FIR
- tristate "Alchemy Au1000 SIR/FIR"
+ tristate "Alchemy IrDA SIR/FIR"
depends on IRDA && MIPS_ALCHEMY
+ help
+ Say Y/M here to build suppor the the IrDA peripheral on the
+ Alchemy Au1000 and Au1100 SoCs.
+ Say M to build a module; it will be called au1k_ir.ko
config SMC_IRCC_FIR
tristate "SMSC IrCC (EXPERIMENTAL)"
diff --git a/drivers/net/irda/au1000_ircc.h b/drivers/net/irda/au1000_ircc.h
deleted file mode 100644
index c072c09a8d91..000000000000
--- a/drivers/net/irda/au1000_ircc.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * Au1000 IrDA driver.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AU1000_IRCC_H
-#define AU1000_IRCC_H
-
-#include <linux/time.h>
-
-#include <linux/spinlock.h>
-#include <linux/pm.h>
-#include <asm/io.h>
-
-#define NUM_IR_IFF 1
-#define NUM_IR_DESC 64
-#define RING_SIZE_4 0x0
-#define RING_SIZE_16 0x3
-#define RING_SIZE_64 0xF
-#define MAX_NUM_IR_DESC 64
-#define MAX_BUF_SIZE 2048
-
-#define BPS_115200 0
-#define BPS_57600 1
-#define BPS_38400 2
-#define BPS_19200 5
-#define BPS_9600 11
-#define BPS_2400 47
-
-/* Ring descriptor flags */
-#define AU_OWN (1<<7) /* tx,rx */
-
-#define IR_DIS_CRC (1<<6) /* tx */
-#define IR_BAD_CRC (1<<5) /* tx */
-#define IR_NEED_PULSE (1<<4) /* tx */
-#define IR_FORCE_UNDER (1<<3) /* tx */
-#define IR_DISABLE_TX (1<<2) /* tx */
-#define IR_HW_UNDER (1<<0) /* tx */
-#define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER)
-
-#define IR_PHY_ERROR (1<<6) /* rx */
-#define IR_CRC_ERROR (1<<5) /* rx */
-#define IR_MAX_LEN (1<<4) /* rx */
-#define IR_FIFO_OVER (1<<3) /* rx */
-#define IR_SIR_ERROR (1<<2) /* rx */
-#define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \
- IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR)
-
-typedef struct db_dest {
- struct db_dest *pnext;
- volatile u32 *vaddr;
- dma_addr_t dma_addr;
-} db_dest_t;
-
-
-typedef struct ring_desc {
- u8 count_0; /* 7:0 */
- u8 count_1; /* 12:8 */
- u8 reserved;
- u8 flags;
- u8 addr_0; /* 7:0 */
- u8 addr_1; /* 15:8 */
- u8 addr_2; /* 23:16 */
- u8 addr_3; /* 31:24 */
-} ring_dest_t;
-
-
-/* Private data for each instance */
-struct au1k_private {
-
- db_dest_t *pDBfree;
- db_dest_t db[2*NUM_IR_DESC];
- volatile ring_dest_t *rx_ring[NUM_IR_DESC];
- volatile ring_dest_t *tx_ring[NUM_IR_DESC];
- db_dest_t *rx_db_inuse[NUM_IR_DESC];
- db_dest_t *tx_db_inuse[NUM_IR_DESC];
- u32 rx_head;
- u32 tx_head;
- u32 tx_tail;
- u32 tx_full;
-
- iobuff_t rx_buff;
-
- struct net_device *netdev;
-
- struct timeval stamp;
- struct timeval now;
- struct qos_info qos;
- struct irlap_cb *irlap;
-
- u8 open;
- u32 speed;
- u32 newspeed;
-
- u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */
- struct timer_list timer;
-
- spinlock_t lock; /* For serializing operations */
-};
-#endif /* AU1000_IRCC_H */
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index a3d696a9456a..fc503aa5288e 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -18,104 +18,220 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
-#include <linux/module.h>
-#include <linux/types.h>
+
#include <linux/init.h>
-#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
-#include <linux/slab.h>
-#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/bitops.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/au1000.h>
-#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_PB1100)
-#include <asm/pb1000.h>
-#elif defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
-#include <asm/db1x00.h>
-#include <asm/mach-db1x00/bcsr.h>
-#else
-#error au1k_ir: unsupported board
-#endif
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/types.h>
#include <net/irda/irda.h>
#include <net/irda/irmod.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda_device.h>
-#include "au1000_ircc.h"
+#include <asm/mach-au1x00/au1000.h>
+
+/* registers */
+#define IR_RING_PTR_STATUS 0x00
+#define IR_RING_BASE_ADDR_H 0x04
+#define IR_RING_BASE_ADDR_L 0x08
+#define IR_RING_SIZE 0x0C
+#define IR_RING_PROMPT 0x10
+#define IR_RING_ADDR_CMPR 0x14
+#define IR_INT_CLEAR 0x18
+#define IR_CONFIG_1 0x20
+#define IR_SIR_FLAGS 0x24
+#define IR_STATUS 0x28
+#define IR_READ_PHY_CONFIG 0x2C
+#define IR_WRITE_PHY_CONFIG 0x30
+#define IR_MAX_PKT_LEN 0x34
+#define IR_RX_BYTE_CNT 0x38
+#define IR_CONFIG_2 0x3C
+#define IR_ENABLE 0x40
+
+/* Config1 */
+#define IR_RX_INVERT_LED (1 << 0)
+#define IR_TX_INVERT_LED (1 << 1)
+#define IR_ST (1 << 2)
+#define IR_SF (1 << 3)
+#define IR_SIR (1 << 4)
+#define IR_MIR (1 << 5)
+#define IR_FIR (1 << 6)
+#define IR_16CRC (1 << 7)
+#define IR_TD (1 << 8)
+#define IR_RX_ALL (1 << 9)
+#define IR_DMA_ENABLE (1 << 10)
+#define IR_RX_ENABLE (1 << 11)
+#define IR_TX_ENABLE (1 << 12)
+#define IR_LOOPBACK (1 << 14)
+#define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \
+ IR_RX_ALL | IR_RX_ENABLE | IR_SF | \
+ IR_16CRC)
+
+/* ir_status */
+#define IR_RX_STATUS (1 << 9)
+#define IR_TX_STATUS (1 << 10)
+#define IR_PHYEN (1 << 15)
+
+/* ir_write_phy_config */
+#define IR_BR(x) (((x) & 0x3f) << 10) /* baud rate */
+#define IR_PW(x) (((x) & 0x1f) << 5) /* pulse width */
+#define IR_P(x) ((x) & 0x1f) /* preamble bits */
+
+/* Config2 */
+#define IR_MODE_INV (1 << 0)
+#define IR_ONE_PIN (1 << 1)
+#define IR_PHYCLK_40MHZ (0 << 2)
+#define IR_PHYCLK_48MHZ (1 << 2)
+#define IR_PHYCLK_56MHZ (2 << 2)
+#define IR_PHYCLK_64MHZ (3 << 2)
+#define IR_DP (1 << 4)
+#define IR_DA (1 << 5)
+#define IR_FLT_HIGH (0 << 6)
+#define IR_FLT_MEDHI (1 << 6)
+#define IR_FLT_MEDLO (2 << 6)
+#define IR_FLT_LO (3 << 6)
+#define IR_IEN (1 << 8)
+
+/* ir_enable */
+#define IR_HC (1 << 3) /* divide SBUS clock by 2 */
+#define IR_CE (1 << 2) /* clock enable */
+#define IR_C (1 << 1) /* coherency bit */
+#define IR_BE (1 << 0) /* set in big endian mode */
+
+#define NUM_IR_DESC 64
+#define RING_SIZE_4 0x0
+#define RING_SIZE_16 0x3
+#define RING_SIZE_64 0xF
+#define MAX_NUM_IR_DESC 64
+#define MAX_BUF_SIZE 2048
+
+/* Ring descriptor flags */
+#define AU_OWN (1 << 7) /* tx,rx */
+#define IR_DIS_CRC (1 << 6) /* tx */
+#define IR_BAD_CRC (1 << 5) /* tx */
+#define IR_NEED_PULSE (1 << 4) /* tx */
+#define IR_FORCE_UNDER (1 << 3) /* tx */
+#define IR_DISABLE_TX (1 << 2) /* tx */
+#define IR_HW_UNDER (1 << 0) /* tx */
+#define IR_TX_ERROR (IR_DIS_CRC | IR_BAD_CRC | IR_HW_UNDER)
+
+#define IR_PHY_ERROR (1 << 6) /* rx */
+#define IR_CRC_ERROR (1 << 5) /* rx */
+#define IR_MAX_LEN (1 << 4) /* rx */
+#define IR_FIFO_OVER (1 << 3) /* rx */
+#define IR_SIR_ERROR (1 << 2) /* rx */
+#define IR_RX_ERROR (IR_PHY_ERROR | IR_CRC_ERROR | \
+ IR_MAX_LEN | IR_FIFO_OVER | IR_SIR_ERROR)
+
+struct db_dest {
+ struct db_dest *pnext;
+ volatile u32 *vaddr;
+ dma_addr_t dma_addr;
+};
-static int au1k_irda_net_init(struct net_device *);
-static int au1k_irda_start(struct net_device *);
-static int au1k_irda_stop(struct net_device *dev);
-static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *);
-static int au1k_irda_rx(struct net_device *);
-static void au1k_irda_interrupt(int, void *);
-static void au1k_tx_timeout(struct net_device *);
-static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int);
-static int au1k_irda_set_speed(struct net_device *dev, int speed);
+struct ring_dest {
+ u8 count_0; /* 7:0 */
+ u8 count_1; /* 12:8 */
+ u8 reserved;
+ u8 flags;
+ u8 addr_0; /* 7:0 */
+ u8 addr_1; /* 15:8 */
+ u8 addr_2; /* 23:16 */
+ u8 addr_3; /* 31:24 */
+};
-static void *dma_alloc(size_t, dma_addr_t *);
-static void dma_free(void *, size_t);
+/* Private data for each instance */
+struct au1k_private {
+ void __iomem *iobase;
+ int irq_rx, irq_tx;
+
+ struct db_dest *pDBfree;
+ struct db_dest db[2 * NUM_IR_DESC];
+ volatile struct ring_dest *rx_ring[NUM_IR_DESC];
+ volatile struct ring_dest *tx_ring[NUM_IR_DESC];
+ struct db_dest *rx_db_inuse[NUM_IR_DESC];
+ struct db_dest *tx_db_inuse[NUM_IR_DESC];
+ u32 rx_head;
+ u32 tx_head;
+ u32 tx_tail;
+ u32 tx_full;
+
+ iobuff_t rx_buff;
+
+ struct net_device *netdev;
+ struct timeval stamp;
+ struct timeval now;
+ struct qos_info qos;
+ struct irlap_cb *irlap;
+
+ u8 open;
+ u32 speed;
+ u32 newspeed;
+
+ struct timer_list timer;
+
+ struct resource *ioarea;
+ struct au1k_irda_platform_data *platdata;
+};
static int qos_mtt_bits = 0x07; /* 1 ms or more */
-static struct net_device *ir_devs[NUM_IR_IFF];
-static char version[] __devinitdata =
- "au1k_ircc:1.2 ppopov@mvista.com\n";
#define RUN_AT(x) (jiffies + (x))
-static DEFINE_SPINLOCK(ir_lock);
+static void au1k_irda_plat_set_phy_mode(struct au1k_private *p, int mode)
+{
+ if (p->platdata && p->platdata->set_phy_mode)
+ p->platdata->set_phy_mode(mode);
+}
-/*
- * IrDA peripheral bug. You have to read the register
- * twice to get the right value.
- */
-u32 read_ir_reg(u32 addr)
-{
- readl(addr);
- return readl(addr);
+static inline unsigned long irda_read(struct au1k_private *p,
+ unsigned long ofs)
+{
+ /*
+ * IrDA peripheral bug. You have to read the register
+ * twice to get the right value.
+ */
+ (void)__raw_readl(p->iobase + ofs);
+ return __raw_readl(p->iobase + ofs);
}
+static inline void irda_write(struct au1k_private *p, unsigned long ofs,
+ unsigned long val)
+{
+ __raw_writel(val, p->iobase + ofs);
+ wmb();
+}
/*
* Buffer allocation/deallocation routines. The buffer descriptor returned
- * has the virtual and dma address of a buffer suitable for
+ * has the virtual and dma address of a buffer suitable for
* both, receive and transmit operations.
*/
-static db_dest_t *GetFreeDB(struct au1k_private *aup)
+static struct db_dest *GetFreeDB(struct au1k_private *aup)
{
- db_dest_t *pDB;
- pDB = aup->pDBfree;
-
- if (pDB) {
- aup->pDBfree = pDB->pnext;
- }
- return pDB;
-}
+ struct db_dest *db;
+ db = aup->pDBfree;
-static void ReleaseDB(struct au1k_private *aup, db_dest_t *pDB)
-{
- db_dest_t *pDBfree = aup->pDBfree;
- if (pDBfree)
- pDBfree->pnext = pDB;
- aup->pDBfree = pDB;
+ if (db)
+ aup->pDBfree = db->pnext;
+ return db;
}
-
/*
DMA memory allocation, derived from pci_alloc_consistent.
However, the Au1000 data cache is coherent (when programmed
so), therefore we return KSEG0 address, not KSEG1.
*/
-static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
+static void *dma_alloc(size_t size, dma_addr_t *dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC | GFP_DMA;
- ret = (void *) __get_free_pages(gfp, get_order(size));
+ ret = (void *)__get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
@@ -125,7 +241,6 @@ static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
return ret;
}
-
static void dma_free(void *vaddr, size_t size)
{
vaddr = (void *)KSEG0ADDR(vaddr);
@@ -133,206 +248,306 @@ static void dma_free(void *vaddr, size_t size)
}
-static void
-setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base)
+static void setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base)
{
int i;
- for (i=0; i<NUM_IR_DESC; i++) {
- aup->rx_ring[i] = (volatile ring_dest_t *)
- (rx_base + sizeof(ring_dest_t)*i);
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ aup->rx_ring[i] = (volatile struct ring_dest *)
+ (rx_base + sizeof(struct ring_dest) * i);
}
- for (i=0; i<NUM_IR_DESC; i++) {
- aup->tx_ring[i] = (volatile ring_dest_t *)
- (tx_base + sizeof(ring_dest_t)*i);
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ aup->tx_ring[i] = (volatile struct ring_dest *)
+ (tx_base + sizeof(struct ring_dest) * i);
}
}
-static int au1k_irda_init(void)
-{
- static unsigned version_printed = 0;
- struct au1k_private *aup;
- struct net_device *dev;
- int err;
-
- if (version_printed++ == 0) printk(version);
-
- dev = alloc_irdadev(sizeof(struct au1k_private));
- if (!dev)
- return -ENOMEM;
-
- dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */
- err = au1k_irda_net_init(dev);
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- ir_devs[0] = dev;
- printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
- return 0;
-
-out1:
- aup = netdev_priv(dev);
- dma_free((void *)aup->db[0].vaddr,
- MAX_BUF_SIZE * 2*NUM_IR_DESC);
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
- kfree(aup->rx_buff.head);
-out:
- free_netdev(dev);
- return err;
-}
-
static int au1k_irda_init_iobuf(iobuff_t *io, int size)
{
io->head = kmalloc(size, GFP_KERNEL);
if (io->head != NULL) {
- io->truesize = size;
- io->in_frame = FALSE;
- io->state = OUTSIDE_FRAME;
- io->data = io->head;
+ io->truesize = size;
+ io->in_frame = FALSE;
+ io->state = OUTSIDE_FRAME;
+ io->data = io->head;
}
return io->head ? 0 : -ENOMEM;
}
-static const struct net_device_ops au1k_irda_netdev_ops = {
- .ndo_open = au1k_irda_start,
- .ndo_stop = au1k_irda_stop,
- .ndo_start_xmit = au1k_irda_hard_xmit,
- .ndo_tx_timeout = au1k_tx_timeout,
- .ndo_do_ioctl = au1k_irda_ioctl,
-};
-
-static int au1k_irda_net_init(struct net_device *dev)
+/*
+ * Set the IrDA communications speed.
+ */
+static int au1k_irda_set_speed(struct net_device *dev, int speed)
{
struct au1k_private *aup = netdev_priv(dev);
- int i, retval = 0, err;
- db_dest_t *pDB, *pDBfree;
- dma_addr_t temp;
+ volatile struct ring_dest *ptxd;
+ unsigned long control;
+ int ret = 0, timeout = 10, i;
- err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
- if (err)
- goto out1;
+ if (speed == aup->speed)
+ return ret;
- dev->netdev_ops = &au1k_irda_netdev_ops;
+ /* disable PHY first */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
- irda_init_max_qos_capabilies(&aup->qos);
+ /* disable RX/TX */
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~(IR_RX_ENABLE | IR_TX_ENABLE));
+ msleep(20);
+ while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) {
+ msleep(20);
+ if (!timeout--) {
+ printk(KERN_ERR "%s: rx/tx disable timeout\n",
+ dev->name);
+ break;
+ }
+ }
- /* The only value we must override it the baudrate */
- aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
- IR_115200|IR_576000 |(IR_4000000 << 8);
-
- aup->qos.min_turn_time.bits = qos_mtt_bits;
- irda_qos_bits_to_value(&aup->qos);
+ /* disable DMA */
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~IR_DMA_ENABLE);
+ msleep(20);
- retval = -ENOMEM;
+ /* After we disable tx/rx. the index pointers go back to zero. */
+ aup->tx_head = aup->tx_tail = aup->rx_head = 0;
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ ptxd = aup->tx_ring[i];
+ ptxd->flags = 0;
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ }
- /* Tx ring follows rx ring + 512 bytes */
- /* we need a 1k aligned buffer */
- aup->rx_ring[0] = (ring_dest_t *)
- dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp);
- if (!aup->rx_ring[0])
- goto out2;
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ ptxd = aup->rx_ring[i];
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ ptxd->flags = AU_OWN;
+ }
- /* allocate the data buffers */
- aup->db[0].vaddr =
- (void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp);
- if (!aup->db[0].vaddr)
- goto out3;
+ if (speed == 4000000)
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_FIR);
+ else
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);
- setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);
+ switch (speed) {
+ case 9600:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(11) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 19200:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(5) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 38400:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(2) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 57600:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(1) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 115200:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 4000000:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_P(15));
+ irda_write(aup, IR_CONFIG_1, IR_FIR | IR_DMA_ENABLE |
+ IR_RX_ENABLE);
+ break;
+ default:
+ printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
+ ret = -EINVAL;
+ break;
+ }
- pDBfree = NULL;
- pDB = aup->db;
- for (i=0; i<(2*NUM_IR_DESC); i++) {
- pDB->pnext = pDBfree;
- pDBfree = pDB;
- pDB->vaddr =
- (u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i);
- pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
- pDB++;
+ aup->speed = speed;
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) | IR_PHYEN);
+
+ control = irda_read(aup, IR_STATUS);
+ irda_write(aup, IR_RING_PROMPT, 0);
+
+ if (control & (1 << 14)) {
+ printk(KERN_ERR "%s: configuration error\n", dev->name);
+ } else {
+ if (control & (1 << 11))
+ printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
+ if (control & (1 << 12))
+ printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
+ if (control & (1 << 13))
+ printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
+ if (control & (1 << 10))
+ printk(KERN_DEBUG "%s TX enabled\n", dev->name);
+ if (control & (1 << 9))
+ printk(KERN_DEBUG "%s RX enabled\n", dev->name);
}
- aup->pDBfree = pDBfree;
- /* attach a data buffer to each descriptor */
- for (i=0; i<NUM_IR_DESC; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) goto out;
- aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
- aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
- aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
- aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
- aup->rx_db_inuse[i] = pDB;
+ return ret;
+}
+
+static void update_rx_stats(struct net_device *dev, u32 status, u32 count)
+{
+ struct net_device_stats *ps = &dev->stats;
+
+ ps->rx_packets++;
+
+ if (status & IR_RX_ERROR) {
+ ps->rx_errors++;
+ if (status & (IR_PHY_ERROR | IR_FIFO_OVER))
+ ps->rx_missed_errors++;
+ if (status & IR_MAX_LEN)
+ ps->rx_length_errors++;
+ if (status & IR_CRC_ERROR)
+ ps->rx_crc_errors++;
+ } else
+ ps->rx_bytes += count;
+}
+
+static void update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
+{
+ struct net_device_stats *ps = &dev->stats;
+
+ ps->tx_packets++;
+ ps->tx_bytes += pkt_len;
+
+ if (status & IR_TX_ERROR) {
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
}
- for (i=0; i<NUM_IR_DESC; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) goto out;
- aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
- aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
- aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
- aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
- aup->tx_ring[i]->count_0 = 0;
- aup->tx_ring[i]->count_1 = 0;
- aup->tx_ring[i]->flags = 0;
- aup->tx_db_inuse[i] = pDB;
+}
+
+static void au1k_tx_ack(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ volatile struct ring_dest *ptxd;
+
+ ptxd = aup->tx_ring[aup->tx_tail];
+ while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
+ update_tx_stats(dev, ptxd->flags,
+ (ptxd->count_1 << 8) | ptxd->count_0);
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ wmb();
+ aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
+ ptxd = aup->tx_ring[aup->tx_tail];
+
+ if (aup->tx_full) {
+ aup->tx_full = 0;
+ netif_wake_queue(dev);
+ }
}
-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
- /* power on */
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
- BCSR_RESETS_IRDA_MODE_FULL);
-#endif
+ if (aup->tx_tail == aup->tx_head) {
+ if (aup->newspeed) {
+ au1k_irda_set_speed(dev, aup->newspeed);
+ aup->newspeed = 0;
+ } else {
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~IR_TX_ENABLE);
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) | IR_RX_ENABLE);
+ irda_write(aup, IR_RING_PROMPT, 0);
+ }
+ }
+}
- return 0;
+static int au1k_irda_rx(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ volatile struct ring_dest *prxd;
+ struct sk_buff *skb;
+ struct db_dest *pDB;
+ u32 flags, count;
-out3:
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
-out2:
- kfree(aup->rx_buff.head);
-out1:
- printk(KERN_ERR "au1k_init_module failed. Returns %d\n", retval);
- return retval;
+ prxd = aup->rx_ring[aup->rx_head];
+ flags = prxd->flags;
+
+ while (!(flags & AU_OWN)) {
+ pDB = aup->rx_db_inuse[aup->rx_head];
+ count = (prxd->count_1 << 8) | prxd->count_0;
+ if (!(flags & IR_RX_ERROR)) {
+ /* good frame */
+ update_rx_stats(dev, flags, count);
+ skb = alloc_skb(count + 1, GFP_ATOMIC);
+ if (skb == NULL) {
+ dev->stats.rx_dropped++;
+ continue;
+ }
+ skb_reserve(skb, 1);
+ if (aup->speed == 4000000)
+ skb_put(skb, count);
+ else
+ skb_put(skb, count - 2);
+ skb_copy_to_linear_data(skb, (void *)pDB->vaddr,
+ count - 2);
+ skb->dev = dev;
+ skb_reset_mac_header(skb);
+ skb->protocol = htons(ETH_P_IRDA);
+ netif_rx(skb);
+ prxd->count_0 = 0;
+ prxd->count_1 = 0;
+ }
+ prxd->flags |= AU_OWN;
+ aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
+ irda_write(aup, IR_RING_PROMPT, 0);
+
+ /* next descriptor */
+ prxd = aup->rx_ring[aup->rx_head];
+ flags = prxd->flags;
+
+ }
+ return 0;
}
+static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct au1k_private *aup = netdev_priv(dev);
+
+ irda_write(aup, IR_INT_CLEAR, 0); /* ack irda interrupts */
+
+ au1k_irda_rx(dev);
+ au1k_tx_ack(dev);
+
+ return IRQ_HANDLED;
+}
static int au1k_init(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
+ u32 enable, ring_address;
int i;
- u32 control;
- u32 ring_address;
- /* bring the device out of reset */
- control = 0xe; /* coherent, clock enable, one half system clock */
-
+ enable = IR_HC | IR_CE | IR_C;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
- control |= 1;
+ enable |= IR_BE;
#endif
aup->tx_head = 0;
aup->tx_tail = 0;
aup->rx_head = 0;
- for (i=0; i<NUM_IR_DESC; i++) {
+ for (i = 0; i < NUM_IR_DESC; i++)
aup->rx_ring[i]->flags = AU_OWN;
- }
- writel(control, IR_INTERFACE_CONFIG);
- au_sync_delay(10);
+ irda_write(aup, IR_ENABLE, enable);
+ msleep(20);
- writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
- au_sync_delay(1);
+ /* disable PHY */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
+ msleep(20);
- writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN);
+ irda_write(aup, IR_MAX_PKT_LEN, MAX_BUF_SIZE);
ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
- writel(ring_address >> 26, IR_RING_BASE_ADDR_H);
- writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L);
+ irda_write(aup, IR_RING_BASE_ADDR_H, ring_address >> 26);
+ irda_write(aup, IR_RING_BASE_ADDR_L, (ring_address >> 10) & 0xffff);
- writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);
+ irda_write(aup, IR_RING_SIZE,
+ (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12));
- writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
- writel(0, IR_RING_ADDR_CMPR);
+ irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN);
+ irda_write(aup, IR_RING_ADDR_CMPR, 0);
au1k_irda_set_speed(dev, 9600);
return 0;
@@ -340,25 +555,28 @@ static int au1k_init(struct net_device *dev)
static int au1k_irda_start(struct net_device *dev)
{
- int retval;
- char hwname[32];
struct au1k_private *aup = netdev_priv(dev);
+ char hwname[32];
+ int retval;
- if ((retval = au1k_init(dev))) {
+ retval = au1k_init(dev);
+ if (retval) {
printk(KERN_ERR "%s: error in au1k_init\n", dev->name);
return retval;
}
- if ((retval = request_irq(AU1000_IRDA_TX_INT, au1k_irda_interrupt,
- 0, dev->name, dev))) {
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
+ retval = request_irq(aup->irq_tx, &au1k_irda_interrupt, 0,
+ dev->name, dev);
+ if (retval) {
+ printk(KERN_ERR "%s: unable to get IRQ %d\n",
dev->name, dev->irq);
return retval;
}
- if ((retval = request_irq(AU1000_IRDA_RX_INT, au1k_irda_interrupt,
- 0, dev->name, dev))) {
- free_irq(AU1000_IRDA_TX_INT, dev);
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
+ retval = request_irq(aup->irq_rx, &au1k_irda_interrupt, 0,
+ dev->name, dev);
+ if (retval) {
+ free_irq(aup->irq_tx, dev);
+ printk(KERN_ERR "%s: unable to get IRQ %d\n",
dev->name, dev->irq);
return retval;
}
@@ -368,9 +586,13 @@ static int au1k_irda_start(struct net_device *dev)
aup->irlap = irlap_open(dev, &aup->qos, hwname);
netif_start_queue(dev);
- writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */
+ /* int enable */
+ irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) | IR_IEN);
+
+ /* power up */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);
- aup->timer.expires = RUN_AT((3*HZ));
+ aup->timer.expires = RUN_AT((3 * HZ));
aup->timer.data = (unsigned long)dev;
return 0;
}
@@ -379,11 +601,12 @@ static int au1k_irda_stop(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+
/* disable interrupts */
- writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2);
- writel(0, IR_CONFIG_1);
- writel(0, IR_INTERFACE_CONFIG); /* disable clock */
- au_sync();
+ irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) & ~IR_IEN);
+ irda_write(aup, IR_CONFIG_1, 0);
+ irda_write(aup, IR_ENABLE, 0); /* disable clock */
if (aup->irlap) {
irlap_close(aup->irlap);
@@ -394,83 +617,12 @@ static int au1k_irda_stop(struct net_device *dev)
del_timer(&aup->timer);
/* disable the interrupt */
- free_irq(AU1000_IRDA_TX_INT, dev);
- free_irq(AU1000_IRDA_RX_INT, dev);
- return 0;
-}
-
-static void __exit au1k_irda_exit(void)
-{
- struct net_device *dev = ir_devs[0];
- struct au1k_private *aup = netdev_priv(dev);
+ free_irq(aup->irq_tx, dev);
+ free_irq(aup->irq_rx, dev);
- unregister_netdev(dev);
-
- dma_free((void *)aup->db[0].vaddr,
- MAX_BUF_SIZE * 2*NUM_IR_DESC);
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
- kfree(aup->rx_buff.head);
- free_netdev(dev);
-}
-
-
-static inline void
-update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &aup->stats;
-
- ps->tx_packets++;
- ps->tx_bytes += pkt_len;
-
- if (status & IR_TX_ERROR) {
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- }
-}
-
-
-static void au1k_tx_ack(struct net_device *dev)
-{
- struct au1k_private *aup = netdev_priv(dev);
- volatile ring_dest_t *ptxd;
-
- ptxd = aup->tx_ring[aup->tx_tail];
- while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
- update_tx_stats(dev, ptxd->flags,
- ptxd->count_1<<8 | ptxd->count_0);
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- au_sync();
-
- aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
- ptxd = aup->tx_ring[aup->tx_tail];
-
- if (aup->tx_full) {
- aup->tx_full = 0;
- netif_wake_queue(dev);
- }
- }
-
- if (aup->tx_tail == aup->tx_head) {
- if (aup->newspeed) {
- au1k_irda_set_speed(dev, aup->newspeed);
- aup->newspeed = 0;
- }
- else {
- writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE,
- IR_CONFIG_1);
- au_sync();
- writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE,
- IR_CONFIG_1);
- writel(0, IR_RING_PROMPT);
- au_sync();
- }
- }
+ return 0;
}
-
/*
* Au1000 transmit routine.
*/
@@ -478,15 +630,12 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
int speed = irda_get_next_speed(skb);
- volatile ring_dest_t *ptxd;
- u32 len;
-
- u32 flags;
- db_dest_t *pDB;
+ volatile struct ring_dest *ptxd;
+ struct db_dest *pDB;
+ u32 len, flags;
- if (speed != aup->speed && speed != -1) {
+ if (speed != aup->speed && speed != -1)
aup->newspeed = speed;
- }
if ((skb->len == 0) && (aup->newspeed)) {
if (aup->tx_tail == aup->tx_head) {
@@ -504,138 +653,47 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
printk(KERN_DEBUG "%s: tx_full\n", dev->name);
netif_stop_queue(dev);
aup->tx_full = 1;
- return NETDEV_TX_BUSY;
- }
- else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
+ return 1;
+ } else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
printk(KERN_DEBUG "%s: tx_full\n", dev->name);
netif_stop_queue(dev);
aup->tx_full = 1;
- return NETDEV_TX_BUSY;
+ return 1;
}
pDB = aup->tx_db_inuse[aup->tx_head];
#if 0
- if (read_ir_reg(IR_RX_BYTE_CNT) != 0) {
- printk("tx warning: rx byte cnt %x\n",
- read_ir_reg(IR_RX_BYTE_CNT));
+ if (irda_read(aup, IR_RX_BYTE_CNT) != 0) {
+ printk(KERN_DEBUG "tx warning: rx byte cnt %x\n",
+ irda_read(aup, IR_RX_BYTE_CNT));
}
#endif
-
+
if (aup->speed == 4000000) {
/* FIR */
- skb_copy_from_linear_data(skb, pDB->vaddr, skb->len);
+ skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
ptxd->count_0 = skb->len & 0xff;
ptxd->count_1 = (skb->len >> 8) & 0xff;
-
- }
- else {
+ } else {
/* SIR */
len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE);
ptxd->count_0 = len & 0xff;
ptxd->count_1 = (len >> 8) & 0xff;
ptxd->flags |= IR_DIS_CRC;
- au_writel(au_readl(0xae00000c) & ~(1<<13), 0xae00000c);
}
ptxd->flags |= AU_OWN;
- au_sync();
+ wmb();
- writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1);
- writel(0, IR_RING_PROMPT);
- au_sync();
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) | IR_TX_ENABLE);
+ irda_write(aup, IR_RING_PROMPT, 0);
dev_kfree_skb(skb);
aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1);
return NETDEV_TX_OK;
}
-
-static inline void
-update_rx_stats(struct net_device *dev, u32 status, u32 count)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &aup->stats;
-
- ps->rx_packets++;
-
- if (status & IR_RX_ERROR) {
- ps->rx_errors++;
- if (status & (IR_PHY_ERROR|IR_FIFO_OVER))
- ps->rx_missed_errors++;
- if (status & IR_MAX_LEN)
- ps->rx_length_errors++;
- if (status & IR_CRC_ERROR)
- ps->rx_crc_errors++;
- }
- else
- ps->rx_bytes += count;
-}
-
-/*
- * Au1000 receive routine.
- */
-static int au1k_irda_rx(struct net_device *dev)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct sk_buff *skb;
- volatile ring_dest_t *prxd;
- u32 flags, count;
- db_dest_t *pDB;
-
- prxd = aup->rx_ring[aup->rx_head];
- flags = prxd->flags;
-
- while (!(flags & AU_OWN)) {
- pDB = aup->rx_db_inuse[aup->rx_head];
- count = prxd->count_1<<8 | prxd->count_0;
- if (!(flags & IR_RX_ERROR)) {
- /* good frame */
- update_rx_stats(dev, flags, count);
- skb=alloc_skb(count+1,GFP_ATOMIC);
- if (skb == NULL) {
- aup->netdev->stats.rx_dropped++;
- continue;
- }
- skb_reserve(skb, 1);
- if (aup->speed == 4000000)
- skb_put(skb, count);
- else
- skb_put(skb, count-2);
- skb_copy_to_linear_data(skb, pDB->vaddr, count - 2);
- skb->dev = dev;
- skb_reset_mac_header(skb);
- skb->protocol = htons(ETH_P_IRDA);
- netif_rx(skb);
- prxd->count_0 = 0;
- prxd->count_1 = 0;
- }
- prxd->flags |= AU_OWN;
- aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
- writel(0, IR_RING_PROMPT);
- au_sync();
-
- /* next descriptor */
- prxd = aup->rx_ring[aup->rx_head];
- flags = prxd->flags;
-
- }
- return 0;
-}
-
-
-static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
-{
- struct net_device *dev = dev_id;
-
- writel(0, IR_INT_CLEAR); /* ack irda interrupts */
-
- au1k_irda_rx(dev);
- au1k_tx_ack(dev);
-
- return IRQ_HANDLED;
-}
-
-
/*
* The Tx ring has been full longer than the watchdog timeout
* value. The transmitter must be hung?
@@ -653,142 +711,7 @@ static void au1k_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
-
-/*
- * Set the IrDA communications speed.
- */
-static int
-au1k_irda_set_speed(struct net_device *dev, int speed)
-{
- unsigned long flags;
- struct au1k_private *aup = netdev_priv(dev);
- u32 control;
- int ret = 0, timeout = 10, i;
- volatile ring_dest_t *ptxd;
-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
- unsigned long irda_resets;
-#endif
-
- if (speed == aup->speed)
- return ret;
-
- spin_lock_irqsave(&ir_lock, flags);
-
- /* disable PHY first */
- writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE);
-
- /* disable RX/TX */
- writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE),
- IR_CONFIG_1);
- au_sync_delay(1);
- while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) {
- mdelay(1);
- if (!timeout--) {
- printk(KERN_ERR "%s: rx/tx disable timeout\n",
- dev->name);
- break;
- }
- }
-
- /* disable DMA */
- writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1);
- au_sync_delay(1);
-
- /*
- * After we disable tx/rx. the index pointers
- * go back to zero.
- */
- aup->tx_head = aup->tx_tail = aup->rx_head = 0;
- for (i=0; i<NUM_IR_DESC; i++) {
- ptxd = aup->tx_ring[i];
- ptxd->flags = 0;
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- }
-
- for (i=0; i<NUM_IR_DESC; i++) {
- ptxd = aup->rx_ring[i];
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- ptxd->flags = AU_OWN;
- }
-
- if (speed == 4000000) {
-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
- bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_FIR_SEL);
-#else /* Pb1000 and Pb1100 */
- writel(1<<13, CPLD_AUX1);
-#endif
- }
- else {
-#if defined(CONFIG_MIPS_DB1000) || defined(CONFIG_MIPS_DB1100)
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_FIR_SEL, 0);
-#else /* Pb1000 and Pb1100 */
- writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
-#endif
- }
-
- switch (speed) {
- case 9600:
- writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 19200:
- writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 38400:
- writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 57600:
- writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 115200:
- writel(12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 4000000:
- writel(0xF, IR_WRITE_PHY_CONFIG);
- writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1);
- break;
- default:
- printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
- ret = -EINVAL;
- break;
- }
-
- aup->speed = speed;
- writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE);
- au_sync();
-
- control = read_ir_reg(IR_ENABLE);
- writel(0, IR_RING_PROMPT);
- au_sync();
-
- if (control & (1<<14)) {
- printk(KERN_ERR "%s: configuration error\n", dev->name);
- }
- else {
- if (control & (1<<11))
- printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
- if (control & (1<<12))
- printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
- if (control & (1<<13))
- printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
- if (control & (1<<10))
- printk(KERN_DEBUG "%s TX enabled\n", dev->name);
- if (control & (1<<9))
- printk(KERN_DEBUG "%s RX enabled\n", dev->name);
- }
-
- spin_unlock_irqrestore(&ir_lock, flags);
- return ret;
-}
-
-static int
-au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
+static int au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
{
struct if_irda_req *rq = (struct if_irda_req *)ifreq;
struct au1k_private *aup = netdev_priv(dev);
@@ -829,8 +752,218 @@ au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
return ret;
}
+static const struct net_device_ops au1k_irda_netdev_ops = {
+ .ndo_open = au1k_irda_start,
+ .ndo_stop = au1k_irda_stop,
+ .ndo_start_xmit = au1k_irda_hard_xmit,
+ .ndo_tx_timeout = au1k_tx_timeout,
+ .ndo_do_ioctl = au1k_irda_ioctl,
+};
+
+static int __devinit au1k_irda_net_init(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ struct db_dest *pDB, *pDBfree;
+ int i, err, retval = 0;
+ dma_addr_t temp;
+
+ err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
+ if (err)
+ goto out1;
+
+ dev->netdev_ops = &au1k_irda_netdev_ops;
+
+ irda_init_max_qos_capabilies(&aup->qos);
+
+ /* The only value we must override it the baudrate */
+ aup->qos.baud_rate.bits = IR_9600 | IR_19200 | IR_38400 |
+ IR_57600 | IR_115200 | IR_576000 | (IR_4000000 << 8);
+
+ aup->qos.min_turn_time.bits = qos_mtt_bits;
+ irda_qos_bits_to_value(&aup->qos);
+
+ retval = -ENOMEM;
+
+ /* Tx ring follows rx ring + 512 bytes */
+ /* we need a 1k aligned buffer */
+ aup->rx_ring[0] = (struct ring_dest *)
+ dma_alloc(2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)),
+ &temp);
+ if (!aup->rx_ring[0])
+ goto out2;
+
+ /* allocate the data buffers */
+ aup->db[0].vaddr =
+ (void *)dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp);
+ if (!aup->db[0].vaddr)
+ goto out3;
+
+ setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);
+
+ pDBfree = NULL;
+ pDB = aup->db;
+ for (i = 0; i < (2 * NUM_IR_DESC); i++) {
+ pDB->pnext = pDBfree;
+ pDBfree = pDB;
+ pDB->vaddr =
+ (u32 *)((unsigned)aup->db[0].vaddr + (MAX_BUF_SIZE * i));
+ pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+ pDB++;
+ }
+ aup->pDBfree = pDBfree;
+
+ /* attach a data buffer to each descriptor */
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB)
+ goto out3;
+ aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
+ aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff);
+ aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff);
+ aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff);
+ aup->rx_db_inuse[i] = pDB;
+ }
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB)
+ goto out3;
+ aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
+ aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff);
+ aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff);
+ aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff);
+ aup->tx_ring[i]->count_0 = 0;
+ aup->tx_ring[i]->count_1 = 0;
+ aup->tx_ring[i]->flags = 0;
+ aup->tx_db_inuse[i] = pDB;
+ }
+
+ return 0;
+
+out3:
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+out2:
+ kfree(aup->rx_buff.head);
+out1:
+ printk(KERN_ERR "au1k_irda_net_init() failed. Returns %d\n", retval);
+ return retval;
+}
+
+static int __devinit au1k_irda_probe(struct platform_device *pdev)
+{
+ struct au1k_private *aup;
+ struct net_device *dev;
+ struct resource *r;
+ int err;
+
+ dev = alloc_irdadev(sizeof(struct au1k_private));
+ if (!dev)
+ return -ENOMEM;
+
+ aup = netdev_priv(dev);
+
+ aup->platdata = pdev->dev.platform_data;
+
+ err = -EINVAL;
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!r)
+ goto out;
+
+ aup->irq_tx = r->start;
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+ if (!r)
+ goto out;
+
+ aup->irq_rx = r->start;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ goto out;
+
+ err = -EBUSY;
+ aup->ioarea = request_mem_region(r->start, r->end - r->start + 1,
+ pdev->name);
+ if (!aup->ioarea)
+ goto out;
+
+ aup->iobase = ioremap_nocache(r->start, r->end - r->start + 1);
+ if (!aup->iobase)
+ goto out2;
+
+ dev->irq = aup->irq_rx;
+
+ err = au1k_irda_net_init(dev);
+ if (err)
+ goto out3;
+ err = register_netdev(dev);
+ if (err)
+ goto out4;
+
+ platform_set_drvdata(pdev, dev);
+
+ printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
+ return 0;
+
+out4:
+ dma_free((void *)aup->db[0].vaddr,
+ MAX_BUF_SIZE * 2 * NUM_IR_DESC);
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+ kfree(aup->rx_buff.head);
+out3:
+ iounmap(aup->iobase);
+out2:
+ release_resource(aup->ioarea);
+ kfree(aup->ioarea);
+out:
+ free_netdev(dev);
+ return err;
+}
+
+static int __devexit au1k_irda_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct au1k_private *aup = netdev_priv(dev);
+
+ unregister_netdev(dev);
+
+ dma_free((void *)aup->db[0].vaddr,
+ MAX_BUF_SIZE * 2 * NUM_IR_DESC);
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+ kfree(aup->rx_buff.head);
+
+ iounmap(aup->iobase);
+ release_resource(aup->ioarea);
+ kfree(aup->ioarea);
+
+ free_netdev(dev);
+
+ return 0;
+}
+
+static struct platform_driver au1k_irda_driver = {
+ .driver = {
+ .name = "au1000-irda",
+ .owner = THIS_MODULE,
+ },
+ .probe = au1k_irda_probe,
+ .remove = __devexit_p(au1k_irda_remove),
+};
+
+static int __init au1k_irda_load(void)
+{
+ return platform_driver_register(&au1k_irda_driver);
+}
+
+static void __exit au1k_irda_unload(void)
+{
+ return platform_driver_unregister(&au1k_irda_driver);
+}
+
MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
MODULE_DESCRIPTION("Au1000 IrDA Device Driver");
-module_init(au1k_irda_init);
-module_exit(au1k_irda_exit);
+module_init(au1k_irda_load);
+module_exit(au1k_irda_unload);
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 72c33fbe451d..66d96f14c274 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -14,7 +14,7 @@
static struct of_bus *of_match_bus(struct device_node *np);
static int __of_address_to_resource(struct device_node *dev,
const __be32 *addrp, u64 size, unsigned int flags,
- struct resource *r);
+ const char *name, struct resource *r);
/* Debug utility */
#ifdef DEBUG
@@ -215,7 +215,7 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
addrp = of_get_pci_address(dev, bar, &size, &flags);
if (addrp == NULL)
return -EINVAL;
- return __of_address_to_resource(dev, addrp, size, flags, r);
+ return __of_address_to_resource(dev, addrp, size, flags, NULL, r);
}
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
#endif /* CONFIG_PCI */
@@ -529,7 +529,7 @@ EXPORT_SYMBOL(of_get_address);
static int __of_address_to_resource(struct device_node *dev,
const __be32 *addrp, u64 size, unsigned int flags,
- struct resource *r)
+ const char *name, struct resource *r)
{
u64 taddr;
@@ -551,7 +551,8 @@ static int __of_address_to_resource(struct device_node *dev,
r->end = taddr + size - 1;
}
r->flags = flags;
- r->name = dev->full_name;
+ r->name = name ? name : dev->full_name;
+
return 0;
}
@@ -569,11 +570,16 @@ int of_address_to_resource(struct device_node *dev, int index,
const __be32 *addrp;
u64 size;
unsigned int flags;
+ const char *name = NULL;
addrp = of_get_address(dev, index, &size, &flags);
if (addrp == NULL)
return -EINVAL;
- return __of_address_to_resource(dev, addrp, size, flags, r);
+
+ /* Get optional "reg-names" property to add a name to a resource */
+ of_property_read_string_index(dev, "reg-names", index, &name);
+
+ return __of_address_to_resource(dev, addrp, size, flags, name, r);
}
EXPORT_SYMBOL_GPL(of_address_to_resource);
diff --git a/drivers/of/irq.c b/drivers/of/irq.c
index 0f0cfa3bca30..9cf00602f566 100644
--- a/drivers/of/irq.c
+++ b/drivers/of/irq.c
@@ -341,9 +341,18 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
/* Only dereference the resource if both the
* resource and the irq are valid. */
if (r && irq) {
+ const char *name = NULL;
+
+ /*
+ * Get optional "interrupts-names" property to add a name
+ * to the resource.
+ */
+ of_property_read_string_index(dev, "interrupt-names", index,
+ &name);
+
r->start = r->end = irq;
r->flags = IORESOURCE_IRQ;
- r->name = dev->full_name;
+ r->name = name ? name : dev->full_name;
}
return irq;
diff --git a/drivers/parport/parport_ip32.c b/drivers/parport/parport_ip32.c
index 0dc34f12f92e..d4716273651e 100644
--- a/drivers/parport/parport_ip32.c
+++ b/drivers/parport/parport_ip32.c
@@ -135,7 +135,7 @@
#define PARPORT_IP32_ENABLE_EPP (1U << 3)
#define PARPORT_IP32_ENABLE_ECP (1U << 4)
static unsigned int features = ~0U;
-static int verbose_probing = DEFAULT_VERBOSE_PROBING;
+static bool verbose_probing = DEFAULT_VERBOSE_PROBING;
/* We do not support more than one port. */
static struct parport *this_port = NULL;
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 095f29e13734..2a47e82821da 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -44,7 +44,7 @@
#define METHOD_NAME__SUN "_SUN"
#define METHOD_NAME_OSHP "OSHP"
-static int debug_acpi;
+static bool debug_acpi;
static acpi_status
decode_type0_hpx_record(union acpi_object *record, struct hotplug_params *hpx)
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c
index efa9f2de51c1..aa41631e9e02 100644
--- a/drivers/pci/hotplug/acpiphp_core.c
+++ b/drivers/pci/hotplug/acpiphp_core.c
@@ -47,7 +47,7 @@
/* name size which is used for entries in pcihpfs */
#define SLOT_NAME_SIZE 21 /* {_SUN} */
-static int debug;
+static bool debug;
int acpiphp_debug;
/* local variables */
diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c
index e525263210ee..c35e8ad6db01 100644
--- a/drivers/pci/hotplug/acpiphp_ibm.c
+++ b/drivers/pci/hotplug/acpiphp_ibm.c
@@ -43,7 +43,7 @@
#define DRIVER_AUTHOR "Irene Zubarev <zubarev@us.ibm.com>, Vernon Mauery <vernux@us.ibm.com>"
#define DRIVER_DESC "ACPI Hot Plug PCI Controller Driver IBM extension"
-static int debug;
+static bool debug;
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c
index 41f6a8d79c81..6bf8d2ab164f 100644
--- a/drivers/pci/hotplug/cpcihp_zt5550.c
+++ b/drivers/pci/hotplug/cpcihp_zt5550.c
@@ -57,8 +57,8 @@
#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
/* local variables */
-static int debug;
-static int poll;
+static bool debug;
+static bool poll;
static struct cpci_hp_controller_ops zt5550_hpc_ops;
static struct cpci_hp_controller zt5550_hpc;
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c
index f1ce99cceac6..187a199da93c 100644
--- a/drivers/pci/hotplug/cpqphp_core.c
+++ b/drivers/pci/hotplug/cpqphp_core.c
@@ -57,8 +57,8 @@ struct irq_routing_table *cpqhp_routing_table;
static void __iomem *smbios_table;
static void __iomem *smbios_start;
static void __iomem *cpqhp_rom_start;
-static int power_mode;
-static int debug;
+static bool power_mode;
+static bool debug;
static int initialized;
#define DRIVER_VERSION "0.9.8"
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index d934dd4fa873..5506e0e8fbc0 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -49,7 +49,7 @@
int ibmphp_debug;
-static int debug;
+static bool debug;
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC (debug, "Debugging mode enabled or not");
MODULE_LICENSE ("GPL");
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c
index 6d2eea93298f..202f4a969eb5 100644
--- a/drivers/pci/hotplug/pci_hotplug_core.c
+++ b/drivers/pci/hotplug/pci_hotplug_core.c
@@ -51,7 +51,7 @@
/* local variables */
-static int debug;
+static bool debug;
#define DRIVER_VERSION "0.5"
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Scott Murray <scottm@somanetworks.com>"
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 9a33fdde2d16..4b7cce1de6ec 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -40,10 +40,10 @@
#define MY_NAME "pciehp"
-extern int pciehp_poll_mode;
+extern bool pciehp_poll_mode;
extern int pciehp_poll_time;
-extern int pciehp_debug;
-extern int pciehp_force;
+extern bool pciehp_debug;
+extern bool pciehp_force;
extern struct workqueue_struct *pciehp_wq;
#define dbg(format, arg...) \
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index b8c99d35ac97..365c6b96c642 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -38,10 +38,10 @@
#include <linux/time.h>
/* Global variables */
-int pciehp_debug;
-int pciehp_poll_mode;
+bool pciehp_debug;
+bool pciehp_poll_mode;
int pciehp_poll_time;
-int pciehp_force;
+bool pciehp_force;
struct workqueue_struct *pciehp_wq;
#define DRIVER_VERSION "0.4"
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c
index 5175d9b26f0b..b20ceaaa31f4 100644
--- a/drivers/pci/hotplug/pcihp_skeleton.c
+++ b/drivers/pci/hotplug/pcihp_skeleton.c
@@ -59,7 +59,7 @@ static LIST_HEAD(slot_list);
#define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
/* local variables */
-static int debug;
+static bool debug;
static int num_slots;
#define DRIVER_VERSION "0.3"
diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h
index 419919a87b0f..df5677440a08 100644
--- a/drivers/pci/hotplug/rpaphp.h
+++ b/drivers/pci/hotplug/rpaphp.h
@@ -46,7 +46,7 @@
#define PRESENT 1 /* Card in slot */
#define MY_NAME "rpaphp"
-extern int rpaphp_debug;
+extern bool rpaphp_debug;
#define dbg(format, arg...) \
do { \
if (rpaphp_debug) \
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c
index 758adb5f47fd..127d6e600185 100644
--- a/drivers/pci/hotplug/rpaphp_core.c
+++ b/drivers/pci/hotplug/rpaphp_core.c
@@ -37,7 +37,7 @@
/* and pci_do_scan_bus */
#include "rpaphp.h"
-int rpaphp_debug;
+bool rpaphp_debug;
LIST_HEAD(rpaphp_slot_head);
#define DRIVER_VERSION "0.1"
diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h
index e0c90e643b5f..ca64932e658b 100644
--- a/drivers/pci/hotplug/shpchp.h
+++ b/drivers/pci/hotplug/shpchp.h
@@ -43,9 +43,9 @@
#define MY_NAME THIS_MODULE->name
#endif
-extern int shpchp_poll_mode;
+extern bool shpchp_poll_mode;
extern int shpchp_poll_time;
-extern int shpchp_debug;
+extern bool shpchp_debug;
extern struct workqueue_struct *shpchp_wq;
extern struct workqueue_struct *shpchp_ordered_wq;
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c
index dd7e0c51a33e..7414fd9ad1d2 100644
--- a/drivers/pci/hotplug/shpchp_core.c
+++ b/drivers/pci/hotplug/shpchp_core.c
@@ -36,8 +36,8 @@
#include "shpchp.h"
/* Global variables */
-int shpchp_debug;
-int shpchp_poll_mode;
+bool shpchp_debug;
+bool shpchp_poll_mode;
int shpchp_poll_time;
struct workqueue_struct *shpchp_wq;
struct workqueue_struct *shpchp_ordered_wq;
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 106be0d08f81..a3cd8cad532a 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -432,7 +432,7 @@ pci_read_config(struct file *filp, struct kobject *kobj,
u8 *data = (u8*) buf;
/* Several chips lock up trying to read undefined config space */
- if (security_capable(&init_user_ns, filp->f_cred, CAP_SYS_ADMIN) == 0) {
+ if (security_capable(filp->f_cred, &init_user_ns, CAP_SYS_ADMIN) == 0) {
size = dev->cfg_size;
} else if (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS) {
size = 128;
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 95489cd9a555..52229863e9fe 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -28,7 +28,7 @@
#include "aerdrv.h"
/* Override the existing corrected and uncorrected error masks */
-static int aer_mask_override;
+static bool aer_mask_override;
module_param(aer_mask_override, bool, 0);
struct aer_error_inj {
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index 9674e9f30d49..0ca053538146 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -27,8 +27,8 @@
#include <linux/kfifo.h>
#include "aerdrv.h"
-static int forceload;
-static int nosourceid;
+static bool forceload;
+static bool nosourceid;
module_param(forceload, bool, 0);
module_param(nosourceid, bool, 0);
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index 6e318ce41136..f9e3fb3a285b 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -155,18 +155,14 @@ config PCMCIA_M8XX
This driver is also available as a module called m8xx_pcmcia.
-config PCMCIA_AU1X00
- tristate "Au1x00 pcmcia support"
- depends on MIPS_ALCHEMY && PCMCIA
-
config PCMCIA_ALCHEMY_DEVBOARD
tristate "Alchemy Db/Pb1xxx PCMCIA socket services"
depends on MIPS_ALCHEMY && PCMCIA
select 64BIT_PHYS_ADDR
help
Enable this driver of you want PCMCIA support on your Alchemy
- Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200 board.
- NOT suitable for the PB1000!
+ Db1000, Db/Pb1100, Db/Pb1500, Db/Pb1550, Db/Pb1200, DB1300
+ board. NOT suitable for the PB1000!
This driver is also available as a module called db1xxx_ss.ko
diff --git a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
index 29935ea921df..ec543a4ff2e4 100644
--- a/drivers/pcmcia/Makefile
+++ b/drivers/pcmcia/Makefile
@@ -29,7 +29,6 @@ obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
-obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
obj-$(CONFIG_PCMCIA_BCM63XX) += bcm63xx_pcmcia.o
obj-$(CONFIG_PCMCIA_VRC4171) += vrc4171_card.o
obj-$(CONFIG_PCMCIA_VRC4173) += vrc4173_cardu.o
@@ -39,9 +38,6 @@ obj-$(CONFIG_AT91_CF) += at91_cf.o
obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
obj-$(CONFIG_PCMCIA_ALCHEMY_DEVBOARD) += db1xxx_ss.o
-au1x00_ss-y += au1000_generic.o
-au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
-
sa1111_cs-y += sa1111_generic.o
sa1111_cs-$(CONFIG_ASSABET_NEPONSET) += sa1100_neponset.o
sa1111_cs-$(CONFIG_SA1100_BADGE4) += sa1100_badge4.o
diff --git a/drivers/pcmcia/au1000_generic.c b/drivers/pcmcia/au1000_generic.c
deleted file mode 100644
index 95dd7c62741f..000000000000
--- a/drivers/pcmcia/au1000_generic.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- *
- * Alchemy Semi Au1000 pcmcia driver
- *
- * Copyright 2001-2003 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * ppopov@embeddedalley.com or source@mvista.com
- *
- * Copyright 2004 Pete Popov, Embedded Alley Solutions, Inc.
- * Updated the driver to 2.6. Followed the sa11xx API and largely
- * copied many of the hardware independent functions.
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * ########################################################################
- *
- *
- */
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/init.h>
-#include <linux/cpufreq.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/notifier.h>
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#include <linux/mutex.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-
-#include <asm/mach-au1x00/au1000.h>
-#include "au1000_generic.h"
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Pete Popov <ppopov@embeddedalley.com>");
-MODULE_DESCRIPTION("Linux PCMCIA Card Services: Au1x00 Socket Controller");
-
-#if 0
-#define debug(x,args...) printk(KERN_DEBUG "%s: " x, __func__ , ##args)
-#else
-#define debug(x,args...)
-#endif
-
-#define MAP_SIZE 0x100000
-extern struct au1000_pcmcia_socket au1000_pcmcia_socket[];
-#define PCMCIA_SOCKET(x) (au1000_pcmcia_socket + (x))
-#define to_au1000_socket(x) container_of(x, struct au1000_pcmcia_socket, socket)
-
-/* Some boards like to support CF cards as IDE root devices, so they
- * grab pcmcia sockets directly.
- */
-u32 *pcmcia_base_vaddrs[2];
-extern const unsigned long mips_io_port_base;
-
-static DEFINE_MUTEX(pcmcia_sockets_lock);
-
-static int (*au1x00_pcmcia_hw_init[])(struct device *dev) = {
- au1x_board_init,
-};
-
-static int
-au1x00_pcmcia_skt_state(struct au1000_pcmcia_socket *skt)
-{
- struct pcmcia_state state;
- unsigned int stat;
-
- memset(&state, 0, sizeof(struct pcmcia_state));
-
- skt->ops->socket_state(skt, &state);
-
- stat = state.detect ? SS_DETECT : 0;
- stat |= state.ready ? SS_READY : 0;
- stat |= state.wrprot ? SS_WRPROT : 0;
- stat |= state.vs_3v ? SS_3VCARD : 0;
- stat |= state.vs_Xv ? SS_XVCARD : 0;
- stat |= skt->cs_state.Vcc ? SS_POWERON : 0;
-
- if (skt->cs_state.flags & SS_IOCARD)
- stat |= state.bvd1 ? SS_STSCHG : 0;
- else {
- if (state.bvd1 == 0)
- stat |= SS_BATDEAD;
- else if (state.bvd2 == 0)
- stat |= SS_BATWARN;
- }
- return stat;
-}
-
-/*
- * au100_pcmcia_config_skt
- *
- * Convert PCMCIA socket state to our socket configure structure.
- */
-static int
-au1x00_pcmcia_config_skt(struct au1000_pcmcia_socket *skt, socket_state_t *state)
-{
- int ret;
-
- ret = skt->ops->configure_socket(skt, state);
- if (ret == 0) {
- skt->cs_state = *state;
- }
-
- if (ret < 0)
- debug("unable to configure socket %d\n", skt->nr);
-
- return ret;
-}
-
-/* au1x00_pcmcia_sock_init()
- *
- * (Re-)Initialise the socket, turning on status interrupts
- * and PCMCIA bus. This must wait for power to stabilise
- * so that the card status signals report correctly.
- *
- * Returns: 0
- */
-static int au1x00_pcmcia_sock_init(struct pcmcia_socket *sock)
-{
- struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
-
- debug("initializing socket %u\n", skt->nr);
-
- skt->ops->socket_init(skt);
- return 0;
-}
-
-/*
- * au1x00_pcmcia_suspend()
- *
- * Remove power on the socket, disable IRQs from the card.
- * Turn off status interrupts, and disable the PCMCIA bus.
- *
- * Returns: 0
- */
-static int au1x00_pcmcia_suspend(struct pcmcia_socket *sock)
-{
- struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
-
- debug("suspending socket %u\n", skt->nr);
-
- skt->ops->socket_suspend(skt);
-
- return 0;
-}
-
-static DEFINE_SPINLOCK(status_lock);
-
-/*
- * au1x00_check_status()
- */
-static void au1x00_check_status(struct au1000_pcmcia_socket *skt)
-{
- unsigned int events;
-
- debug("entering PCMCIA monitoring thread\n");
-
- do {
- unsigned int status;
- unsigned long flags;
-
- status = au1x00_pcmcia_skt_state(skt);
-
- spin_lock_irqsave(&status_lock, flags);
- events = (status ^ skt->status) & skt->cs_state.csc_mask;
- skt->status = status;
- spin_unlock_irqrestore(&status_lock, flags);
-
- debug("events: %s%s%s%s%s%s\n",
- events == 0 ? "<NONE>" : "",
- events & SS_DETECT ? "DETECT " : "",
- events & SS_READY ? "READY " : "",
- events & SS_BATDEAD ? "BATDEAD " : "",
- events & SS_BATWARN ? "BATWARN " : "",
- events & SS_STSCHG ? "STSCHG " : "");
-
- if (events)
- pcmcia_parse_events(&skt->socket, events);
- } while (events);
-}
-
-/*
- * au1x00_pcmcia_poll_event()
- * Let's poll for events in addition to IRQs since IRQ only is unreliable...
- */
-static void au1x00_pcmcia_poll_event(unsigned long dummy)
-{
- struct au1000_pcmcia_socket *skt = (struct au1000_pcmcia_socket *)dummy;
- debug("polling for events\n");
-
- mod_timer(&skt->poll_timer, jiffies + AU1000_PCMCIA_POLL_PERIOD);
-
- au1x00_check_status(skt);
-}
-
-/* au1x00_pcmcia_get_status()
- *
- * From the sa11xx_core.c:
- * Implements the get_status() operation for the in-kernel PCMCIA
- * service (formerly SS_GetStatus in Card Services). Essentially just
- * fills in bits in `status' according to internal driver state or
- * the value of the voltage detect chipselect register.
- *
- * As a debugging note, during card startup, the PCMCIA core issues
- * three set_socket() commands in a row the first with RESET deasserted,
- * the second with RESET asserted, and the last with RESET deasserted
- * again. Following the third set_socket(), a get_status() command will
- * be issued. The kernel is looking for the SS_READY flag (see
- * setup_socket(), reset_socket(), and unreset_socket() in cs.c).
- *
- * Returns: 0
- */
-static int
-au1x00_pcmcia_get_status(struct pcmcia_socket *sock, unsigned int *status)
-{
- struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
-
- skt->status = au1x00_pcmcia_skt_state(skt);
- *status = skt->status;
-
- return 0;
-}
-
-/* au1x00_pcmcia_set_socket()
- * Implements the set_socket() operation for the in-kernel PCMCIA
- * service (formerly SS_SetSocket in Card Services). We more or
- * less punt all of this work and let the kernel handle the details
- * of power configuration, reset, &c. We also record the value of
- * `state' in order to regurgitate it to the PCMCIA core later.
- *
- * Returns: 0
- */
-static int
-au1x00_pcmcia_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
- struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
-
- debug("for sock %u\n", skt->nr);
-
- debug("\tmask: %s%s%s%s%s%s\n\tflags: %s%s%s%s%s%s\n",
- (state->csc_mask==0)?"<NONE>":"",
- (state->csc_mask&SS_DETECT)?"DETECT ":"",
- (state->csc_mask&SS_READY)?"READY ":"",
- (state->csc_mask&SS_BATDEAD)?"BATDEAD ":"",
- (state->csc_mask&SS_BATWARN)?"BATWARN ":"",
- (state->csc_mask&SS_STSCHG)?"STSCHG ":"",
- (state->flags==0)?"<NONE>":"",
- (state->flags&SS_PWR_AUTO)?"PWR_AUTO ":"",
- (state->flags&SS_IOCARD)?"IOCARD ":"",
- (state->flags&SS_RESET)?"RESET ":"",
- (state->flags&SS_SPKR_ENA)?"SPKR_ENA ":"",
- (state->flags&SS_OUTPUT_ENA)?"OUTPUT_ENA ":"");
- debug("\tVcc %d Vpp %d irq %d\n",
- state->Vcc, state->Vpp, state->io_irq);
-
- return au1x00_pcmcia_config_skt(skt, state);
-}
-
-int
-au1x00_pcmcia_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *map)
-{
- struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
- unsigned int speed;
-
- if(map->map>=MAX_IO_WIN){
- debug("map (%d) out of range\n", map->map);
- return -1;
- }
-
- if(map->flags&MAP_ACTIVE){
- speed=(map->speed>0)?map->speed:AU1000_PCMCIA_IO_SPEED;
- skt->spd_io[map->map] = speed;
- }
-
- map->start=(unsigned int)(u32)skt->virt_io;
- map->stop=map->start+MAP_SIZE;
- return 0;
-
-} /* au1x00_pcmcia_set_io_map() */
-
-
-static int
-au1x00_pcmcia_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *map)
-{
- struct au1000_pcmcia_socket *skt = to_au1000_socket(sock);
- unsigned short speed = map->speed;
-
- if(map->map>=MAX_WIN){
- debug("map (%d) out of range\n", map->map);
- return -1;
- }
-
- if (map->flags & MAP_ATTRIB) {
- skt->spd_attr[map->map] = speed;
- skt->spd_mem[map->map] = 0;
- } else {
- skt->spd_attr[map->map] = 0;
- skt->spd_mem[map->map] = speed;
- }
-
- if (map->flags & MAP_ATTRIB) {
- map->static_start = skt->phys_attr + map->card_start;
- }
- else {
- map->static_start = skt->phys_mem + map->card_start;
- }
-
- debug("set_mem_map %d start %08lx card_start %08x\n",
- map->map, map->static_start, map->card_start);
- return 0;
-
-} /* au1x00_pcmcia_set_mem_map() */
-
-static struct pccard_operations au1x00_pcmcia_operations = {
- .init = au1x00_pcmcia_sock_init,
- .suspend = au1x00_pcmcia_suspend,
- .get_status = au1x00_pcmcia_get_status,
- .set_socket = au1x00_pcmcia_set_socket,
- .set_io_map = au1x00_pcmcia_set_io_map,
- .set_mem_map = au1x00_pcmcia_set_mem_map,
-};
-
-static const char *skt_names[] = {
- "PCMCIA socket 0",
- "PCMCIA socket 1",
-};
-
-struct skt_dev_info {
- int nskt;
-};
-
-int au1x00_pcmcia_socket_probe(struct device *dev, struct pcmcia_low_level *ops, int first, int nr)
-{
- struct skt_dev_info *sinfo;
- struct au1000_pcmcia_socket *skt;
- int ret, i;
-
- sinfo = kzalloc(sizeof(struct skt_dev_info), GFP_KERNEL);
- if (!sinfo) {
- ret = -ENOMEM;
- goto out;
- }
-
- sinfo->nskt = nr;
-
- /*
- * Initialise the per-socket structure.
- */
- for (i = 0; i < nr; i++) {
- skt = PCMCIA_SOCKET(i);
- memset(skt, 0, sizeof(*skt));
-
- skt->socket.resource_ops = &pccard_static_ops;
- skt->socket.ops = &au1x00_pcmcia_operations;
- skt->socket.owner = ops->owner;
- skt->socket.dev.parent = dev;
-
- init_timer(&skt->poll_timer);
- skt->poll_timer.function = au1x00_pcmcia_poll_event;
- skt->poll_timer.data = (unsigned long)skt;
- skt->poll_timer.expires = jiffies + AU1000_PCMCIA_POLL_PERIOD;
-
- skt->nr = first + i;
- skt->irq = 255;
- skt->dev = dev;
- skt->ops = ops;
-
- skt->res_skt.name = skt_names[skt->nr];
- skt->res_io.name = "io";
- skt->res_io.flags = IORESOURCE_MEM | IORESOURCE_BUSY;
- skt->res_mem.name = "memory";
- skt->res_mem.flags = IORESOURCE_MEM;
- skt->res_attr.name = "attribute";
- skt->res_attr.flags = IORESOURCE_MEM;
-
- /*
- * PCMCIA client drivers use the inb/outb macros to access the
- * IO registers. Since mips_io_port_base is added to the
- * access address of the mips implementation of inb/outb,
- * we need to subtract it here because we want to access the
- * I/O or MEM address directly, without going through this
- * "mips_io_port_base" mechanism.
- */
- if (i == 0) {
- skt->virt_io = (void *)
- (ioremap((phys_t)AU1X_SOCK0_IO, 0x1000) -
- (u32)mips_io_port_base);
- skt->phys_attr = AU1X_SOCK0_PHYS_ATTR;
- skt->phys_mem = AU1X_SOCK0_PHYS_MEM;
- }
- else {
- skt->virt_io = (void *)
- (ioremap((phys_t)AU1X_SOCK1_IO, 0x1000) -
- (u32)mips_io_port_base);
- skt->phys_attr = AU1X_SOCK1_PHYS_ATTR;
- skt->phys_mem = AU1X_SOCK1_PHYS_MEM;
- }
- pcmcia_base_vaddrs[i] = (u32 *)skt->virt_io;
- ret = ops->hw_init(skt);
-
- skt->socket.features = SS_CAP_STATIC_MAP|SS_CAP_PCCARD;
- skt->socket.irq_mask = 0;
- skt->socket.map_size = MAP_SIZE;
- skt->socket.pci_irq = skt->irq;
- skt->socket.io_offset = (unsigned long)skt->virt_io;
-
- skt->status = au1x00_pcmcia_skt_state(skt);
-
- ret = pcmcia_register_socket(&skt->socket);
- if (ret)
- goto out_err;
-
- WARN_ON(skt->socket.sock != i);
-
- add_timer(&skt->poll_timer);
- }
-
- dev_set_drvdata(dev, sinfo);
- return 0;
-
-
-out_err:
- ops->hw_shutdown(skt);
- while (i-- > 0) {
- skt = PCMCIA_SOCKET(i);
-
- del_timer_sync(&skt->poll_timer);
- pcmcia_unregister_socket(&skt->socket);
- if (i == 0) {
- iounmap(skt->virt_io + (u32)mips_io_port_base);
- skt->virt_io = NULL;
- }
-#ifndef CONFIG_MIPS_XXS1500
- else {
- iounmap(skt->virt_io + (u32)mips_io_port_base);
- skt->virt_io = NULL;
- }
-#endif
- ops->hw_shutdown(skt);
-
- }
- kfree(sinfo);
-out:
- return ret;
-}
-
-int au1x00_drv_pcmcia_remove(struct platform_device *dev)
-{
- struct skt_dev_info *sinfo = platform_get_drvdata(dev);
- int i;
-
- mutex_lock(&pcmcia_sockets_lock);
- platform_set_drvdata(dev, NULL);
-
- for (i = 0; i < sinfo->nskt; i++) {
- struct au1000_pcmcia_socket *skt = PCMCIA_SOCKET(i);
-
- del_timer_sync(&skt->poll_timer);
- pcmcia_unregister_socket(&skt->socket);
- skt->ops->hw_shutdown(skt);
- au1x00_pcmcia_config_skt(skt, &dead_socket);
- iounmap(skt->virt_io + (u32)mips_io_port_base);
- skt->virt_io = NULL;
- }
-
- kfree(sinfo);
- mutex_unlock(&pcmcia_sockets_lock);
- return 0;
-}
-
-
-/*
- * PCMCIA "Driver" API
- */
-
-static int au1x00_drv_pcmcia_probe(struct platform_device *dev)
-{
- int i, ret = -ENODEV;
-
- mutex_lock(&pcmcia_sockets_lock);
- for (i=0; i < ARRAY_SIZE(au1x00_pcmcia_hw_init); i++) {
- ret = au1x00_pcmcia_hw_init[i](&dev->dev);
- if (ret == 0)
- break;
- }
- mutex_unlock(&pcmcia_sockets_lock);
- return ret;
-}
-
-static struct platform_driver au1x00_pcmcia_driver = {
- .driver = {
- .name = "au1x00-pcmcia",
- .owner = THIS_MODULE,
- },
- .probe = au1x00_drv_pcmcia_probe,
- .remove = au1x00_drv_pcmcia_remove,
-};
-
-
-/* au1x00_pcmcia_init()
- *
- * This routine performs low-level PCMCIA initialization and then
- * registers this socket driver with Card Services.
- *
- * Returns: 0 on success, -ve error code on failure
- */
-static int __init au1x00_pcmcia_init(void)
-{
- int error = 0;
- error = platform_driver_register(&au1x00_pcmcia_driver);
- return error;
-}
-
-/* au1x00_pcmcia_exit()
- * Invokes the low-level kernel service to free IRQs associated with this
- * socket controller and reset GPIO edge detection.
- */
-static void __exit au1x00_pcmcia_exit(void)
-{
- platform_driver_unregister(&au1x00_pcmcia_driver);
-}
-
-module_init(au1x00_pcmcia_init);
-module_exit(au1x00_pcmcia_exit);
diff --git a/drivers/pcmcia/au1000_generic.h b/drivers/pcmcia/au1000_generic.h
deleted file mode 100644
index 5c36bda2963b..000000000000
--- a/drivers/pcmcia/au1000_generic.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Alchemy Semi Au1000 pcmcia driver include file
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#ifndef __ASM_AU1000_PCMCIA_H
-#define __ASM_AU1000_PCMCIA_H
-
-/* include the world */
-
-#include <pcmcia/ss.h>
-#include <pcmcia/cistpl.h>
-#include "cs_internal.h"
-
-#define AU1000_PCMCIA_POLL_PERIOD (2*HZ)
-#define AU1000_PCMCIA_IO_SPEED (255)
-#define AU1000_PCMCIA_MEM_SPEED (300)
-
-#define AU1X_SOCK0_IO 0xF00000000ULL
-#define AU1X_SOCK0_PHYS_ATTR 0xF40000000ULL
-#define AU1X_SOCK0_PHYS_MEM 0xF80000000ULL
-
-/* pcmcia socket 1 needs external glue logic so the memory map
- * differs from board to board.
- */
-#if defined(CONFIG_MIPS_PB1000)
-#define AU1X_SOCK1_IO 0xF08000000ULL
-#define AU1X_SOCK1_PHYS_ATTR 0xF48000000ULL
-#define AU1X_SOCK1_PHYS_MEM 0xF88000000ULL
-#endif
-
-struct pcmcia_state {
- unsigned detect: 1,
- ready: 1,
- wrprot: 1,
- bvd1: 1,
- bvd2: 1,
- vs_3v: 1,
- vs_Xv: 1;
-};
-
-struct pcmcia_configure {
- unsigned sock: 8,
- vcc: 8,
- vpp: 8,
- output: 1,
- speaker: 1,
- reset: 1;
-};
-
-struct pcmcia_irqs {
- int sock;
- int irq;
- const char *str;
-};
-
-
-struct au1000_pcmcia_socket {
- struct pcmcia_socket socket;
-
- /*
- * Info from low level handler
- */
- struct device *dev;
- unsigned int nr;
- unsigned int irq;
-
- /*
- * Core PCMCIA state
- */
- struct pcmcia_low_level *ops;
-
- unsigned int status;
- socket_state_t cs_state;
-
- unsigned short spd_io[MAX_IO_WIN];
- unsigned short spd_mem[MAX_WIN];
- unsigned short spd_attr[MAX_WIN];
-
- struct resource res_skt;
- struct resource res_io;
- struct resource res_mem;
- struct resource res_attr;
-
- void * virt_io;
- unsigned int phys_io;
- unsigned int phys_attr;
- unsigned int phys_mem;
- unsigned short speed_io, speed_attr, speed_mem;
-
- unsigned int irq_state;
-
- struct timer_list poll_timer;
-};
-
-struct pcmcia_low_level {
- struct module *owner;
-
- int (*hw_init)(struct au1000_pcmcia_socket *);
- void (*hw_shutdown)(struct au1000_pcmcia_socket *);
-
- void (*socket_state)(struct au1000_pcmcia_socket *, struct pcmcia_state *);
- int (*configure_socket)(struct au1000_pcmcia_socket *, struct socket_state_t *);
-
- /*
- * Enable card status IRQs on (re-)initialisation. This can
- * be called at initialisation, power management event, or
- * pcmcia event.
- */
- void (*socket_init)(struct au1000_pcmcia_socket *);
-
- /*
- * Disable card status IRQs and PCMCIA bus on suspend.
- */
- void (*socket_suspend)(struct au1000_pcmcia_socket *);
-};
-
-extern int au1x_board_init(struct device *dev);
-
-#endif /* __ASM_AU1000_PCMCIA_H */
diff --git a/drivers/pcmcia/au1000_pb1x00.c b/drivers/pcmcia/au1000_pb1x00.c
deleted file mode 100644
index b2396647a165..000000000000
--- a/drivers/pcmcia/au1000_pb1x00.c
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- *
- * Alchemy Semi Pb1000 boards specific pcmcia routines.
- *
- * Copyright 2002 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
- *
- * ########################################################################
- *
- * This program is free software; you can distribute it and/or modify it
- * under the terms of the GNU General Public License (Version 2) as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- */
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/ioport.h>
-#include <linux/kernel.h>
-#include <linux/timer.h>
-#include <linux/mm.h>
-#include <linux/proc_fs.h>
-#include <linux/types.h>
-
-#include <pcmcia/ss.h>
-#include <pcmcia/cistpl.h>
-
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-
-#include <asm/au1000.h>
-#include <asm/au1000_pcmcia.h>
-
-#define debug(fmt, arg...) do { } while (0)
-
-#include <asm/pb1000.h>
-#define PCMCIA_IRQ AU1000_GPIO_15
-
-static int pb1x00_pcmcia_init(struct pcmcia_init *init)
-{
- u16 pcr;
- pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
-
- au_writel(0x8000, PB1000_MDR); /* clear pcmcia interrupt */
- au_sync_delay(100);
- au_writel(0x4000, PB1000_MDR); /* enable pcmcia interrupt */
- au_sync();
-
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1);
- au_writel(pcr, PB1000_PCR);
- au_sync_delay(20);
-
- return PCMCIA_NUM_SOCKS;
-}
-
-static int pb1x00_pcmcia_shutdown(void)
-{
- u16 pcr;
- pcr = PCR_SLOT_0_RST | PCR_SLOT_1_RST;
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,0);
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,1);
- au_writel(pcr, PB1000_PCR);
- au_sync_delay(20);
- return 0;
-}
-
-static int
-pb1x00_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
-{
- u32 inserted0, inserted1;
- u16 vs0, vs1;
-
- vs0 = vs1 = (u16)au_readl(PB1000_ACR1);
- inserted0 = !(vs0 & (ACR1_SLOT_0_CD1 | ACR1_SLOT_0_CD2));
- inserted1 = !(vs1 & (ACR1_SLOT_1_CD1 | ACR1_SLOT_1_CD2));
- vs0 = (vs0 >> 4) & 0x3;
- vs1 = (vs1 >> 12) & 0x3;
-
- state->ready = 0;
- state->vs_Xv = 0;
- state->vs_3v = 0;
- state->detect = 0;
-
- if (sock == 0) {
- if (inserted0) {
- switch (vs0) {
- case 0:
- case 2:
- state->vs_3v=1;
- break;
- case 3: /* 5V */
- break;
- default:
- /* return without setting 'detect' */
- printk(KERN_ERR "pb1x00 bad VS (%d)\n",
- vs0);
- return 0;
- }
- state->detect = 1;
- }
- }
- else {
- if (inserted1) {
- switch (vs1) {
- case 0:
- case 2:
- state->vs_3v=1;
- break;
- case 3: /* 5V */
- break;
- default:
- /* return without setting 'detect' */
- printk(KERN_ERR "pb1x00 bad VS (%d)\n",
- vs1);
- return 0;
- }
- state->detect = 1;
- }
- }
-
- if (state->detect) {
- state->ready = 1;
- }
-
- state->bvd1=1;
- state->bvd2=1;
- state->wrprot=0;
- return 1;
-}
-
-
-static int pb1x00_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
-{
-
- if(info->sock > PCMCIA_MAX_SOCK) return -1;
-
- /*
- * Even in the case of the Pb1000, both sockets are connected
- * to the same irq line.
- */
- info->irq = PCMCIA_IRQ;
-
- return 0;
-}
-
-
-static int
-pb1x00_pcmcia_configure_socket(const struct pcmcia_configure *configure)
-{
- u16 pcr;
-
- if(configure->sock > PCMCIA_MAX_SOCK) return -1;
-
- pcr = au_readl(PB1000_PCR);
-
- if (configure->sock == 0) {
- pcr &= ~(PCR_SLOT_0_VCC0 | PCR_SLOT_0_VCC1 |
- PCR_SLOT_0_VPP0 | PCR_SLOT_0_VPP1);
- }
- else {
- pcr &= ~(PCR_SLOT_1_VCC0 | PCR_SLOT_1_VCC1 |
- PCR_SLOT_1_VPP0 | PCR_SLOT_1_VPP1);
- }
-
- pcr &= ~PCR_SLOT_0_RST;
- debug("Vcc %dV Vpp %dV, pcr %x\n",
- configure->vcc, configure->vpp, pcr);
- switch(configure->vcc){
- case 0: /* Vcc 0 */
- switch(configure->vpp) {
- case 0:
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_GND,
- configure->sock);
- break;
- case 12:
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_12V,
- configure->sock);
- break;
- case 50:
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_5V,
- configure->sock);
- break;
- case 33:
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_3V,
- configure->sock);
- break;
- default:
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
- configure->sock);
- printk("%s: bad Vcc/Vpp (%d:%d)\n",
- __func__,
- configure->vcc,
- configure->vpp);
- break;
- }
- break;
- case 50: /* Vcc 5V */
- switch(configure->vpp) {
- case 0:
- pcr |= SET_VCC_VPP(VCC_5V,VPP_GND,
- configure->sock);
- break;
- case 50:
- pcr |= SET_VCC_VPP(VCC_5V,VPP_5V,
- configure->sock);
- break;
- case 12:
- pcr |= SET_VCC_VPP(VCC_5V,VPP_12V,
- configure->sock);
- break;
- case 33:
- pcr |= SET_VCC_VPP(VCC_5V,VPP_3V,
- configure->sock);
- break;
- default:
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
- configure->sock);
- printk("%s: bad Vcc/Vpp (%d:%d)\n",
- __func__,
- configure->vcc,
- configure->vpp);
- break;
- }
- break;
- case 33: /* Vcc 3.3V */
- switch(configure->vpp) {
- case 0:
- pcr |= SET_VCC_VPP(VCC_3V,VPP_GND,
- configure->sock);
- break;
- case 50:
- pcr |= SET_VCC_VPP(VCC_3V,VPP_5V,
- configure->sock);
- break;
- case 12:
- pcr |= SET_VCC_VPP(VCC_3V,VPP_12V,
- configure->sock);
- break;
- case 33:
- pcr |= SET_VCC_VPP(VCC_3V,VPP_3V,
- configure->sock);
- break;
- default:
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,
- configure->sock);
- printk("%s: bad Vcc/Vpp (%d:%d)\n",
- __func__,
- configure->vcc,
- configure->vpp);
- break;
- }
- break;
- default: /* what's this ? */
- pcr |= SET_VCC_VPP(VCC_HIZ,VPP_HIZ,configure->sock);
- printk(KERN_ERR "%s: bad Vcc %d\n",
- __func__, configure->vcc);
- break;
- }
-
- if (configure->sock == 0) {
- pcr &= ~(PCR_SLOT_0_RST);
- if (configure->reset)
- pcr |= PCR_SLOT_0_RST;
- }
- else {
- pcr &= ~(PCR_SLOT_1_RST);
- if (configure->reset)
- pcr |= PCR_SLOT_1_RST;
- }
- au_writel(pcr, PB1000_PCR);
- au_sync_delay(300);
-
- return 0;
-}
-
-
-struct pcmcia_low_level pb1x00_pcmcia_ops = {
- pb1x00_pcmcia_init,
- pb1x00_pcmcia_shutdown,
- pb1x00_pcmcia_socket_state,
- pb1x00_pcmcia_get_irq_info,
- pb1x00_pcmcia_configure_socket
-};
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
index 3e49df6d5e3b..5b7c22784aff 100644
--- a/drivers/pcmcia/db1xxx_ss.c
+++ b/drivers/pcmcia/db1xxx_ss.c
@@ -7,7 +7,7 @@
/* This is a fairly generic PCMCIA socket driver suitable for the
* following Alchemy Development boards:
- * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200.
+ * Db1000, Db/Pb1500, Db/Pb1100, Db/Pb1550, Db/Pb1200, Db1300
*
* The Db1000 is used as a reference: Per-socket card-, carddetect- and
* statuschange IRQs connected to SoC GPIOs, control and status register
@@ -18,6 +18,7 @@
* - Pb1100/Pb1500: single socket only; voltage key bits VS are
* at STATUS[5:4] (instead of STATUS[1:0]).
* - Au1200-based: additional card-eject irqs, irqs not gpios!
+ * - Db1300: Db1200-like, no pwr ctrl, single socket (#1).
*/
#include <linux/delay.h>
@@ -59,11 +60,17 @@ struct db1x_pcmcia_sock {
#define BOARD_TYPE_DEFAULT 0 /* most boards */
#define BOARD_TYPE_DB1200 1 /* IRQs aren't gpios */
#define BOARD_TYPE_PB1100 2 /* VS bits slightly different */
+#define BOARD_TYPE_DB1300 3 /* no power control */
int board_type;
};
#define to_db1x_socket(x) container_of(x, struct db1x_pcmcia_sock, socket)
+static int db1300_card_inserted(struct db1x_pcmcia_sock *sock)
+{
+ return bcsr_read(BCSR_SIGSTAT) & (1 << 8);
+}
+
/* DB/PB1200: check CPLD SIGSTATUS register bit 10/12 */
static int db1200_card_inserted(struct db1x_pcmcia_sock *sock)
{
@@ -84,6 +91,8 @@ static int db1x_card_inserted(struct db1x_pcmcia_sock *sock)
switch (sock->board_type) {
case BOARD_TYPE_DB1200:
return db1200_card_inserted(sock);
+ case BOARD_TYPE_DB1300:
+ return db1300_card_inserted(sock);
default:
return db1000_card_inserted(sock);
}
@@ -160,7 +169,8 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
* ejection handler have been registered and the currently
* active one disabled.
*/
- if (sock->board_type == BOARD_TYPE_DB1200) {
+ if ((sock->board_type == BOARD_TYPE_DB1200) ||
+ (sock->board_type == BOARD_TYPE_DB1300)) {
ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
IRQF_DISABLED, "pcmcia_insert", sock);
if (ret)
@@ -174,7 +184,7 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
}
/* enable the currently silent one */
- if (db1200_card_inserted(sock))
+ if (db1x_card_inserted(sock))
enable_irq(sock->eject_irq);
else
enable_irq(sock->insert_irq);
@@ -270,7 +280,8 @@ static int db1x_pcmcia_configure(struct pcmcia_socket *skt,
}
/* create new voltage code */
- cr_set |= ((v << 2) | p) << (sock->nr * 8);
+ if (sock->board_type != BOARD_TYPE_DB1300)
+ cr_set |= ((v << 2) | p) << (sock->nr * 8);
changed = state->flags ^ sock->old_flags;
@@ -343,6 +354,10 @@ static int db1x_pcmcia_get_status(struct pcmcia_socket *skt,
/* if Vcc is not zero, we have applied power to a card */
status |= GET_VCC(cr, sock->nr) ? SS_POWERON : 0;
+ /* DB1300: power always on, but don't tell when no card present */
+ if ((sock->board_type == BOARD_TYPE_DB1300) && (status & SS_DETECT))
+ status = SS_POWERON | SS_3VCARD | SS_DETECT;
+
/* reset de-asserted? then we're ready */
status |= (GET_RESET(cr, sock->nr)) ? SS_READY : SS_RESET;
@@ -419,6 +434,9 @@ static int __devinit db1x_pcmcia_socket_probe(struct platform_device *pdev)
case BCSR_WHOAMI_PB1200 ... BCSR_WHOAMI_DB1200:
sock->board_type = BOARD_TYPE_DB1200;
break;
+ case BCSR_WHOAMI_DB1300:
+ sock->board_type = BOARD_TYPE_DB1300;
+ break;
default:
printk(KERN_INFO "db1xxx-ss: unknown board %d!\n", bid);
ret = -ENODEV;
diff --git a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
index 9dc565c615bd..849c0c11d2af 100644
--- a/drivers/pcmcia/yenta_socket.c
+++ b/drivers/pcmcia/yenta_socket.c
@@ -24,15 +24,15 @@
#include "yenta_socket.h"
#include "i82365.h"
-static int disable_clkrun;
+static bool disable_clkrun;
module_param(disable_clkrun, bool, 0444);
MODULE_PARM_DESC(disable_clkrun, "If PC card doesn't function properly, please try this option");
-static int isa_probe = 1;
+static bool isa_probe = 1;
module_param(isa_probe, bool, 0444);
MODULE_PARM_DESC(isa_probe, "If set ISA interrupts are probed (default). Set to N to disable probing");
-static int pwr_irqs_off;
+static bool pwr_irqs_off;
module_param(pwr_irqs_off, bool, 0644);
MODULE_PARM_DESC(pwr_irqs_off, "Force IRQs off during power-on of slot. Use only when seeing IRQ storms!");
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c
index 8877b836d27c..d96734478324 100644
--- a/drivers/platform/x86/compal-laptop.c
+++ b/drivers/platform/x86/compal-laptop.c
@@ -189,7 +189,7 @@ struct compal_data{
/* =============== */
/* General globals */
/* =============== */
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c
index 7f88c7923fc6..6ee0b5c90933 100644
--- a/drivers/platform/x86/intel_oaktrail.c
+++ b/drivers/platform/x86/intel_oaktrail.c
@@ -95,7 +95,7 @@
#define OT_EC_BL_CONTROL_ON_DATA 0x1A
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c
index f204643c5052..bb5132128b33 100644
--- a/drivers/platform/x86/msi-laptop.c
+++ b/drivers/platform/x86/msi-laptop.c
@@ -89,7 +89,7 @@ static int msi_laptop_resume(struct platform_device *device);
#define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force, "Force driver load, ignore DMI data");
diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c
index 09e26bfd4643..fd73ea89b857 100644
--- a/drivers/platform/x86/samsung-laptop.c
+++ b/drivers/platform/x86/samsung-laptop.c
@@ -228,12 +228,12 @@ static struct platform_device *sdev;
static struct rfkill *rfk;
static bool has_stepping_quirk;
-static int force;
+static bool force;
module_param(force, bool, 0);
MODULE_PARM_DESC(force,
"Disable the DMI check and forces the driver to be loaded");
-static int debug;
+static bool debug;
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 62533c105da4..ea0c6075b720 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -378,13 +378,13 @@ static unsigned int bright_maxlvl; /* 0 = unknown */
#ifdef CONFIG_THINKPAD_ACPI_DEBUGFACILITIES
static int dbg_wlswemul;
-static int tpacpi_wlsw_emulstate;
+static bool tpacpi_wlsw_emulstate;
static int dbg_bluetoothemul;
-static int tpacpi_bluetooth_emulstate;
+static bool tpacpi_bluetooth_emulstate;
static int dbg_wwanemul;
-static int tpacpi_wwan_emulstate;
+static bool tpacpi_wwan_emulstate;
static int dbg_uwbemul;
-static int tpacpi_uwb_emulstate;
+static bool tpacpi_uwb_emulstate;
#endif
@@ -6444,7 +6444,7 @@ static struct ibm_struct brightness_driver_data = {
static int alsa_index = ~((1 << (SNDRV_CARDS - 3)) - 1); /* last three slots */
static char *alsa_id = "ThinkPadEC";
-static int alsa_enable = SNDRV_DEFAULT_ENABLE1;
+static bool alsa_enable = SNDRV_DEFAULT_ENABLE1;
struct tpacpi_alsa_data {
struct snd_card *card;
@@ -6487,7 +6487,7 @@ static enum tpacpi_volume_access_mode volume_mode =
TPACPI_VOL_MODE_MAX;
static enum tpacpi_volume_capabilities volume_capabilities;
-static int volume_control_allowed;
+static bool volume_control_allowed;
/*
* Used to syncronize writers to TP_EC_AUDIO and
@@ -7265,7 +7265,7 @@ enum fan_control_commands {
* and also watchdog cmd */
};
-static int fan_control_allowed;
+static bool fan_control_allowed;
static enum fan_status_access_mode fan_status_access_mode;
static enum fan_control_access_mode fan_control_access_mode;
@@ -8437,7 +8437,7 @@ static struct proc_dir_entry *proc_dir;
* Module and infrastructure proble, init and exit handling
*/
-static int force_load;
+static bool force_load;
#ifdef CONFIG_THINKPAD_ACPI_DEBUG
static const char * __init str_supported(int is_supported)
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c
index a134c26870b0..42a4dcc25f92 100644
--- a/drivers/platform/x86/wmi.c
+++ b/drivers/platform/x86/wmi.c
@@ -82,12 +82,12 @@ struct wmi_block {
#define ACPI_WMI_STRING 0x4 /* GUID takes & returns a string */
#define ACPI_WMI_EVENT 0x8 /* GUID is an event */
-static int debug_event;
+static bool debug_event;
module_param(debug_event, bool, 0444);
MODULE_PARM_DESC(debug_event,
"Log WMI Events [0/1]");
-static int debug_dump_wdg;
+static bool debug_dump_wdg;
module_param(debug_dump_wdg, bool, 0444);
MODULE_PARM_DESC(debug_dump_wdg,
"Dump available WMI interfaces [0/1]");
diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c
index 545874b1df9e..076e211a40b7 100644
--- a/drivers/power/ds2760_battery.c
+++ b/drivers/power/ds2760_battery.c
@@ -64,7 +64,7 @@ static unsigned int cache_time = 1000;
module_param(cache_time, uint, 0644);
MODULE_PARM_DESC(cache_time, "cache time in milliseconds");
-static unsigned int pmod_enabled;
+static bool pmod_enabled;
module_param(pmod_enabled, bool, 0644);
MODULE_PARM_DESC(pmod_enabled, "PMOD enable bit");
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c
index e91b8ddc2793..c9b92531ae60 100644
--- a/drivers/regulator/ab8500.c
+++ b/drivers/regulator/ab8500.c
@@ -16,8 +16,8 @@
#include <linux/module.h>
#include <linux/err.h>
#include <linux/platform_device.h>
-#include <linux/mfd/ab8500.h>
#include <linux/mfd/abx500.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/ab8500.h>
diff --git a/drivers/rtc/rtc-ab8500.c b/drivers/rtc/rtc-ab8500.c
index a0a9810adf0b..4bcf9ca2818a 100644
--- a/drivers/rtc/rtc-ab8500.c
+++ b/drivers/rtc/rtc-ab8500.c
@@ -15,7 +15,7 @@
#include <linux/platform_device.h>
#include <linux/rtc.h>
#include <linux/mfd/abx500.h>
-#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <linux/delay.h>
#define AB8500_RTC_SOFF_STAT_REG 0x00
diff --git a/drivers/rtc/rtc-max8925.c b/drivers/rtc/rtc-max8925.c
index 4a5529346b47..2d71943bc436 100644
--- a/drivers/rtc/rtc-max8925.c
+++ b/drivers/rtc/rtc-max8925.c
@@ -261,6 +261,8 @@ static int __devinit max8925_rtc_probe(struct platform_device *pdev)
/* XXX - isn't this redundant? */
platform_set_drvdata(pdev, info);
+ device_init_wakeup(&pdev->dev, 1);
+
info->rtc_dev = rtc_device_register("max8925-rtc", &pdev->dev,
&max8925_rtc_ops, THIS_MODULE);
ret = PTR_ERR(info->rtc_dev);
@@ -290,10 +292,34 @@ static int __devexit max8925_rtc_remove(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
+static int max8925_rtc_suspend(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+
+ if (device_may_wakeup(dev))
+ chip->wakeup_flag |= 1 << MAX8925_IRQ_RTC_ALARM0;
+ return 0;
+}
+static int max8925_rtc_resume(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
+
+ if (device_may_wakeup(dev))
+ chip->wakeup_flag &= ~(1 << MAX8925_IRQ_RTC_ALARM0);
+ return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(max8925_rtc_pm_ops, max8925_rtc_suspend, max8925_rtc_resume);
+
static struct platform_driver max8925_rtc_driver = {
.driver = {
.name = "max8925-rtc",
.owner = THIS_MODULE,
+ .pm = &max8925_rtc_pm_ops,
},
.probe = max8925_rtc_probe,
.remove = __devexit_p(max8925_rtc_remove),
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index e5cb9248a442..f3b8bb84faf2 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -75,7 +75,7 @@ static LIST_HEAD(raw3270_devices);
static int raw3270_registered;
/* Module parameters */
-static int tubxcorrect = 0;
+static bool tubxcorrect = 0;
module_param(tubxcorrect, bool, 0);
/*
diff --git a/drivers/s390/char/vmwatchdog.c b/drivers/s390/char/vmwatchdog.c
index 11312f401c70..2211277a1079 100644
--- a/drivers/s390/char/vmwatchdog.c
+++ b/drivers/s390/char/vmwatchdog.c
@@ -28,9 +28,9 @@
#define MAX_CMDLEN 240
#define MIN_INTERVAL 15
static char vmwdt_cmd[MAX_CMDLEN] = "IPL";
-static int vmwdt_conceal;
+static bool vmwdt_conceal;
-static int vmwdt_nowayout = WATCHDOG_NOWAYOUT;
+static bool vmwdt_nowayout = WATCHDOG_NOWAYOUT;
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");
diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c
index 2985eb439485..204ca728e7fd 100644
--- a/drivers/s390/cio/cmf.c
+++ b/drivers/s390/cio/cmf.c
@@ -98,7 +98,7 @@ enum cmb_format {
* enum cmb_format.
*/
static int format = CMF_AUTODETECT;
-module_param(format, bool, 0444);
+module_param(format, bint, 0444);
/**
* struct cmb_operations - functions to use depending on cmb_format
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index 195823a51aab..ed119cedaae0 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -102,7 +102,7 @@ static int setup_dmaspeed[MAXBOARDS] __initdata = { -1, -1, -1, -1 };
*/
#if defined(MODULE)
-static int isapnp = 0;
+static bool isapnp = 0;
static int aha1542[] = {0x330, 11, 4, -1};
module_param_array(aha1542, int, NULL, 0);
module_param(isapnp, bool, 0);
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index f5b718d3c31b..13aeca3d51f2 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -546,7 +546,7 @@ static struct ParameterData __devinitdata cfg_data[] = {
* command line overrides will be used. If set to 1 then safe and
* slow settings will be used.
*/
-static int use_safe_settings = 0;
+static bool use_safe_settings = 0;
module_param_named(safe, use_safe_settings, bool, 0);
MODULE_PARM_DESC(safe, "Use safe and slow settings only. Default: false");
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index f6a50c98c36f..002924963cd8 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -59,11 +59,11 @@ MODULE_PARM_DESC(trans_mode, "transfer mode (0: BIOS(default) 1: Async 2: Ultra2
#define ASYNC_MODE 1
#define ULTRA20M_MODE 2
-static int auto_param = 0; /* default: ON */
+static bool auto_param = 0; /* default: ON */
module_param (auto_param, bool, 0);
MODULE_PARM_DESC(auto_param, "AutoParameter mode (0: ON(default) 1: OFF)");
-static int disc_priv = 1; /* default: OFF */
+static bool disc_priv = 1; /* default: OFF */
module_param (disc_priv, bool, 0);
MODULE_PARM_DESC(disc_priv, "disconnection privilege mode (0: ON 1: OFF(default))");
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
index ca86721a71b9..b61a753eb896 100644
--- a/drivers/scsi/pcmcia/nsp_cs.c
+++ b/drivers/scsi/pcmcia/nsp_cs.c
@@ -70,7 +70,7 @@ module_param(nsp_burst_mode, int, 0);
MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
/* Release IO ports after configuration? */
-static int free_ports = 0;
+static bool free_ports = 0;
module_param(free_ports, bool, 0);
MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c
index 44f76e8b58af..c77628afbf9f 100644
--- a/drivers/scsi/scsi_netlink.c
+++ b/drivers/scsi/scsi_netlink.c
@@ -112,7 +112,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb)
goto next_msg;
}
- if (security_netlink_recv(skb, CAP_SYS_ADMIN)) {
+ if (!capable(CAP_SYS_ADMIN)) {
err = -EPERM;
goto next_msg;
}
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 7b3f8075e2a5..c691fb50e6cb 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1075,6 +1075,10 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, "
"cmd=0x%x\n", disk->disk_name, cmd));
+ error = scsi_verify_blk_ioctl(bdev, cmd);
+ if (error < 0)
+ return error;
+
/*
* If we are in the middle of error recovery, don't let anyone
* else try and use this device. Also, if error recovery fails, it
@@ -1097,7 +1101,7 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
error = scsi_ioctl(sdp, cmd, p);
break;
default:
- error = scsi_cmd_ioctl(disk->queue, disk, mode, cmd, p);
+ error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p);
if (error != -ENOTTY)
break;
error = scsi_ioctl(sdp, cmd, p);
@@ -1267,6 +1271,11 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
unsigned int cmd, unsigned long arg)
{
struct scsi_device *sdev = scsi_disk(bdev->bd_disk)->device;
+ int ret;
+
+ ret = scsi_verify_blk_ioctl(bdev, cmd);
+ if (ret < 0)
+ return ret;
/*
* If we are in the middle of error recovery, don't let anyone
@@ -1278,8 +1287,6 @@ static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
return -ENODEV;
if (sdev->host->hostt->compat_ioctl) {
- int ret;
-
ret = sdev->host->hostt->compat_ioctl(sdev, cmd, (void __user *)arg);
return ret;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 56abf55e49da..3f9a47ec67dc 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -87,12 +87,12 @@ config SPI_BFIN_SPORT
Enable support for a SPI bus via the Blackfin SPORT peripheral.
config SPI_AU1550
- tristate "Au1550/Au12x0 SPI Controller"
+ tristate "Au1550/Au1200/Au1300 SPI Controller"
depends on MIPS_ALCHEMY && EXPERIMENTAL
select SPI_BITBANG
help
If you say yes to this option, support will be included for the
- Au1550 SPI controller (may also work with Au1200,Au1210,Au1250).
+ PSC SPI controller found on Au1550, Au1200 and Au1300 series.
config SPI_BITBANG
tristate "Utilities for Bitbanging SPI masters"
@@ -332,8 +332,7 @@ config SPI_STMP3XXX
config SPI_TEGRA
tristate "Nvidia Tegra SPI controller"
- depends on ARCH_TEGRA
- select TEGRA_SYSTEM_DMA
+ depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA
help
SPI driver for NVidia Tegra SoCs
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index 0d18d80bcd25..9bcf87ae4c00 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -61,7 +61,7 @@ EXPORT_SYMBOL(comedi_debug);
module_param(comedi_debug, int, 0644);
#endif
-int comedi_autoconfig = 1;
+bool comedi_autoconfig = 1;
module_param(comedi_autoconfig, bool, 0444);
static int comedi_num_legacy_minors;
diff --git a/drivers/staging/comedi/comedi_fops.h b/drivers/staging/comedi/comedi_fops.h
index da4b4f5553f5..006cf14c577a 100644
--- a/drivers/staging/comedi/comedi_fops.h
+++ b/drivers/staging/comedi/comedi_fops.h
@@ -1,10 +1,11 @@
#ifndef _COMEDI_FOPS_H
#define _COMEDI_FOPS_H
+#include <linux/types.h>
extern struct class *comedi_class;
extern const struct file_operations comedi_fops;
-extern int comedi_autoconfig;
+extern bool comedi_autoconfig;
extern struct comedi_driver *comedi_drivers;
#endif /* _COMEDI_FOPS_H */
diff --git a/drivers/staging/media/go7007/snd-go7007.c b/drivers/staging/media/go7007/snd-go7007.c
index deac938d8505..d071c838ac2a 100644
--- a/drivers/staging/media/go7007/snd-go7007.c
+++ b/drivers/staging/media/go7007/snd-go7007.c
@@ -38,7 +38,7 @@
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
-static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
module_param_array(index, int, NULL, 0444);
module_param_array(id, charp, NULL, 0444);
diff --git a/drivers/staging/media/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c
index c5a0d27a02dc..4d20e9f74118 100644
--- a/drivers/staging/media/lirc/lirc_bt829.c
+++ b/drivers/staging/media/lirc/lirc_bt829.c
@@ -53,7 +53,7 @@ static unsigned char do_get_bits(void);
#define DRIVER_NAME "lirc_bt829"
-static int debug;
+static bool debug;
#define dprintk(fmt, args...) \
do { \
if (debug) \
diff --git a/drivers/staging/media/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c
index 6cd4cd67a1dd..7a2501776679 100644
--- a/drivers/staging/media/lirc/lirc_igorplugusb.c
+++ b/drivers/staging/media/lirc/lirc_igorplugusb.c
@@ -62,9 +62,9 @@
/* debugging support */
#ifdef CONFIG_USB_DEBUG
-static int debug = 1;
+static bool debug = 1;
#else
-static int debug;
+static bool debug;
#endif
#define dprintk(fmt, args...) \
diff --git a/drivers/staging/media/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index 792aac0a8e7b..dd2bca7b56fa 100644
--- a/drivers/staging/media/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
@@ -63,8 +63,8 @@
/*** Global Variables ***/
-static int debug;
-static int check_pselecd;
+static bool debug;
+static bool check_pselecd;
unsigned int irq = LIRC_IRQ;
unsigned int io = LIRC_PORT;
@@ -752,4 +752,4 @@ module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging messages");
module_param(check_pselecd, bool, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(debug, "Check for printer (default: 0)");
+MODULE_PARM_DESC(check_pselecd, "Check for printer (default: 0)");
diff --git a/drivers/staging/media/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index 8a060a8a7224..2aac67c98283 100644
--- a/drivers/staging/media/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
@@ -107,13 +107,13 @@ struct lirc_serial {
static int type;
static int io;
static int irq;
-static int iommap;
+static bool iommap;
static int ioshift;
-static int softcarrier = 1;
-static int share_irq;
-static int debug;
+static bool softcarrier = 1;
+static bool share_irq;
+static bool debug;
static int sense = -1; /* -1 = auto, 0 = active high, 1 = active low */
-static int txsense; /* 0 = active high, 1 = active low */
+static bool txsense; /* 0 = active high, 1 = active low */
#define dprintk(fmt, args...) \
do { \
diff --git a/drivers/staging/media/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c
index 6903d3992eca..c94382b917ac 100644
--- a/drivers/staging/media/lirc/lirc_sir.c
+++ b/drivers/staging/media/lirc/lirc_sir.c
@@ -173,7 +173,7 @@ static DEFINE_SPINLOCK(hardware_lock);
static int rx_buf[RBUF_LEN];
static unsigned int rx_tail, rx_head;
-static int debug;
+static bool debug;
#define dprintk(fmt, args...) \
do { \
if (debug) \
diff --git a/drivers/staging/media/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c
index 0302d82a12f7..76ea4a8f2c75 100644
--- a/drivers/staging/media/lirc/lirc_zilog.c
+++ b/drivers/staging/media/lirc/lirc_zilog.c
@@ -155,8 +155,8 @@ static struct mutex tx_data_lock;
#define zilog_info(s, args...) printk(KERN_INFO KBUILD_MODNAME ": " s, ## args)
/* module parameters */
-static int debug; /* debug output */
-static int tx_only; /* only handle the IR Tx function */
+static bool debug; /* debug output */
+static bool tx_only; /* only handle the IR Tx function */
static int minor = -1; /* minor number */
#define dprintk(fmt, args...) \
diff --git a/drivers/staging/octeon/Makefile b/drivers/staging/octeon/Makefile
index fc850bac88c1..9012dee0c348 100644
--- a/drivers/staging/octeon/Makefile
+++ b/drivers/staging/octeon/Makefile
@@ -20,9 +20,4 @@ octeon-ethernet-y += ethernet-sgmii.o
octeon-ethernet-y += ethernet-spi.o
octeon-ethernet-y += ethernet-tx.o
octeon-ethernet-y += ethernet-xaui.o
-octeon-ethernet-y += cvmx-pko.o cvmx-spi.o cvmx-cmd-queue.o \
- cvmx-helper-board.o cvmx-helper.o cvmx-helper-xaui.o \
- cvmx-helper-rgmii.o cvmx-helper-sgmii.o cvmx-helper-npi.o \
- cvmx-helper-loop.o cvmx-helper-spi.o cvmx-helper-util.o \
- cvmx-interrupt-decodes.o cvmx-interrupt-rsl.o
diff --git a/drivers/staging/octeon/cvmx-packet.h b/drivers/staging/octeon/cvmx-packet.h
deleted file mode 100644
index 62ffe78a8c81..000000000000
--- a/drivers/staging/octeon/cvmx-packet.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/***********************license start***************
- * Author: Cavium Networks
- *
- * Contact: support@caviumnetworks.com
- * This file is part of the OCTEON SDK
- *
- * Copyright (c) 2003-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.
- *
- * This file is distributed in the hope that it will be useful, but
- * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
- * NONINFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- * or visit http://www.gnu.org/licenses/.
- *
- * This file may also be available under a different license from Cavium.
- * Contact Cavium Networks for more information
- ***********************license end**************************************/
-
-/**
- *
- * Packet buffer defines.
- */
-
-#ifndef __CVMX_PACKET_H__
-#define __CVMX_PACKET_H__
-
-/**
- * This structure defines a buffer pointer on Octeon
- */
-union cvmx_buf_ptr {
- void *ptr;
- uint64_t u64;
- struct {
- /*
- * if set, invert the "free" pick of the overall
- * packet. HW always sets this bit to 0 on inbound
- * packet
- */
- uint64_t i:1;
- /*
- * Indicates the amount to back up to get to the
- * buffer start in cache lines. In most cases this is
- * less than one complete cache line, so the value is
- * zero.
- */
- uint64_t back:4;
- /* The pool that the buffer came from / goes to */
- uint64_t pool:3;
- /* The size of the segment pointed to by addr (in bytes) */
- uint64_t size:16;
- /* Pointer to the first byte of the data, NOT buffer */
- uint64_t addr:40;
- } s;
-};
-
-#endif /* __CVMX_PACKET_H__ */
diff --git a/drivers/staging/octeon/cvmx-smix-defs.h b/drivers/staging/octeon/cvmx-smix-defs.h
deleted file mode 100644
index 9ae45fcbe3e3..000000000000
--- a/drivers/staging/octeon/cvmx-smix-defs.h
+++ /dev/null
@@ -1,178 +0,0 @@
-/***********************license start***************
- * Author: Cavium Networks
- *
- * Contact: support@caviumnetworks.com
- * This file is part of the OCTEON SDK
- *
- * Copyright (c) 2003-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.
- *
- * This file is distributed in the hope that it will be useful, but
- * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
- * NONINFRINGEMENT. See the GNU General Public License for more
- * details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this file; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- * or visit http://www.gnu.org/licenses/.
- *
- * This file may also be available under a different license from Cavium.
- * Contact Cavium Networks for more information
- ***********************license end**************************************/
-
-#ifndef __CVMX_SMIX_DEFS_H__
-#define __CVMX_SMIX_DEFS_H__
-
-#define CVMX_SMIX_CLK(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001818ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_CMD(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001800ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_EN(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001820ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_RD_DAT(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001810ull + (((offset) & 1) * 256))
-#define CVMX_SMIX_WR_DAT(offset) \
- CVMX_ADD_IO_SEG(0x0001180000001808ull + (((offset) & 1) * 256))
-
-union cvmx_smix_clk {
- uint64_t u64;
- struct cvmx_smix_clk_s {
- uint64_t reserved_25_63:39;
- uint64_t mode:1;
- uint64_t reserved_21_23:3;
- uint64_t sample_hi:5;
- uint64_t sample_mode:1;
- uint64_t reserved_14_14:1;
- uint64_t clk_idle:1;
- uint64_t preamble:1;
- uint64_t sample:4;
- uint64_t phase:8;
- } s;
- struct cvmx_smix_clk_cn30xx {
- uint64_t reserved_21_63:43;
- uint64_t sample_hi:5;
- uint64_t reserved_14_15:2;
- uint64_t clk_idle:1;
- uint64_t preamble:1;
- uint64_t sample:4;
- uint64_t phase:8;
- } cn30xx;
- struct cvmx_smix_clk_cn30xx cn31xx;
- struct cvmx_smix_clk_cn30xx cn38xx;
- struct cvmx_smix_clk_cn30xx cn38xxp2;
- struct cvmx_smix_clk_cn50xx {
- uint64_t reserved_25_63:39;
- uint64_t mode:1;
- uint64_t reserved_21_23:3;
- uint64_t sample_hi:5;
- uint64_t reserved_14_15:2;
- uint64_t clk_idle:1;
- uint64_t preamble:1;
- uint64_t sample:4;
- uint64_t phase:8;
- } cn50xx;
- struct cvmx_smix_clk_s cn52xx;
- struct cvmx_smix_clk_cn50xx cn52xxp1;
- struct cvmx_smix_clk_s cn56xx;
- struct cvmx_smix_clk_cn50xx cn56xxp1;
- struct cvmx_smix_clk_cn30xx cn58xx;
- struct cvmx_smix_clk_cn30xx cn58xxp1;
-};
-
-union cvmx_smix_cmd {
- uint64_t u64;
- struct cvmx_smix_cmd_s {
- uint64_t reserved_18_63:46;
- uint64_t phy_op:2;
- uint64_t reserved_13_15:3;
- uint64_t phy_adr:5;
- uint64_t reserved_5_7:3;
- uint64_t reg_adr:5;
- } s;
- struct cvmx_smix_cmd_cn30xx {
- uint64_t reserved_17_63:47;
- uint64_t phy_op:1;
- uint64_t reserved_13_15:3;
- uint64_t phy_adr:5;
- uint64_t reserved_5_7:3;
- uint64_t reg_adr:5;
- } cn30xx;
- struct cvmx_smix_cmd_cn30xx cn31xx;
- struct cvmx_smix_cmd_cn30xx cn38xx;
- struct cvmx_smix_cmd_cn30xx cn38xxp2;
- struct cvmx_smix_cmd_s cn50xx;
- struct cvmx_smix_cmd_s cn52xx;
- struct cvmx_smix_cmd_s cn52xxp1;
- struct cvmx_smix_cmd_s cn56xx;
- struct cvmx_smix_cmd_s cn56xxp1;
- struct cvmx_smix_cmd_cn30xx cn58xx;
- struct cvmx_smix_cmd_cn30xx cn58xxp1;
-};
-
-union cvmx_smix_en {
- uint64_t u64;
- struct cvmx_smix_en_s {
- uint64_t reserved_1_63:63;
- uint64_t en:1;
- } s;
- struct cvmx_smix_en_s cn30xx;
- struct cvmx_smix_en_s cn31xx;
- struct cvmx_smix_en_s cn38xx;
- struct cvmx_smix_en_s cn38xxp2;
- struct cvmx_smix_en_s cn50xx;
- struct cvmx_smix_en_s cn52xx;
- struct cvmx_smix_en_s cn52xxp1;
- struct cvmx_smix_en_s cn56xx;
- struct cvmx_smix_en_s cn56xxp1;
- struct cvmx_smix_en_s cn58xx;
- struct cvmx_smix_en_s cn58xxp1;
-};
-
-union cvmx_smix_rd_dat {
- uint64_t u64;
- struct cvmx_smix_rd_dat_s {
- uint64_t reserved_18_63:46;
- uint64_t pending:1;
- uint64_t val:1;
- uint64_t dat:16;
- } s;
- struct cvmx_smix_rd_dat_s cn30xx;
- struct cvmx_smix_rd_dat_s cn31xx;
- struct cvmx_smix_rd_dat_s cn38xx;
- struct cvmx_smix_rd_dat_s cn38xxp2;
- struct cvmx_smix_rd_dat_s cn50xx;
- struct cvmx_smix_rd_dat_s cn52xx;
- struct cvmx_smix_rd_dat_s cn52xxp1;
- struct cvmx_smix_rd_dat_s cn56xx;
- struct cvmx_smix_rd_dat_s cn56xxp1;
- struct cvmx_smix_rd_dat_s cn58xx;
- struct cvmx_smix_rd_dat_s cn58xxp1;
-};
-
-union cvmx_smix_wr_dat {
- uint64_t u64;
- struct cvmx_smix_wr_dat_s {
- uint64_t reserved_18_63:46;
- uint64_t pending:1;
- uint64_t val:1;
- uint64_t dat:16;
- } s;
- struct cvmx_smix_wr_dat_s cn30xx;
- struct cvmx_smix_wr_dat_s cn31xx;
- struct cvmx_smix_wr_dat_s cn38xx;
- struct cvmx_smix_wr_dat_s cn38xxp2;
- struct cvmx_smix_wr_dat_s cn50xx;
- struct cvmx_smix_wr_dat_s cn52xx;
- struct cvmx_smix_wr_dat_s cn52xxp1;
- struct cvmx_smix_wr_dat_s cn56xx;
- struct cvmx_smix_wr_dat_s cn56xxp1;
- struct cvmx_smix_wr_dat_s cn58xx;
- struct cvmx_smix_wr_dat_s cn58xxp1;
-};
-
-#endif
diff --git a/drivers/staging/octeon/ethernet-defines.h b/drivers/staging/octeon/ethernet-defines.h
index 6a2cd50a17df..bdaec8d2ca0c 100644
--- a/drivers/staging/octeon/ethernet-defines.h
+++ b/drivers/staging/octeon/ethernet-defines.h
@@ -59,7 +59,7 @@
#ifndef __ETHERNET_DEFINES_H__
#define __ETHERNET_DEFINES_H__
-#include "cvmx-config.h"
+#include <asm/octeon/cvmx-config.h>
#define OCTEON_ETHERNET_VERSION "1.9"
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c
index f18e3e140413..63800ba71d06 100644
--- a/drivers/staging/octeon/ethernet-mdio.c
+++ b/drivers/staging/octeon/ethernet-mdio.c
@@ -38,9 +38,9 @@
#include "ethernet-mdio.h"
#include "ethernet-util.h"
-#include "cvmx-helper-board.h"
+#include <asm/octeon/cvmx-helper-board.h>
-#include "cvmx-smix-defs.h"
+#include <asm/octeon/cvmx-smix-defs.h>
static void cvm_oct_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
diff --git a/drivers/staging/octeon/ethernet-mem.c b/drivers/staging/octeon/ethernet-mem.c
index 635bb86cdcff..78b6cb743769 100644
--- a/drivers/staging/octeon/ethernet-mem.c
+++ b/drivers/staging/octeon/ethernet-mem.c
@@ -32,7 +32,7 @@
#include "ethernet-defines.h"
-#include "cvmx-fpa.h"
+#include <asm/octeon/cvmx-fpa.h>
/**
* cvm_oct_fill_hw_skbuff - fill the supplied hardware pool with skbuffs
diff --git a/drivers/staging/octeon/ethernet-rgmii.c b/drivers/staging/octeon/ethernet-rgmii.c
index c3d73f8431ae..d8f5f694ec35 100644
--- a/drivers/staging/octeon/ethernet-rgmii.c
+++ b/drivers/staging/octeon/ethernet-rgmii.c
@@ -37,11 +37,11 @@
#include "octeon-ethernet.h"
#include "ethernet-util.h"
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-helper.h>
#include <asm/octeon/cvmx-ipd-defs.h>
#include <asm/octeon/cvmx-npi-defs.h>
-#include "cvmx-gmxx-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
DEFINE_SPINLOCK(global_register_lock);
diff --git a/drivers/staging/octeon/ethernet-rx.c b/drivers/staging/octeon/ethernet-rx.c
index 8b307b428791..400df8cbee53 100644
--- a/drivers/staging/octeon/ethernet-rx.c
+++ b/drivers/staging/octeon/ethernet-rx.c
@@ -52,14 +52,14 @@
#include "octeon-ethernet.h"
#include "ethernet-util.h"
-#include "cvmx-helper.h"
-#include "cvmx-wqe.h"
-#include "cvmx-fau.h"
-#include "cvmx-pow.h"
-#include "cvmx-pip.h"
-#include "cvmx-scratch.h"
-
-#include "cvmx-gmxx-defs.h"
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-wqe.h>
+#include <asm/octeon/cvmx-fau.h>
+#include <asm/octeon/cvmx-pow.h>
+#include <asm/octeon/cvmx-pip.h>
+#include <asm/octeon/cvmx-scratch.h>
+
+#include <asm/octeon/cvmx-gmxx-defs.h>
struct cvm_napi_wrapper {
struct napi_struct napi;
diff --git a/drivers/staging/octeon/ethernet-rx.h b/drivers/staging/octeon/ethernet-rx.h
index a0743b85d54e..9240c85ce241 100644
--- a/drivers/staging/octeon/ethernet-rx.h
+++ b/drivers/staging/octeon/ethernet-rx.h
@@ -24,7 +24,7 @@
* This file may also be available under a different license from Cavium.
* Contact Cavium Networks for more information
*********************************************************************/
-#include "cvmx-fau.h"
+#include <asm/octeon/cvmx-fau.h>
void cvm_oct_poll_controller(struct net_device *dev);
void cvm_oct_rx_initialize(void);
diff --git a/drivers/staging/octeon/ethernet-sgmii.c b/drivers/staging/octeon/ethernet-sgmii.c
index 5e148b512c97..d3e82430eba6 100644
--- a/drivers/staging/octeon/ethernet-sgmii.c
+++ b/drivers/staging/octeon/ethernet-sgmii.c
@@ -35,9 +35,9 @@
#include "octeon-ethernet.h"
#include "ethernet-util.h"
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-helper.h>
-#include "cvmx-gmxx-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
int cvm_oct_sgmii_open(struct net_device *dev)
{
diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c
index d0e2d514968a..af8d62818f13 100644
--- a/drivers/staging/octeon/ethernet-spi.c
+++ b/drivers/staging/octeon/ethernet-spi.c
@@ -35,11 +35,11 @@
#include "octeon-ethernet.h"
#include "ethernet-util.h"
-#include "cvmx-spi.h"
+#include <asm/octeon/cvmx-spi.h>
#include <asm/octeon/cvmx-npi-defs.h>
-#include "cvmx-spxx-defs.h"
-#include "cvmx-stxx-defs.h"
+#include <asm/octeon/cvmx-spxx-defs.h>
+#include <asm/octeon/cvmx-stxx-defs.h>
static int number_spi_ports;
static int need_retrain[2] = { 0, 0 };
diff --git a/drivers/staging/octeon/ethernet-tx.c b/drivers/staging/octeon/ethernet-tx.c
index 2542c3743904..56d74dc2fbd5 100644
--- a/drivers/staging/octeon/ethernet-tx.c
+++ b/drivers/staging/octeon/ethernet-tx.c
@@ -47,13 +47,13 @@
#include "ethernet-tx.h"
#include "ethernet-util.h"
-#include "cvmx-wqe.h"
-#include "cvmx-fau.h"
-#include "cvmx-pip.h"
-#include "cvmx-pko.h"
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-wqe.h>
+#include <asm/octeon/cvmx-fau.h>
+#include <asm/octeon/cvmx-pip.h>
+#include <asm/octeon/cvmx-pko.h>
+#include <asm/octeon/cvmx-helper.h>
-#include "cvmx-gmxx-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
#define CVM_OCT_SKB_CB(skb) ((u64 *)((skb)->cb))
diff --git a/drivers/staging/octeon/ethernet-xaui.c b/drivers/staging/octeon/ethernet-xaui.c
index 861a4b3fe857..419f8c34ecdf 100644
--- a/drivers/staging/octeon/ethernet-xaui.c
+++ b/drivers/staging/octeon/ethernet-xaui.c
@@ -35,9 +35,9 @@
#include "octeon-ethernet.h"
#include "ethernet-util.h"
-#include "cvmx-helper.h"
+#include <asm/octeon/cvmx-helper.h>
-#include "cvmx-gmxx-defs.h"
+#include <asm/octeon/cvmx-gmxx-defs.h>
int cvm_oct_xaui_open(struct net_device *dev)
{
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c
index 076f86675ce6..9112cd882154 100644
--- a/drivers/staging/octeon/ethernet.c
+++ b/drivers/staging/octeon/ethernet.c
@@ -44,14 +44,14 @@
#include "ethernet-mdio.h"
#include "ethernet-util.h"
-#include "cvmx-pip.h"
-#include "cvmx-pko.h"
-#include "cvmx-fau.h"
-#include "cvmx-ipd.h"
-#include "cvmx-helper.h"
-
-#include "cvmx-gmxx-defs.h"
-#include "cvmx-smix-defs.h"
+#include <asm/octeon/cvmx-pip.h>
+#include <asm/octeon/cvmx-pko.h>
+#include <asm/octeon/cvmx-fau.h>
+#include <asm/octeon/cvmx-ipd.h>
+#include <asm/octeon/cvmx-helper.h>
+
+#include <asm/octeon/cvmx-gmxx-defs.h>
+#include <asm/octeon/cvmx-smix-defs.h>
#if defined(CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS) \
&& CONFIG_CAVIUM_OCTEON_NUM_PACKET_BUFFERS
diff --git a/drivers/staging/quatech_usb2/quatech_usb2.c b/drivers/staging/quatech_usb2/quatech_usb2.c
index 02fafecd4773..897a3a99c794 100644
--- a/drivers/staging/quatech_usb2/quatech_usb2.c
+++ b/drivers/staging/quatech_usb2/quatech_usb2.c
@@ -16,7 +16,7 @@
#include <linux/usb/serial.h>
#include <linux/uaccess.h>
-static int debug;
+static bool debug;
/* Version Information */
#define DRIVER_VERSION "v2.00"
diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c
index c44e41af2880..1c5780f1571b 100644
--- a/drivers/staging/serqt_usb2/serqt_usb2.c
+++ b/drivers/staging/serqt_usb2/serqt_usb2.c
@@ -16,7 +16,7 @@
#include <linux/usb/serial.h>
#include <linux/uaccess.h>
-static int debug;
+static bool debug;
/* Version Information */
#define DRIVER_VERSION "v2.14"
diff --git a/drivers/staging/speakup/speakup.h b/drivers/staging/speakup/speakup.h
index 412b87947f66..e66579e6147a 100644
--- a/drivers/staging/speakup/speakup.h
+++ b/drivers/staging/speakup/speakup.h
@@ -116,7 +116,7 @@ extern int bleep_time, bell_pos;
extern int spell_delay, key_echo;
extern short punc_mask;
extern short pitch_shift, synth_flags;
-extern int quiet_boot;
+extern bool quiet_boot;
extern char *synth_name;
extern struct bleep unprocessed_sound;
diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c
index c241074a4b5e..2222d6919ef5 100644
--- a/drivers/staging/speakup/synth.c
+++ b/drivers/staging/speakup/synth.c
@@ -22,7 +22,7 @@ static struct spk_synth *synths[MAXSYNTHS];
struct spk_synth *synth;
char pitch_buff[32] = "";
static int module_status;
-int quiet_boot;
+bool quiet_boot;
struct speakup_info_t speakup_info = {
.spinlock = __SPIN_LOCK_UNLOCKED(speakup_info.spinlock),
diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c
index 08a449b4abf9..f50582169b24 100644
--- a/drivers/staging/vme/bridges/vme_tsi148.c
+++ b/drivers/staging/vme/bridges/vme_tsi148.c
@@ -41,7 +41,7 @@ static void __exit tsi148_exit(void);
/* Module parameter */
-static int err_chk;
+static bool err_chk;
static int geoid;
static const char driver_name[] = "vme_tsi148";
diff --git a/drivers/tty/rocket.c b/drivers/tty/rocket.c
index 6a1241c7f841..de88aa5566e5 100644
--- a/drivers/tty/rocket.c
+++ b/drivers/tty/rocket.c
@@ -118,7 +118,7 @@ static unsigned long board2;
static unsigned long board3;
static unsigned long board4;
static unsigned long controller;
-static int support_low_speed;
+static bool support_low_speed;
static unsigned long modem1;
static unsigned long modem2;
static unsigned long modem3;
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index f32a2ea70100..aca2386c5ef1 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1605,4 +1605,27 @@ config SERIAL_XILINX_PS_UART_CONSOLE
help
Enable a Xilinx PS UART port to be the system console.
+config SERIAL_AR933X
+ bool "AR933X serial port support"
+ depends on SOC_AR933X
+ select SERIAL_CORE
+ help
+ If you have an Atheros AR933X SOC based board and want to use the
+ built-in UART of the SoC, say Y to this option.
+
+config SERIAL_AR933X_CONSOLE
+ bool "Console on AR933X serial port"
+ depends on SERIAL_AR933X=y
+ select SERIAL_CORE_CONSOLE
+ help
+ Enable a built-in UART port of the AR933X to be the system console.
+
+config SERIAL_AR933X_NR_UARTS
+ int "Maximum number of AR933X serial ports"
+ depends on SERIAL_AR933X
+ default "2"
+ help
+ Set this to the number of serial ports you want the driver
+ to support.
+
endmenu
diff --git a/drivers/tty/serial/Makefile b/drivers/tty/serial/Makefile
index 07e0494c6830..f5b01f2ce525 100644
--- a/drivers/tty/serial/Makefile
+++ b/drivers/tty/serial/Makefile
@@ -91,3 +91,4 @@ obj-$(CONFIG_SERIAL_MXS_AUART) += mxs-auart.o
obj-$(CONFIG_SERIAL_LANTIQ) += lantiq.o
obj-$(CONFIG_SERIAL_XILINX_PS_UART) += xilinx_uartps.o
obj-$(CONFIG_SERIAL_SIRFSOC) += sirfsoc_uart.o
+obj-$(CONFIG_SERIAL_AR933X) += ar933x_uart.o
diff --git a/drivers/tty/serial/ar933x_uart.c b/drivers/tty/serial/ar933x_uart.c
new file mode 100644
index 000000000000..e4f60e2b87f3
--- /dev/null
+++ b/drivers/tty/serial/ar933x_uart.c
@@ -0,0 +1,688 @@
+/*
+ * Atheros AR933X SoC built-in UART driver
+ *
+ * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+
+#include <asm/mach-ath79/ar933x_uart.h>
+#include <asm/mach-ath79/ar933x_uart_platform.h>
+
+#define DRIVER_NAME "ar933x-uart"
+
+#define AR933X_DUMMY_STATUS_RD 0x01
+
+static struct uart_driver ar933x_uart_driver;
+
+struct ar933x_uart_port {
+ struct uart_port port;
+ unsigned int ier; /* shadow Interrupt Enable Register */
+};
+
+static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up,
+ int offset)
+{
+ return readl(up->port.membase + offset);
+}
+
+static inline void ar933x_uart_write(struct ar933x_uart_port *up,
+ int offset, unsigned int value)
+{
+ writel(value, up->port.membase + offset);
+}
+
+static inline void ar933x_uart_rmw(struct ar933x_uart_port *up,
+ unsigned int offset,
+ unsigned int mask,
+ unsigned int val)
+{
+ unsigned int t;
+
+ t = ar933x_uart_read(up, offset);
+ t &= ~mask;
+ t |= val;
+ ar933x_uart_write(up, offset, t);
+}
+
+static inline void ar933x_uart_rmw_set(struct ar933x_uart_port *up,
+ unsigned int offset,
+ unsigned int val)
+{
+ ar933x_uart_rmw(up, offset, 0, val);
+}
+
+static inline void ar933x_uart_rmw_clear(struct ar933x_uart_port *up,
+ unsigned int offset,
+ unsigned int val)
+{
+ ar933x_uart_rmw(up, offset, val, 0);
+}
+
+static inline void ar933x_uart_start_tx_interrupt(struct ar933x_uart_port *up)
+{
+ up->ier |= AR933X_UART_INT_TX_EMPTY;
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+}
+
+static inline void ar933x_uart_stop_tx_interrupt(struct ar933x_uart_port *up)
+{
+ up->ier &= ~AR933X_UART_INT_TX_EMPTY;
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+}
+
+static inline void ar933x_uart_putc(struct ar933x_uart_port *up, int ch)
+{
+ unsigned int rdata;
+
+ rdata = ch & AR933X_UART_DATA_TX_RX_MASK;
+ rdata |= AR933X_UART_DATA_TX_CSR;
+ ar933x_uart_write(up, AR933X_UART_DATA_REG, rdata);
+}
+
+static unsigned int ar933x_uart_tx_empty(struct uart_port *port)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+ unsigned long flags;
+ unsigned int rdata;
+
+ spin_lock_irqsave(&up->port.lock, flags);
+ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+ return (rdata & AR933X_UART_DATA_TX_CSR) ? 0 : TIOCSER_TEMT;
+}
+
+static unsigned int ar933x_uart_get_mctrl(struct uart_port *port)
+{
+ return TIOCM_CAR;
+}
+
+static void ar933x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
+{
+}
+
+static void ar933x_uart_start_tx(struct uart_port *port)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+
+ ar933x_uart_start_tx_interrupt(up);
+}
+
+static void ar933x_uart_stop_tx(struct uart_port *port)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+
+ ar933x_uart_stop_tx_interrupt(up);
+}
+
+static void ar933x_uart_stop_rx(struct uart_port *port)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+
+ up->ier &= ~AR933X_UART_INT_RX_VALID;
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+}
+
+static void ar933x_uart_break_ctl(struct uart_port *port, int break_state)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+ unsigned long flags;
+
+ spin_lock_irqsave(&up->port.lock, flags);
+ if (break_state == -1)
+ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_TX_BREAK);
+ else
+ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_TX_BREAK);
+ spin_unlock_irqrestore(&up->port.lock, flags);
+}
+
+static void ar933x_uart_enable_ms(struct uart_port *port)
+{
+}
+
+static void ar933x_uart_set_termios(struct uart_port *port,
+ struct ktermios *new,
+ struct ktermios *old)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+ unsigned int cs;
+ unsigned long flags;
+ unsigned int baud, scale;
+
+ /* Only CS8 is supported */
+ new->c_cflag &= ~CSIZE;
+ new->c_cflag |= CS8;
+
+ /* Only one stop bit is supported */
+ new->c_cflag &= ~CSTOPB;
+
+ cs = 0;
+ if (new->c_cflag & PARENB) {
+ if (!(new->c_cflag & PARODD))
+ cs |= AR933X_UART_CS_PARITY_EVEN;
+ else
+ cs |= AR933X_UART_CS_PARITY_ODD;
+ } else {
+ cs |= AR933X_UART_CS_PARITY_NONE;
+ }
+
+ /* Mark/space parity is not supported */
+ new->c_cflag &= ~CMSPAR;
+
+ baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
+ scale = (port->uartclk / (16 * baud)) - 1;
+
+ /*
+ * Ok, we're now changing the port state. Do it with
+ * interrupts disabled.
+ */
+ spin_lock_irqsave(&up->port.lock, flags);
+
+ /* Update the per-port timeout. */
+ uart_update_timeout(port, new->c_cflag, baud);
+
+ up->port.ignore_status_mask = 0;
+
+ /* ignore all characters if CREAD is not set */
+ if ((new->c_cflag & CREAD) == 0)
+ up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
+
+ ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
+ scale << AR933X_UART_CLOCK_SCALE_S | 8192);
+
+ /* setup configuration register */
+ ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
+
+ /* enable host interrupt */
+ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_HOST_INT_EN);
+
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+ if (tty_termios_baud_rate(new))
+ tty_termios_encode_baud_rate(new, baud, baud);
+}
+
+static void ar933x_uart_rx_chars(struct ar933x_uart_port *up)
+{
+ struct tty_struct *tty;
+ int max_count = 256;
+
+ tty = tty_port_tty_get(&up->port.state->port);
+ do {
+ unsigned int rdata;
+ unsigned char ch;
+
+ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
+ if ((rdata & AR933X_UART_DATA_RX_CSR) == 0)
+ break;
+
+ /* remove the character from the FIFO */
+ ar933x_uart_write(up, AR933X_UART_DATA_REG,
+ AR933X_UART_DATA_RX_CSR);
+
+ if (!tty) {
+ /* discard the data if no tty available */
+ continue;
+ }
+
+ up->port.icount.rx++;
+ ch = rdata & AR933X_UART_DATA_TX_RX_MASK;
+
+ if (uart_handle_sysrq_char(&up->port, ch))
+ continue;
+
+ if ((up->port.ignore_status_mask & AR933X_DUMMY_STATUS_RD) == 0)
+ tty_insert_flip_char(tty, ch, TTY_NORMAL);
+ } while (max_count-- > 0);
+
+ if (tty) {
+ tty_flip_buffer_push(tty);
+ tty_kref_put(tty);
+ }
+}
+
+static void ar933x_uart_tx_chars(struct ar933x_uart_port *up)
+{
+ struct circ_buf *xmit = &up->port.state->xmit;
+ int count;
+
+ if (uart_tx_stopped(&up->port))
+ return;
+
+ count = up->port.fifosize;
+ do {
+ unsigned int rdata;
+
+ rdata = ar933x_uart_read(up, AR933X_UART_DATA_REG);
+ if ((rdata & AR933X_UART_DATA_TX_CSR) == 0)
+ break;
+
+ if (up->port.x_char) {
+ ar933x_uart_putc(up, up->port.x_char);
+ up->port.icount.tx++;
+ up->port.x_char = 0;
+ continue;
+ }
+
+ if (uart_circ_empty(xmit))
+ break;
+
+ ar933x_uart_putc(up, xmit->buf[xmit->tail]);
+
+ xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+ up->port.icount.tx++;
+ } while (--count > 0);
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&up->port);
+
+ if (!uart_circ_empty(xmit))
+ ar933x_uart_start_tx_interrupt(up);
+}
+
+static irqreturn_t ar933x_uart_interrupt(int irq, void *dev_id)
+{
+ struct ar933x_uart_port *up = dev_id;
+ unsigned int status;
+
+ status = ar933x_uart_read(up, AR933X_UART_CS_REG);
+ if ((status & AR933X_UART_CS_HOST_INT) == 0)
+ return IRQ_NONE;
+
+ spin_lock(&up->port.lock);
+
+ status = ar933x_uart_read(up, AR933X_UART_INT_REG);
+ status &= ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
+
+ if (status & AR933X_UART_INT_RX_VALID) {
+ ar933x_uart_write(up, AR933X_UART_INT_REG,
+ AR933X_UART_INT_RX_VALID);
+ ar933x_uart_rx_chars(up);
+ }
+
+ if (status & AR933X_UART_INT_TX_EMPTY) {
+ ar933x_uart_write(up, AR933X_UART_INT_REG,
+ AR933X_UART_INT_TX_EMPTY);
+ ar933x_uart_stop_tx_interrupt(up);
+ ar933x_uart_tx_chars(up);
+ }
+
+ spin_unlock(&up->port.lock);
+
+ return IRQ_HANDLED;
+}
+
+static int ar933x_uart_startup(struct uart_port *port)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+ unsigned long flags;
+ int ret;
+
+ ret = request_irq(up->port.irq, ar933x_uart_interrupt,
+ up->port.irqflags, dev_name(up->port.dev), up);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&up->port.lock, flags);
+
+ /* Enable HOST interrupts */
+ ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_HOST_INT_EN);
+
+ /* Enable RX interrupts */
+ up->ier = AR933X_UART_INT_RX_VALID;
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+
+ spin_unlock_irqrestore(&up->port.lock, flags);
+
+ return 0;
+}
+
+static void ar933x_uart_shutdown(struct uart_port *port)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+
+ /* Disable all interrupts */
+ up->ier = 0;
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
+
+ /* Disable break condition */
+ ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
+ AR933X_UART_CS_TX_BREAK);
+
+ free_irq(up->port.irq, up);
+}
+
+static const char *ar933x_uart_type(struct uart_port *port)
+{
+ return (port->type == PORT_AR933X) ? "AR933X UART" : NULL;
+}
+
+static void ar933x_uart_release_port(struct uart_port *port)
+{
+ /* Nothing to release ... */
+}
+
+static int ar933x_uart_request_port(struct uart_port *port)
+{
+ /* UARTs always present */
+ return 0;
+}
+
+static void ar933x_uart_config_port(struct uart_port *port, int flags)
+{
+ if (flags & UART_CONFIG_TYPE)
+ port->type = PORT_AR933X;
+}
+
+static int ar933x_uart_verify_port(struct uart_port *port,
+ struct serial_struct *ser)
+{
+ if (ser->type != PORT_UNKNOWN &&
+ ser->type != PORT_AR933X)
+ return -EINVAL;
+
+ if (ser->irq < 0 || ser->irq >= NR_IRQS)
+ return -EINVAL;
+
+ if (ser->baud_base < 28800)
+ return -EINVAL;
+
+ return 0;
+}
+
+static struct uart_ops ar933x_uart_ops = {
+ .tx_empty = ar933x_uart_tx_empty,
+ .set_mctrl = ar933x_uart_set_mctrl,
+ .get_mctrl = ar933x_uart_get_mctrl,
+ .stop_tx = ar933x_uart_stop_tx,
+ .start_tx = ar933x_uart_start_tx,
+ .stop_rx = ar933x_uart_stop_rx,
+ .enable_ms = ar933x_uart_enable_ms,
+ .break_ctl = ar933x_uart_break_ctl,
+ .startup = ar933x_uart_startup,
+ .shutdown = ar933x_uart_shutdown,
+ .set_termios = ar933x_uart_set_termios,
+ .type = ar933x_uart_type,
+ .release_port = ar933x_uart_release_port,
+ .request_port = ar933x_uart_request_port,
+ .config_port = ar933x_uart_config_port,
+ .verify_port = ar933x_uart_verify_port,
+};
+
+#ifdef CONFIG_SERIAL_AR933X_CONSOLE
+
+static struct ar933x_uart_port *
+ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS];
+
+static void ar933x_uart_wait_xmitr(struct ar933x_uart_port *up)
+{
+ unsigned int status;
+ unsigned int timeout = 60000;
+
+ /* Wait up to 60ms for the character(s) to be sent. */
+ do {
+ status = ar933x_uart_read(up, AR933X_UART_DATA_REG);
+ if (--timeout == 0)
+ break;
+ udelay(1);
+ } while ((status & AR933X_UART_DATA_TX_CSR) == 0);
+}
+
+static void ar933x_uart_console_putchar(struct uart_port *port, int ch)
+{
+ struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
+
+ ar933x_uart_wait_xmitr(up);
+ ar933x_uart_putc(up, ch);
+}
+
+static void ar933x_uart_console_write(struct console *co, const char *s,
+ unsigned int count)
+{
+ struct ar933x_uart_port *up = ar933x_console_ports[co->index];
+ unsigned long flags;
+ unsigned int int_en;
+ int locked = 1;
+
+ local_irq_save(flags);
+
+ if (up->port.sysrq)
+ locked = 0;
+ else if (oops_in_progress)
+ locked = spin_trylock(&up->port.lock);
+ else
+ spin_lock(&up->port.lock);
+
+ /*
+ * First save the IER then disable the interrupts
+ */
+ int_en = ar933x_uart_read(up, AR933X_UART_INT_EN_REG);
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, 0);
+
+ uart_console_write(&up->port, s, count, ar933x_uart_console_putchar);
+
+ /*
+ * Finally, wait for transmitter to become empty
+ * and restore the IER
+ */
+ ar933x_uart_wait_xmitr(up);
+ ar933x_uart_write(up, AR933X_UART_INT_EN_REG, int_en);
+
+ ar933x_uart_write(up, AR933X_UART_INT_REG, AR933X_UART_INT_ALLINTS);
+
+ if (locked)
+ spin_unlock(&up->port.lock);
+
+ local_irq_restore(flags);
+}
+
+static int ar933x_uart_console_setup(struct console *co, char *options)
+{
+ struct ar933x_uart_port *up;
+ int baud = 115200;
+ int bits = 8;
+ int parity = 'n';
+ int flow = 'n';
+
+ if (co->index < 0 || co->index >= CONFIG_SERIAL_AR933X_NR_UARTS)
+ return -EINVAL;
+
+ up = ar933x_console_ports[co->index];
+ if (!up)
+ return -ENODEV;
+
+ if (options)
+ uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+ return uart_set_options(&up->port, co, baud, parity, bits, flow);
+}
+
+static struct console ar933x_uart_console = {
+ .name = "ttyATH",
+ .write = ar933x_uart_console_write,
+ .device = uart_console_device,
+ .setup = ar933x_uart_console_setup,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+ .data = &ar933x_uart_driver,
+};
+
+static void ar933x_uart_add_console_port(struct ar933x_uart_port *up)
+{
+ ar933x_console_ports[up->port.line] = up;
+}
+
+#define AR933X_SERIAL_CONSOLE (&ar933x_uart_console)
+
+#else
+
+static inline void ar933x_uart_add_console_port(struct ar933x_uart_port *up) {}
+
+#define AR933X_SERIAL_CONSOLE NULL
+
+#endif /* CONFIG_SERIAL_AR933X_CONSOLE */
+
+static struct uart_driver ar933x_uart_driver = {
+ .owner = THIS_MODULE,
+ .driver_name = DRIVER_NAME,
+ .dev_name = "ttyATH",
+ .nr = CONFIG_SERIAL_AR933X_NR_UARTS,
+ .cons = AR933X_SERIAL_CONSOLE,
+};
+
+static int __devinit ar933x_uart_probe(struct platform_device *pdev)
+{
+ struct ar933x_uart_platform_data *pdata;
+ struct ar933x_uart_port *up;
+ struct uart_port *port;
+ struct resource *mem_res;
+ struct resource *irq_res;
+ int id;
+ int ret;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata)
+ return -EINVAL;
+
+ id = pdev->id;
+ if (id == -1)
+ id = 0;
+
+ if (id > CONFIG_SERIAL_AR933X_NR_UARTS)
+ return -EINVAL;
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem_res) {
+ dev_err(&pdev->dev, "no MEM resource\n");
+ return -EINVAL;
+ }
+
+ irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!irq_res) {
+ dev_err(&pdev->dev, "no IRQ resource\n");
+ return -EINVAL;
+ }
+
+ up = kzalloc(sizeof(struct ar933x_uart_port), GFP_KERNEL);
+ if (!up)
+ return -ENOMEM;
+
+ port = &up->port;
+ port->mapbase = mem_res->start;
+
+ port->membase = ioremap(mem_res->start, AR933X_UART_REGS_SIZE);
+ if (!port->membase) {
+ ret = -ENOMEM;
+ goto err_free_up;
+ }
+
+ port->line = id;
+ port->irq = irq_res->start;
+ port->dev = &pdev->dev;
+ port->type = PORT_AR933X;
+ port->iotype = UPIO_MEM32;
+ port->uartclk = pdata->uartclk;
+
+ port->regshift = 2;
+ port->fifosize = AR933X_UART_FIFO_SIZE;
+ port->ops = &ar933x_uart_ops;
+
+ ar933x_uart_add_console_port(up);
+
+ ret = uart_add_one_port(&ar933x_uart_driver, &up->port);
+ if (ret)
+ goto err_unmap;
+
+ platform_set_drvdata(pdev, up);
+ return 0;
+
+err_unmap:
+ iounmap(up->port.membase);
+err_free_up:
+ kfree(up);
+ return ret;
+}
+
+static int __devexit ar933x_uart_remove(struct platform_device *pdev)
+{
+ struct ar933x_uart_port *up;
+
+ up = platform_get_drvdata(pdev);
+ platform_set_drvdata(pdev, NULL);
+
+ if (up) {
+ uart_remove_one_port(&ar933x_uart_driver, &up->port);
+ iounmap(up->port.membase);
+ kfree(up);
+ }
+
+ return 0;
+}
+
+static struct platform_driver ar933x_uart_platform_driver = {
+ .probe = ar933x_uart_probe,
+ .remove = __devexit_p(ar933x_uart_remove),
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ar933x_uart_init(void)
+{
+ int ret;
+
+ ar933x_uart_driver.nr = CONFIG_SERIAL_AR933X_NR_UARTS;
+ ret = uart_register_driver(&ar933x_uart_driver);
+ if (ret)
+ goto err_out;
+
+ ret = platform_driver_register(&ar933x_uart_platform_driver);
+ if (ret)
+ goto err_unregister_uart_driver;
+
+ return 0;
+
+err_unregister_uart_driver:
+ uart_unregister_driver(&ar933x_uart_driver);
+err_out:
+ return ret;
+}
+
+static void __exit ar933x_uart_exit(void)
+{
+ platform_driver_unregister(&ar933x_uart_platform_driver);
+ uart_unregister_driver(&ar933x_uart_driver);
+}
+
+module_init(ar933x_uart_init);
+module_exit(ar933x_uart_exit);
+
+MODULE_DESCRIPTION("Atheros AR933X UART driver");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/tty/synclink.c b/drivers/tty/synclink.c
index e67fb20490d2..ff8017f87914 100644
--- a/drivers/tty/synclink.c
+++ b/drivers/tty/synclink.c
@@ -850,7 +850,7 @@ static int mgsl_device_count;
* .text section address and breakpoint on module load.
* This is useful for use with gdb and add-symbol-file command.
*/
-static int break_on_load;
+static bool break_on_load;
/*
* Driver major number, defaults to zero to get auto
diff --git a/drivers/tty/synclinkmp.c b/drivers/tty/synclinkmp.c
index 0f6b796c95c5..a7efe538df00 100644
--- a/drivers/tty/synclinkmp.c
+++ b/drivers/tty/synclinkmp.c
@@ -456,7 +456,7 @@ static int synclinkmp_device_count = 0;
* .text section address and breakpoint on module load.
* This is useful for use with gdb and add-symbol-file command.
*/
-static int break_on_load = 0;
+static bool break_on_load = 0;
/*
* Driver major number, defaults to zero to get auto
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c
index b42092e1f164..98dd9e49b684 100644
--- a/drivers/usb/atm/speedtch.c
+++ b/drivers/usb/atm/speedtch.c
@@ -73,9 +73,9 @@ static const char speedtch_driver_name[] = "speedtch";
#define DEFAULT_SW_BUFFERING 0
static unsigned int altsetting = 0; /* zero means: use the default */
-static int dl_512_first = DEFAULT_DL_512_FIRST;
-static int enable_isoc = DEFAULT_ENABLE_ISOC;
-static int sw_buffering = DEFAULT_SW_BUFFERING;
+static bool dl_512_first = DEFAULT_DL_512_FIRST;
+static bool enable_isoc = DEFAULT_ENABLE_ISOC;
+static bool sw_buffering = DEFAULT_SW_BUFFERING;
#define DEFAULT_B_MAX_DSL 8128
#define DEFAULT_MODEM_MODE 11
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index 00f171a7a8a0..01ea5d7421d4 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -542,7 +542,7 @@ static int modem_index;
static unsigned int debug;
static unsigned int altsetting[NB_MODEM] = {
[0 ... (NB_MODEM - 1)] = FASTEST_ISO_INTF};
-static int sync_wait[NB_MODEM];
+static bool sync_wait[NB_MODEM];
static char *cmv_file[NB_MODEM];
static int annex[NB_MODEM];
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 3af5e2dd1d82..8df4b76465ac 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -93,7 +93,7 @@ struct async {
u8 bulk_status;
};
-static int usbfs_snoop;
+static bool usbfs_snoop;
module_param(usbfs_snoop, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic");
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 79d339e2e700..a0613d8f9be7 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -102,7 +102,7 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait);
static struct task_struct *khubd_task;
/* cycle leds on hubs that aren't blinking for attention */
-static int blinkenlights = 0;
+static bool blinkenlights = 0;
module_param (blinkenlights, bool, S_IRUGO);
MODULE_PARM_DESC (blinkenlights, "true to cycle leds on hubs");
@@ -131,12 +131,12 @@ MODULE_PARM_DESC(initial_descriptor_timeout,
* otherwise the new scheme is used. If that fails and "use_both_schemes"
* is set, then the driver will make another attempt, using the other scheme.
*/
-static int old_scheme_first = 0;
+static bool old_scheme_first = 0;
module_param(old_scheme_first, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(old_scheme_first,
"start with the old device initialization scheme");
-static int use_both_schemes = 1;
+static bool use_both_schemes = 1;
module_param(use_both_schemes, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(use_both_schemes,
"try the other device initialization scheme if the "
@@ -2026,7 +2026,7 @@ static unsigned hub_is_wusb(struct usb_hub *hub)
#define SET_ADDRESS_TRIES 2
#define GET_DESCRIPTOR_TRIES 2
#define SET_CONFIG_TRIES (2 * (use_both_schemes + 1))
-#define USE_NEW_SCHEME(i) ((i) / 2 == old_scheme_first)
+#define USE_NEW_SCHEME(i) ((i) / 2 == (int)old_scheme_first)
#define HUB_ROOT_RESET_TIME 50 /* times are in msec */
#define HUB_SHORT_RESET_TIME 10
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 1382c90d0834..8ca9f994a280 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -47,7 +47,7 @@
const char *usbcore_name = "usbcore";
-static int nousb; /* Disable USB when built into kernel image */
+static bool nousb; /* Disable USB when built into kernel image */
#ifdef CONFIG_USB_SUSPEND
static int usb_autosuspend_delay = 2; /* Default delay value,
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c
index e9a2c5c44454..c16ff55a74e8 100644
--- a/drivers/usb/gadget/amd5536udc.c
+++ b/drivers/usb/gadget/amd5536udc.c
@@ -152,15 +152,15 @@ static const char *ep_string[] = {
};
/* DMA usage flag */
-static int use_dma = 1;
+static bool use_dma = 1;
/* packet per buffer dma */
-static int use_dma_ppb = 1;
+static bool use_dma_ppb = 1;
/* with per descr. update */
-static int use_dma_ppb_du;
+static bool use_dma_ppb_du;
/* buffer fill mode */
static int use_dma_bufferfill_mode;
/* full speed only mode */
-static int use_fullspeed;
+static bool use_fullspeed;
/* tx buffer size for high speed */
static unsigned long hs_tx_buf = UDC_EPIN_BUFF_SIZE;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 0cd764d59351..a28f6ffcd0f3 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -250,9 +250,9 @@ static struct usb_configuration rndis_config_driver = {
/*-------------------------------------------------------------------------*/
#ifdef CONFIG_USB_ETH_EEM
-static int use_eem = 1;
+static bool use_eem = 1;
#else
-static int use_eem;
+static bool use_eem;
#endif
module_param(use_eem, bool, 0);
MODULE_PARM_DESC(use_eem, "use CDC EEM mode");
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index e0f30fc70e45..47766f0e7caa 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -303,16 +303,16 @@ MODULE_LICENSE("Dual BSD/GPL");
static struct {
char *file[FSG_MAX_LUNS];
char *serial;
- int ro[FSG_MAX_LUNS];
- int nofua[FSG_MAX_LUNS];
+ bool ro[FSG_MAX_LUNS];
+ bool nofua[FSG_MAX_LUNS];
unsigned int num_filenames;
unsigned int num_ros;
unsigned int num_nofuas;
unsigned int nluns;
- int removable;
- int can_stall;
- int cdrom;
+ bool removable;
+ bool can_stall;
+ bool cdrom;
char *transport_parm;
char *protocol_parm;
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c
index 4c81d540bc26..7322d293213e 100644
--- a/drivers/usb/gadget/net2272.c
+++ b/drivers/usb/gadget/net2272.c
@@ -69,7 +69,7 @@ static const char * const ep_name[] = {
*
* If use_dma is disabled, pio will be used instead.
*/
-static int use_dma = 0;
+static bool use_dma = 0;
module_param(use_dma, bool, 0644);
/*
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
index cf1f36454d08..cdedd1336745 100644
--- a/drivers/usb/gadget/net2280.c
+++ b/drivers/usb/gadget/net2280.c
@@ -90,8 +90,8 @@ static const char *const ep_name [] = {
* Some gadget drivers work better with the dma support here than others.
* These two parameters let you use PIO or more aggressive DMA.
*/
-static int use_dma = 1;
-static int use_dma_chaining = 0;
+static bool use_dma = 1;
+static bool use_dma_chaining = 0;
/* "modprobe net2280 use_dma=n" etc */
module_param (use_dma, bool, S_IRUGO);
@@ -112,7 +112,7 @@ module_param (fifo_mode, ushort, 0644);
* USB suspend requests will be ignored. This is acceptable for
* self-powered devices
*/
-static int enable_suspend = 0;
+static bool enable_suspend = 0;
/* "modprobe net2280 enable_suspend=1" etc */
module_param (enable_suspend, bool, S_IRUGO);
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c
index 7db5bbe6251b..576cd8578b45 100644
--- a/drivers/usb/gadget/omap_udc.c
+++ b/drivers/usb/gadget/omap_udc.c
@@ -98,7 +98,7 @@ module_param (fifo_mode, uint, 0);
MODULE_PARM_DESC (fifo_mode, "endpoint configuration");
#ifdef USE_DMA
-static unsigned use_dma = 1;
+static bool use_dma = 1;
/* "modprobe omap_udc use_dma=y", or else as a kernel
* boot parameter "omap_udc:use_dma=y"
diff --git a/drivers/usb/gadget/pch_udc.c b/drivers/usb/gadget/pch_udc.c
index dd2313cce1d3..a3fcaae4bc2a 100644
--- a/drivers/usb/gadget/pch_udc.c
+++ b/drivers/usb/gadget/pch_udc.c
@@ -359,7 +359,7 @@ struct pch_udc_dev {
static const char ep0_string[] = "ep0in";
static DEFINE_SPINLOCK(udc_stall_spinlock); /* stall spin lock */
struct pch_udc_dev *pch_udc; /* pointer to device object */
-static int speed_fs;
+static bool speed_fs;
module_param_named(speed_fs, speed_fs, bool, S_IRUGO);
MODULE_PARM_DESC(speed_fs, "true for Full speed operation");
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index ed1b816e58d8..ad9e5b2df642 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -123,11 +123,11 @@ MODULE_AUTHOR("Al Borchers");
MODULE_AUTHOR("David Brownell");
MODULE_LICENSE("GPL");
-static int use_acm = true;
+static bool use_acm = true;
module_param(use_acm, bool, 0);
MODULE_PARM_DESC(use_acm, "Use CDC ACM, default=yes");
-static int use_obex = false;
+static bool use_obex = false;
module_param(use_obex, bool, 0);
MODULE_PARM_DESC(use_obex, "Use CDC OBEX, default=no");
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index 20697cc132d1..31d34832907e 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -81,7 +81,7 @@ module_param(buflen, uint, 0);
* work better with hosts where config changes are problematic or
* controllers (like original superh) that only support one config.
*/
-static int loopdefault = 0;
+static bool loopdefault = 0;
module_param(loopdefault, bool, S_IRUGO|S_IWUSR);
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 4c0c9734251d..91413cac97be 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -219,7 +219,7 @@ config USB_CNS3XXX_EHCI
config USB_EHCI_ATH79
bool "EHCI support for AR7XXX/AR9XXX SoCs"
- depends on USB_EHCI_HCD && (SOC_AR71XX || SOC_AR724X || SOC_AR913X)
+ depends on USB_EHCI_HCD && (SOC_AR71XX || SOC_AR724X || SOC_AR913X || SOC_AR933X)
select USB_EHCI_ROOT_HUB_TT
default y
---help---
diff --git a/drivers/usb/host/alchemy-common.c b/drivers/usb/host/alchemy-common.c
index b4192c964d0d..936af8359fb2 100644
--- a/drivers/usb/host/alchemy-common.c
+++ b/drivers/usb/host/alchemy-common.c
@@ -52,9 +52,263 @@
USBCFG_EBE | USBCFG_EME | USBCFG_OBE | \
USBCFG_OME)
+/* Au1300 USB config registers */
+#define USB_DWC_CTRL1 0x00
+#define USB_DWC_CTRL2 0x04
+#define USB_VBUS_TIMER 0x10
+#define USB_SBUS_CTRL 0x14
+#define USB_MSR_ERR 0x18
+#define USB_DWC_CTRL3 0x1C
+#define USB_DWC_CTRL4 0x20
+#define USB_OTG_STATUS 0x28
+#define USB_DWC_CTRL5 0x2C
+#define USB_DWC_CTRL6 0x30
+#define USB_DWC_CTRL7 0x34
+#define USB_PHY_STATUS 0xC0
+#define USB_INT_STATUS 0xC4
+#define USB_INT_ENABLE 0xC8
+
+#define USB_DWC_CTRL1_OTGD 0x04 /* set to DISable OTG */
+#define USB_DWC_CTRL1_HSTRS 0x02 /* set to ENable EHCI */
+#define USB_DWC_CTRL1_DCRS 0x01 /* set to ENable UDC */
+
+#define USB_DWC_CTRL2_PHY1RS 0x04 /* set to enable PHY1 */
+#define USB_DWC_CTRL2_PHY0RS 0x02 /* set to enable PHY0 */
+#define USB_DWC_CTRL2_PHYRS 0x01 /* set to enable PHY */
+
+#define USB_DWC_CTRL3_OHCI1_CKEN (1 << 19)
+#define USB_DWC_CTRL3_OHCI0_CKEN (1 << 18)
+#define USB_DWC_CTRL3_EHCI0_CKEN (1 << 17)
+#define USB_DWC_CTRL3_OTG0_CKEN (1 << 16)
+
+#define USB_SBUS_CTRL_SBCA 0x04 /* coherent access */
+
+#define USB_INTEN_FORCE 0x20
+#define USB_INTEN_PHY 0x10
+#define USB_INTEN_UDC 0x08
+#define USB_INTEN_EHCI 0x04
+#define USB_INTEN_OHCI1 0x02
+#define USB_INTEN_OHCI0 0x01
static DEFINE_SPINLOCK(alchemy_usb_lock);
+static inline void __au1300_usb_phyctl(void __iomem *base, int enable)
+{
+ unsigned long r, s;
+
+ r = __raw_readl(base + USB_DWC_CTRL2);
+ s = __raw_readl(base + USB_DWC_CTRL3);
+
+ s &= USB_DWC_CTRL3_OHCI1_CKEN | USB_DWC_CTRL3_OHCI0_CKEN |
+ USB_DWC_CTRL3_EHCI0_CKEN | USB_DWC_CTRL3_OTG0_CKEN;
+
+ if (enable) {
+ /* simply enable all PHYs */
+ r |= USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
+ USB_DWC_CTRL2_PHYRS;
+ __raw_writel(r, base + USB_DWC_CTRL2);
+ wmb();
+ } else if (!s) {
+ /* no USB block active, do disable all PHYs */
+ r &= ~(USB_DWC_CTRL2_PHY1RS | USB_DWC_CTRL2_PHY0RS |
+ USB_DWC_CTRL2_PHYRS);
+ __raw_writel(r, base + USB_DWC_CTRL2);
+ wmb();
+ }
+}
+
+static inline void __au1300_ohci_control(void __iomem *base, int enable, int id)
+{
+ unsigned long r;
+
+ if (enable) {
+ __raw_writel(1, base + USB_DWC_CTRL7); /* start OHCI clock */
+ wmb();
+
+ r = __raw_readl(base + USB_DWC_CTRL3); /* enable OHCI block */
+ r |= (id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
+ : USB_DWC_CTRL3_OHCI1_CKEN;
+ __raw_writel(r, base + USB_DWC_CTRL3);
+ wmb();
+
+ __au1300_usb_phyctl(base, enable); /* power up the PHYs */
+
+ r = __raw_readl(base + USB_INT_ENABLE);
+ r |= (id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1;
+ __raw_writel(r, base + USB_INT_ENABLE);
+ wmb();
+
+ /* reset the OHCI start clock bit */
+ __raw_writel(0, base + USB_DWC_CTRL7);
+ wmb();
+ } else {
+ r = __raw_readl(base + USB_INT_ENABLE);
+ r &= ~((id == 0) ? USB_INTEN_OHCI0 : USB_INTEN_OHCI1);
+ __raw_writel(r, base + USB_INT_ENABLE);
+ wmb();
+
+ r = __raw_readl(base + USB_DWC_CTRL3);
+ r &= ~((id == 0) ? USB_DWC_CTRL3_OHCI0_CKEN
+ : USB_DWC_CTRL3_OHCI1_CKEN);
+ __raw_writel(r, base + USB_DWC_CTRL3);
+ wmb();
+
+ __au1300_usb_phyctl(base, enable);
+ }
+}
+
+static inline void __au1300_ehci_control(void __iomem *base, int enable)
+{
+ unsigned long r;
+
+ if (enable) {
+ r = __raw_readl(base + USB_DWC_CTRL3);
+ r |= USB_DWC_CTRL3_EHCI0_CKEN;
+ __raw_writel(r, base + USB_DWC_CTRL3);
+ wmb();
+
+ r = __raw_readl(base + USB_DWC_CTRL1);
+ r |= USB_DWC_CTRL1_HSTRS;
+ __raw_writel(r, base + USB_DWC_CTRL1);
+ wmb();
+
+ __au1300_usb_phyctl(base, enable);
+
+ r = __raw_readl(base + USB_INT_ENABLE);
+ r |= USB_INTEN_EHCI;
+ __raw_writel(r, base + USB_INT_ENABLE);
+ wmb();
+ } else {
+ r = __raw_readl(base + USB_INT_ENABLE);
+ r &= ~USB_INTEN_EHCI;
+ __raw_writel(r, base + USB_INT_ENABLE);
+ wmb();
+
+ r = __raw_readl(base + USB_DWC_CTRL1);
+ r &= ~USB_DWC_CTRL1_HSTRS;
+ __raw_writel(r, base + USB_DWC_CTRL1);
+ wmb();
+
+ r = __raw_readl(base + USB_DWC_CTRL3);
+ r &= ~USB_DWC_CTRL3_EHCI0_CKEN;
+ __raw_writel(r, base + USB_DWC_CTRL3);
+ wmb();
+
+ __au1300_usb_phyctl(base, enable);
+ }
+}
+
+static inline void __au1300_udc_control(void __iomem *base, int enable)
+{
+ unsigned long r;
+
+ if (enable) {
+ r = __raw_readl(base + USB_DWC_CTRL1);
+ r |= USB_DWC_CTRL1_DCRS;
+ __raw_writel(r, base + USB_DWC_CTRL1);
+ wmb();
+
+ __au1300_usb_phyctl(base, enable);
+
+ r = __raw_readl(base + USB_INT_ENABLE);
+ r |= USB_INTEN_UDC;
+ __raw_writel(r, base + USB_INT_ENABLE);
+ wmb();
+ } else {
+ r = __raw_readl(base + USB_INT_ENABLE);
+ r &= ~USB_INTEN_UDC;
+ __raw_writel(r, base + USB_INT_ENABLE);
+ wmb();
+
+ r = __raw_readl(base + USB_DWC_CTRL1);
+ r &= ~USB_DWC_CTRL1_DCRS;
+ __raw_writel(r, base + USB_DWC_CTRL1);
+ wmb();
+
+ __au1300_usb_phyctl(base, enable);
+ }
+}
+
+static inline void __au1300_otg_control(void __iomem *base, int enable)
+{
+ unsigned long r;
+ if (enable) {
+ r = __raw_readl(base + USB_DWC_CTRL3);
+ r |= USB_DWC_CTRL3_OTG0_CKEN;
+ __raw_writel(r, base + USB_DWC_CTRL3);
+ wmb();
+
+ r = __raw_readl(base + USB_DWC_CTRL1);
+ r &= ~USB_DWC_CTRL1_OTGD;
+ __raw_writel(r, base + USB_DWC_CTRL1);
+ wmb();
+
+ __au1300_usb_phyctl(base, enable);
+ } else {
+ r = __raw_readl(base + USB_DWC_CTRL1);
+ r |= USB_DWC_CTRL1_OTGD;
+ __raw_writel(r, base + USB_DWC_CTRL1);
+ wmb();
+
+ r = __raw_readl(base + USB_DWC_CTRL3);
+ r &= ~USB_DWC_CTRL3_OTG0_CKEN;
+ __raw_writel(r, base + USB_DWC_CTRL3);
+ wmb();
+
+ __au1300_usb_phyctl(base, enable);
+ }
+}
+
+static inline int au1300_usb_control(int block, int enable)
+{
+ void __iomem *base =
+ (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
+ int ret = 0;
+
+ switch (block) {
+ case ALCHEMY_USB_OHCI0:
+ __au1300_ohci_control(base, enable, 0);
+ break;
+ case ALCHEMY_USB_OHCI1:
+ __au1300_ohci_control(base, enable, 1);
+ break;
+ case ALCHEMY_USB_EHCI0:
+ __au1300_ehci_control(base, enable);
+ break;
+ case ALCHEMY_USB_UDC0:
+ __au1300_udc_control(base, enable);
+ break;
+ case ALCHEMY_USB_OTG0:
+ __au1300_otg_control(base, enable);
+ break;
+ default:
+ ret = -ENODEV;
+ }
+ return ret;
+}
+
+static inline void au1300_usb_init(void)
+{
+ void __iomem *base =
+ (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
+
+ /* set some sane defaults. Note: we don't fiddle with DWC_CTRL4
+ * here at all: Port 2 routing (EHCI or UDC) must be set either
+ * by boot firmware or platform init code; I can't autodetect
+ * a sane setting.
+ */
+ __raw_writel(0, base + USB_INT_ENABLE); /* disable all USB irqs */
+ wmb();
+ __raw_writel(0, base + USB_DWC_CTRL3); /* disable all clocks */
+ wmb();
+ __raw_writel(~0, base + USB_MSR_ERR); /* clear all errors */
+ wmb();
+ __raw_writel(~0, base + USB_INT_STATUS); /* clear int status */
+ wmb();
+ /* set coherent access bit */
+ __raw_writel(USB_SBUS_CTRL_SBCA, base + USB_SBUS_CTRL);
+ wmb();
+}
static inline void __au1200_ohci_control(void __iomem *base, int enable)
{
@@ -233,6 +487,9 @@ int alchemy_usb_control(int block, int enable)
case ALCHEMY_CPU_AU1200:
ret = au1200_usb_control(block, enable);
break;
+ case ALCHEMY_CPU_AU1300:
+ ret = au1300_usb_control(block, enable);
+ break;
default:
ret = -ENODEV;
}
@@ -281,6 +538,20 @@ static void au1200_usb_pm(int susp)
}
}
+static void au1300_usb_pm(int susp)
+{
+ void __iomem *base =
+ (void __iomem *)KSEG1ADDR(AU1300_USB_CTL_PHYS_ADDR);
+ /* remember Port2 routing */
+ if (susp) {
+ alchemy_usb_pmdata[0] = __raw_readl(base + USB_DWC_CTRL4);
+ } else {
+ au1300_usb_init();
+ __raw_writel(alchemy_usb_pmdata[0], base + USB_DWC_CTRL4);
+ wmb();
+ }
+}
+
static void alchemy_usb_pm(int susp)
{
switch (alchemy_get_cputype()) {
@@ -295,6 +566,9 @@ static void alchemy_usb_pm(int susp)
case ALCHEMY_CPU_AU1200:
au1200_usb_pm(susp);
break;
+ case ALCHEMY_CPU_AU1300:
+ au1300_usb_pm(susp);
+ break;
}
}
@@ -328,6 +602,9 @@ static int __init alchemy_usb_init(void)
case ALCHEMY_CPU_AU1200:
au1200_usb_init();
break;
+ case ALCHEMY_CPU_AU1300:
+ au1300_usb_init();
+ break;
}
register_syscore_ops(&alchemy_usb_pm_ops);
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c
index afb6743cf094..f1424f9bc363 100644
--- a/drivers/usb/host/ehci-ath79.c
+++ b/drivers/usb/host/ehci-ath79.c
@@ -33,6 +33,10 @@ static const struct platform_device_id ehci_ath79_id_table[] = {
.driver_data = EHCI_ATH79_IP_V2,
},
{
+ .name = "ar933x-ehci",
+ .driver_data = EHCI_ATH79_IP_V2,
+ },
+ {
/* terminating entry */
},
};
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e311a511529b..a007a9fe0f87 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -112,7 +112,7 @@ module_param (park, uint, S_IRUGO);
MODULE_PARM_DESC (park, "park setting; 1-3 back-to-back async packets");
/* for flakey hardware, ignore overcurrent indicators */
-static int ignore_oc = 0;
+static bool ignore_oc = 0;
module_param (ignore_oc, bool, S_IRUGO);
MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications");
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c
index 40d886adff53..4ea63b2cac42 100644
--- a/drivers/usb/host/ohci-au1xxx.c
+++ b/drivers/usb/host/ohci-au1xxx.c
@@ -89,7 +89,7 @@ static const struct hc_driver ohci_au1xxx_hc_driver = {
static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
{
- int ret;
+ int ret, unit;
struct usb_hcd *hcd;
if (usb_disabled())
@@ -120,7 +120,9 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
goto err2;
}
- if (alchemy_usb_control(ALCHEMY_USB_OHCI0, 1)) {
+ unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
+ ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
+ if (alchemy_usb_control(unit, 1)) {
printk(KERN_INFO "%s: controller init failed!\n", pdev->name);
ret = -ENODEV;
goto err3;
@@ -135,7 +137,7 @@ static int ohci_hcd_au1xxx_drv_probe(struct platform_device *pdev)
return ret;
}
- alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
+ alchemy_usb_control(unit, 0);
err3:
iounmap(hcd->regs);
err2:
@@ -148,9 +150,12 @@ err1:
static int ohci_hcd_au1xxx_drv_remove(struct platform_device *pdev)
{
struct usb_hcd *hcd = platform_get_drvdata(pdev);
+ int unit;
+ unit = (hcd->rsrc_start == AU1300_USB_OHCI1_PHYS_ADDR) ?
+ ALCHEMY_USB_OHCI1 : ALCHEMY_USB_OHCI0;
usb_remove_hcd(hcd);
- alchemy_usb_control(ALCHEMY_USB_OHCI0, 0);
+ alchemy_usb_control(unit, 0);
iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
usb_put_hcd(hcd);
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5f5a63241436..34b9edd86651 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -115,13 +115,13 @@ static inline void sb800_prefetch(struct ohci_hcd *ohci, int on)
/* Some boards misreport power switching/overcurrent */
-static int distrust_firmware = 1;
+static bool distrust_firmware = 1;
module_param (distrust_firmware, bool, 0);
MODULE_PARM_DESC (distrust_firmware,
"true to distrust firmware power/overcurrent setup");
/* Some boards leave IR set wrongly, since they fail BIOS/SMM handshakes */
-static int no_handshake = 0;
+static bool no_handshake = 0;
module_param (no_handshake, bool, 0);
MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake");
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c
index 6f62de5c6e35..015c7c62ed49 100644
--- a/drivers/usb/host/oxu210hp-hcd.c
+++ b/drivers/usb/host/oxu210hp-hcd.c
@@ -233,7 +233,7 @@ module_param(park, uint, S_IRUGO);
MODULE_PARM_DESC(park, "park setting; 1-3 back-to-back async packets");
/* For flakey hardware, ignore overcurrent indicators */
-static int ignore_oc;
+static bool ignore_oc;
module_param(ignore_oc, bool, S_IRUGO);
MODULE_PARM_DESC(ignore_oc, "ignore bogus hardware overcurrent indications");
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c
index 533d12cca371..16dd6a6abf00 100644
--- a/drivers/usb/host/u132-hcd.c
+++ b/drivers/usb/host/u132-hcd.c
@@ -74,7 +74,7 @@ MODULE_LICENSE("GPL");
#define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444)
INT_MODULE_PARM(testing, 0);
/* Some boards misreport power switching/overcurrent*/
-static int distrust_firmware = 1;
+static bool distrust_firmware = 1;
module_param(distrust_firmware, bool, 0);
MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren"
"t setup");
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c
index c8ae199cfbb8..6b5eb1017e2c 100644
--- a/drivers/usb/host/uhci-hcd.c
+++ b/drivers/usb/host/uhci-hcd.c
@@ -59,7 +59,7 @@
#define DRIVER_DESC "USB Universal Host Controller Interface driver"
/* for flakey hardware, ignore overcurrent indicators */
-static int ignore_oc;
+static bool ignore_oc;
module_param(ignore_oc, bool, S_IRUGO);
MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications");
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c
index 2dbe600fbc11..a4a3c7cd4a11 100644
--- a/drivers/usb/misc/ftdi-elan.c
+++ b/drivers/usb/misc/ftdi-elan.c
@@ -53,7 +53,7 @@ MODULE_AUTHOR("Tony Olech");
MODULE_DESCRIPTION("FTDI ELAN driver");
MODULE_LICENSE("GPL");
#define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444)
-static int distrust_firmware = 1;
+static bool distrust_firmware = 1;
module_param(distrust_firmware, bool, 0);
MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren"
"t setup");
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 2453a39b4794..4fd0dc835ae5 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -62,7 +62,7 @@ MODULE_LICENSE("GPL");
/* Module parameters */
static DEFINE_MUTEX(iowarrior_mutex);
-static int debug = 0;
+static bool debug = 0;
module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c
index 53be7aef6308..66bc376005d2 100644
--- a/drivers/usb/musb/cppi_dma.c
+++ b/drivers/usb/musb/cppi_dma.c
@@ -750,7 +750,7 @@ cppi_next_tx_segment(struct musb *musb, struct cppi_channel *tx)
* So this module parameter lets the heuristic be disabled. When using
* gadgetfs, the heuristic will probably need to be disabled.
*/
-static int cppi_rx_rndis = 1;
+static bool cppi_rx_rndis = 1;
module_param(cppi_rx_rndis, bool, 0);
MODULE_PARM_DESC(cppi_rx_rndis, "enable/disable RX RNDIS heuristic");
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index f6ff7923048b..56cf0243979e 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -1586,7 +1586,7 @@ irqreturn_t musb_interrupt(struct musb *musb)
EXPORT_SYMBOL_GPL(musb_interrupt);
#ifndef CONFIG_MUSB_PIO_ONLY
-static int __initdata use_dma = 1;
+static bool __initdata use_dma = 1;
/* "modprobe ... use_dma=0" etc */
module_param(use_dma, bool, 0);
diff --git a/drivers/usb/otg/ab8500-usb.c b/drivers/usb/otg/ab8500-usb.c
index 07ccea9ada40..74fe6e62e0f7 100644
--- a/drivers/usb/otg/ab8500-usb.c
+++ b/drivers/usb/otg/ab8500-usb.c
@@ -30,7 +30,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/mfd/abx500.h>
-#include <linux/mfd/ab8500.h>
+#include <linux/mfd/abx500/ab8500.h>
#define AB8500_MAIN_WD_CTRL_REG 0x01
#define AB8500_USB_LINE_STAT_REG 0x80
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c
index b43d07df4c44..123bf9155339 100644
--- a/drivers/usb/serial/aircable.c
+++ b/drivers/usb/serial/aircable.c
@@ -52,7 +52,7 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-static int debug;
+static bool debug;
/* Vendor and Product ID */
#define AIRCABLE_VID 0x16CA
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c
index 18e875b92e00..69328dcfd91a 100644
--- a/drivers/usb/serial/ark3116.c
+++ b/drivers/usb/serial/ark3116.c
@@ -37,7 +37,7 @@
#include <linux/mutex.h>
#include <linux/spinlock.h>
-static int debug;
+static bool debug;
/*
* Version information
*/
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index f9f29b289f2f..29ffeb6279c7 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -37,7 +37,7 @@
#include <linux/usb/serial.h>
#include "belkin_sa.h"
-static int debug;
+static bool debug;
/*
* Version Information
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index 0e77511060c0..5e53cc59e652 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -70,7 +70,7 @@
#define CH341_NBREAK_BITS_REG2 0x40
-static int debug;
+static bool debug;
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x4348, 0x5523) },
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index adfe660ed008..fba1147ed916 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -49,7 +49,7 @@ static void cp210x_break_ctl(struct tty_struct *, int);
static int cp210x_startup(struct usb_serial *);
static void cp210x_dtr_rts(struct usb_serial_port *p, int on);
-static int debug;
+static bool debug;
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x045B, 0x0053) }, /* Renesas RX610 RX-Stick */
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c
index 98bf83349838..6bc3802a581a 100644
--- a/drivers/usb/serial/cyberjack.c
+++ b/drivers/usb/serial/cyberjack.c
@@ -43,7 +43,7 @@
#define CYBERJACK_LOCAL_BUF_SIZE 32
-static int debug;
+static bool debug;
/*
* Version Information
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 07680d6b792b..3bdeafa29c24 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -46,10 +46,10 @@
#include "cypress_m8.h"
-static int debug;
-static int stats;
+static bool debug;
+static bool stats;
static int interval;
-static int unstable_bauds;
+static bool unstable_bauds;
/*
* Version Information
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index 6d26a77d0f2a..b23bebd721a1 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -251,7 +251,7 @@ static int digi_read_oob_callback(struct urb *urb);
/* Statics */
-static int debug;
+static bool debug;
static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE(DIGI_VENDOR_ID, DIGI_2_ID) },
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c
index 504b5585ea45..aced6817bf95 100644
--- a/drivers/usb/serial/empeg.c
+++ b/drivers/usb/serial/empeg.c
@@ -28,7 +28,7 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-static int debug;
+static bool debug;
/*
* Version Information
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index c290df97108e..01b6404df395 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -55,7 +55,7 @@
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>, Andreas Mohr, Johan Hovold <jhovold@gmail.com>"
#define DRIVER_DESC "USB FTDI Serial Converters Driver"
-static int debug;
+static bool debug;
static __u16 vendor = FTDI_VID;
static __u16 product;
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c
index e21ce9ddfc63..5d4b099dcf8b 100644
--- a/drivers/usb/serial/funsoft.c
+++ b/drivers/usb/serial/funsoft.c
@@ -16,7 +16,7 @@
#include <linux/usb/serial.h>
#include <linux/uaccess.h>
-static int debug;
+static bool debug;
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x1404, 0xcddc) },
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c
index bf12565f8e87..21343378c322 100644
--- a/drivers/usb/serial/garmin_gps.c
+++ b/drivers/usb/serial/garmin_gps.c
@@ -42,7 +42,7 @@
static int initial_mode = 1;
/* debug flag */
-static int debug;
+static bool debug;
#define GARMIN_VENDOR_ID 0x091E
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
index abd2ee2b2f99..0497575e4799 100644
--- a/drivers/usb/serial/io_edgeport.c
+++ b/drivers/usb/serial/io_edgeport.c
@@ -191,7 +191,7 @@ static const struct divisor_table_entry divisor_table[] = {
};
/* local variables */
-static int debug;
+static bool debug;
static atomic_t CmdUrbs; /* Number of outstanding Command Write Urbs */
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index e44d375edaad..65bf06aa591a 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -210,10 +210,10 @@ static unsigned char OperationalMajorVersion;
static unsigned char OperationalMinorVersion;
static unsigned short OperationalBuildNumber;
-static int debug;
+static bool debug;
static int closing_wait = EDGE_CLOSING_WAIT;
-static int ignore_cpu_rev;
+static bool ignore_cpu_rev;
static int default_uart_mode; /* RS232 */
static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c
index 36f5cbe90485..06053a920dd8 100644
--- a/drivers/usb/serial/ipaq.c
+++ b/drivers/usb/serial/ipaq.c
@@ -34,7 +34,7 @@
#define DRIVER_DESC "USB PocketPC PDA driver"
static __u16 product, vendor;
-static int debug;
+static bool debug;
static int connect_retries = KP_RETRIES;
static int initial_wait;
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 5170799d6e94..6f9356f3f99e 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -147,7 +147,7 @@ static struct usb_driver usb_ipw_driver = {
.no_dynamic_id = 1,
};
-static int debug;
+static bool debug;
static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port)
{
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c
index 0c537da0d3cd..84a396e83671 100644
--- a/drivers/usb/serial/ir-usb.c
+++ b/drivers/usb/serial/ir-usb.c
@@ -45,7 +45,7 @@
#define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Johan Hovold <jhovold@gmail.com>"
#define DRIVER_DESC "USB IR Dongle driver"
-static int debug;
+static bool debug;
/* if overridden by the user, then use their value for the size of the read and
* write urbs */
diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c
index 64d0ffd4440b..3077a4436976 100644
--- a/drivers/usb/serial/iuu_phoenix.c
+++ b/drivers/usb/serial/iuu_phoenix.c
@@ -34,9 +34,9 @@
#ifdef CONFIG_USB_SERIAL_DEBUG
-static int debug = 1;
+static bool debug = 1;
#else
-static int debug;
+static bool debug;
#endif
/*
@@ -65,7 +65,7 @@ static int clockmode = 1;
static int cdmode = 1;
static int iuu_cardin;
static int iuu_cardout;
-static int xmas;
+static bool xmas;
static int vcc_default = 5;
static void read_rxcmd_callback(struct urb *urb);
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index bc8dc203e818..4cc36c761801 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -45,7 +45,7 @@
#include <linux/usb/serial.h>
#include "keyspan.h"
-static int debug;
+static bool debug;
/*
* Version Information
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c
index a40615674a68..7c62a7048302 100644
--- a/drivers/usb/serial/keyspan_pda.c
+++ b/drivers/usb/serial/keyspan_pda.c
@@ -31,7 +31,7 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-static int debug;
+static bool debug;
/* make a simple define to handle if we are compiling keyspan_pda or xircom support */
#if defined(CONFIG_USB_SERIAL_KEYSPAN_PDA) || defined(CONFIG_USB_SERIAL_KEYSPAN_PDA_MODULE)
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
index 19373cb7c5bf..fc064e1442ca 100644
--- a/drivers/usb/serial/kl5kusb105.c
+++ b/drivers/usb/serial/kl5kusb105.c
@@ -49,7 +49,7 @@
#include <linux/usb/serial.h>
#include "kl5kusb105.h"
-static int debug;
+static bool debug;
/*
* Version Information
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index a975bb80303f..27fa9c8a77b0 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -45,7 +45,7 @@
#define DRIVER_AUTHOR "Wolfgang Grandegger <wolfgang@ces.ch>"
#define DRIVER_DESC "Magic Control Technology USB-RS232 converter driver"
-static int debug;
+static bool debug;
/*
* Function prototypes
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
index 19d112f51b97..4554ee49e635 100644
--- a/drivers/usb/serial/mos7720.c
+++ b/drivers/usb/serial/mos7720.c
@@ -71,7 +71,7 @@ struct moschip_port {
struct urb *write_urb_pool[NUM_URBS];
};
-static int debug;
+static bool debug;
static struct usb_serial_driver moschip7720_2port_driver;
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c
index 55cfd6265b98..03b5e249e95e 100644
--- a/drivers/usb/serial/mos7840.c
+++ b/drivers/usb/serial/mos7840.c
@@ -263,7 +263,7 @@ struct moschip_port {
};
-static int debug;
+static bool debug;
/*
* mos7840_set_reg_sync
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c
index 1f00f243c26c..b28f1db0195f 100644
--- a/drivers/usb/serial/navman.c
+++ b/drivers/usb/serial/navman.c
@@ -21,7 +21,7 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-static int debug;
+static bool debug;
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0a99, 0x0001) }, /* Talon Technology device */
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c
index 45a8c55881d3..8b8d58a2ac12 100644
--- a/drivers/usb/serial/omninet.c
+++ b/drivers/usb/serial/omninet.c
@@ -23,7 +23,7 @@
#include <linux/usb.h>
#include <linux/usb/serial.h>
-static int debug;
+static bool debug;
/*
* Version Information
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c
index 691f57a9d712..262ded9e076b 100644
--- a/drivers/usb/serial/opticon.c
+++ b/drivers/usb/serial/opticon.c
@@ -32,7 +32,7 @@
* an examples of 1D barcode types are EAN, UPC, Code39, IATA etc.. */
#define DRIVER_DESC "Opticon USB barcode to serial driver (1D)"
-static int debug;
+static bool debug;
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x065a, 0x0009) },
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index c96b6b6509fb..420d9857394a 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -1234,7 +1234,7 @@ static struct usb_serial_driver option_1port_device = {
#endif
};
-static int debug;
+static bool debug;
/* per port private data */
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c
index 2161d1c3c089..e287fd32682c 100644
--- a/drivers/usb/serial/oti6858.c
+++ b/drivers/usb/serial/oti6858.c
@@ -74,7 +74,7 @@ static struct usb_driver oti6858_driver = {
.no_dynamic_id = 1,
};
-static int debug;
+static bool debug;
/* requests */
#define OTI6858_REQ_GET_STATUS (USB_DIR_IN | USB_TYPE_VENDOR | 0x00)
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 329295615d06..3d8cda57ce7a 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -36,7 +36,7 @@
*/
#define DRIVER_DESC "Prolific PL2303 USB to serial adaptor driver"
-static int debug;
+static bool debug;
#define PL2303_CLOSING_WAIT (30*HZ)
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
index aa9367f5b421..1d5deee3be52 100644
--- a/drivers/usb/serial/qcserial.c
+++ b/drivers/usb/serial/qcserial.c
@@ -22,7 +22,7 @@
#define DRIVER_AUTHOR "Qualcomm Inc"
#define DRIVER_DESC "Qualcomm USB Serial driver"
-static int debug;
+static bool debug;
static const struct usb_device_id id_table[] = {
{USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c
index a36e2313eed0..d074b3740dcb 100644
--- a/drivers/usb/serial/safe_serial.c
+++ b/drivers/usb/serial/safe_serial.c
@@ -81,9 +81,9 @@
#define CONFIG_USB_SERIAL_SAFE_PADDED 0
#endif
-static int debug;
-static int safe = 1;
-static int padded = CONFIG_USB_SERIAL_SAFE_PADDED;
+static bool debug;
+static bool safe = 1;
+static bool padded = CONFIG_USB_SERIAL_SAFE_PADDED;
#define DRIVER_VERSION "v0.1"
#define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com, Johan Hovold <jhovold@gmail.com>"
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index f2485429172f..fdae0a4407cb 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -46,8 +46,8 @@
allocations > PAGE_SIZE and the number of packets in a page
is an integer 512 is the largest possible packet on EHCI */
-static int debug;
-static int nmea;
+static bool debug;
+static bool nmea;
/* Used in interface blacklisting */
struct sierra_iface_info {
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index 180ea6c7911c..d7f5eee18f00 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -33,7 +33,7 @@
#define DRIVER_VERSION "v0.10"
#define DRIVER_DESC "SPCP8x5 USB to serial adaptor driver"
-static int debug;
+static bool debug;
#define SPCP8x5_007_VID 0x04FC
#define SPCP8x5_007_PID 0x0201
diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c
index 87362e48796e..7697858d8858 100644
--- a/drivers/usb/serial/ssu100.c
+++ b/drivers/usb/serial/ssu100.c
@@ -46,7 +46,7 @@
#define FULLPWRBIT 0x00000080
#define NEXT_BOARD_POWER_BIT 0x00000004
-static int debug;
+static bool debug;
/* Version Information */
#define DRIVER_VERSION "v0.1"
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c
index c70cc012d03f..50651cf4fc61 100644
--- a/drivers/usb/serial/symbolserial.c
+++ b/drivers/usb/serial/symbolserial.c
@@ -20,7 +20,7 @@
#include <linux/usb/serial.h>
#include <linux/uaccess.h>
-static int debug;
+static bool debug;
static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x05e0, 0x0600) },
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 4af21f46096e..8468eb769a29 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -150,7 +150,7 @@ static int ti_download_firmware(struct ti_device *tdev);
/* Data */
/* module parameters */
-static int debug;
+static bool debug;
static int closing_wait = TI_DEFAULT_CLOSING_WAIT;
static ushort vendor_3410[TI_EXTRA_VID_PID_COUNT];
static unsigned int vendor_3410_count;
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index ce6c1a65a544..611b206591cb 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -61,7 +61,7 @@ static struct usb_driver usb_serial_driver = {
drivers depend on it.
*/
-static int debug;
+static bool debug;
/* initially all NULL */
static struct usb_serial *serial_table[SERIAL_TTY_MINORS];
static DEFINE_MUTEX(table_lock);
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index d555ca9567b8..c88657dd31c8 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -37,7 +37,7 @@
#include <linux/serial.h>
#include "usb-wwan.h"
-static int debug;
+static bool debug;
void usb_wwan_dtr_rts(struct usb_serial_port *port, int on)
{
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index 1c11959a7d58..210e4b10dc11 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -52,7 +52,7 @@ static int palm_os_4_probe(struct usb_serial *serial,
const struct usb_device_id *id);
/* Parameters that may be passed into the module. */
-static int debug;
+static bool debug;
static __u16 vendor;
static __u16 product;
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c
index 11af903cb09f..7e0acf5c8e38 100644
--- a/drivers/usb/serial/whiteheat.c
+++ b/drivers/usb/serial/whiteheat.c
@@ -36,7 +36,7 @@
#include <linux/ihex.h>
#include "whiteheat.h" /* WhiteHEAT specific commands */
-static int debug;
+static bool debug;
#ifndef CMSPAR
#define CMSPAR 0
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index d83e967e4e15..6ca0c407c144 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1763,16 +1763,16 @@ config FB_AU1100
au1100fb:panel=<name>.
config FB_AU1200
- bool "Au1200 LCD Driver"
+ bool "Au1200/Au1300 LCD Driver"
depends on (FB = y) && MIPS_ALCHEMY
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_SYS_FOPS
help
- This is the framebuffer driver for the AMD Au1200 SOC. It can drive
- various panels and CRTs by passing in kernel cmd line option
- au1200fb:panel=<name>.
+ This is the framebuffer driver for the Au1200/Au1300 SOCs.
+ It can drive various panels and CRTs by passing in kernel cmd line
+ option au1200fb:panel=<name>.
config FB_VT8500
bool "VT8500 LCD Driver"
@@ -2413,7 +2413,6 @@ source "drivers/video/omap/Kconfig"
source "drivers/video/omap2/Kconfig"
source "drivers/video/backlight/Kconfig"
-source "drivers/video/display/Kconfig"
if VT
source "drivers/video/console/Kconfig"
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 9b9d8fff7732..142606814d98 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -13,7 +13,7 @@ fb-objs := $(fb-y)
obj-$(CONFIG_VT) += console/
obj-$(CONFIG_LOGO) += logo/
-obj-y += backlight/ display/
+obj-y += backlight/
obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 5ea6596dd824..f23cae094f1b 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -152,10 +152,10 @@
- hsstrt: Start of horizontal synchronization pulse
- hsstop: End of horizontal synchronization pulse
- - htotal: Last value on the line (i.e. line length = htotal+1)
+ - htotal: Last value on the line (i.e. line length = htotal + 1)
- vsstrt: Start of vertical synchronization pulse
- vsstop: End of vertical synchronization pulse
- - vtotal: Last line value (i.e. number of lines = vtotal+1)
+ - vtotal: Last line value (i.e. number of lines = vtotal + 1)
- hcenter: Start of vertical retrace for interlace
You can specify the blanking timings independently. Currently I just set
@@ -184,7 +184,7 @@
clock):
- diwstrt_h: Horizontal start of the visible window
- - diwstop_h: Horizontal stop+1(*) of the visible window
+ - diwstop_h: Horizontal stop + 1(*) of the visible window
- diwstrt_v: Vertical start of the visible window
- diwstop_v: Vertical stop of the visible window
- ddfstrt: Horizontal start of display DMA
@@ -193,7 +193,7 @@
Sprite positioning:
- - sprstrt_h: Horizontal start-4 of sprite
+ - sprstrt_h: Horizontal start - 4 of sprite
- sprstrt_v: Vertical start of sprite
(*) Even Commodore did it wrong in the AGA monitor drivers by not adding 1.
@@ -212,21 +212,21 @@
display parameters. Here's what I found out:
- ddfstrt and ddfstop are best aligned to 64 pixels.
- - the chipset needs 64+4 horizontal pixels after the DMA start before the
- first pixel is output, so diwstrt_h = ddfstrt+64+4 if you want to
- display the first pixel on the line too. Increase diwstrt_h for virtual
- screen panning.
+ - the chipset needs 64 + 4 horizontal pixels after the DMA start before
+ the first pixel is output, so diwstrt_h = ddfstrt + 64 + 4 if you want
+ to display the first pixel on the line too. Increase diwstrt_h for
+ virtual screen panning.
- the display DMA always fetches 64 pixels at a time (fmode = 3).
- - ddfstop is ddfstrt+#pixels-64.
- - diwstop_h = diwstrt_h+xres+1. Because of the additional 1 this can be 1
- more than htotal.
+ - ddfstop is ddfstrt+#pixels - 64.
+ - diwstop_h = diwstrt_h + xres + 1. Because of the additional 1 this can
+ be 1 more than htotal.
- hscroll simply adds a delay to the display output. Smooth horizontal
- panning needs an extra 64 pixels on the left to prefetch the pixels that
- `fall off' on the left.
+ panning needs an extra 64 pixels on the left to prefetch the pixels that
+ `fall off' on the left.
- if ddfstrt < 192, the sprite DMA cycles are all stolen by the bitplane
- DMA, so it's best to make the DMA start as late as possible.
+ DMA, so it's best to make the DMA start as late as possible.
- you really don't want to make ddfstrt < 128, since this will steal DMA
- cycles from the other DMA channels (audio, floppy and Chip RAM refresh).
+ cycles from the other DMA channels (audio, floppy and Chip RAM refresh).
- I make diwstop_h and diwstop_v as large as possible.
General dependencies
@@ -234,8 +234,8 @@
- all values are SHRES pixel (35ns)
- table 1:fetchstart table 2:prefetch table 3:fetchsize
- ------------------ ---------------- -----------------
+ table 1:fetchstart table 2:prefetch table 3:fetchsize
+ ------------------ ---------------- -----------------
Pixclock # SHRES|HIRES|LORES # SHRES|HIRES|LORES # SHRES|HIRES|LORES
-------------#------+-----+------#------+-----+------#------+-----+------
Bus width 1x # 16 | 32 | 64 # 16 | 32 | 64 # 64 | 64 | 64
@@ -245,21 +245,21 @@
- chipset needs 4 pixels before the first pixel is output
- ddfstrt must be aligned to fetchstart (table 1)
- chipset needs also prefetch (table 2) to get first pixel data, so
- ddfstrt = ((diwstrt_h-4) & -fetchstart) - prefetch
+ ddfstrt = ((diwstrt_h - 4) & -fetchstart) - prefetch
- for horizontal panning decrease diwstrt_h
- the length of a fetchline must be aligned to fetchsize (table 3)
- if fetchstart is smaller than fetchsize, then ddfstrt can a little bit
- moved to optimize use of dma (useful for OCS/ECS overscan displays)
- - ddfstop is ddfstrt+ddfsize-fetchsize
+ moved to optimize use of dma (useful for OCS/ECS overscan displays)
+ - ddfstop is ddfstrt + ddfsize - fetchsize
- If C= didn't change anything for AGA, then at following positions the
- dma bus is already used:
- ddfstrt < 48 -> memory refresh
- < 96 -> disk dma
- < 160 -> audio dma
- < 192 -> sprite 0 dma
- < 416 -> sprite dma (32 per sprite)
+ dma bus is already used:
+ ddfstrt < 48 -> memory refresh
+ < 96 -> disk dma
+ < 160 -> audio dma
+ < 192 -> sprite 0 dma
+ < 416 -> sprite dma (32 per sprite)
- in accordance with the hardware reference manual a hardware stop is at
- 192, but AGA (ECS?) can go below this.
+ 192, but AGA (ECS?) can go below this.
DMA priorities
--------------
@@ -269,7 +269,7 @@
the hardware cursor:
- if you want to start display DMA too early, you lose the ability to
- do smooth horizontal panning (xpanstep 1 -> 64).
+ do smooth horizontal panning (xpanstep 1 -> 64).
- if you want to go even further, you lose the hardware cursor too.
IMHO a hardware cursor is more important for X than horizontal scrolling,
@@ -286,8 +286,8 @@
Standard VGA timings
--------------------
- xres yres left right upper lower hsync vsync
- ---- ---- ---- ----- ----- ----- ----- -----
+ xres yres left right upper lower hsync vsync
+ ---- ---- ---- ----- ----- ----- ----- -----
80x25 720 400 27 45 35 12 108 2
80x30 720 480 27 45 30 9 108 2
@@ -297,8 +297,8 @@
As a comparison, graphics/monitor.h suggests the following:
- xres yres left right upper lower hsync vsync
- ---- ---- ---- ----- ----- ----- ----- -----
+ xres yres left right upper lower hsync vsync
+ ---- ---- ---- ----- ----- ----- ----- -----
VGA 640 480 52 112 24 19 112 - 2 +
VGA70 640 400 52 112 27 21 112 - 2 -
@@ -309,10 +309,10 @@
VSYNC HSYNC Vertical size Vertical total
----- ----- ------------- --------------
- + + Reserved Reserved
- + - 400 414
- - + 350 362
- - - 480 496
+ + + Reserved Reserved
+ + - 400 414
+ - + 350 362
+ - - 480 496
Source: CL-GD542X Technical Reference Manual, Cirrus Logic, Oct 1992
@@ -326,33 +326,34 @@
-----------
- a scanline is 64 µs long, of which 52.48 µs are visible. This is about
- 736 visible 70 ns pixels per line.
+ 736 visible 70 ns pixels per line.
- we have 625 scanlines, of which 575 are visible (interlaced); after
- rounding this becomes 576.
+ rounding this becomes 576.
RETMA -> NTSC
-------------
- a scanline is 63.5 µs long, of which 53.5 µs are visible. This is about
- 736 visible 70 ns pixels per line.
+ 736 visible 70 ns pixels per line.
- we have 525 scanlines, of which 485 are visible (interlaced); after
- rounding this becomes 484.
+ rounding this becomes 484.
Thus if you want a PAL compatible display, you have to do the following:
- set the FB_SYNC_BROADCAST flag to indicate that standard broadcast
- timings are to be used.
- - make sure upper_margin+yres+lower_margin+vsync_len = 625 for an
- interlaced, 312 for a non-interlaced and 156 for a doublescanned
- display.
- - make sure left_margin+xres+right_margin+hsync_len = 1816 for a SHRES,
- 908 for a HIRES and 454 for a LORES display.
+ timings are to be used.
+ - make sure upper_margin + yres + lower_margin + vsync_len = 625 for an
+ interlaced, 312 for a non-interlaced and 156 for a doublescanned
+ display.
+ - make sure left_margin + xres + right_margin + hsync_len = 1816 for a
+ SHRES, 908 for a HIRES and 454 for a LORES display.
- the left visible part begins at 360 (SHRES; HIRES:180, LORES:90),
- left_margin+2*hsync_len must be greater or equal.
+ left_margin + 2 * hsync_len must be greater or equal.
- the upper visible part begins at 48 (interlaced; non-interlaced:24,
- doublescanned:12), upper_margin+2*vsync_len must be greater or equal.
+ doublescanned:12), upper_margin + 2 * vsync_len must be greater or
+ equal.
- ami_encode_var() calculates margins with a hsync of 5320 ns and a vsync
- of 4 scanlines
+ of 4 scanlines
The settings for a NTSC compatible display are straightforward.
@@ -361,7 +362,7 @@
anything about horizontal/vertical synchronization nor refresh rates.
- -- Geert --
+ -- Geert --
*******************************************************************************/
@@ -540,45 +541,45 @@ static u_short maxfmode, chipset;
* Various macros
*/
-#define up2(v) (((v)+1) & -2)
+#define up2(v) (((v) + 1) & -2)
#define down2(v) ((v) & -2)
#define div2(v) ((v)>>1)
#define mod2(v) ((v) & 1)
-#define up4(v) (((v)+3) & -4)
+#define up4(v) (((v) + 3) & -4)
#define down4(v) ((v) & -4)
-#define mul4(v) ((v)<<2)
+#define mul4(v) ((v) << 2)
#define div4(v) ((v)>>2)
#define mod4(v) ((v) & 3)
-#define up8(v) (((v)+7) & -8)
+#define up8(v) (((v) + 7) & -8)
#define down8(v) ((v) & -8)
#define div8(v) ((v)>>3)
#define mod8(v) ((v) & 7)
-#define up16(v) (((v)+15) & -16)
+#define up16(v) (((v) + 15) & -16)
#define down16(v) ((v) & -16)
#define div16(v) ((v)>>4)
#define mod16(v) ((v) & 15)
-#define up32(v) (((v)+31) & -32)
+#define up32(v) (((v) + 31) & -32)
#define down32(v) ((v) & -32)
#define div32(v) ((v)>>5)
#define mod32(v) ((v) & 31)
-#define up64(v) (((v)+63) & -64)
+#define up64(v) (((v) + 63) & -64)
#define down64(v) ((v) & -64)
#define div64(v) ((v)>>6)
#define mod64(v) ((v) & 63)
-#define upx(x,v) (((v)+(x)-1) & -(x))
-#define downx(x,v) ((v) & -(x))
-#define modx(x,v) ((v) & ((x)-1))
+#define upx(x, v) (((v) + (x) - 1) & -(x))
+#define downx(x, v) ((v) & -(x))
+#define modx(x, v) ((v) & ((x) - 1))
/* if x1 is not a constant, this macro won't make real sense :-) */
#ifdef __mc68000__
#define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \
- "d" (x2), "d" ((long)((x1)/0x100000000ULL)), "0" ((long)(x1))); res;})
+ "d" (x2), "d" ((long)((x1) / 0x100000000ULL)), "0" ((long)(x1))); res;})
#else
/* We know a bit about the numbers, so we can do it this way */
#define DIVUL(x1, x2) ((((long)((unsigned long long)x1 >> 8) / x2) << 8) + \
@@ -607,7 +608,7 @@ static u_short maxfmode, chipset;
#define VIDEOMEMSIZE_ECS_1M (393216) /* ECS (1MB) : max 1024*768*16 */
#define VIDEOMEMSIZE_OCS (262144) /* OCS : max ca. 800*600*16 */
-#define SPRITEMEMSIZE (64*64/4) /* max 64*64*4 */
+#define SPRITEMEMSIZE (64 * 64 / 4) /* max 64*64*4 */
#define DUMMYSPRITEMEMSIZE (8)
static u_long spritememory;
@@ -634,9 +635,9 @@ static u_long min_fstrt = 192;
* Copper Instructions
*/
-#define CMOVE(val, reg) (CUSTOM_OFS(reg)<<16 | (val))
-#define CMOVE2(val, reg) ((CUSTOM_OFS(reg)+2)<<16 | (val))
-#define CWAIT(x, y) (((y) & 0x1fe)<<23 | ((x) & 0x7f0)<<13 | 0x0001fffe)
+#define CMOVE(val, reg) (CUSTOM_OFS(reg) << 16 | (val))
+#define CMOVE2(val, reg) ((CUSTOM_OFS(reg) + 2) << 16 | (val))
+#define CWAIT(x, y) (((y) & 0x1fe) << 23 | ((x) & 0x7f0) << 13 | 0x0001fffe)
#define CEND (0xfffffffe)
@@ -709,7 +710,7 @@ static u_short *lofsprite, *shfsprite, *dummysprite;
* Current Video Mode
*/
-static struct amifb_par {
+struct amifb_par {
/* General Values */
@@ -772,15 +773,6 @@ static struct amifb_par {
/* Additional AGA Hardware Registers */
u_short fmode; /* vmode */
-} currentpar;
-
-
-static struct fb_info fb_info = {
- .fix = {
- .id = "Amiga ",
- .visual = FB_VISUAL_PSEUDOCOLOR,
- .accel = FB_ACCEL_AMIGABLITT
- }
};
@@ -820,116 +812,123 @@ static u_short is_lace = 0; /* Screen is laced */
static struct fb_videomode ami_modedb[] __initdata = {
- /*
- * AmigaOS Video Modes
- *
- * If you change these, make sure to update DEFMODE_* as well!
- */
-
- {
- /* 640x200, 15 kHz, 60 Hz (NTSC) */
- "ntsc", 60, 640, 200, TAG_HIRES, 106, 86, 44, 16, 76, 2,
- FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
- "ntsc-lace", 60, 640, 400, TAG_HIRES, 106, 86, 88, 33, 76, 4,
- FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x256, 15 kHz, 50 Hz (PAL) */
- "pal", 50, 640, 256, TAG_HIRES, 106, 86, 40, 14, 76, 2,
- FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
- "pal-lace", 50, 640, 512, TAG_HIRES, 106, 86, 80, 29, 76, 4,
- FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x480, 29 kHz, 57 Hz */
- "multiscan", 57, 640, 480, TAG_SHRES, 96, 112, 29, 8, 72, 8,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x960, 29 kHz, 57 Hz interlaced */
- "multiscan-lace", 57, 640, 960, TAG_SHRES, 96, 112, 58, 16, 72, 16,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x200, 15 kHz, 72 Hz */
- "euro36", 72, 640, 200, TAG_HIRES, 92, 124, 6, 6, 52, 5,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x400, 15 kHz, 72 Hz interlaced */
- "euro36-lace", 72, 640, 400, TAG_HIRES, 92, 124, 12, 12, 52, 10,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x400, 29 kHz, 68 Hz */
- "euro72", 68, 640, 400, TAG_SHRES, 164, 92, 9, 9, 80, 8,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x800, 29 kHz, 68 Hz interlaced */
- "euro72-lace", 68, 640, 800, TAG_SHRES, 164, 92, 18, 18, 80, 16,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 800x300, 23 kHz, 70 Hz */
- "super72", 70, 800, 300, TAG_SHRES, 212, 140, 10, 11, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 800x600, 23 kHz, 70 Hz interlaced */
- "super72-lace", 70, 800, 600, TAG_SHRES, 212, 140, 20, 22, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x200, 27 kHz, 57 Hz doublescan */
- "dblntsc", 57, 640, 200, TAG_SHRES, 196, 124, 18, 17, 80, 4,
- 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
- }, {
- /* 640x400, 27 kHz, 57 Hz */
- "dblntsc-ff", 57, 640, 400, TAG_SHRES, 196, 124, 36, 35, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x800, 27 kHz, 57 Hz interlaced */
- "dblntsc-lace", 57, 640, 800, TAG_SHRES, 196, 124, 72, 70, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x256, 27 kHz, 47 Hz doublescan */
- "dblpal", 47, 640, 256, TAG_SHRES, 196, 124, 14, 13, 80, 4,
- 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
- }, {
- /* 640x512, 27 kHz, 47 Hz */
- "dblpal-ff", 47, 640, 512, TAG_SHRES, 196, 124, 28, 27, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x1024, 27 kHz, 47 Hz interlaced */
- "dblpal-lace", 47, 640, 1024, TAG_SHRES, 196, 124, 56, 54, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- },
-
- /*
- * VGA Video Modes
- */
-
- {
- /* 640x480, 31 kHz, 60 Hz (VGA) */
- "vga", 60, 640, 480, TAG_SHRES, 64, 96, 30, 9, 112, 2,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 640x400, 31 kHz, 70 Hz (VGA) */
- "vga70", 70, 640, 400, TAG_SHRES, 64, 96, 35, 12, 112, 2,
- FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- },
+ /*
+ * AmigaOS Video Modes
+ *
+ * If you change these, make sure to update DEFMODE_* as well!
+ */
+
+ {
+ /* 640x200, 15 kHz, 60 Hz (NTSC) */
+ "ntsc", 60, 640, 200, TAG_HIRES, 106, 86, 44, 16, 76, 2,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
+ "ntsc-lace", 60, 640, 400, TAG_HIRES, 106, 86, 88, 33, 76, 4,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x256, 15 kHz, 50 Hz (PAL) */
+ "pal", 50, 640, 256, TAG_HIRES, 106, 86, 40, 14, 76, 2,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
+ "pal-lace", 50, 640, 512, TAG_HIRES, 106, 86, 80, 29, 76, 4,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x480, 29 kHz, 57 Hz */
+ "multiscan", 57, 640, 480, TAG_SHRES, 96, 112, 29, 8, 72, 8,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x960, 29 kHz, 57 Hz interlaced */
+ "multiscan-lace", 57, 640, 960, TAG_SHRES, 96, 112, 58, 16, 72,
+ 16,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x200, 15 kHz, 72 Hz */
+ "euro36", 72, 640, 200, TAG_HIRES, 92, 124, 6, 6, 52, 5,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 15 kHz, 72 Hz interlaced */
+ "euro36-lace", 72, 640, 400, TAG_HIRES, 92, 124, 12, 12, 52,
+ 10,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 29 kHz, 68 Hz */
+ "euro72", 68, 640, 400, TAG_SHRES, 164, 92, 9, 9, 80, 8,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x800, 29 kHz, 68 Hz interlaced */
+ "euro72-lace", 68, 640, 800, TAG_SHRES, 164, 92, 18, 18, 80,
+ 16,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 800x300, 23 kHz, 70 Hz */
+ "super72", 70, 800, 300, TAG_SHRES, 212, 140, 10, 11, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 800x600, 23 kHz, 70 Hz interlaced */
+ "super72-lace", 70, 800, 600, TAG_SHRES, 212, 140, 20, 22, 80,
+ 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x200, 27 kHz, 57 Hz doublescan */
+ "dblntsc", 57, 640, 200, TAG_SHRES, 196, 124, 18, 17, 80, 4,
+ 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 27 kHz, 57 Hz */
+ "dblntsc-ff", 57, 640, 400, TAG_SHRES, 196, 124, 36, 35, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x800, 27 kHz, 57 Hz interlaced */
+ "dblntsc-lace", 57, 640, 800, TAG_SHRES, 196, 124, 72, 70, 80,
+ 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x256, 27 kHz, 47 Hz doublescan */
+ "dblpal", 47, 640, 256, TAG_SHRES, 196, 124, 14, 13, 80, 4,
+ 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
+ }, {
+ /* 640x512, 27 kHz, 47 Hz */
+ "dblpal-ff", 47, 640, 512, TAG_SHRES, 196, 124, 28, 27, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x1024, 27 kHz, 47 Hz interlaced */
+ "dblpal-lace", 47, 640, 1024, TAG_SHRES, 196, 124, 56, 54, 80,
+ 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
+ },
+
+ /*
+ * VGA Video Modes
+ */
+
+ {
+ /* 640x480, 31 kHz, 60 Hz (VGA) */
+ "vga", 60, 640, 480, TAG_SHRES, 64, 96, 30, 9, 112, 2,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 640x400, 31 kHz, 70 Hz (VGA) */
+ "vga70", 70, 640, 400, TAG_SHRES, 64, 96, 35, 12, 112, 2,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT,
+ FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ },
#if 0
- /*
- * A2024 video modes
- * These modes don't work yet because there's no A2024 driver.
- */
-
- {
- /* 1024x800, 10 Hz */
- "a2024-10", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }, {
- /* 1024x800, 15 Hz */
- "a2024-15", 15, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /*
+ * A2024 video modes
+ * These modes don't work yet because there's no A2024 driver.
+ */
+
+ {
+ /* 1024x800, 10 Hz */
+ "a2024-10", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }, {
+ /* 1024x800, 15 Hz */
+ "a2024-15", 15, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
+ }
#endif
};
@@ -953,6 +952,11 @@ static int round_down_bpp = 1; /* for mode probing */
static int amifb_ilbm = 0; /* interleaved or normal bitplanes */
static int amifb_inverse = 0;
+static u32 amifb_hfmin __initdata; /* monitor hfreq lower limit (Hz) */
+static u32 amifb_hfmax __initdata; /* monitor hfreq upper limit (Hz) */
+static u16 amifb_vfmin __initdata; /* monitor vfreq lower limit (Hz) */
+static u16 amifb_vfmax __initdata; /* monitor vfreq upper limit (Hz) */
+
/*
* Macros for the conversion from real world values to hardware register
@@ -992,19 +996,20 @@ static int amifb_inverse = 0;
/* bplcon1 (smooth scrolling) */
#define hscroll2hw(hscroll) \
- (((hscroll)<<12 & 0x3000) | ((hscroll)<<8 & 0xc300) | \
- ((hscroll)<<4 & 0x0c00) | ((hscroll)<<2 & 0x00f0) | ((hscroll)>>2 & 0x000f))
+ (((hscroll) << 12 & 0x3000) | ((hscroll) << 8 & 0xc300) | \
+ ((hscroll) << 4 & 0x0c00) | ((hscroll) << 2 & 0x00f0) | \
+ ((hscroll)>>2 & 0x000f))
/* diwstrt/diwstop/diwhigh (visible display window) */
#define diwstrt2hw(diwstrt_h, diwstrt_v) \
- (((diwstrt_v)<<7 & 0xff00) | ((diwstrt_h)>>2 & 0x00ff))
+ (((diwstrt_v) << 7 & 0xff00) | ((diwstrt_h)>>2 & 0x00ff))
#define diwstop2hw(diwstop_h, diwstop_v) \
- (((diwstop_v)<<7 & 0xff00) | ((diwstop_h)>>2 & 0x00ff))
+ (((diwstop_v) << 7 & 0xff00) | ((diwstop_h)>>2 & 0x00ff))
#define diwhigh2hw(diwstrt_h, diwstrt_v, diwstop_h, diwstop_v) \
- (((diwstop_h)<<3 & 0x2000) | ((diwstop_h)<<11 & 0x1800) | \
+ (((diwstop_h) << 3 & 0x2000) | ((diwstop_h) << 11 & 0x1800) | \
((diwstop_v)>>1 & 0x0700) | ((diwstrt_h)>>5 & 0x0020) | \
- ((diwstrt_h)<<3 & 0x0018) | ((diwstrt_v)>>9 & 0x0007))
+ ((diwstrt_h) << 3 & 0x0018) | ((diwstrt_v)>>9 & 0x0007))
/* ddfstrt/ddfstop (display DMA) */
@@ -1015,38 +1020,39 @@ static int amifb_inverse = 0;
#define hsstrt2hw(hsstrt) (div8(hsstrt))
#define hsstop2hw(hsstop) (div8(hsstop))
-#define htotal2hw(htotal) (div8(htotal)-1)
+#define htotal2hw(htotal) (div8(htotal) - 1)
#define vsstrt2hw(vsstrt) (div2(vsstrt))
#define vsstop2hw(vsstop) (div2(vsstop))
-#define vtotal2hw(vtotal) (div2(vtotal)-1)
+#define vtotal2hw(vtotal) (div2(vtotal) - 1)
#define hcenter2hw(htotal) (div8(htotal))
/* hbstrt/hbstop/vbstrt/vbstop (blanking timings) */
-#define hbstrt2hw(hbstrt) (((hbstrt)<<8 & 0x0700) | ((hbstrt)>>3 & 0x00ff))
-#define hbstop2hw(hbstop) (((hbstop)<<8 & 0x0700) | ((hbstop)>>3 & 0x00ff))
+#define hbstrt2hw(hbstrt) (((hbstrt) << 8 & 0x0700) | ((hbstrt)>>3 & 0x00ff))
+#define hbstop2hw(hbstop) (((hbstop) << 8 & 0x0700) | ((hbstop)>>3 & 0x00ff))
#define vbstrt2hw(vbstrt) (div2(vbstrt))
#define vbstop2hw(vbstop) (div2(vbstop))
/* colour */
#define rgb2hw8_high(red, green, blue) \
- (((red & 0xf0)<<4) | (green & 0xf0) | ((blue & 0xf0)>>4))
+ (((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0)>>4))
#define rgb2hw8_low(red, green, blue) \
- (((red & 0x0f)<<8) | ((green & 0x0f)<<4) | (blue & 0x0f))
+ (((red & 0x0f) << 8) | ((green & 0x0f) << 4) | (blue & 0x0f))
#define rgb2hw4(red, green, blue) \
- (((red & 0xf0)<<4) | (green & 0xf0) | ((blue & 0xf0)>>4))
+ (((red & 0xf0) << 4) | (green & 0xf0) | ((blue & 0xf0)>>4))
#define rgb2hw2(red, green, blue) \
- (((red & 0xc0)<<4) | (green & 0xc0) | ((blue & 0xc0)>>4))
+ (((red & 0xc0) << 4) | (green & 0xc0) | ((blue & 0xc0)>>4))
/* sprpos/sprctl (sprite positioning) */
#define spr2hw_pos(start_v, start_h) \
- (((start_v)<<7&0xff00) | ((start_h)>>3&0x00ff))
+ (((start_v) << 7 & 0xff00) | ((start_h)>>3 & 0x00ff))
#define spr2hw_ctl(start_v, start_h, stop_v) \
- (((stop_v)<<7&0xff00) | ((start_v)>>4&0x0040) | ((stop_v)>>5&0x0020) | \
- ((start_h)<<3&0x0018) | ((start_v)>>7&0x0004) | ((stop_v)>>8&0x0002) | \
- ((start_h)>>2&0x0001))
+ (((stop_v) << 7 & 0xff00) | ((start_v)>>4 & 0x0040) | \
+ ((stop_v)>>5 & 0x0020) | ((start_h) << 3 & 0x0018) | \
+ ((start_v)>>7 & 0x0004) | ((stop_v)>>8 & 0x0002) | \
+ ((start_h)>>2 & 0x0001))
/* get current vertical position of beam */
#define get_vbpos() ((u_short)((*(u_long volatile *)&custom.vposr >> 7) & 0xffe))
@@ -1055,7 +1061,7 @@ static int amifb_inverse = 0;
* Copper Initialisation List
*/
-#define COPINITSIZE (sizeof(copins)*40)
+#define COPINITSIZE (sizeof(copins) * 40)
enum {
cip_bplcon0
@@ -1066,7 +1072,7 @@ enum {
* Don't change the order, build_copper()/rebuild_copper() rely on this
*/
-#define COPLISTSIZE (sizeof(copins)*64)
+#define COPLISTSIZE (sizeof(copins) * 64)
enum {
cop_wait, cop_bplcon0,
@@ -1108,82 +1114,1199 @@ static u_short sprfetchmode[3] = {
};
+/* --------------------------- Hardware routines --------------------------- */
+
/*
- * Interface used by the world
+ * Get the video params out of `var'. If a value doesn't fit, round
+ * it up, if it's too big, return -EINVAL.
*/
-int amifb_setup(char*);
+static int ami_decode_var(struct fb_var_screeninfo *var, struct amifb_par *par,
+ const struct fb_info *info)
+{
+ u_short clk_shift, line_shift;
+ u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n;
+ u_int htotal, vtotal;
-static int amifb_check_var(struct fb_var_screeninfo *var,
- struct fb_info *info);
-static int amifb_set_par(struct fb_info *info);
-static int amifb_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info);
-static int amifb_blank(int blank, struct fb_info *info);
-static int amifb_pan_display(struct fb_var_screeninfo *var,
- struct fb_info *info);
-static void amifb_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect);
-static void amifb_copyarea(struct fb_info *info,
- const struct fb_copyarea *region);
-static void amifb_imageblit(struct fb_info *info,
- const struct fb_image *image);
-static int amifb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg);
+ /*
+ * Find a matching Pixel Clock
+ */
+ for (clk_shift = TAG_SHRES; clk_shift <= TAG_LORES; clk_shift++)
+ if (var->pixclock <= pixclock[clk_shift])
+ break;
+ if (clk_shift > TAG_LORES) {
+ DPRINTK("pixclock too high\n");
+ return -EINVAL;
+ }
+ par->clk_shift = clk_shift;
/*
- * Interface to the low level console driver
+ * Check the Geometry Values
*/
-static void amifb_deinit(struct platform_device *pdev);
+ if ((par->xres = var->xres) < 64)
+ par->xres = 64;
+ if ((par->yres = var->yres) < 64)
+ par->yres = 64;
+ if ((par->vxres = var->xres_virtual) < par->xres)
+ par->vxres = par->xres;
+ if ((par->vyres = var->yres_virtual) < par->yres)
+ par->vyres = par->yres;
+
+ par->bpp = var->bits_per_pixel;
+ if (!var->nonstd) {
+ if (par->bpp < 1)
+ par->bpp = 1;
+ if (par->bpp > maxdepth[clk_shift]) {
+ if (round_down_bpp && maxdepth[clk_shift])
+ par->bpp = maxdepth[clk_shift];
+ else {
+ DPRINTK("invalid bpp\n");
+ return -EINVAL;
+ }
+ }
+ } else if (var->nonstd == FB_NONSTD_HAM) {
+ if (par->bpp < 6)
+ par->bpp = 6;
+ if (par->bpp != 6) {
+ if (par->bpp < 8)
+ par->bpp = 8;
+ if (par->bpp != 8 || !IS_AGA) {
+ DPRINTK("invalid bpp for ham mode\n");
+ return -EINVAL;
+ }
+ }
+ } else {
+ DPRINTK("unknown nonstd mode\n");
+ return -EINVAL;
+ }
/*
- * Internal routines
+ * FB_VMODE_SMOOTH_XPAN will be cleared, if one of the folloing
+ * checks failed and smooth scrolling is not possible
*/
-static int flash_cursor(void);
-static irqreturn_t amifb_interrupt(int irq, void *dev_id);
-static u_long chipalloc(u_long size);
-static void chipfree(void);
+ par->vmode = var->vmode | FB_VMODE_SMOOTH_XPAN;
+ switch (par->vmode & FB_VMODE_MASK) {
+ case FB_VMODE_INTERLACED:
+ line_shift = 0;
+ break;
+ case FB_VMODE_NONINTERLACED:
+ line_shift = 1;
+ break;
+ case FB_VMODE_DOUBLE:
+ if (!IS_AGA) {
+ DPRINTK("double mode only possible with aga\n");
+ return -EINVAL;
+ }
+ line_shift = 2;
+ break;
+ default:
+ DPRINTK("unknown video mode\n");
+ return -EINVAL;
+ break;
+ }
+ par->line_shift = line_shift;
/*
- * Hardware routines
+ * Vertical and Horizontal Timings
*/
-static int ami_decode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par);
-static int ami_encode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par);
-static void ami_pan_var(struct fb_var_screeninfo *var);
-static int ami_update_par(void);
-static void ami_update_display(void);
-static void ami_init_display(void);
-static void ami_do_blank(void);
-static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix);
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data);
-static int ami_get_cursorstate(struct fb_cursorstate *state);
-static int ami_set_cursorstate(struct fb_cursorstate *state);
-static void ami_set_sprite(void);
-static void ami_init_copper(void);
-static void ami_reinit_copper(void);
-static void ami_build_copper(void);
-static void ami_rebuild_copper(void);
+ xres_n = par->xres << clk_shift;
+ yres_n = par->yres << line_shift;
+ par->htotal = down8((var->left_margin + par->xres + var->right_margin +
+ var->hsync_len) << clk_shift);
+ par->vtotal =
+ down2(((var->upper_margin + par->yres + var->lower_margin +
+ var->vsync_len) << line_shift) + 1);
+ if (IS_AGA)
+ par->bplcon3 = sprpixmode[clk_shift];
+ else
+ par->bplcon3 = 0;
+ if (var->sync & FB_SYNC_BROADCAST) {
+ par->diwstop_h = par->htotal -
+ ((var->right_margin - var->hsync_len) << clk_shift);
+ if (IS_AGA)
+ par->diwstop_h += mod4(var->hsync_len);
+ else
+ par->diwstop_h = down4(par->diwstop_h);
+
+ par->diwstrt_h = par->diwstop_h - xres_n;
+ par->diwstop_v = par->vtotal -
+ ((var->lower_margin - var->vsync_len) << line_shift);
+ par->diwstrt_v = par->diwstop_v - yres_n;
+ if (par->diwstop_h >= par->htotal + 8) {
+ DPRINTK("invalid diwstop_h\n");
+ return -EINVAL;
+ }
+ if (par->diwstop_v > par->vtotal) {
+ DPRINTK("invalid diwstop_v\n");
+ return -EINVAL;
+ }
+
+ if (!IS_OCS) {
+ /* Initialize sync with some reasonable values for pwrsave */
+ par->hsstrt = 160;
+ par->hsstop = 320;
+ par->vsstrt = 30;
+ par->vsstop = 34;
+ } else {
+ par->hsstrt = 0;
+ par->hsstop = 0;
+ par->vsstrt = 0;
+ par->vsstop = 0;
+ }
+ if (par->vtotal > (PAL_VTOTAL + NTSC_VTOTAL) / 2) {
+ /* PAL video mode */
+ if (par->htotal != PAL_HTOTAL) {
+ DPRINTK("htotal invalid for pal\n");
+ return -EINVAL;
+ }
+ if (par->diwstrt_h < PAL_DIWSTRT_H) {
+ DPRINTK("diwstrt_h too low for pal\n");
+ return -EINVAL;
+ }
+ if (par->diwstrt_v < PAL_DIWSTRT_V) {
+ DPRINTK("diwstrt_v too low for pal\n");
+ return -EINVAL;
+ }
+ htotal = PAL_HTOTAL>>clk_shift;
+ vtotal = PAL_VTOTAL>>1;
+ if (!IS_OCS) {
+ par->beamcon0 = BMC0_PAL;
+ par->bplcon3 |= BPC3_BRDRBLNK;
+ } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
+ AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
+ par->beamcon0 = BMC0_PAL;
+ par->hsstop = 1;
+ } else if (amiga_vblank != 50) {
+ DPRINTK("pal not supported by this chipset\n");
+ return -EINVAL;
+ }
+ } else {
+ /* NTSC video mode
+ * In the AGA chipset seems to be hardware bug with BPC3_BRDRBLNK
+ * and NTSC activated, so than better let diwstop_h <= 1812
+ */
+ if (par->htotal != NTSC_HTOTAL) {
+ DPRINTK("htotal invalid for ntsc\n");
+ return -EINVAL;
+ }
+ if (par->diwstrt_h < NTSC_DIWSTRT_H) {
+ DPRINTK("diwstrt_h too low for ntsc\n");
+ return -EINVAL;
+ }
+ if (par->diwstrt_v < NTSC_DIWSTRT_V) {
+ DPRINTK("diwstrt_v too low for ntsc\n");
+ return -EINVAL;
+ }
+ htotal = NTSC_HTOTAL>>clk_shift;
+ vtotal = NTSC_VTOTAL>>1;
+ if (!IS_OCS) {
+ par->beamcon0 = 0;
+ par->bplcon3 |= BPC3_BRDRBLNK;
+ } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
+ AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
+ par->beamcon0 = 0;
+ par->hsstop = 1;
+ } else if (amiga_vblank != 60) {
+ DPRINTK("ntsc not supported by this chipset\n");
+ return -EINVAL;
+ }
+ }
+ if (IS_OCS) {
+ if (par->diwstrt_h >= 1024 || par->diwstop_h < 1024 ||
+ par->diwstrt_v >= 512 || par->diwstop_v < 256) {
+ DPRINTK("invalid position for display on ocs\n");
+ return -EINVAL;
+ }
+ }
+ } else if (!IS_OCS) {
+ /* Programmable video mode */
+ par->hsstrt = var->right_margin << clk_shift;
+ par->hsstop = (var->right_margin + var->hsync_len) << clk_shift;
+ par->diwstop_h = par->htotal - mod8(par->hsstrt) + 8 - (1 << clk_shift);
+ if (!IS_AGA)
+ par->diwstop_h = down4(par->diwstop_h) - 16;
+ par->diwstrt_h = par->diwstop_h - xres_n;
+ par->hbstop = par->diwstrt_h + 4;
+ par->hbstrt = par->diwstop_h + 4;
+ if (par->hbstrt >= par->htotal + 8)
+ par->hbstrt -= par->htotal;
+ par->hcenter = par->hsstrt + (par->htotal >> 1);
+ par->vsstrt = var->lower_margin << line_shift;
+ par->vsstop = (var->lower_margin + var->vsync_len) << line_shift;
+ par->diwstop_v = par->vtotal;
+ if ((par->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
+ par->diwstop_v -= 2;
+ par->diwstrt_v = par->diwstop_v - yres_n;
+ par->vbstop = par->diwstrt_v - 2;
+ par->vbstrt = par->diwstop_v - 2;
+ if (par->vtotal > 2048) {
+ DPRINTK("vtotal too high\n");
+ return -EINVAL;
+ }
+ if (par->htotal > 2048) {
+ DPRINTK("htotal too high\n");
+ return -EINVAL;
+ }
+ par->bplcon3 |= BPC3_EXTBLKEN;
+ par->beamcon0 = BMC0_HARDDIS | BMC0_VARVBEN | BMC0_LOLDIS |
+ BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN |
+ BMC0_PAL | BMC0_VARCSYEN;
+ if (var->sync & FB_SYNC_HOR_HIGH_ACT)
+ par->beamcon0 |= BMC0_HSYTRUE;
+ if (var->sync & FB_SYNC_VERT_HIGH_ACT)
+ par->beamcon0 |= BMC0_VSYTRUE;
+ if (var->sync & FB_SYNC_COMP_HIGH_ACT)
+ par->beamcon0 |= BMC0_CSYTRUE;
+ htotal = par->htotal>>clk_shift;
+ vtotal = par->vtotal>>1;
+ } else {
+ DPRINTK("only broadcast modes possible for ocs\n");
+ return -EINVAL;
+ }
+
+ /*
+ * Checking the DMA timing
+ */
+
+ fconst = 16 << maxfmode << clk_shift;
+
+ /*
+ * smallest window start value without turn off other dma cycles
+ * than sprite1-7, unless you change min_fstrt
+ */
+
+
+ fsize = ((maxfmode + clk_shift <= 1) ? fconst : 64);
+ fstrt = downx(fconst, par->diwstrt_h - 4) - fsize;
+ if (fstrt < min_fstrt) {
+ DPRINTK("fetch start too low\n");
+ return -EINVAL;
+ }
+
+ /*
+ * smallest window start value where smooth scrolling is possible
+ */
+
+ fstrt = downx(fconst, par->diwstrt_h - fconst + (1 << clk_shift) - 4) -
+ fsize;
+ if (fstrt < min_fstrt)
+ par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
+
+ maxfetchstop = down16(par->htotal - 80);
+
+ fstrt = downx(fconst, par->diwstrt_h - 4) - 64 - fconst;
+ fsize = upx(fconst, xres_n +
+ modx(fconst, downx(1 << clk_shift, par->diwstrt_h - 4)));
+ if (fstrt + fsize > maxfetchstop)
+ par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
+
+ fsize = upx(fconst, xres_n);
+ if (fstrt + fsize > maxfetchstop) {
+ DPRINTK("fetch stop too high\n");
+ return -EINVAL;
+ }
+
+ if (maxfmode + clk_shift <= 1) {
+ fsize = up64(xres_n + fconst - 1);
+ if (min_fstrt + fsize - 64 > maxfetchstop)
+ par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
+
+ fsize = up64(xres_n);
+ if (min_fstrt + fsize - 64 > maxfetchstop) {
+ DPRINTK("fetch size too high\n");
+ return -EINVAL;
+ }
+
+ fsize -= 64;
+ } else
+ fsize -= fconst;
+
+ /*
+ * Check if there is enough time to update the bitplane pointers for ywrap
+ */
+
+ if (par->htotal - fsize - 64 < par->bpp * 64)
+ par->vmode &= ~FB_VMODE_YWRAP;
+
+ /*
+ * Bitplane calculations and check the Memory Requirements
+ */
+
+ if (amifb_ilbm) {
+ par->next_plane = div8(upx(16 << maxfmode, par->vxres));
+ par->next_line = par->bpp * par->next_plane;
+ if (par->next_line * par->vyres > info->fix.smem_len) {
+ DPRINTK("too few video mem\n");
+ return -EINVAL;
+ }
+ } else {
+ par->next_line = div8(upx(16 << maxfmode, par->vxres));
+ par->next_plane = par->vyres * par->next_line;
+ if (par->next_plane * par->bpp > info->fix.smem_len) {
+ DPRINTK("too few video mem\n");
+ return -EINVAL;
+ }
+ }
+
+ /*
+ * Hardware Register Values
+ */
+
+ par->bplcon0 = BPC0_COLOR | bplpixmode[clk_shift];
+ if (!IS_OCS)
+ par->bplcon0 |= BPC0_ECSENA;
+ if (par->bpp == 8)
+ par->bplcon0 |= BPC0_BPU3;
+ else
+ par->bplcon0 |= par->bpp << 12;
+ if (var->nonstd == FB_NONSTD_HAM)
+ par->bplcon0 |= BPC0_HAM;
+ if (var->sync & FB_SYNC_EXT)
+ par->bplcon0 |= BPC0_ERSY;
+
+ if (IS_AGA)
+ par->fmode = bplfetchmode[maxfmode];
+
+ switch (par->vmode & FB_VMODE_MASK) {
+ case FB_VMODE_INTERLACED:
+ par->bplcon0 |= BPC0_LACE;
+ break;
+ case FB_VMODE_DOUBLE:
+ if (IS_AGA)
+ par->fmode |= FMODE_SSCAN2 | FMODE_BSCAN2;
+ break;
+ }
+
+ if (!((par->vmode ^ var->vmode) & FB_VMODE_YWRAP)) {
+ par->xoffset = var->xoffset;
+ par->yoffset = var->yoffset;
+ if (par->vmode & FB_VMODE_YWRAP) {
+ if (par->xoffset || par->yoffset < 0 ||
+ par->yoffset >= par->vyres)
+ par->xoffset = par->yoffset = 0;
+ } else {
+ if (par->xoffset < 0 ||
+ par->xoffset > upx(16 << maxfmode, par->vxres - par->xres) ||
+ par->yoffset < 0 || par->yoffset > par->vyres - par->yres)
+ par->xoffset = par->yoffset = 0;
+ }
+ } else
+ par->xoffset = par->yoffset = 0;
+
+ par->crsr.crsr_x = par->crsr.crsr_y = 0;
+ par->crsr.spot_x = par->crsr.spot_y = 0;
+ par->crsr.height = par->crsr.width = 0;
+
+ return 0;
+}
+
+ /*
+ * Fill the `var' structure based on the values in `par' and maybe
+ * other values read out of the hardware.
+ */
+
+static void ami_encode_var(struct fb_var_screeninfo *var,
+ struct amifb_par *par)
+{
+ u_short clk_shift, line_shift;
+
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
+
+ clk_shift = par->clk_shift;
+ line_shift = par->line_shift;
+
+ var->xres = par->xres;
+ var->yres = par->yres;
+ var->xres_virtual = par->vxres;
+ var->yres_virtual = par->vyres;
+ var->xoffset = par->xoffset;
+ var->yoffset = par->yoffset;
+
+ var->bits_per_pixel = par->bpp;
+ var->grayscale = 0;
+
+ var->red.offset = 0;
+ var->red.msb_right = 0;
+ var->red.length = par->bpp;
+ if (par->bplcon0 & BPC0_HAM)
+ var->red.length -= 2;
+ var->blue = var->green = var->red;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ var->transp.msb_right = 0;
+
+ if (par->bplcon0 & BPC0_HAM)
+ var->nonstd = FB_NONSTD_HAM;
+ else
+ var->nonstd = 0;
+ var->activate = 0;
+
+ var->height = -1;
+ var->width = -1;
+
+ var->pixclock = pixclock[clk_shift];
+
+ if (IS_AGA && par->fmode & FMODE_BSCAN2)
+ var->vmode = FB_VMODE_DOUBLE;
+ else if (par->bplcon0 & BPC0_LACE)
+ var->vmode = FB_VMODE_INTERLACED;
+ else
+ var->vmode = FB_VMODE_NONINTERLACED;
+
+ if (!IS_OCS && par->beamcon0 & BMC0_VARBEAMEN) {
+ var->hsync_len = (par->hsstop - par->hsstrt)>>clk_shift;
+ var->right_margin = par->hsstrt>>clk_shift;
+ var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
+ var->vsync_len = (par->vsstop - par->vsstrt)>>line_shift;
+ var->lower_margin = par->vsstrt>>line_shift;
+ var->upper_margin = (par->vtotal>>line_shift) - var->yres - var->lower_margin - var->vsync_len;
+ var->sync = 0;
+ if (par->beamcon0 & BMC0_HSYTRUE)
+ var->sync |= FB_SYNC_HOR_HIGH_ACT;
+ if (par->beamcon0 & BMC0_VSYTRUE)
+ var->sync |= FB_SYNC_VERT_HIGH_ACT;
+ if (par->beamcon0 & BMC0_CSYTRUE)
+ var->sync |= FB_SYNC_COMP_HIGH_ACT;
+ } else {
+ var->sync = FB_SYNC_BROADCAST;
+ var->hsync_len = (152>>clk_shift) + mod4(par->diwstop_h);
+ var->right_margin = ((par->htotal - down4(par->diwstop_h))>>clk_shift) + var->hsync_len;
+ var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
+ var->vsync_len = 4>>line_shift;
+ var->lower_margin = ((par->vtotal - par->diwstop_v)>>line_shift) + var->vsync_len;
+ var->upper_margin = (((par->vtotal - 2)>>line_shift) + 1) - var->yres -
+ var->lower_margin - var->vsync_len;
+ }
+
+ if (par->bplcon0 & BPC0_ERSY)
+ var->sync |= FB_SYNC_EXT;
+ if (par->vmode & FB_VMODE_YWRAP)
+ var->vmode |= FB_VMODE_YWRAP;
+}
+
+
+ /*
+ * Update hardware
+ */
+
+static void ami_update_par(struct fb_info *info)
+{
+ struct amifb_par *par = info->par;
+ short clk_shift, vshift, fstrt, fsize, fstop, fconst, shift, move, mod;
+
+ clk_shift = par->clk_shift;
+
+ if (!(par->vmode & FB_VMODE_SMOOTH_XPAN))
+ par->xoffset = upx(16 << maxfmode, par->xoffset);
+
+ fconst = 16 << maxfmode << clk_shift;
+ vshift = modx(16 << maxfmode, par->xoffset);
+ fstrt = par->diwstrt_h - (vshift << clk_shift) - 4;
+ fsize = (par->xres + vshift) << clk_shift;
+ shift = modx(fconst, fstrt);
+ move = downx(2 << maxfmode, div8(par->xoffset));
+ if (maxfmode + clk_shift > 1) {
+ fstrt = downx(fconst, fstrt) - 64;
+ fsize = upx(fconst, fsize);
+ fstop = fstrt + fsize - fconst;
+ } else {
+ mod = fstrt = downx(fconst, fstrt) - fconst;
+ fstop = fstrt + upx(fconst, fsize) - 64;
+ fsize = up64(fsize);
+ fstrt = fstop - fsize + 64;
+ if (fstrt < min_fstrt) {
+ fstop += min_fstrt - fstrt;
+ fstrt = min_fstrt;
+ }
+ move = move - div8((mod - fstrt)>>clk_shift);
+ }
+ mod = par->next_line - div8(fsize>>clk_shift);
+ par->ddfstrt = fstrt;
+ par->ddfstop = fstop;
+ par->bplcon1 = hscroll2hw(shift);
+ par->bpl2mod = mod;
+ if (par->bplcon0 & BPC0_LACE)
+ par->bpl2mod += par->next_line;
+ if (IS_AGA && (par->fmode & FMODE_BSCAN2))
+ par->bpl1mod = -div8(fsize>>clk_shift);
+ else
+ par->bpl1mod = par->bpl2mod;
+
+ if (par->yoffset) {
+ par->bplpt0 = info->fix.smem_start +
+ par->next_line * par->yoffset + move;
+ if (par->vmode & FB_VMODE_YWRAP) {
+ if (par->yoffset > par->vyres - par->yres) {
+ par->bplpt0wrap = info->fix.smem_start + move;
+ if (par->bplcon0 & BPC0_LACE &&
+ mod2(par->diwstrt_v + par->vyres -
+ par->yoffset))
+ par->bplpt0wrap += par->next_line;
+ }
+ }
+ } else
+ par->bplpt0 = info->fix.smem_start + move;
+
+ if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v))
+ par->bplpt0 += par->next_line;
+}
+
+
+ /*
+ * Pan or Wrap the Display
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ * in `var'.
+ */
+
+static void ami_pan_var(struct fb_var_screeninfo *var, struct fb_info *info)
+{
+ struct amifb_par *par = info->par;
+
+ par->xoffset = var->xoffset;
+ par->yoffset = var->yoffset;
+ if (var->vmode & FB_VMODE_YWRAP)
+ par->vmode |= FB_VMODE_YWRAP;
+ else
+ par->vmode &= ~FB_VMODE_YWRAP;
+
+ do_vmode_pan = 0;
+ ami_update_par(info);
+ do_vmode_pan = 1;
+}
+
+
+static void ami_update_display(const struct amifb_par *par)
+{
+ custom.bplcon1 = par->bplcon1;
+ custom.bpl1mod = par->bpl1mod;
+ custom.bpl2mod = par->bpl2mod;
+ custom.ddfstrt = ddfstrt2hw(par->ddfstrt);
+ custom.ddfstop = ddfstop2hw(par->ddfstop);
+}
+
+ /*
+ * Change the video mode (called by VBlank interrupt)
+ */
+
+static void ami_init_display(const struct amifb_par *par)
+{
+ int i;
+
+ custom.bplcon0 = par->bplcon0 & ~BPC0_LACE;
+ custom.bplcon2 = (IS_OCS ? 0 : BPC2_KILLEHB) | BPC2_PF2P2 | BPC2_PF1P2;
+ if (!IS_OCS) {
+ custom.bplcon3 = par->bplcon3;
+ if (IS_AGA)
+ custom.bplcon4 = BPC4_ESPRM4 | BPC4_OSPRM4;
+ if (par->beamcon0 & BMC0_VARBEAMEN) {
+ custom.htotal = htotal2hw(par->htotal);
+ custom.hbstrt = hbstrt2hw(par->hbstrt);
+ custom.hbstop = hbstop2hw(par->hbstop);
+ custom.hsstrt = hsstrt2hw(par->hsstrt);
+ custom.hsstop = hsstop2hw(par->hsstop);
+ custom.hcenter = hcenter2hw(par->hcenter);
+ custom.vtotal = vtotal2hw(par->vtotal);
+ custom.vbstrt = vbstrt2hw(par->vbstrt);
+ custom.vbstop = vbstop2hw(par->vbstop);
+ custom.vsstrt = vsstrt2hw(par->vsstrt);
+ custom.vsstop = vsstop2hw(par->vsstop);
+ }
+ }
+ if (!IS_OCS || par->hsstop)
+ custom.beamcon0 = par->beamcon0;
+ if (IS_AGA)
+ custom.fmode = par->fmode;
+
+ /*
+ * The minimum period for audio depends on htotal
+ */
+
+ amiga_audio_min_period = div16(par->htotal);
+
+ is_lace = par->bplcon0 & BPC0_LACE ? 1 : 0;
+#if 1
+ if (is_lace) {
+ i = custom.vposr >> 15;
+ } else {
+ custom.vposw = custom.vposr | 0x8000;
+ i = 1;
+ }
+#else
+ i = 1;
+ custom.vposw = custom.vposr | 0x8000;
+#endif
+ custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][i]);
+}
+
+ /*
+ * (Un)Blank the screen (called by VBlank interrupt)
+ */
+
+static void ami_do_blank(const struct amifb_par *par)
+{
+#if defined(CONFIG_FB_AMIGA_AGA)
+ u_short bplcon3 = par->bplcon3;
+#endif
+ u_char red, green, blue;
+
+ if (do_blank > 0) {
+ custom.dmacon = DMAF_RASTER | DMAF_SPRITE;
+ red = green = blue = 0;
+ if (!IS_OCS && do_blank > 1) {
+ switch (do_blank) {
+ case FB_BLANK_VSYNC_SUSPEND:
+ custom.hsstrt = hsstrt2hw(par->hsstrt);
+ custom.hsstop = hsstop2hw(par->hsstop);
+ custom.vsstrt = vsstrt2hw(par->vtotal + 4);
+ custom.vsstop = vsstop2hw(par->vtotal + 4);
+ break;
+ case FB_BLANK_HSYNC_SUSPEND:
+ custom.hsstrt = hsstrt2hw(par->htotal + 16);
+ custom.hsstop = hsstop2hw(par->htotal + 16);
+ custom.vsstrt = vsstrt2hw(par->vsstrt);
+ custom.vsstop = vsstrt2hw(par->vsstop);
+ break;
+ case FB_BLANK_POWERDOWN:
+ custom.hsstrt = hsstrt2hw(par->htotal + 16);
+ custom.hsstop = hsstop2hw(par->htotal + 16);
+ custom.vsstrt = vsstrt2hw(par->vtotal + 4);
+ custom.vsstop = vsstop2hw(par->vtotal + 4);
+ break;
+ }
+ if (!(par->beamcon0 & BMC0_VARBEAMEN)) {
+ custom.htotal = htotal2hw(par->htotal);
+ custom.vtotal = vtotal2hw(par->vtotal);
+ custom.beamcon0 = BMC0_HARDDIS | BMC0_VARBEAMEN |
+ BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARCSYEN;
+ }
+ }
+ } else {
+ custom.dmacon = DMAF_SETCLR | DMAF_RASTER | DMAF_SPRITE;
+ red = red0;
+ green = green0;
+ blue = blue0;
+ if (!IS_OCS) {
+ custom.hsstrt = hsstrt2hw(par->hsstrt);
+ custom.hsstop = hsstop2hw(par->hsstop);
+ custom.vsstrt = vsstrt2hw(par->vsstrt);
+ custom.vsstop = vsstop2hw(par->vsstop);
+ custom.beamcon0 = par->beamcon0;
+ }
+ }
+#if defined(CONFIG_FB_AMIGA_AGA)
+ if (IS_AGA) {
+ custom.bplcon3 = bplcon3;
+ custom.color[0] = rgb2hw8_high(red, green, blue);
+ custom.bplcon3 = bplcon3 | BPC3_LOCT;
+ custom.color[0] = rgb2hw8_low(red, green, blue);
+ custom.bplcon3 = bplcon3;
+ } else
+#endif
+#if defined(CONFIG_FB_AMIGA_ECS)
+ if (par->bplcon0 & BPC0_SHRES) {
+ u_short color, mask;
+ int i;
+
+ mask = 0x3333;
+ color = rgb2hw2(red, green, blue);
+ for (i = 12; i >= 0; i -= 4)
+ custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
+ mask <<= 2; color >>= 2;
+ for (i = 3; i >= 0; i--)
+ custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
+ } else
+#endif
+ custom.color[0] = rgb2hw4(red, green, blue);
+ is_blanked = do_blank > 0 ? do_blank : 0;
+}
+
+static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix,
+ const struct amifb_par *par)
+{
+ fix->crsr_width = fix->crsr_xsize = par->crsr.width;
+ fix->crsr_height = fix->crsr_ysize = par->crsr.height;
+ fix->crsr_color1 = 17;
+ fix->crsr_color2 = 18;
+ return 0;
+}
+
+static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var,
+ u_char __user *data,
+ const struct amifb_par *par)
+{
+ register u_short *lspr, *sspr;
+#ifdef __mc68000__
+ register u_long datawords asm ("d2");
+#else
+ register u_long datawords;
+#endif
+ register short delta;
+ register u_char color;
+ short height, width, bits, words;
+ int size, alloc;
+
+ size = par->crsr.height * par->crsr.width;
+ alloc = var->height * var->width;
+ var->height = par->crsr.height;
+ var->width = par->crsr.width;
+ var->xspot = par->crsr.spot_x;
+ var->yspot = par->crsr.spot_y;
+ if (size > var->height * var->width)
+ return -ENAMETOOLONG;
+ if (!access_ok(VERIFY_WRITE, data, size))
+ return -EFAULT;
+ delta = 1 << par->crsr.fmode;
+ lspr = lofsprite + (delta << 1);
+ if (par->bplcon0 & BPC0_LACE)
+ sspr = shfsprite + (delta << 1);
+ else
+ sspr = NULL;
+ for (height = (short)var->height - 1; height >= 0; height--) {
+ bits = 0; words = delta; datawords = 0;
+ for (width = (short)var->width - 1; width >= 0; width--) {
+ if (bits == 0) {
+ bits = 16; --words;
+#ifdef __mc68000__
+ asm volatile ("movew %1@(%3:w:2),%0 ; swap %0 ; movew %1@+,%0"
+ : "=d" (datawords), "=a" (lspr) : "1" (lspr), "d" (delta));
+#else
+ datawords = (*(lspr + delta) << 16) | (*lspr++);
+#endif
+ }
+ --bits;
+#ifdef __mc68000__
+ asm volatile (
+ "clrb %0 ; swap %1 ; lslw #1,%1 ; roxlb #1,%0 ; "
+ "swap %1 ; lslw #1,%1 ; roxlb #1,%0"
+ : "=d" (color), "=d" (datawords) : "1" (datawords));
+#else
+ color = (((datawords >> 30) & 2)
+ | ((datawords >> 15) & 1));
+ datawords <<= 1;
+#endif
+ put_user(color, data++);
+ }
+ if (bits > 0) {
+ --words; ++lspr;
+ }
+ while (--words >= 0)
+ ++lspr;
+#ifdef __mc68000__
+ asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:"
+ : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta));
+#else
+ lspr += delta;
+ if (sspr) {
+ u_short *tmp = lspr;
+ lspr = sspr;
+ sspr = tmp;
+ }
+#endif
+ }
+ return 0;
+}
+
+static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var,
+ u_char __user *data, struct amifb_par *par)
+{
+ register u_short *lspr, *sspr;
+#ifdef __mc68000__
+ register u_long datawords asm ("d2");
+#else
+ register u_long datawords;
+#endif
+ register short delta;
+ u_short fmode;
+ short height, width, bits, words;
+
+ if (!var->width)
+ return -EINVAL;
+ else if (var->width <= 16)
+ fmode = TAG_FMODE_1;
+ else if (var->width <= 32)
+ fmode = TAG_FMODE_2;
+ else if (var->width <= 64)
+ fmode = TAG_FMODE_4;
+ else
+ return -EINVAL;
+ if (fmode > maxfmode)
+ return -EINVAL;
+ if (!var->height)
+ return -EINVAL;
+ if (!access_ok(VERIFY_READ, data, var->width * var->height))
+ return -EFAULT;
+ delta = 1 << fmode;
+ lofsprite = shfsprite = (u_short *)spritememory;
+ lspr = lofsprite + (delta << 1);
+ if (par->bplcon0 & BPC0_LACE) {
+ if (((var->height + 4) << fmode << 2) > SPRITEMEMSIZE)
+ return -EINVAL;
+ memset(lspr, 0, (var->height + 4) << fmode << 2);
+ shfsprite += ((var->height + 5)&-2) << fmode;
+ sspr = shfsprite + (delta << 1);
+ } else {
+ if (((var->height + 2) << fmode << 2) > SPRITEMEMSIZE)
+ return -EINVAL;
+ memset(lspr, 0, (var->height + 2) << fmode << 2);
+ sspr = NULL;
+ }
+ for (height = (short)var->height - 1; height >= 0; height--) {
+ bits = 16; words = delta; datawords = 0;
+ for (width = (short)var->width - 1; width >= 0; width--) {
+ unsigned long tdata = 0;
+ get_user(tdata, data);
+ data++;
+#ifdef __mc68000__
+ asm volatile (
+ "lsrb #1,%2 ; roxlw #1,%0 ; swap %0 ; "
+ "lsrb #1,%2 ; roxlw #1,%0 ; swap %0"
+ : "=d" (datawords)
+ : "0" (datawords), "d" (tdata));
+#else
+ datawords = ((datawords << 1) & 0xfffefffe);
+ datawords |= tdata & 1;
+ datawords |= (tdata & 2) << (16 - 1);
+#endif
+ if (--bits == 0) {
+ bits = 16; --words;
+#ifdef __mc68000__
+ asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+"
+ : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta));
+#else
+ *(lspr + delta) = (u_short) (datawords >> 16);
+ *lspr++ = (u_short) (datawords & 0xffff);
+#endif
+ }
+ }
+ if (bits < 16) {
+ --words;
+#ifdef __mc68000__
+ asm volatile (
+ "swap %2 ; lslw %4,%2 ; movew %2,%0@(%3:w:2) ; "
+ "swap %2 ; lslw %4,%2 ; movew %2,%0@+"
+ : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta), "d" (bits));
+#else
+ *(lspr + delta) = (u_short) (datawords >> (16 + bits));
+ *lspr++ = (u_short) ((datawords & 0x0000ffff) >> bits);
+#endif
+ }
+ while (--words >= 0) {
+#ifdef __mc68000__
+ asm volatile ("moveql #0,%%d0 ; movew %%d0,%0@(%2:w:2) ; movew %%d0,%0@+"
+ : "=a" (lspr) : "0" (lspr), "d" (delta) : "d0");
+#else
+ *(lspr + delta) = 0;
+ *lspr++ = 0;
+#endif
+ }
+#ifdef __mc68000__
+ asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:"
+ : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta));
+#else
+ lspr += delta;
+ if (sspr) {
+ u_short *tmp = lspr;
+ lspr = sspr;
+ sspr = tmp;
+ }
+#endif
+ }
+ par->crsr.height = var->height;
+ par->crsr.width = var->width;
+ par->crsr.spot_x = var->xspot;
+ par->crsr.spot_y = var->yspot;
+ par->crsr.fmode = fmode;
+ if (IS_AGA) {
+ par->fmode &= ~(FMODE_SPAGEM | FMODE_SPR32);
+ par->fmode |= sprfetchmode[fmode];
+ custom.fmode = par->fmode;
+ }
+ return 0;
+}
+
+static int ami_get_cursorstate(struct fb_cursorstate *state,
+ const struct amifb_par *par)
+{
+ state->xoffset = par->crsr.crsr_x;
+ state->yoffset = par->crsr.crsr_y;
+ state->mode = cursormode;
+ return 0;
+}
+
+static int ami_set_cursorstate(struct fb_cursorstate *state,
+ struct amifb_par *par)
+{
+ par->crsr.crsr_x = state->xoffset;
+ par->crsr.crsr_y = state->yoffset;
+ if ((cursormode = state->mode) == FB_CURSOR_OFF)
+ cursorstate = -1;
+ do_cursor = 1;
+ return 0;
+}
+
+static void ami_set_sprite(const struct amifb_par *par)
+{
+ copins *copl, *cops;
+ u_short hs, vs, ve;
+ u_long pl, ps, pt;
+ short mx, my;
+
+ cops = copdisplay.list[currentcop][0];
+ copl = copdisplay.list[currentcop][1];
+ ps = pl = ZTWO_PADDR(dummysprite);
+ mx = par->crsr.crsr_x - par->crsr.spot_x;
+ my = par->crsr.crsr_y - par->crsr.spot_y;
+ if (!(par->vmode & FB_VMODE_YWRAP)) {
+ mx -= par->xoffset;
+ my -= par->yoffset;
+ }
+ if (!is_blanked && cursorstate > 0 && par->crsr.height > 0 &&
+ mx > -(short)par->crsr.width && mx < par->xres &&
+ my > -(short)par->crsr.height && my < par->yres) {
+ pl = ZTWO_PADDR(lofsprite);
+ hs = par->diwstrt_h + (mx << par->clk_shift) - 4;
+ vs = par->diwstrt_v + (my << par->line_shift);
+ ve = vs + (par->crsr.height << par->line_shift);
+ if (par->bplcon0 & BPC0_LACE) {
+ ps = ZTWO_PADDR(shfsprite);
+ lofsprite[0] = spr2hw_pos(vs, hs);
+ shfsprite[0] = spr2hw_pos(vs + 1, hs);
+ if (mod2(vs)) {
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
+ shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve + 1);
+ pt = pl; pl = ps; ps = pt;
+ } else {
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve + 1);
+ shfsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs + 1, hs, ve);
+ }
+ } else {
+ lofsprite[0] = spr2hw_pos(vs, hs) | (IS_AGA && (par->fmode & FMODE_BSCAN2) ? 0x80 : 0);
+ lofsprite[1 << par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
+ }
+ }
+ copl[cop_spr0ptrh].w[1] = highw(pl);
+ copl[cop_spr0ptrl].w[1] = loww(pl);
+ if (par->bplcon0 & BPC0_LACE) {
+ cops[cop_spr0ptrh].w[1] = highw(ps);
+ cops[cop_spr0ptrl].w[1] = loww(ps);
+ }
+}
+
+
+ /*
+ * Initialise the Copper Initialisation List
+ */
+
+static void __init ami_init_copper(void)
+{
+ copins *cop = copdisplay.init;
+ u_long p;
+ int i;
+
+ if (!IS_OCS) {
+ (cop++)->l = CMOVE(BPC0_COLOR | BPC0_SHRES | BPC0_ECSENA, bplcon0);
+ (cop++)->l = CMOVE(0x0181, diwstrt);
+ (cop++)->l = CMOVE(0x0281, diwstop);
+ (cop++)->l = CMOVE(0x0000, diwhigh);
+ } else
+ (cop++)->l = CMOVE(BPC0_COLOR, bplcon0);
+ p = ZTWO_PADDR(dummysprite);
+ for (i = 0; i < 8; i++) {
+ (cop++)->l = CMOVE(0, spr[i].pos);
+ (cop++)->l = CMOVE(highw(p), sprpt[i]);
+ (cop++)->l = CMOVE2(loww(p), sprpt[i]);
+ }
+
+ (cop++)->l = CMOVE(IF_SETCLR | IF_COPER, intreq);
+ copdisplay.wait = cop;
+ (cop++)->l = CEND;
+ (cop++)->l = CMOVE(0, copjmp2);
+ cop->l = CEND;
+
+ custom.cop1lc = (u_short *)ZTWO_PADDR(copdisplay.init);
+ custom.copjmp1 = 0;
+}
+
+static void ami_reinit_copper(const struct amifb_par *par)
+{
+ copdisplay.init[cip_bplcon0].w[1] = ~(BPC0_BPU3 | BPC0_BPU2 | BPC0_BPU1 | BPC0_BPU0) & par->bplcon0;
+ copdisplay.wait->l = CWAIT(32, par->diwstrt_v - 4);
+}
+
+
+ /*
+ * Rebuild the Copper List
+ *
+ * We only change the things that are not static
+ */
+
+static void ami_rebuild_copper(const struct amifb_par *par)
+{
+ copins *copl, *cops;
+ u_short line, h_end1, h_end2;
+ short i;
+ u_long p;
+
+ if (IS_AGA && maxfmode + par->clk_shift == 0)
+ h_end1 = par->diwstrt_h - 64;
+ else
+ h_end1 = par->htotal - 32;
+ h_end2 = par->ddfstop + 64;
+
+ ami_set_sprite(par);
+
+ copl = copdisplay.rebuild[1];
+ p = par->bplpt0;
+ if (par->vmode & FB_VMODE_YWRAP) {
+ if ((par->vyres - par->yoffset) != 1 || !mod2(par->diwstrt_v)) {
+ if (par->yoffset > par->vyres - par->yres) {
+ for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
+ (copl++)->l = CMOVE(highw(p), bplpt[i]);
+ (copl++)->l = CMOVE2(loww(p), bplpt[i]);
+ }
+ line = par->diwstrt_v + ((par->vyres - par->yoffset) << par->line_shift) - 1;
+ while (line >= 512) {
+ (copl++)->l = CWAIT(h_end1, 510);
+ line -= 512;
+ }
+ if (line >= 510 && IS_AGA && maxfmode + par->clk_shift == 0)
+ (copl++)->l = CWAIT(h_end1, line);
+ else
+ (copl++)->l = CWAIT(h_end2, line);
+ p = par->bplpt0wrap;
+ }
+ } else
+ p = par->bplpt0wrap;
+ }
+ for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
+ (copl++)->l = CMOVE(highw(p), bplpt[i]);
+ (copl++)->l = CMOVE2(loww(p), bplpt[i]);
+ }
+ copl->l = CEND;
+
+ if (par->bplcon0 & BPC0_LACE) {
+ cops = copdisplay.rebuild[0];
+ p = par->bplpt0;
+ if (mod2(par->diwstrt_v))
+ p -= par->next_line;
+ else
+ p += par->next_line;
+ if (par->vmode & FB_VMODE_YWRAP) {
+ if ((par->vyres - par->yoffset) != 1 || mod2(par->diwstrt_v)) {
+ if (par->yoffset > par->vyres - par->yres + 1) {
+ for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
+ (cops++)->l = CMOVE(highw(p), bplpt[i]);
+ (cops++)->l = CMOVE2(loww(p), bplpt[i]);
+ }
+ line = par->diwstrt_v + ((par->vyres - par->yoffset) << par->line_shift) - 2;
+ while (line >= 512) {
+ (cops++)->l = CWAIT(h_end1, 510);
+ line -= 512;
+ }
+ if (line > 510 && IS_AGA && maxfmode + par->clk_shift == 0)
+ (cops++)->l = CWAIT(h_end1, line);
+ else
+ (cops++)->l = CWAIT(h_end2, line);
+ p = par->bplpt0wrap;
+ if (mod2(par->diwstrt_v + par->vyres -
+ par->yoffset))
+ p -= par->next_line;
+ else
+ p += par->next_line;
+ }
+ } else
+ p = par->bplpt0wrap - par->next_line;
+ }
+ for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
+ (cops++)->l = CMOVE(highw(p), bplpt[i]);
+ (cops++)->l = CMOVE2(loww(p), bplpt[i]);
+ }
+ cops->l = CEND;
+ }
+}
+
+
+ /*
+ * Build the Copper List
+ */
+
+static void ami_build_copper(struct fb_info *info)
+{
+ struct amifb_par *par = info->par;
+ copins *copl, *cops;
+ u_long p;
+
+ currentcop = 1 - currentcop;
+
+ copl = copdisplay.list[currentcop][1];
+
+ (copl++)->l = CWAIT(0, 10);
+ (copl++)->l = CMOVE(par->bplcon0, bplcon0);
+ (copl++)->l = CMOVE(0, sprpt[0]);
+ (copl++)->l = CMOVE2(0, sprpt[0]);
+
+ if (par->bplcon0 & BPC0_LACE) {
+ cops = copdisplay.list[currentcop][0];
+
+ (cops++)->l = CWAIT(0, 10);
+ (cops++)->l = CMOVE(par->bplcon0, bplcon0);
+ (cops++)->l = CMOVE(0, sprpt[0]);
+ (cops++)->l = CMOVE2(0, sprpt[0]);
+
+ (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v + 1), diwstrt);
+ (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v + 1), diwstop);
+ (cops++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
+ (cops++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
+ if (!IS_OCS) {
+ (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v + 1,
+ par->diwstop_h, par->diwstop_v + 1), diwhigh);
+ (cops++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
+ par->diwstop_h, par->diwstop_v), diwhigh);
+#if 0
+ if (par->beamcon0 & BMC0_VARBEAMEN) {
+ (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
+ (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt + 1), vbstrt);
+ (copl++)->l = CMOVE(vbstop2hw(par->vbstop + 1), vbstop);
+ (cops++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
+ (cops++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
+ (cops++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
+ }
+#endif
+ }
+ p = ZTWO_PADDR(copdisplay.list[currentcop][0]);
+ (copl++)->l = CMOVE(highw(p), cop2lc);
+ (copl++)->l = CMOVE2(loww(p), cop2lc);
+ p = ZTWO_PADDR(copdisplay.list[currentcop][1]);
+ (cops++)->l = CMOVE(highw(p), cop2lc);
+ (cops++)->l = CMOVE2(loww(p), cop2lc);
+ copdisplay.rebuild[0] = cops;
+ } else {
+ (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
+ (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
+ if (!IS_OCS) {
+ (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
+ par->diwstop_h, par->diwstop_v), diwhigh);
+#if 0
+ if (par->beamcon0 & BMC0_VARBEAMEN) {
+ (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
+ (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
+ (copl++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
+ }
+#endif
+ }
+ }
+ copdisplay.rebuild[1] = copl;
+
+ ami_update_par(info);
+ ami_rebuild_copper(info->par);
+}
-static struct fb_ops amifb_ops = {
- .owner = THIS_MODULE,
- .fb_check_var = amifb_check_var,
- .fb_set_par = amifb_set_par,
- .fb_setcolreg = amifb_setcolreg,
- .fb_blank = amifb_blank,
- .fb_pan_display = amifb_pan_display,
- .fb_fillrect = amifb_fillrect,
- .fb_copyarea = amifb_copyarea,
- .fb_imageblit = amifb_imageblit,
- .fb_ioctl = amifb_ioctl,
-};
static void __init amifb_setup_mcap(char *spec)
{
@@ -1216,13 +2339,13 @@ static void __init amifb_setup_mcap(char *spec)
if (hmax <= 0 || hmax <= hmin)
return;
- fb_info.monspecs.vfmin = vmin;
- fb_info.monspecs.vfmax = vmax;
- fb_info.monspecs.hfmin = hmin;
- fb_info.monspecs.hfmax = hmax;
+ amifb_hfmin = hmin;
+ amifb_hfmax = hmax;
+ amifb_vfmin = vmin;
+ amifb_vfmax = vmax;
}
-int __init amifb_setup(char *options)
+static int __init amifb_setup(char *options)
{
char *this_opt;
@@ -1238,9 +2361,9 @@ int __init amifb_setup(char *options)
} else if (!strcmp(this_opt, "ilbm"))
amifb_ilbm = 1;
else if (!strncmp(this_opt, "monitorcap:", 11))
- amifb_setup_mcap(this_opt+11);
+ amifb_setup_mcap(this_opt + 11);
else if (!strncmp(this_opt, "fstart:", 7))
- min_fstrt = simple_strtoul(this_opt+7, NULL, 0);
+ min_fstrt = simple_strtoul(this_opt + 7, NULL, 0);
else
mode_option = this_opt;
}
@@ -1259,7 +2382,8 @@ static int amifb_check_var(struct fb_var_screeninfo *var,
struct amifb_par par;
/* Validate wanted screen parameters */
- if ((err = ami_decode_var(var, &par)))
+ err = ami_decode_var(var, &par, info);
+ if (err)
return err;
/* Encode (possibly rounded) screen parameters */
@@ -1270,16 +2394,19 @@ static int amifb_check_var(struct fb_var_screeninfo *var,
static int amifb_set_par(struct fb_info *info)
{
- struct amifb_par *par = (struct amifb_par *)info->par;
+ struct amifb_par *par = info->par;
+ int error;
do_vmode_pan = 0;
do_vmode_full = 0;
/* Decode wanted screen parameters */
- ami_decode_var(&info->var, par);
+ error = ami_decode_var(&info->var, par, info);
+ if (error)
+ return error;
/* Set new videomode */
- ami_build_copper();
+ ami_build_copper(info);
/* Set VBlank trigger */
do_vmode_full = 1;
@@ -1295,20 +2422,20 @@ static int amifb_set_par(struct fb_info *info)
info->fix.type = FB_TYPE_PLANES;
info->fix.type_aux = 0;
}
- info->fix.line_length = div8(upx(16<<maxfmode, par->vxres));
+ info->fix.line_length = div8(upx(16 << maxfmode, par->vxres));
if (par->vmode & FB_VMODE_YWRAP) {
info->fix.ywrapstep = 1;
info->fix.xpanstep = 0;
info->fix.ypanstep = 0;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YWRAP |
- FBINFO_READS_FAST; /* override SCROLL_REDRAW */
+ FBINFO_READS_FAST; /* override SCROLL_REDRAW */
} else {
info->fix.ywrapstep = 0;
if (par->vmode & FB_VMODE_SMOOTH_XPAN)
info->fix.xpanstep = 1;
else
- info->fix.xpanstep = 16<<maxfmode;
+ info->fix.xpanstep = 16 << maxfmode;
info->fix.ypanstep = 1;
info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
}
@@ -1317,6 +2444,95 @@ static int amifb_set_par(struct fb_info *info)
/*
+ * Set a single color register. The values supplied are already
+ * rounded down to the hardware's capabilities (according to the
+ * entries in the var structure). Return != 0 for invalid regno.
+ */
+
+static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ const struct amifb_par *par = info->par;
+
+ if (IS_AGA) {
+ if (regno > 255)
+ return 1;
+ } else if (par->bplcon0 & BPC0_SHRES) {
+ if (regno > 3)
+ return 1;
+ } else {
+ if (regno > 31)
+ return 1;
+ }
+ red >>= 8;
+ green >>= 8;
+ blue >>= 8;
+ if (!regno) {
+ red0 = red;
+ green0 = green;
+ blue0 = blue;
+ }
+
+ /*
+ * Update the corresponding Hardware Color Register, unless it's Color
+ * Register 0 and the screen is blanked.
+ *
+ * VBlank is switched off to protect bplcon3 or ecs_palette[] from
+ * being changed by ami_do_blank() during the VBlank.
+ */
+
+ if (regno || !is_blanked) {
+#if defined(CONFIG_FB_AMIGA_AGA)
+ if (IS_AGA) {
+ u_short bplcon3 = par->bplcon3;
+ VBlankOff();
+ custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000);
+ custom.color[regno & 31] = rgb2hw8_high(red, green,
+ blue);
+ custom.bplcon3 = bplcon3 | (regno << 8 & 0xe000) |
+ BPC3_LOCT;
+ custom.color[regno & 31] = rgb2hw8_low(red, green,
+ blue);
+ custom.bplcon3 = bplcon3;
+ VBlankOn();
+ } else
+#endif
+#if defined(CONFIG_FB_AMIGA_ECS)
+ if (par->bplcon0 & BPC0_SHRES) {
+ u_short color, mask;
+ int i;
+
+ mask = 0x3333;
+ color = rgb2hw2(red, green, blue);
+ VBlankOff();
+ for (i = regno + 12; i >= (int)regno; i -= 4)
+ custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
+ mask <<= 2; color >>= 2;
+ regno = down16(regno) + mul4(mod4(regno));
+ for (i = regno + 3; i >= (int)regno; i--)
+ custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
+ VBlankOn();
+ } else
+#endif
+ custom.color[regno] = rgb2hw4(red, green, blue);
+ }
+ return 0;
+}
+
+
+ /*
+ * Blank the display.
+ */
+
+static int amifb_blank(int blank, struct fb_info *info)
+{
+ do_blank = blank ? blank : -1;
+
+ return 0;
+}
+
+
+ /*
* Pan or Wrap the Display
*
* This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
@@ -1327,18 +2543,19 @@ static int amifb_pan_display(struct fb_var_screeninfo *var,
{
if (var->vmode & FB_VMODE_YWRAP) {
if (var->yoffset < 0 ||
- var->yoffset >= info->var.yres_virtual || var->xoffset)
- return -EINVAL;
+ var->yoffset >= info->var.yres_virtual || var->xoffset)
+ return -EINVAL;
} else {
/*
* TODO: There will be problems when xpan!=1, so some columns
* on the right side will never be seen
*/
- if (var->xoffset+info->var.xres > upx(16<<maxfmode, info->var.xres_virtual) ||
- var->yoffset+info->var.yres > info->var.yres_virtual)
+ if (var->xoffset + info->var.xres >
+ upx(16 << maxfmode, info->var.xres_virtual) ||
+ var->yoffset + info->var.yres > info->var.yres_virtual)
return -EINVAL;
}
- ami_pan_var(var);
+ ami_pan_var(var, info);
info->var.xoffset = var->xoffset;
info->var.yoffset = var->yoffset;
if (var->vmode & FB_VMODE_YWRAP)
@@ -1360,10 +2577,10 @@ static int amifb_pan_display(struct fb_var_screeninfo *var,
#endif
- /*
- * Compose two values, using a bitmask as decision value
- * This is equivalent to (a & mask) | (b & ~mask)
- */
+ /*
+ * Compose two values, using a bitmask as decision value
+ * This is equivalent to (a & mask) | (b & ~mask)
+ */
static inline unsigned long comp(unsigned long a, unsigned long b,
unsigned long mask)
@@ -1379,29 +2596,29 @@ static inline unsigned long xor(unsigned long a, unsigned long b,
}
- /*
- * Unaligned forward bit copy using 32-bit or 64-bit memory accesses
- */
+ /*
+ * Unaligned forward bit copy using 32-bit or 64-bit memory accesses
+ */
static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
int src_idx, u32 n)
{
unsigned long first, last;
- int shift = dst_idx-src_idx, left, right;
+ int shift = dst_idx - src_idx, left, right;
unsigned long d0, d1;
int m;
if (!n)
return;
- shift = dst_idx-src_idx;
+ shift = dst_idx - src_idx;
first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+ last = ~(~0UL >> ((dst_idx + n) % BITS_PER_LONG));
if (!shift) {
// Same alignment for source and dest
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single word
if (last)
first &= last;
@@ -1413,7 +2630,7 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
*dst = comp(*src, *dst, first);
dst++;
src++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1439,17 +2656,17 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
} else {
// Different alignment for source and dest
- right = shift & (BITS_PER_LONG-1);
- left = -shift & (BITS_PER_LONG-1);
+ right = shift & (BITS_PER_LONG - 1);
+ left = -shift & (BITS_PER_LONG - 1);
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single destination word
if (last)
first &= last;
if (shift > 0) {
// Single source word
*dst = comp(*src >> right, *dst, first);
- } else if (src_idx+n <= BITS_PER_LONG) {
+ } else if (src_idx + n <= BITS_PER_LONG) {
// Single source word
*dst = comp(*src << left, *dst, first);
} else {
@@ -1467,7 +2684,7 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
// Single source word
*dst = comp(d0 >> right, *dst, first);
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
} else {
// 2 source words
d1 = *src++;
@@ -1475,7 +2692,7 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
first);
d0 = d1;
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1519,40 +2736,40 @@ static void bitcpy(unsigned long *dst, int dst_idx, const unsigned long *src,
}
- /*
- * Unaligned reverse bit copy using 32-bit or 64-bit memory accesses
- */
+ /*
+ * Unaligned reverse bit copy using 32-bit or 64-bit memory accesses
+ */
static void bitcpy_rev(unsigned long *dst, int dst_idx,
const unsigned long *src, int src_idx, u32 n)
{
unsigned long first, last;
- int shift = dst_idx-src_idx, left, right;
+ int shift = dst_idx - src_idx, left, right;
unsigned long d0, d1;
int m;
if (!n)
return;
- dst += (n-1)/BITS_PER_LONG;
- src += (n-1)/BITS_PER_LONG;
- if ((n-1) % BITS_PER_LONG) {
- dst_idx += (n-1) % BITS_PER_LONG;
+ dst += (n - 1) / BITS_PER_LONG;
+ src += (n - 1) / BITS_PER_LONG;
+ if ((n - 1) % BITS_PER_LONG) {
+ dst_idx += (n - 1) % BITS_PER_LONG;
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= BITS_PER_LONG-1;
- src_idx += (n-1) % BITS_PER_LONG;
+ dst_idx &= BITS_PER_LONG - 1;
+ src_idx += (n - 1) % BITS_PER_LONG;
src += src_idx >> SHIFT_PER_LONG;
- src_idx &= BITS_PER_LONG-1;
+ src_idx &= BITS_PER_LONG - 1;
}
- shift = dst_idx-src_idx;
- first = ~0UL << (BITS_PER_LONG-1-dst_idx);
- last = ~(~0UL << (BITS_PER_LONG-1-((dst_idx-n) % BITS_PER_LONG)));
+ shift = dst_idx - src_idx;
+ first = ~0UL << (BITS_PER_LONG - 1 - dst_idx);
+ last = ~(~0UL << (BITS_PER_LONG - 1 - ((dst_idx - n) % BITS_PER_LONG)));
if (!shift) {
// Same alignment for source and dest
- if ((unsigned long)dst_idx+1 >= n) {
+ if ((unsigned long)dst_idx + 1 >= n) {
// Single word
if (last)
first &= last;
@@ -1564,7 +2781,7 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
*dst = comp(*src, *dst, first);
dst--;
src--;
- n -= dst_idx+1;
+ n -= dst_idx + 1;
}
// Main chunk
@@ -1590,17 +2807,17 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
} else {
// Different alignment for source and dest
- right = shift & (BITS_PER_LONG-1);
- left = -shift & (BITS_PER_LONG-1);
+ right = shift & (BITS_PER_LONG - 1);
+ left = -shift & (BITS_PER_LONG - 1);
- if ((unsigned long)dst_idx+1 >= n) {
+ if ((unsigned long)dst_idx + 1 >= n) {
// Single destination word
if (last)
first &= last;
if (shift < 0) {
// Single source word
*dst = comp(*src << left, *dst, first);
- } else if (1+(unsigned long)src_idx >= n) {
+ } else if (1 + (unsigned long)src_idx >= n) {
// Single source word
*dst = comp(*src >> right, *dst, first);
} else {
@@ -1618,7 +2835,7 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
// Single source word
*dst = comp(d0 << left, *dst, first);
dst--;
- n -= dst_idx+1;
+ n -= dst_idx + 1;
} else {
// 2 source words
d1 = *src--;
@@ -1626,7 +2843,7 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
first);
d0 = d1;
dst--;
- n -= dst_idx+1;
+ n -= dst_idx + 1;
}
// Main chunk
@@ -1670,30 +2887,30 @@ static void bitcpy_rev(unsigned long *dst, int dst_idx,
}
- /*
- * Unaligned forward inverting bit copy using 32-bit or 64-bit memory
- * accesses
- */
+ /*
+ * Unaligned forward inverting bit copy using 32-bit or 64-bit memory
+ * accesses
+ */
static void bitcpy_not(unsigned long *dst, int dst_idx,
const unsigned long *src, int src_idx, u32 n)
{
unsigned long first, last;
- int shift = dst_idx-src_idx, left, right;
+ int shift = dst_idx - src_idx, left, right;
unsigned long d0, d1;
int m;
if (!n)
return;
- shift = dst_idx-src_idx;
+ shift = dst_idx - src_idx;
first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+ last = ~(~0UL >> ((dst_idx + n) % BITS_PER_LONG));
if (!shift) {
// Same alignment for source and dest
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single word
if (last)
first &= last;
@@ -1705,7 +2922,7 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
*dst = comp(~*src, *dst, first);
dst++;
src++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1731,17 +2948,17 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
} else {
// Different alignment for source and dest
- right = shift & (BITS_PER_LONG-1);
- left = -shift & (BITS_PER_LONG-1);
+ right = shift & (BITS_PER_LONG - 1);
+ left = -shift & (BITS_PER_LONG - 1);
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single destination word
if (last)
first &= last;
if (shift > 0) {
// Single source word
*dst = comp(~*src >> right, *dst, first);
- } else if (src_idx+n <= BITS_PER_LONG) {
+ } else if (src_idx + n <= BITS_PER_LONG) {
// Single source word
*dst = comp(~*src << left, *dst, first);
} else {
@@ -1759,7 +2976,7 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
// Single source word
*dst = comp(d0 >> right, *dst, first);
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
} else {
// 2 source words
d1 = ~*src++;
@@ -1767,7 +2984,7 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
first);
d0 = d1;
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1811,9 +3028,9 @@ static void bitcpy_not(unsigned long *dst, int dst_idx,
}
- /*
- * Unaligned 32-bit pattern fill using 32/64-bit memory accesses
- */
+ /*
+ * Unaligned 32-bit pattern fill using 32/64-bit memory accesses
+ */
static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
{
@@ -1828,9 +3045,9 @@ static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
#endif
first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+ last = ~(~0UL >> ((dst_idx + n) % BITS_PER_LONG));
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single word
if (last)
first &= last;
@@ -1841,7 +3058,7 @@ static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
if (first) {
*dst = comp(val, *dst, first);
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1867,9 +3084,9 @@ static void bitfill32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
}
- /*
- * Unaligned 32-bit pattern xor using 32/64-bit memory accesses
- */
+ /*
+ * Unaligned 32-bit pattern xor using 32/64-bit memory accesses
+ */
static void bitxor32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
{
@@ -1884,9 +3101,9 @@ static void bitxor32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
#endif
first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+n) % BITS_PER_LONG));
+ last = ~(~0UL >> ((dst_idx + n) % BITS_PER_LONG));
- if (dst_idx+n <= BITS_PER_LONG) {
+ if (dst_idx + n <= BITS_PER_LONG) {
// Single word
if (last)
first &= last;
@@ -1897,7 +3114,7 @@ static void bitxor32(unsigned long *dst, int dst_idx, u32 pat, u32 n)
if (first) {
*dst = xor(val, *dst, first);
dst++;
- n -= BITS_PER_LONG-dst_idx;
+ n -= BITS_PER_LONG - dst_idx;
}
// Main chunk
@@ -1924,12 +3141,12 @@ static inline void fill_one_line(int bpp, unsigned long next_plane,
{
while (1) {
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
+ dst_idx &= (BITS_PER_LONG - 1);
bitfill32(dst, dst_idx, color & 1 ? ~0 : 0, n);
if (!--bpp)
break;
color >>= 1;
- dst_idx += next_plane*8;
+ dst_idx += next_plane * 8;
}
}
@@ -1939,12 +3156,12 @@ static inline void xor_one_line(int bpp, unsigned long next_plane,
{
while (color) {
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
+ dst_idx &= (BITS_PER_LONG - 1);
bitxor32(dst, dst_idx, color & 1 ? ~0 : 0, n);
if (!--bpp)
break;
color >>= 1;
- dst_idx += next_plane*8;
+ dst_idx += next_plane * 8;
}
}
@@ -1952,7 +3169,7 @@ static inline void xor_one_line(int bpp, unsigned long next_plane,
static void amifb_fillrect(struct fb_info *info,
const struct fb_fillrect *rect)
{
- struct amifb_par *par = (struct amifb_par *)info->par;
+ struct amifb_par *par = info->par;
int dst_idx, x2, y2;
unsigned long *dst;
u32 width, height;
@@ -1972,23 +3189,23 @@ static void amifb_fillrect(struct fb_info *info,
height = y2 - rect->dy;
dst = (unsigned long *)
- ((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
- dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
- dst_idx += rect->dy*par->next_line*8+rect->dx;
+ ((unsigned long)info->screen_base & ~(BYTES_PER_LONG - 1));
+ dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG - 1)) * 8;
+ dst_idx += rect->dy * par->next_line * 8 + rect->dx;
while (height--) {
switch (rect->rop) {
- case ROP_COPY:
+ case ROP_COPY:
fill_one_line(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, width,
rect->color);
break;
- case ROP_XOR:
+ case ROP_XOR:
xor_one_line(info->var.bits_per_pixel, par->next_plane,
dst, dst_idx, width, rect->color);
break;
}
- dst_idx += par->next_line*8;
+ dst_idx += par->next_line * 8;
}
}
@@ -1998,14 +3215,14 @@ static inline void copy_one_line(int bpp, unsigned long next_plane,
{
while (1) {
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
+ dst_idx &= (BITS_PER_LONG - 1);
src += src_idx >> SHIFT_PER_LONG;
- src_idx &= (BITS_PER_LONG-1);
+ src_idx &= (BITS_PER_LONG - 1);
bitcpy(dst, dst_idx, src, src_idx, n);
if (!--bpp)
break;
- dst_idx += next_plane*8;
- src_idx += next_plane*8;
+ dst_idx += next_plane * 8;
+ src_idx += next_plane * 8;
}
}
@@ -2015,14 +3232,14 @@ static inline void copy_one_line_rev(int bpp, unsigned long next_plane,
{
while (1) {
dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
+ dst_idx &= (BITS_PER_LONG - 1);
src += src_idx >> SHIFT_PER_LONG;
- src_idx &= (BITS_PER_LONG-1);
+ src_idx &= (BITS_PER_LONG - 1);
bitcpy_rev(dst, dst_idx, src, src_idx, n);
if (!--bpp)
break;
- dst_idx += next_plane*8;
- src_idx += next_plane*8;
+ dst_idx += next_plane * 8;
+ src_idx += next_plane * 8;
}
}
@@ -2030,7 +3247,7 @@ static inline void copy_one_line_rev(int bpp, unsigned long next_plane,
static void amifb_copyarea(struct fb_info *info,
const struct fb_copyarea *area)
{
- struct amifb_par *par = (struct amifb_par *)info->par;
+ struct amifb_par *par = info->par;
int x2, y2;
u32 dx, dy, sx, sy, width, height;
unsigned long *dst, *src;
@@ -2065,16 +3282,16 @@ static void amifb_copyarea(struct fb_info *info,
rev_copy = 1;
}
dst = (unsigned long *)
- ((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
+ ((unsigned long)info->screen_base & ~(BYTES_PER_LONG - 1));
src = dst;
- dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
+ dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG - 1)) * 8;
src_idx = dst_idx;
- dst_idx += dy*par->next_line*8+dx;
- src_idx += sy*par->next_line*8+sx;
+ dst_idx += dy * par->next_line * 8 + dx;
+ src_idx += sy * par->next_line * 8 + sx;
if (rev_copy) {
while (height--) {
- dst_idx -= par->next_line*8;
- src_idx -= par->next_line*8;
+ dst_idx -= par->next_line * 8;
+ src_idx -= par->next_line * 8;
copy_one_line_rev(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, src,
src_idx, width);
@@ -2084,8 +3301,8 @@ static void amifb_copyarea(struct fb_info *info,
copy_one_line(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, src,
src_idx, width);
- dst_idx += par->next_line*8;
- src_idx += par->next_line*8;
+ dst_idx += par->next_line * 8;
+ src_idx += par->next_line * 8;
}
}
}
@@ -2095,34 +3312,35 @@ static inline void expand_one_line(int bpp, unsigned long next_plane,
unsigned long *dst, int dst_idx, u32 n,
const u8 *data, u32 bgcolor, u32 fgcolor)
{
- const unsigned long *src;
- int src_idx;
-
- while (1) {
- dst += dst_idx >> SHIFT_PER_LONG;
- dst_idx &= (BITS_PER_LONG-1);
- if ((bgcolor ^ fgcolor) & 1) {
- src = (unsigned long *)((unsigned long)data & ~(BYTES_PER_LONG-1));
- src_idx = ((unsigned long)data & (BYTES_PER_LONG-1))*8;
- if (fgcolor & 1)
- bitcpy(dst, dst_idx, src, src_idx, n);
- else
- bitcpy_not(dst, dst_idx, src, src_idx, n);
- /* set or clear */
- } else
- bitfill32(dst, dst_idx, fgcolor & 1 ? ~0 : 0, n);
- if (!--bpp)
- break;
- bgcolor >>= 1;
- fgcolor >>= 1;
- dst_idx += next_plane*8;
- }
+ const unsigned long *src;
+ int src_idx;
+
+ while (1) {
+ dst += dst_idx >> SHIFT_PER_LONG;
+ dst_idx &= (BITS_PER_LONG - 1);
+ if ((bgcolor ^ fgcolor) & 1) {
+ src = (unsigned long *)
+ ((unsigned long)data & ~(BYTES_PER_LONG - 1));
+ src_idx = ((unsigned long)data & (BYTES_PER_LONG - 1)) * 8;
+ if (fgcolor & 1)
+ bitcpy(dst, dst_idx, src, src_idx, n);
+ else
+ bitcpy_not(dst, dst_idx, src, src_idx, n);
+ /* set or clear */
+ } else
+ bitfill32(dst, dst_idx, fgcolor & 1 ? ~0 : 0, n);
+ if (!--bpp)
+ break;
+ bgcolor >>= 1;
+ fgcolor >>= 1;
+ dst_idx += next_plane * 8;
+ }
}
static void amifb_imageblit(struct fb_info *info, const struct fb_image *image)
{
- struct amifb_par *par = (struct amifb_par *)info->par;
+ struct amifb_par *par = info->par;
int x2, y2;
unsigned long *dst;
int dst_idx;
@@ -2145,17 +3363,17 @@ static void amifb_imageblit(struct fb_info *info, const struct fb_image *image)
if (image->depth == 1) {
dst = (unsigned long *)
- ((unsigned long)info->screen_base & ~(BYTES_PER_LONG-1));
- dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG-1))*8;
- dst_idx += dy*par->next_line*8+dx;
+ ((unsigned long)info->screen_base & ~(BYTES_PER_LONG - 1));
+ dst_idx = ((unsigned long)info->screen_base & (BYTES_PER_LONG - 1)) * 8;
+ dst_idx += dy * par->next_line * 8 + dx;
src = image->data;
- pitch = (image->width+7)/8;
+ pitch = (image->width + 7) / 8;
while (height--) {
expand_one_line(info->var.bits_per_pixel,
par->next_plane, dst, dst_idx, width,
src, image->bg_color,
image->fg_color);
- dst_idx += par->next_line*8;
+ dst_idx += par->next_line * 8;
src += pitch;
}
} else {
@@ -2182,45 +3400,119 @@ static int amifb_ioctl(struct fb_info *info,
int i;
switch (cmd) {
- case FBIOGET_FCURSORINFO:
- i = ami_get_fix_cursorinfo(&crsr.fix);
- if (i)
- return i;
- return copy_to_user(argp, &crsr.fix,
- sizeof(crsr.fix)) ? -EFAULT : 0;
-
- case FBIOGET_VCURSORINFO:
- i = ami_get_var_cursorinfo(&crsr.var,
- ((struct fb_var_cursorinfo __user *)arg)->data);
- if (i)
- return i;
- return copy_to_user(argp, &crsr.var,
- sizeof(crsr.var)) ? -EFAULT : 0;
-
- case FBIOPUT_VCURSORINFO:
- if (copy_from_user(&crsr.var, argp, sizeof(crsr.var)))
- return -EFAULT;
- return ami_set_var_cursorinfo(&crsr.var,
- ((struct fb_var_cursorinfo __user *)arg)->data);
-
- case FBIOGET_CURSORSTATE:
- i = ami_get_cursorstate(&crsr.state);
- if (i)
- return i;
- return copy_to_user(argp, &crsr.state,
- sizeof(crsr.state)) ? -EFAULT : 0;
-
- case FBIOPUT_CURSORSTATE:
- if (copy_from_user(&crsr.state, argp,
- sizeof(crsr.state)))
- return -EFAULT;
- return ami_set_cursorstate(&crsr.state);
+ case FBIOGET_FCURSORINFO:
+ i = ami_get_fix_cursorinfo(&crsr.fix, info->par);
+ if (i)
+ return i;
+ return copy_to_user(argp, &crsr.fix,
+ sizeof(crsr.fix)) ? -EFAULT : 0;
+
+ case FBIOGET_VCURSORINFO:
+ i = ami_get_var_cursorinfo(&crsr.var,
+ ((struct fb_var_cursorinfo __user *)arg)->data,
+ info->par);
+ if (i)
+ return i;
+ return copy_to_user(argp, &crsr.var,
+ sizeof(crsr.var)) ? -EFAULT : 0;
+
+ case FBIOPUT_VCURSORINFO:
+ if (copy_from_user(&crsr.var, argp, sizeof(crsr.var)))
+ return -EFAULT;
+ return ami_set_var_cursorinfo(&crsr.var,
+ ((struct fb_var_cursorinfo __user *)arg)->data,
+ info->par);
+
+ case FBIOGET_CURSORSTATE:
+ i = ami_get_cursorstate(&crsr.state, info->par);
+ if (i)
+ return i;
+ return copy_to_user(argp, &crsr.state,
+ sizeof(crsr.state)) ? -EFAULT : 0;
+
+ case FBIOPUT_CURSORSTATE:
+ if (copy_from_user(&crsr.state, argp, sizeof(crsr.state)))
+ return -EFAULT;
+ return ami_set_cursorstate(&crsr.state, info->par);
}
return -EINVAL;
}
/*
+ * Flash the cursor (called by VBlank interrupt)
+ */
+
+static int flash_cursor(void)
+{
+ static int cursorcount = 1;
+
+ if (cursormode == FB_CURSOR_FLASH) {
+ if (!--cursorcount) {
+ cursorstate = -cursorstate;
+ cursorcount = cursorrate;
+ if (!is_blanked)
+ return 1;
+ }
+ }
+ return 0;
+}
+
+ /*
+ * VBlank Display Interrupt
+ */
+
+static irqreturn_t amifb_interrupt(int irq, void *dev_id)
+{
+ struct amifb_par *par = dev_id;
+
+ if (do_vmode_pan || do_vmode_full)
+ ami_update_display(par);
+
+ if (do_vmode_full)
+ ami_init_display(par);
+
+ if (do_vmode_pan) {
+ flash_cursor();
+ ami_rebuild_copper(par);
+ do_cursor = do_vmode_pan = 0;
+ } else if (do_cursor) {
+ flash_cursor();
+ ami_set_sprite(par);
+ do_cursor = 0;
+ } else {
+ if (flash_cursor())
+ ami_set_sprite(par);
+ }
+
+ if (do_blank) {
+ ami_do_blank(par);
+ do_blank = 0;
+ }
+
+ if (do_vmode_full) {
+ ami_reinit_copper(par);
+ do_vmode_full = 0;
+ }
+ return IRQ_HANDLED;
+}
+
+
+static struct fb_ops amifb_ops = {
+ .owner = THIS_MODULE,
+ .fb_check_var = amifb_check_var,
+ .fb_set_par = amifb_set_par,
+ .fb_setcolreg = amifb_setcolreg,
+ .fb_blank = amifb_blank,
+ .fb_pan_display = amifb_pan_display,
+ .fb_fillrect = amifb_fillrect,
+ .fb_copyarea = amifb_copyarea,
+ .fb_imageblit = amifb_imageblit,
+ .fb_ioctl = amifb_ioctl,
+};
+
+
+ /*
* Allocate, Clear and Align a Block of Chip Memory
*/
@@ -2250,6 +3542,7 @@ static inline void chipfree(void)
static int __init amifb_probe(struct platform_device *pdev)
{
+ struct fb_info *info;
int tag, i, err = 0;
u_long chipptr;
u_int defmode;
@@ -2265,71 +3558,80 @@ static int __init amifb_probe(struct platform_device *pdev)
#endif
custom.dmacon = DMAF_ALL | DMAF_MASTER;
+ info = framebuffer_alloc(sizeof(struct amifb_par), &pdev->dev);
+ if (!info) {
+ dev_err(&pdev->dev, "framebuffer_alloc failed\n");
+ return -ENOMEM;
+ }
+
+ strcpy(info->fix.id, "Amiga ");
+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ info->fix.accel = FB_ACCEL_AMIGABLITT;
+
switch (amiga_chipset) {
#ifdef CONFIG_FB_AMIGA_OCS
- case CS_OCS:
- strcat(fb_info.fix.id, "OCS");
+ case CS_OCS:
+ strcat(info->fix.id, "OCS");
default_chipset:
- chipset = TAG_OCS;
- maxdepth[TAG_SHRES] = 0; /* OCS means no SHRES */
- maxdepth[TAG_HIRES] = 4;
- maxdepth[TAG_LORES] = 6;
- maxfmode = TAG_FMODE_1;
- defmode = amiga_vblank == 50 ? DEFMODE_PAL
- : DEFMODE_NTSC;
- fb_info.fix.smem_len = VIDEOMEMSIZE_OCS;
- break;
+ chipset = TAG_OCS;
+ maxdepth[TAG_SHRES] = 0; /* OCS means no SHRES */
+ maxdepth[TAG_HIRES] = 4;
+ maxdepth[TAG_LORES] = 6;
+ maxfmode = TAG_FMODE_1;
+ defmode = amiga_vblank == 50 ? DEFMODE_PAL : DEFMODE_NTSC;
+ info->fix.smem_len = VIDEOMEMSIZE_OCS;
+ break;
#endif /* CONFIG_FB_AMIGA_OCS */
#ifdef CONFIG_FB_AMIGA_ECS
- case CS_ECS:
- strcat(fb_info.fix.id, "ECS");
- chipset = TAG_ECS;
- maxdepth[TAG_SHRES] = 2;
- maxdepth[TAG_HIRES] = 4;
- maxdepth[TAG_LORES] = 6;
- maxfmode = TAG_FMODE_1;
- if (AMIGAHW_PRESENT(AMBER_FF))
- defmode = amiga_vblank == 50 ? DEFMODE_AMBER_PAL
- : DEFMODE_AMBER_NTSC;
- else
- defmode = amiga_vblank == 50 ? DEFMODE_PAL
- : DEFMODE_NTSC;
- if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
- VIDEOMEMSIZE_ECS_2M)
- fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_2M;
- else
- fb_info.fix.smem_len = VIDEOMEMSIZE_ECS_1M;
- break;
+ case CS_ECS:
+ strcat(info->fix.id, "ECS");
+ chipset = TAG_ECS;
+ maxdepth[TAG_SHRES] = 2;
+ maxdepth[TAG_HIRES] = 4;
+ maxdepth[TAG_LORES] = 6;
+ maxfmode = TAG_FMODE_1;
+ if (AMIGAHW_PRESENT(AMBER_FF))
+ defmode = amiga_vblank == 50 ? DEFMODE_AMBER_PAL
+ : DEFMODE_AMBER_NTSC;
+ else
+ defmode = amiga_vblank == 50 ? DEFMODE_PAL
+ : DEFMODE_NTSC;
+ if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT >
+ VIDEOMEMSIZE_ECS_2M)
+ info->fix.smem_len = VIDEOMEMSIZE_ECS_2M;
+ else
+ info->fix.smem_len = VIDEOMEMSIZE_ECS_1M;
+ break;
#endif /* CONFIG_FB_AMIGA_ECS */
#ifdef CONFIG_FB_AMIGA_AGA
- case CS_AGA:
- strcat(fb_info.fix.id, "AGA");
- chipset = TAG_AGA;
- maxdepth[TAG_SHRES] = 8;
- maxdepth[TAG_HIRES] = 8;
- maxdepth[TAG_LORES] = 8;
- maxfmode = TAG_FMODE_4;
- defmode = DEFMODE_AGA;
- if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
- VIDEOMEMSIZE_AGA_2M)
- fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_2M;
- else
- fb_info.fix.smem_len = VIDEOMEMSIZE_AGA_1M;
- break;
+ case CS_AGA:
+ strcat(info->fix.id, "AGA");
+ chipset = TAG_AGA;
+ maxdepth[TAG_SHRES] = 8;
+ maxdepth[TAG_HIRES] = 8;
+ maxdepth[TAG_LORES] = 8;
+ maxfmode = TAG_FMODE_4;
+ defmode = DEFMODE_AGA;
+ if (amiga_chip_avail() - CHIPRAM_SAFETY_LIMIT >
+ VIDEOMEMSIZE_AGA_2M)
+ info->fix.smem_len = VIDEOMEMSIZE_AGA_2M;
+ else
+ info->fix.smem_len = VIDEOMEMSIZE_AGA_1M;
+ break;
#endif /* CONFIG_FB_AMIGA_AGA */
- default:
+ default:
#ifdef CONFIG_FB_AMIGA_OCS
- printk("Unknown graphics chipset, defaulting to OCS\n");
- strcat(fb_info.fix.id, "Unknown");
- goto default_chipset;
+ printk("Unknown graphics chipset, defaulting to OCS\n");
+ strcat(info->fix.id, "Unknown");
+ goto default_chipset;
#else /* CONFIG_FB_AMIGA_OCS */
- err = -ENODEV;
- goto amifb_error;
+ err = -ENODEV;
+ goto release;
#endif /* CONFIG_FB_AMIGA_OCS */
- break;
+ break;
}
/*
@@ -2356,42 +3658,44 @@ default_chipset:
}
}
- /*
- * These monitor specs are for a typical Amiga monitor (e.g. A1960)
- */
- if (fb_info.monspecs.hfmin == 0) {
- fb_info.monspecs.hfmin = 15000;
- fb_info.monspecs.hfmax = 38000;
- fb_info.monspecs.vfmin = 49;
- fb_info.monspecs.vfmax = 90;
+ if (amifb_hfmin) {
+ info->monspecs.hfmin = amifb_hfmin;
+ info->monspecs.hfmax = amifb_hfmax;
+ info->monspecs.vfmin = amifb_vfmin;
+ info->monspecs.vfmax = amifb_vfmax;
+ } else {
+ /*
+ * These are for a typical Amiga monitor (e.g. A1960)
+ */
+ info->monspecs.hfmin = 15000;
+ info->monspecs.hfmax = 38000;
+ info->monspecs.vfmin = 49;
+ info->monspecs.vfmax = 90;
}
- fb_info.fbops = &amifb_ops;
- fb_info.par = &currentpar;
- fb_info.flags = FBINFO_DEFAULT;
- fb_info.device = &pdev->dev;
+ info->fbops = &amifb_ops;
+ info->flags = FBINFO_DEFAULT;
+ info->device = &pdev->dev;
- if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, ami_modedb,
+ if (!fb_find_mode(&info->var, info, mode_option, ami_modedb,
NUM_TOTAL_MODES, &ami_modedb[defmode], 4)) {
err = -EINVAL;
- goto amifb_error;
+ goto release;
}
fb_videomode_to_modelist(ami_modedb, NUM_TOTAL_MODES,
- &fb_info.modelist);
+ &info->modelist);
round_down_bpp = 0;
- chipptr = chipalloc(fb_info.fix.smem_len+
- SPRITEMEMSIZE+
- DUMMYSPRITEMEMSIZE+
- COPINITSIZE+
- 4*COPLISTSIZE);
+ chipptr = chipalloc(info->fix.smem_len + SPRITEMEMSIZE +
+ DUMMYSPRITEMEMSIZE + COPINITSIZE +
+ 4 * COPLISTSIZE);
if (!chipptr) {
err = -ENOMEM;
- goto amifb_error;
+ goto release;
}
- assignchunk(videomemory, u_long, chipptr, fb_info.fix.smem_len);
+ assignchunk(videomemory, u_long, chipptr, info->fix.smem_len);
assignchunk(spritememory, u_long, chipptr, SPRITEMEMSIZE);
assignchunk(dummysprite, u_short *, chipptr, DUMMYSPRITEMEMSIZE);
assignchunk(copdisplay.init, copins *, chipptr, COPINITSIZE);
@@ -2403,1398 +3707,78 @@ default_chipset:
/*
* access the videomem with writethrough cache
*/
- fb_info.fix.smem_start = (u_long)ZTWO_PADDR(videomemory);
- videomemory = (u_long)ioremap_writethrough(fb_info.fix.smem_start,
- fb_info.fix.smem_len);
+ info->fix.smem_start = (u_long)ZTWO_PADDR(videomemory);
+ videomemory = (u_long)ioremap_writethrough(info->fix.smem_start,
+ info->fix.smem_len);
if (!videomemory) {
- printk("amifb: WARNING! unable to map videomem cached writethrough\n");
- fb_info.screen_base = (char *)ZTWO_VADDR(fb_info.fix.smem_start);
+ dev_warn(&pdev->dev,
+ "Unable to map videomem cached writethrough\n");
+ info->screen_base = (char *)ZTWO_VADDR(info->fix.smem_start);
} else
- fb_info.screen_base = (char *)videomemory;
+ info->screen_base = (char *)videomemory;
memset(dummysprite, 0, DUMMYSPRITEMEMSIZE);
/*
- * Enable Display DMA
- */
-
- custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
- DMAF_BLITTER | DMAF_SPRITE;
-
- /*
* Make sure the Copper has something to do
*/
-
ami_init_copper();
- if (request_irq(IRQ_AMIGA_COPPER, amifb_interrupt, 0,
- "fb vertb handler", &currentpar)) {
- err = -EBUSY;
- goto amifb_error;
- }
-
- err = fb_alloc_cmap(&fb_info.cmap, 1<<fb_info.var.bits_per_pixel, 0);
- if (err)
- goto amifb_error;
-
- if (register_framebuffer(&fb_info) < 0) {
- err = -EINVAL;
- goto amifb_error;
- }
-
- printk("fb%d: %s frame buffer device, using %dK of video memory\n",
- fb_info.node, fb_info.fix.id, fb_info.fix.smem_len>>10);
-
- return 0;
-
-amifb_error:
- amifb_deinit(pdev);
- return err;
-}
-
-static void amifb_deinit(struct platform_device *pdev)
-{
- if (fb_info.cmap.len)
- fb_dealloc_cmap(&fb_info.cmap);
- fb_dealloc_cmap(&fb_info.cmap);
- chipfree();
- if (videomemory)
- iounmap((void*)videomemory);
- custom.dmacon = DMAF_ALL | DMAF_MASTER;
-}
-
-
- /*
- * Blank the display.
- */
-
-static int amifb_blank(int blank, struct fb_info *info)
-{
- do_blank = blank ? blank : -1;
-
- return 0;
-}
-
- /*
- * Flash the cursor (called by VBlank interrupt)
- */
-
-static int flash_cursor(void)
-{
- static int cursorcount = 1;
-
- if (cursormode == FB_CURSOR_FLASH) {
- if (!--cursorcount) {
- cursorstate = -cursorstate;
- cursorcount = cursorrate;
- if (!is_blanked)
- return 1;
- }
- }
- return 0;
-}
-
- /*
- * VBlank Display Interrupt
- */
-
-static irqreturn_t amifb_interrupt(int irq, void *dev_id)
-{
- if (do_vmode_pan || do_vmode_full)
- ami_update_display();
-
- if (do_vmode_full)
- ami_init_display();
-
- if (do_vmode_pan) {
- flash_cursor();
- ami_rebuild_copper();
- do_cursor = do_vmode_pan = 0;
- } else if (do_cursor) {
- flash_cursor();
- ami_set_sprite();
- do_cursor = 0;
- } else {
- if (flash_cursor())
- ami_set_sprite();
- }
-
- if (do_blank) {
- ami_do_blank();
- do_blank = 0;
- }
-
- if (do_vmode_full) {
- ami_reinit_copper();
- do_vmode_full = 0;
- }
- return IRQ_HANDLED;
-}
-
-/* --------------------------- Hardware routines --------------------------- */
-
- /*
- * Get the video params out of `var'. If a value doesn't fit, round
- * it up, if it's too big, return -EINVAL.
- */
-
-static int ami_decode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par)
-{
- u_short clk_shift, line_shift;
- u_long maxfetchstop, fstrt, fsize, fconst, xres_n, yres_n;
- u_int htotal, vtotal;
-
- /*
- * Find a matching Pixel Clock
- */
-
- for (clk_shift = TAG_SHRES; clk_shift <= TAG_LORES; clk_shift++)
- if (var->pixclock <= pixclock[clk_shift])
- break;
- if (clk_shift > TAG_LORES) {
- DPRINTK("pixclock too high\n");
- return -EINVAL;
- }
- par->clk_shift = clk_shift;
-
- /*
- * Check the Geometry Values
- */
-
- if ((par->xres = var->xres) < 64)
- par->xres = 64;
- if ((par->yres = var->yres) < 64)
- par->yres = 64;
- if ((par->vxres = var->xres_virtual) < par->xres)
- par->vxres = par->xres;
- if ((par->vyres = var->yres_virtual) < par->yres)
- par->vyres = par->yres;
-
- par->bpp = var->bits_per_pixel;
- if (!var->nonstd) {
- if (par->bpp < 1)
- par->bpp = 1;
- if (par->bpp > maxdepth[clk_shift]) {
- if (round_down_bpp && maxdepth[clk_shift])
- par->bpp = maxdepth[clk_shift];
- else {
- DPRINTK("invalid bpp\n");
- return -EINVAL;
- }
- }
- } else if (var->nonstd == FB_NONSTD_HAM) {
- if (par->bpp < 6)
- par->bpp = 6;
- if (par->bpp != 6) {
- if (par->bpp < 8)
- par->bpp = 8;
- if (par->bpp != 8 || !IS_AGA) {
- DPRINTK("invalid bpp for ham mode\n");
- return -EINVAL;
- }
- }
- } else {
- DPRINTK("unknown nonstd mode\n");
- return -EINVAL;
- }
-
- /*
- * FB_VMODE_SMOOTH_XPAN will be cleared, if one of the folloing
- * checks failed and smooth scrolling is not possible
- */
-
- par->vmode = var->vmode | FB_VMODE_SMOOTH_XPAN;
- switch (par->vmode & FB_VMODE_MASK) {
- case FB_VMODE_INTERLACED:
- line_shift = 0;
- break;
- case FB_VMODE_NONINTERLACED:
- line_shift = 1;
- break;
- case FB_VMODE_DOUBLE:
- if (!IS_AGA) {
- DPRINTK("double mode only possible with aga\n");
- return -EINVAL;
- }
- line_shift = 2;
- break;
- default:
- DPRINTK("unknown video mode\n");
- return -EINVAL;
- break;
- }
- par->line_shift = line_shift;
-
- /*
- * Vertical and Horizontal Timings
- */
-
- xres_n = par->xres<<clk_shift;
- yres_n = par->yres<<line_shift;
- par->htotal = down8((var->left_margin+par->xres+var->right_margin+var->hsync_len)<<clk_shift);
- par->vtotal = down2(((var->upper_margin+par->yres+var->lower_margin+var->vsync_len)<<line_shift)+1);
-
- if (IS_AGA)
- par->bplcon3 = sprpixmode[clk_shift];
- else
- par->bplcon3 = 0;
- if (var->sync & FB_SYNC_BROADCAST) {
- par->diwstop_h = par->htotal-((var->right_margin-var->hsync_len)<<clk_shift);
- if (IS_AGA)
- par->diwstop_h += mod4(var->hsync_len);
- else
- par->diwstop_h = down4(par->diwstop_h);
-
- par->diwstrt_h = par->diwstop_h - xres_n;
- par->diwstop_v = par->vtotal-((var->lower_margin-var->vsync_len)<<line_shift);
- par->diwstrt_v = par->diwstop_v - yres_n;
- if (par->diwstop_h >= par->htotal+8) {
- DPRINTK("invalid diwstop_h\n");
- return -EINVAL;
- }
- if (par->diwstop_v > par->vtotal) {
- DPRINTK("invalid diwstop_v\n");
- return -EINVAL;
- }
-
- if (!IS_OCS) {
- /* Initialize sync with some reasonable values for pwrsave */
- par->hsstrt = 160;
- par->hsstop = 320;
- par->vsstrt = 30;
- par->vsstop = 34;
- } else {
- par->hsstrt = 0;
- par->hsstop = 0;
- par->vsstrt = 0;
- par->vsstop = 0;
- }
- if (par->vtotal > (PAL_VTOTAL+NTSC_VTOTAL)/2) {
- /* PAL video mode */
- if (par->htotal != PAL_HTOTAL) {
- DPRINTK("htotal invalid for pal\n");
- return -EINVAL;
- }
- if (par->diwstrt_h < PAL_DIWSTRT_H) {
- DPRINTK("diwstrt_h too low for pal\n");
- return -EINVAL;
- }
- if (par->diwstrt_v < PAL_DIWSTRT_V) {
- DPRINTK("diwstrt_v too low for pal\n");
- return -EINVAL;
- }
- htotal = PAL_HTOTAL>>clk_shift;
- vtotal = PAL_VTOTAL>>1;
- if (!IS_OCS) {
- par->beamcon0 = BMC0_PAL;
- par->bplcon3 |= BPC3_BRDRBLNK;
- } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
- AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
- par->beamcon0 = BMC0_PAL;
- par->hsstop = 1;
- } else if (amiga_vblank != 50) {
- DPRINTK("pal not supported by this chipset\n");
- return -EINVAL;
- }
- } else {
- /* NTSC video mode
- * In the AGA chipset seems to be hardware bug with BPC3_BRDRBLNK
- * and NTSC activated, so than better let diwstop_h <= 1812
- */
- if (par->htotal != NTSC_HTOTAL) {
- DPRINTK("htotal invalid for ntsc\n");
- return -EINVAL;
- }
- if (par->diwstrt_h < NTSC_DIWSTRT_H) {
- DPRINTK("diwstrt_h too low for ntsc\n");
- return -EINVAL;
- }
- if (par->diwstrt_v < NTSC_DIWSTRT_V) {
- DPRINTK("diwstrt_v too low for ntsc\n");
- return -EINVAL;
- }
- htotal = NTSC_HTOTAL>>clk_shift;
- vtotal = NTSC_VTOTAL>>1;
- if (!IS_OCS) {
- par->beamcon0 = 0;
- par->bplcon3 |= BPC3_BRDRBLNK;
- } else if (AMIGAHW_PRESENT(AGNUS_HR_PAL) ||
- AMIGAHW_PRESENT(AGNUS_HR_NTSC)) {
- par->beamcon0 = 0;
- par->hsstop = 1;
- } else if (amiga_vblank != 60) {
- DPRINTK("ntsc not supported by this chipset\n");
- return -EINVAL;
- }
- }
- if (IS_OCS) {
- if (par->diwstrt_h >= 1024 || par->diwstop_h < 1024 ||
- par->diwstrt_v >= 512 || par->diwstop_v < 256) {
- DPRINTK("invalid position for display on ocs\n");
- return -EINVAL;
- }
- }
- } else if (!IS_OCS) {
- /* Programmable video mode */
- par->hsstrt = var->right_margin<<clk_shift;
- par->hsstop = (var->right_margin+var->hsync_len)<<clk_shift;
- par->diwstop_h = par->htotal - mod8(par->hsstrt) + 8 - (1 << clk_shift);
- if (!IS_AGA)
- par->diwstop_h = down4(par->diwstop_h) - 16;
- par->diwstrt_h = par->diwstop_h - xres_n;
- par->hbstop = par->diwstrt_h + 4;
- par->hbstrt = par->diwstop_h + 4;
- if (par->hbstrt >= par->htotal + 8)
- par->hbstrt -= par->htotal;
- par->hcenter = par->hsstrt + (par->htotal >> 1);
- par->vsstrt = var->lower_margin<<line_shift;
- par->vsstop = (var->lower_margin+var->vsync_len)<<line_shift;
- par->diwstop_v = par->vtotal;
- if ((par->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
- par->diwstop_v -= 2;
- par->diwstrt_v = par->diwstop_v - yres_n;
- par->vbstop = par->diwstrt_v - 2;
- par->vbstrt = par->diwstop_v - 2;
- if (par->vtotal > 2048) {
- DPRINTK("vtotal too high\n");
- return -EINVAL;
- }
- if (par->htotal > 2048) {
- DPRINTK("htotal too high\n");
- return -EINVAL;
- }
- par->bplcon3 |= BPC3_EXTBLKEN;
- par->beamcon0 = BMC0_HARDDIS | BMC0_VARVBEN | BMC0_LOLDIS |
- BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARBEAMEN |
- BMC0_PAL | BMC0_VARCSYEN;
- if (var->sync & FB_SYNC_HOR_HIGH_ACT)
- par->beamcon0 |= BMC0_HSYTRUE;
- if (var->sync & FB_SYNC_VERT_HIGH_ACT)
- par->beamcon0 |= BMC0_VSYTRUE;
- if (var->sync & FB_SYNC_COMP_HIGH_ACT)
- par->beamcon0 |= BMC0_CSYTRUE;
- htotal = par->htotal>>clk_shift;
- vtotal = par->vtotal>>1;
- } else {
- DPRINTK("only broadcast modes possible for ocs\n");
- return -EINVAL;
- }
-
- /*
- * Checking the DMA timing
- */
-
- fconst = 16<<maxfmode<<clk_shift;
-
- /*
- * smallest window start value without turn off other dma cycles
- * than sprite1-7, unless you change min_fstrt
- */
-
-
- fsize = ((maxfmode+clk_shift <= 1) ? fconst : 64);
- fstrt = downx(fconst, par->diwstrt_h-4) - fsize;
- if (fstrt < min_fstrt) {
- DPRINTK("fetch start too low\n");
- return -EINVAL;
- }
-
- /*
- * smallest window start value where smooth scrolling is possible
- */
-
- fstrt = downx(fconst, par->diwstrt_h-fconst+(1<<clk_shift)-4) - fsize;
- if (fstrt < min_fstrt)
- par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
-
- maxfetchstop = down16(par->htotal - 80);
-
- fstrt = downx(fconst, par->diwstrt_h-4) - 64 - fconst;
- fsize = upx(fconst, xres_n + modx(fconst, downx(1<<clk_shift, par->diwstrt_h-4)));
- if (fstrt + fsize > maxfetchstop)
- par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
-
- fsize = upx(fconst, xres_n);
- if (fstrt + fsize > maxfetchstop) {
- DPRINTK("fetch stop too high\n");
- return -EINVAL;
- }
-
- if (maxfmode + clk_shift <= 1) {
- fsize = up64(xres_n + fconst - 1);
- if (min_fstrt + fsize - 64 > maxfetchstop)
- par->vmode &= ~FB_VMODE_SMOOTH_XPAN;
-
- fsize = up64(xres_n);
- if (min_fstrt + fsize - 64 > maxfetchstop) {
- DPRINTK("fetch size too high\n");
- return -EINVAL;
- }
-
- fsize -= 64;
- } else
- fsize -= fconst;
-
- /*
- * Check if there is enough time to update the bitplane pointers for ywrap
- */
-
- if (par->htotal-fsize-64 < par->bpp*64)
- par->vmode &= ~FB_VMODE_YWRAP;
-
- /*
- * Bitplane calculations and check the Memory Requirements
- */
-
- if (amifb_ilbm) {
- par->next_plane = div8(upx(16<<maxfmode, par->vxres));
- par->next_line = par->bpp*par->next_plane;
- if (par->next_line * par->vyres > fb_info.fix.smem_len) {
- DPRINTK("too few video mem\n");
- return -EINVAL;
- }
- } else {
- par->next_line = div8(upx(16<<maxfmode, par->vxres));
- par->next_plane = par->vyres*par->next_line;
- if (par->next_plane * par->bpp > fb_info.fix.smem_len) {
- DPRINTK("too few video mem\n");
- return -EINVAL;
- }
- }
-
- /*
- * Hardware Register Values
- */
-
- par->bplcon0 = BPC0_COLOR | bplpixmode[clk_shift];
- if (!IS_OCS)
- par->bplcon0 |= BPC0_ECSENA;
- if (par->bpp == 8)
- par->bplcon0 |= BPC0_BPU3;
- else
- par->bplcon0 |= par->bpp<<12;
- if (var->nonstd == FB_NONSTD_HAM)
- par->bplcon0 |= BPC0_HAM;
- if (var->sync & FB_SYNC_EXT)
- par->bplcon0 |= BPC0_ERSY;
-
- if (IS_AGA)
- par->fmode = bplfetchmode[maxfmode];
-
- switch (par->vmode & FB_VMODE_MASK) {
- case FB_VMODE_INTERLACED:
- par->bplcon0 |= BPC0_LACE;
- break;
- case FB_VMODE_DOUBLE:
- if (IS_AGA)
- par->fmode |= FMODE_SSCAN2 | FMODE_BSCAN2;
- break;
- }
-
- if (!((par->vmode ^ var->vmode) & FB_VMODE_YWRAP)) {
- par->xoffset = var->xoffset;
- par->yoffset = var->yoffset;
- if (par->vmode & FB_VMODE_YWRAP) {
- if (par->xoffset || par->yoffset < 0 || par->yoffset >= par->vyres)
- par->xoffset = par->yoffset = 0;
- } else {
- if (par->xoffset < 0 || par->xoffset > upx(16<<maxfmode, par->vxres-par->xres) ||
- par->yoffset < 0 || par->yoffset > par->vyres-par->yres)
- par->xoffset = par->yoffset = 0;
- }
- } else
- par->xoffset = par->yoffset = 0;
-
- par->crsr.crsr_x = par->crsr.crsr_y = 0;
- par->crsr.spot_x = par->crsr.spot_y = 0;
- par->crsr.height = par->crsr.width = 0;
-
- return 0;
-}
-
- /*
- * Fill the `var' structure based on the values in `par' and maybe
- * other values read out of the hardware.
- */
-
-static int ami_encode_var(struct fb_var_screeninfo *var,
- struct amifb_par *par)
-{
- u_short clk_shift, line_shift;
-
- memset(var, 0, sizeof(struct fb_var_screeninfo));
-
- clk_shift = par->clk_shift;
- line_shift = par->line_shift;
-
- var->xres = par->xres;
- var->yres = par->yres;
- var->xres_virtual = par->vxres;
- var->yres_virtual = par->vyres;
- var->xoffset = par->xoffset;
- var->yoffset = par->yoffset;
-
- var->bits_per_pixel = par->bpp;
- var->grayscale = 0;
-
- var->red.offset = 0;
- var->red.msb_right = 0;
- var->red.length = par->bpp;
- if (par->bplcon0 & BPC0_HAM)
- var->red.length -= 2;
- var->blue = var->green = var->red;
- var->transp.offset = 0;
- var->transp.length = 0;
- var->transp.msb_right = 0;
-
- if (par->bplcon0 & BPC0_HAM)
- var->nonstd = FB_NONSTD_HAM;
- else
- var->nonstd = 0;
- var->activate = 0;
-
- var->height = -1;
- var->width = -1;
-
- var->pixclock = pixclock[clk_shift];
-
- if (IS_AGA && par->fmode & FMODE_BSCAN2)
- var->vmode = FB_VMODE_DOUBLE;
- else if (par->bplcon0 & BPC0_LACE)
- var->vmode = FB_VMODE_INTERLACED;
- else
- var->vmode = FB_VMODE_NONINTERLACED;
-
- if (!IS_OCS && par->beamcon0 & BMC0_VARBEAMEN) {
- var->hsync_len = (par->hsstop-par->hsstrt)>>clk_shift;
- var->right_margin = par->hsstrt>>clk_shift;
- var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
- var->vsync_len = (par->vsstop-par->vsstrt)>>line_shift;
- var->lower_margin = par->vsstrt>>line_shift;
- var->upper_margin = (par->vtotal>>line_shift) - var->yres - var->lower_margin - var->vsync_len;
- var->sync = 0;
- if (par->beamcon0 & BMC0_HSYTRUE)
- var->sync |= FB_SYNC_HOR_HIGH_ACT;
- if (par->beamcon0 & BMC0_VSYTRUE)
- var->sync |= FB_SYNC_VERT_HIGH_ACT;
- if (par->beamcon0 & BMC0_CSYTRUE)
- var->sync |= FB_SYNC_COMP_HIGH_ACT;
- } else {
- var->sync = FB_SYNC_BROADCAST;
- var->hsync_len = (152>>clk_shift) + mod4(par->diwstop_h);
- var->right_margin = ((par->htotal - down4(par->diwstop_h))>>clk_shift) + var->hsync_len;
- var->left_margin = (par->htotal>>clk_shift) - var->xres - var->right_margin - var->hsync_len;
- var->vsync_len = 4>>line_shift;
- var->lower_margin = ((par->vtotal - par->diwstop_v)>>line_shift) + var->vsync_len;
- var->upper_margin = (((par->vtotal - 2)>>line_shift) + 1) - var->yres -
- var->lower_margin - var->vsync_len;
- }
-
- if (par->bplcon0 & BPC0_ERSY)
- var->sync |= FB_SYNC_EXT;
- if (par->vmode & FB_VMODE_YWRAP)
- var->vmode |= FB_VMODE_YWRAP;
-
- return 0;
-}
-
-
/*
- * Pan or Wrap the Display
- *
- * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
- * in `var'.
- */
-
-static void ami_pan_var(struct fb_var_screeninfo *var)
-{
- struct amifb_par *par = &currentpar;
-
- par->xoffset = var->xoffset;
- par->yoffset = var->yoffset;
- if (var->vmode & FB_VMODE_YWRAP)
- par->vmode |= FB_VMODE_YWRAP;
- else
- par->vmode &= ~FB_VMODE_YWRAP;
-
- do_vmode_pan = 0;
- ami_update_par();
- do_vmode_pan = 1;
-}
-
- /*
- * Update hardware
- */
-
-static int ami_update_par(void)
-{
- struct amifb_par *par = &currentpar;
- short clk_shift, vshift, fstrt, fsize, fstop, fconst, shift, move, mod;
-
- clk_shift = par->clk_shift;
-
- if (!(par->vmode & FB_VMODE_SMOOTH_XPAN))
- par->xoffset = upx(16<<maxfmode, par->xoffset);
-
- fconst = 16<<maxfmode<<clk_shift;
- vshift = modx(16<<maxfmode, par->xoffset);
- fstrt = par->diwstrt_h - (vshift<<clk_shift) - 4;
- fsize = (par->xres+vshift)<<clk_shift;
- shift = modx(fconst, fstrt);
- move = downx(2<<maxfmode, div8(par->xoffset));
- if (maxfmode + clk_shift > 1) {
- fstrt = downx(fconst, fstrt) - 64;
- fsize = upx(fconst, fsize);
- fstop = fstrt + fsize - fconst;
- } else {
- mod = fstrt = downx(fconst, fstrt) - fconst;
- fstop = fstrt + upx(fconst, fsize) - 64;
- fsize = up64(fsize);
- fstrt = fstop - fsize + 64;
- if (fstrt < min_fstrt) {
- fstop += min_fstrt - fstrt;
- fstrt = min_fstrt;
- }
- move = move - div8((mod-fstrt)>>clk_shift);
- }
- mod = par->next_line - div8(fsize>>clk_shift);
- par->ddfstrt = fstrt;
- par->ddfstop = fstop;
- par->bplcon1 = hscroll2hw(shift);
- par->bpl2mod = mod;
- if (par->bplcon0 & BPC0_LACE)
- par->bpl2mod += par->next_line;
- if (IS_AGA && (par->fmode & FMODE_BSCAN2))
- par->bpl1mod = -div8(fsize>>clk_shift);
- else
- par->bpl1mod = par->bpl2mod;
-
- if (par->yoffset) {
- par->bplpt0 = fb_info.fix.smem_start + par->next_line*par->yoffset + move;
- if (par->vmode & FB_VMODE_YWRAP) {
- if (par->yoffset > par->vyres-par->yres) {
- par->bplpt0wrap = fb_info.fix.smem_start + move;
- if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v+par->vyres-par->yoffset))
- par->bplpt0wrap += par->next_line;
- }
- }
- } else
- par->bplpt0 = fb_info.fix.smem_start + move;
-
- if (par->bplcon0 & BPC0_LACE && mod2(par->diwstrt_v))
- par->bplpt0 += par->next_line;
-
- return 0;
-}
-
-
- /*
- * Set a single color register. The values supplied are already
- * rounded down to the hardware's capabilities (according to the
- * entries in the var structure). Return != 0 for invalid regno.
- */
-
-static int amifb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
-{
- if (IS_AGA) {
- if (regno > 255)
- return 1;
- } else if (currentpar.bplcon0 & BPC0_SHRES) {
- if (regno > 3)
- return 1;
- } else {
- if (regno > 31)
- return 1;
- }
- red >>= 8;
- green >>= 8;
- blue >>= 8;
- if (!regno) {
- red0 = red;
- green0 = green;
- blue0 = blue;
- }
-
- /*
- * Update the corresponding Hardware Color Register, unless it's Color
- * Register 0 and the screen is blanked.
- *
- * VBlank is switched off to protect bplcon3 or ecs_palette[] from
- * being changed by ami_do_blank() during the VBlank.
- */
-
- if (regno || !is_blanked) {
-#if defined(CONFIG_FB_AMIGA_AGA)
- if (IS_AGA) {
- u_short bplcon3 = currentpar.bplcon3;
- VBlankOff();
- custom.bplcon3 = bplcon3 | (regno<<8 & 0xe000);
- custom.color[regno&31] = rgb2hw8_high(red, green, blue);
- custom.bplcon3 = bplcon3 | (regno<<8 & 0xe000) | BPC3_LOCT;
- custom.color[regno&31] = rgb2hw8_low(red, green, blue);
- custom.bplcon3 = bplcon3;
- VBlankOn();
- } else
-#endif
-#if defined(CONFIG_FB_AMIGA_ECS)
- if (currentpar.bplcon0 & BPC0_SHRES) {
- u_short color, mask;
- int i;
-
- mask = 0x3333;
- color = rgb2hw2(red, green, blue);
- VBlankOff();
- for (i = regno+12; i >= (int)regno; i -= 4)
- custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- mask <<=2; color >>= 2;
- regno = down16(regno)+mul4(mod4(regno));
- for (i = regno+3; i >= (int)regno; i--)
- custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- VBlankOn();
- } else
-#endif
- custom.color[regno] = rgb2hw4(red, green, blue);
- }
- return 0;
-}
-
-static void ami_update_display(void)
-{
- struct amifb_par *par = &currentpar;
-
- custom.bplcon1 = par->bplcon1;
- custom.bpl1mod = par->bpl1mod;
- custom.bpl2mod = par->bpl2mod;
- custom.ddfstrt = ddfstrt2hw(par->ddfstrt);
- custom.ddfstop = ddfstop2hw(par->ddfstop);
-}
-
- /*
- * Change the video mode (called by VBlank interrupt)
- */
-
-static void ami_init_display(void)
-{
- struct amifb_par *par = &currentpar;
- int i;
-
- custom.bplcon0 = par->bplcon0 & ~BPC0_LACE;
- custom.bplcon2 = (IS_OCS ? 0 : BPC2_KILLEHB) | BPC2_PF2P2 | BPC2_PF1P2;
- if (!IS_OCS) {
- custom.bplcon3 = par->bplcon3;
- if (IS_AGA)
- custom.bplcon4 = BPC4_ESPRM4 | BPC4_OSPRM4;
- if (par->beamcon0 & BMC0_VARBEAMEN) {
- custom.htotal = htotal2hw(par->htotal);
- custom.hbstrt = hbstrt2hw(par->hbstrt);
- custom.hbstop = hbstop2hw(par->hbstop);
- custom.hsstrt = hsstrt2hw(par->hsstrt);
- custom.hsstop = hsstop2hw(par->hsstop);
- custom.hcenter = hcenter2hw(par->hcenter);
- custom.vtotal = vtotal2hw(par->vtotal);
- custom.vbstrt = vbstrt2hw(par->vbstrt);
- custom.vbstop = vbstop2hw(par->vbstop);
- custom.vsstrt = vsstrt2hw(par->vsstrt);
- custom.vsstop = vsstop2hw(par->vsstop);
- }
- }
- if (!IS_OCS || par->hsstop)
- custom.beamcon0 = par->beamcon0;
- if (IS_AGA)
- custom.fmode = par->fmode;
-
- /*
- * The minimum period for audio depends on htotal
- */
-
- amiga_audio_min_period = div16(par->htotal);
-
- is_lace = par->bplcon0 & BPC0_LACE ? 1 : 0;
-#if 1
- if (is_lace) {
- i = custom.vposr >> 15;
- } else {
- custom.vposw = custom.vposr | 0x8000;
- i = 1;
- }
-#else
- i = 1;
- custom.vposw = custom.vposr | 0x8000;
-#endif
- custom.cop2lc = (u_short *)ZTWO_PADDR(copdisplay.list[currentcop][i]);
-}
-
- /*
- * (Un)Blank the screen (called by VBlank interrupt)
+ * Enable Display DMA
*/
+ custom.dmacon = DMAF_SETCLR | DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
+ DMAF_BLITTER | DMAF_SPRITE;
-static void ami_do_blank(void)
-{
- struct amifb_par *par = &currentpar;
-#if defined(CONFIG_FB_AMIGA_AGA)
- u_short bplcon3 = par->bplcon3;
-#endif
- u_char red, green, blue;
-
- if (do_blank > 0) {
- custom.dmacon = DMAF_RASTER | DMAF_SPRITE;
- red = green = blue = 0;
- if (!IS_OCS && do_blank > 1) {
- switch (do_blank) {
- case FB_BLANK_VSYNC_SUSPEND:
- custom.hsstrt = hsstrt2hw(par->hsstrt);
- custom.hsstop = hsstop2hw(par->hsstop);
- custom.vsstrt = vsstrt2hw(par->vtotal+4);
- custom.vsstop = vsstop2hw(par->vtotal+4);
- break;
- case FB_BLANK_HSYNC_SUSPEND:
- custom.hsstrt = hsstrt2hw(par->htotal+16);
- custom.hsstop = hsstop2hw(par->htotal+16);
- custom.vsstrt = vsstrt2hw(par->vsstrt);
- custom.vsstop = vsstrt2hw(par->vsstop);
- break;
- case FB_BLANK_POWERDOWN:
- custom.hsstrt = hsstrt2hw(par->htotal+16);
- custom.hsstop = hsstop2hw(par->htotal+16);
- custom.vsstrt = vsstrt2hw(par->vtotal+4);
- custom.vsstop = vsstop2hw(par->vtotal+4);
- break;
- }
- if (!(par->beamcon0 & BMC0_VARBEAMEN)) {
- custom.htotal = htotal2hw(par->htotal);
- custom.vtotal = vtotal2hw(par->vtotal);
- custom.beamcon0 = BMC0_HARDDIS | BMC0_VARBEAMEN |
- BMC0_VARVSYEN | BMC0_VARHSYEN | BMC0_VARCSYEN;
- }
- }
- } else {
- custom.dmacon = DMAF_SETCLR | DMAF_RASTER | DMAF_SPRITE;
- red = red0;
- green = green0;
- blue = blue0;
- if (!IS_OCS) {
- custom.hsstrt = hsstrt2hw(par->hsstrt);
- custom.hsstop = hsstop2hw(par->hsstop);
- custom.vsstrt = vsstrt2hw(par->vsstrt);
- custom.vsstop = vsstop2hw(par->vsstop);
- custom.beamcon0 = par->beamcon0;
- }
- }
-#if defined(CONFIG_FB_AMIGA_AGA)
- if (IS_AGA) {
- custom.bplcon3 = bplcon3;
- custom.color[0] = rgb2hw8_high(red, green, blue);
- custom.bplcon3 = bplcon3 | BPC3_LOCT;
- custom.color[0] = rgb2hw8_low(red, green, blue);
- custom.bplcon3 = bplcon3;
- } else
-#endif
-#if defined(CONFIG_FB_AMIGA_ECS)
- if (par->bplcon0 & BPC0_SHRES) {
- u_short color, mask;
- int i;
-
- mask = 0x3333;
- color = rgb2hw2(red, green, blue);
- for (i = 12; i >= 0; i -= 4)
- custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- mask <<=2; color >>= 2;
- for (i = 3; i >= 0; i--)
- custom.color[i] = ecs_palette[i] = (ecs_palette[i] & mask) | color;
- } else
-#endif
- custom.color[0] = rgb2hw4(red, green, blue);
- is_blanked = do_blank > 0 ? do_blank : 0;
-}
-
-static int ami_get_fix_cursorinfo(struct fb_fix_cursorinfo *fix)
-{
- struct amifb_par *par = &currentpar;
-
- fix->crsr_width = fix->crsr_xsize = par->crsr.width;
- fix->crsr_height = fix->crsr_ysize = par->crsr.height;
- fix->crsr_color1 = 17;
- fix->crsr_color2 = 18;
- return 0;
-}
-
-static int ami_get_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
-{
- struct amifb_par *par = &currentpar;
- register u_short *lspr, *sspr;
-#ifdef __mc68000__
- register u_long datawords asm ("d2");
-#else
- register u_long datawords;
-#endif
- register short delta;
- register u_char color;
- short height, width, bits, words;
- int size, alloc;
-
- size = par->crsr.height*par->crsr.width;
- alloc = var->height*var->width;
- var->height = par->crsr.height;
- var->width = par->crsr.width;
- var->xspot = par->crsr.spot_x;
- var->yspot = par->crsr.spot_y;
- if (size > var->height*var->width)
- return -ENAMETOOLONG;
- if (!access_ok(VERIFY_WRITE, data, size))
- return -EFAULT;
- delta = 1<<par->crsr.fmode;
- lspr = lofsprite + (delta<<1);
- if (par->bplcon0 & BPC0_LACE)
- sspr = shfsprite + (delta<<1);
- else
- sspr = NULL;
- for (height = (short)var->height-1; height >= 0; height--) {
- bits = 0; words = delta; datawords = 0;
- for (width = (short)var->width-1; width >= 0; width--) {
- if (bits == 0) {
- bits = 16; --words;
-#ifdef __mc68000__
- asm volatile ("movew %1@(%3:w:2),%0 ; swap %0 ; movew %1@+,%0"
- : "=d" (datawords), "=a" (lspr) : "1" (lspr), "d" (delta));
-#else
- datawords = (*(lspr+delta) << 16) | (*lspr++);
-#endif
- }
- --bits;
-#ifdef __mc68000__
- asm volatile (
- "clrb %0 ; swap %1 ; lslw #1,%1 ; roxlb #1,%0 ; "
- "swap %1 ; lslw #1,%1 ; roxlb #1,%0"
- : "=d" (color), "=d" (datawords) : "1" (datawords));
-#else
- color = (((datawords >> 30) & 2)
- | ((datawords >> 15) & 1));
- datawords <<= 1;
-#endif
- put_user(color, data++);
- }
- if (bits > 0) {
- --words; ++lspr;
- }
- while (--words >= 0)
- ++lspr;
-#ifdef __mc68000__
- asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:"
- : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta));
-#else
- lspr += delta;
- if (sspr) {
- u_short *tmp = lspr;
- lspr = sspr;
- sspr = tmp;
- }
-#endif
- }
- return 0;
-}
-
-static int ami_set_var_cursorinfo(struct fb_var_cursorinfo *var, u_char __user *data)
-{
- struct amifb_par *par = &currentpar;
- register u_short *lspr, *sspr;
-#ifdef __mc68000__
- register u_long datawords asm ("d2");
-#else
- register u_long datawords;
-#endif
- register short delta;
- u_short fmode;
- short height, width, bits, words;
+ err = request_irq(IRQ_AMIGA_COPPER, amifb_interrupt, 0,
+ "fb vertb handler", info->par);
+ if (err)
+ goto disable_dma;
- if (!var->width)
- return -EINVAL;
- else if (var->width <= 16)
- fmode = TAG_FMODE_1;
- else if (var->width <= 32)
- fmode = TAG_FMODE_2;
- else if (var->width <= 64)
- fmode = TAG_FMODE_4;
- else
- return -EINVAL;
- if (fmode > maxfmode)
- return -EINVAL;
- if (!var->height)
- return -EINVAL;
- if (!access_ok(VERIFY_READ, data, var->width*var->height))
- return -EFAULT;
- delta = 1<<fmode;
- lofsprite = shfsprite = (u_short *)spritememory;
- lspr = lofsprite + (delta<<1);
- if (par->bplcon0 & BPC0_LACE) {
- if (((var->height+4)<<fmode<<2) > SPRITEMEMSIZE)
- return -EINVAL;
- memset(lspr, 0, (var->height+4)<<fmode<<2);
- shfsprite += ((var->height+5)&-2)<<fmode;
- sspr = shfsprite + (delta<<1);
- } else {
- if (((var->height+2)<<fmode<<2) > SPRITEMEMSIZE)
- return -EINVAL;
- memset(lspr, 0, (var->height+2)<<fmode<<2);
- sspr = NULL;
- }
- for (height = (short)var->height-1; height >= 0; height--) {
- bits = 16; words = delta; datawords = 0;
- for (width = (short)var->width-1; width >= 0; width--) {
- unsigned long tdata = 0;
- get_user(tdata, data);
- data++;
-#ifdef __mc68000__
- asm volatile (
- "lsrb #1,%2 ; roxlw #1,%0 ; swap %0 ; "
- "lsrb #1,%2 ; roxlw #1,%0 ; swap %0"
- : "=d" (datawords)
- : "0" (datawords), "d" (tdata));
-#else
- datawords = ((datawords << 1) & 0xfffefffe);
- datawords |= tdata & 1;
- datawords |= (tdata & 2) << (16-1);
-#endif
- if (--bits == 0) {
- bits = 16; --words;
-#ifdef __mc68000__
- asm volatile ("swap %2 ; movew %2,%0@(%3:w:2) ; swap %2 ; movew %2,%0@+"
- : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta));
-#else
- *(lspr+delta) = (u_short) (datawords >> 16);
- *lspr++ = (u_short) (datawords & 0xffff);
-#endif
- }
- }
- if (bits < 16) {
- --words;
-#ifdef __mc68000__
- asm volatile (
- "swap %2 ; lslw %4,%2 ; movew %2,%0@(%3:w:2) ; "
- "swap %2 ; lslw %4,%2 ; movew %2,%0@+"
- : "=a" (lspr) : "0" (lspr), "d" (datawords), "d" (delta), "d" (bits));
-#else
- *(lspr+delta) = (u_short) (datawords >> (16+bits));
- *lspr++ = (u_short) ((datawords & 0x0000ffff) >> bits);
-#endif
- }
- while (--words >= 0) {
-#ifdef __mc68000__
- asm volatile ("moveql #0,%%d0 ; movew %%d0,%0@(%2:w:2) ; movew %%d0,%0@+"
- : "=a" (lspr) : "0" (lspr), "d" (delta) : "d0");
-#else
- *(lspr+delta) = 0;
- *lspr++ = 0;
-#endif
- }
-#ifdef __mc68000__
- asm volatile ("lea %0@(%4:w:2),%0 ; tstl %1 ; jeq 1f ; exg %0,%1\n1:"
- : "=a" (lspr), "=a" (sspr) : "0" (lspr), "1" (sspr), "d" (delta));
-#else
- lspr += delta;
- if (sspr) {
- u_short *tmp = lspr;
- lspr = sspr;
- sspr = tmp;
- }
-#endif
- }
- par->crsr.height = var->height;
- par->crsr.width = var->width;
- par->crsr.spot_x = var->xspot;
- par->crsr.spot_y = var->yspot;
- par->crsr.fmode = fmode;
- if (IS_AGA) {
- par->fmode &= ~(FMODE_SPAGEM | FMODE_SPR32);
- par->fmode |= sprfetchmode[fmode];
- custom.fmode = par->fmode;
- }
- return 0;
-}
+ err = fb_alloc_cmap(&info->cmap, 1 << info->var.bits_per_pixel, 0);
+ if (err)
+ goto free_irq;
-static int ami_get_cursorstate(struct fb_cursorstate *state)
-{
- struct amifb_par *par = &currentpar;
+ dev_set_drvdata(&pdev->dev, info);
- state->xoffset = par->crsr.crsr_x;
- state->yoffset = par->crsr.crsr_y;
- state->mode = cursormode;
- return 0;
-}
+ err = register_framebuffer(info);
+ if (err)
+ goto unset_drvdata;
-static int ami_set_cursorstate(struct fb_cursorstate *state)
-{
- struct amifb_par *par = &currentpar;
+ printk("fb%d: %s frame buffer device, using %dK of video memory\n",
+ info->node, info->fix.id, info->fix.smem_len>>10);
- par->crsr.crsr_x = state->xoffset;
- par->crsr.crsr_y = state->yoffset;
- if ((cursormode = state->mode) == FB_CURSOR_OFF)
- cursorstate = -1;
- do_cursor = 1;
return 0;
-}
-
-static void ami_set_sprite(void)
-{
- struct amifb_par *par = &currentpar;
- copins *copl, *cops;
- u_short hs, vs, ve;
- u_long pl, ps, pt;
- short mx, my;
-
- cops = copdisplay.list[currentcop][0];
- copl = copdisplay.list[currentcop][1];
- ps = pl = ZTWO_PADDR(dummysprite);
- mx = par->crsr.crsr_x-par->crsr.spot_x;
- my = par->crsr.crsr_y-par->crsr.spot_y;
- if (!(par->vmode & FB_VMODE_YWRAP)) {
- mx -= par->xoffset;
- my -= par->yoffset;
- }
- if (!is_blanked && cursorstate > 0 && par->crsr.height > 0 &&
- mx > -(short)par->crsr.width && mx < par->xres &&
- my > -(short)par->crsr.height && my < par->yres) {
- pl = ZTWO_PADDR(lofsprite);
- hs = par->diwstrt_h + (mx<<par->clk_shift) - 4;
- vs = par->diwstrt_v + (my<<par->line_shift);
- ve = vs + (par->crsr.height<<par->line_shift);
- if (par->bplcon0 & BPC0_LACE) {
- ps = ZTWO_PADDR(shfsprite);
- lofsprite[0] = spr2hw_pos(vs, hs);
- shfsprite[0] = spr2hw_pos(vs+1, hs);
- if (mod2(vs)) {
- lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
- shfsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs+1, hs, ve+1);
- pt = pl; pl = ps; ps = pt;
- } else {
- lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve+1);
- shfsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs+1, hs, ve);
- }
- } else {
- lofsprite[0] = spr2hw_pos(vs, hs) | (IS_AGA && (par->fmode & FMODE_BSCAN2) ? 0x80 : 0);
- lofsprite[1<<par->crsr.fmode] = spr2hw_ctl(vs, hs, ve);
- }
- }
- copl[cop_spr0ptrh].w[1] = highw(pl);
- copl[cop_spr0ptrl].w[1] = loww(pl);
- if (par->bplcon0 & BPC0_LACE) {
- cops[cop_spr0ptrh].w[1] = highw(ps);
- cops[cop_spr0ptrl].w[1] = loww(ps);
- }
-}
-
-
- /*
- * Initialise the Copper Initialisation List
- */
-
-static void __init ami_init_copper(void)
-{
- copins *cop = copdisplay.init;
- u_long p;
- int i;
-
- if (!IS_OCS) {
- (cop++)->l = CMOVE(BPC0_COLOR | BPC0_SHRES | BPC0_ECSENA, bplcon0);
- (cop++)->l = CMOVE(0x0181, diwstrt);
- (cop++)->l = CMOVE(0x0281, diwstop);
- (cop++)->l = CMOVE(0x0000, diwhigh);
- } else
- (cop++)->l = CMOVE(BPC0_COLOR, bplcon0);
- p = ZTWO_PADDR(dummysprite);
- for (i = 0; i < 8; i++) {
- (cop++)->l = CMOVE(0, spr[i].pos);
- (cop++)->l = CMOVE(highw(p), sprpt[i]);
- (cop++)->l = CMOVE2(loww(p), sprpt[i]);
- }
-
- (cop++)->l = CMOVE(IF_SETCLR | IF_COPER, intreq);
- copdisplay.wait = cop;
- (cop++)->l = CEND;
- (cop++)->l = CMOVE(0, copjmp2);
- cop->l = CEND;
-
- custom.cop1lc = (u_short *)ZTWO_PADDR(copdisplay.init);
- custom.copjmp1 = 0;
-}
-static void ami_reinit_copper(void)
-{
- struct amifb_par *par = &currentpar;
-
- copdisplay.init[cip_bplcon0].w[1] = ~(BPC0_BPU3 | BPC0_BPU2 | BPC0_BPU1 | BPC0_BPU0) & par->bplcon0;
- copdisplay.wait->l = CWAIT(32, par->diwstrt_v-4);
+unset_drvdata:
+ dev_set_drvdata(&pdev->dev, NULL);
+ fb_dealloc_cmap(&info->cmap);
+free_irq:
+ free_irq(IRQ_AMIGA_COPPER, info->par);
+disable_dma:
+ custom.dmacon = DMAF_ALL | DMAF_MASTER;
+ if (videomemory)
+ iounmap((void *)videomemory);
+ chipfree();
+release:
+ framebuffer_release(info);
+ return err;
}
- /*
- * Build the Copper List
- */
-
-static void ami_build_copper(void)
-{
- struct amifb_par *par = &currentpar;
- copins *copl, *cops;
- u_long p;
-
- currentcop = 1 - currentcop;
-
- copl = copdisplay.list[currentcop][1];
-
- (copl++)->l = CWAIT(0, 10);
- (copl++)->l = CMOVE(par->bplcon0, bplcon0);
- (copl++)->l = CMOVE(0, sprpt[0]);
- (copl++)->l = CMOVE2(0, sprpt[0]);
-
- if (par->bplcon0 & BPC0_LACE) {
- cops = copdisplay.list[currentcop][0];
-
- (cops++)->l = CWAIT(0, 10);
- (cops++)->l = CMOVE(par->bplcon0, bplcon0);
- (cops++)->l = CMOVE(0, sprpt[0]);
- (cops++)->l = CMOVE2(0, sprpt[0]);
-
- (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v+1), diwstrt);
- (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v+1), diwstop);
- (cops++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
- (cops++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
- if (!IS_OCS) {
- (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v+1,
- par->diwstop_h, par->diwstop_v+1), diwhigh);
- (cops++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
- par->diwstop_h, par->diwstop_v), diwhigh);
-#if 0
- if (par->beamcon0 & BMC0_VARBEAMEN) {
- (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
- (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt+1), vbstrt);
- (copl++)->l = CMOVE(vbstop2hw(par->vbstop+1), vbstop);
- (cops++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
- (cops++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
- (cops++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
- }
-#endif
- }
- p = ZTWO_PADDR(copdisplay.list[currentcop][0]);
- (copl++)->l = CMOVE(highw(p), cop2lc);
- (copl++)->l = CMOVE2(loww(p), cop2lc);
- p = ZTWO_PADDR(copdisplay.list[currentcop][1]);
- (cops++)->l = CMOVE(highw(p), cop2lc);
- (cops++)->l = CMOVE2(loww(p), cop2lc);
- copdisplay.rebuild[0] = cops;
- } else {
- (copl++)->l = CMOVE(diwstrt2hw(par->diwstrt_h, par->diwstrt_v), diwstrt);
- (copl++)->l = CMOVE(diwstop2hw(par->diwstop_h, par->diwstop_v), diwstop);
- if (!IS_OCS) {
- (copl++)->l = CMOVE(diwhigh2hw(par->diwstrt_h, par->diwstrt_v,
- par->diwstop_h, par->diwstop_v), diwhigh);
-#if 0
- if (par->beamcon0 & BMC0_VARBEAMEN) {
- (copl++)->l = CMOVE(vtotal2hw(par->vtotal), vtotal);
- (copl++)->l = CMOVE(vbstrt2hw(par->vbstrt), vbstrt);
- (copl++)->l = CMOVE(vbstop2hw(par->vbstop), vbstop);
- }
-#endif
- }
- }
- copdisplay.rebuild[1] = copl;
-
- ami_update_par();
- ami_rebuild_copper();
-}
-
- /*
- * Rebuild the Copper List
- *
- * We only change the things that are not static
- */
-
-static void ami_rebuild_copper(void)
-{
- struct amifb_par *par = &currentpar;
- copins *copl, *cops;
- u_short line, h_end1, h_end2;
- short i;
- u_long p;
-
- if (IS_AGA && maxfmode + par->clk_shift == 0)
- h_end1 = par->diwstrt_h-64;
- else
- h_end1 = par->htotal-32;
- h_end2 = par->ddfstop+64;
-
- ami_set_sprite();
-
- copl = copdisplay.rebuild[1];
- p = par->bplpt0;
- if (par->vmode & FB_VMODE_YWRAP) {
- if ((par->vyres-par->yoffset) != 1 || !mod2(par->diwstrt_v)) {
- if (par->yoffset > par->vyres-par->yres) {
- for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
- (copl++)->l = CMOVE(highw(p), bplpt[i]);
- (copl++)->l = CMOVE2(loww(p), bplpt[i]);
- }
- line = par->diwstrt_v + ((par->vyres-par->yoffset)<<par->line_shift) - 1;
- while (line >= 512) {
- (copl++)->l = CWAIT(h_end1, 510);
- line -= 512;
- }
- if (line >= 510 && IS_AGA && maxfmode + par->clk_shift == 0)
- (copl++)->l = CWAIT(h_end1, line);
- else
- (copl++)->l = CWAIT(h_end2, line);
- p = par->bplpt0wrap;
- }
- } else p = par->bplpt0wrap;
- }
- for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
- (copl++)->l = CMOVE(highw(p), bplpt[i]);
- (copl++)->l = CMOVE2(loww(p), bplpt[i]);
- }
- copl->l = CEND;
-
- if (par->bplcon0 & BPC0_LACE) {
- cops = copdisplay.rebuild[0];
- p = par->bplpt0;
- if (mod2(par->diwstrt_v))
- p -= par->next_line;
- else
- p += par->next_line;
- if (par->vmode & FB_VMODE_YWRAP) {
- if ((par->vyres-par->yoffset) != 1 || mod2(par->diwstrt_v)) {
- if (par->yoffset > par->vyres-par->yres+1) {
- for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
- (cops++)->l = CMOVE(highw(p), bplpt[i]);
- (cops++)->l = CMOVE2(loww(p), bplpt[i]);
- }
- line = par->diwstrt_v + ((par->vyres-par->yoffset)<<par->line_shift) - 2;
- while (line >= 512) {
- (cops++)->l = CWAIT(h_end1, 510);
- line -= 512;
- }
- if (line > 510 && IS_AGA && maxfmode + par->clk_shift == 0)
- (cops++)->l = CWAIT(h_end1, line);
- else
- (cops++)->l = CWAIT(h_end2, line);
- p = par->bplpt0wrap;
- if (mod2(par->diwstrt_v+par->vyres-par->yoffset))
- p -= par->next_line;
- else
- p += par->next_line;
- }
- } else p = par->bplpt0wrap - par->next_line;
- }
- for (i = 0; i < (short)par->bpp; i++, p += par->next_plane) {
- (cops++)->l = CMOVE(highw(p), bplpt[i]);
- (cops++)->l = CMOVE2(loww(p), bplpt[i]);
- }
- cops->l = CEND;
- }
-}
static int __exit amifb_remove(struct platform_device *pdev)
{
- unregister_framebuffer(&fb_info);
- amifb_deinit(pdev);
+ struct fb_info *info = dev_get_drvdata(&pdev->dev);
+
+ unregister_framebuffer(info);
+ dev_set_drvdata(&pdev->dev, NULL);
+ fb_dealloc_cmap(&info->cmap);
+ free_irq(IRQ_AMIGA_COPPER, info->par);
+ custom.dmacon = DMAF_ALL | DMAF_MASTER;
+ if (videomemory)
+ iounmap((void *)videomemory);
+ chipfree();
+ framebuffer_release(info);
amifb_video_off();
return 0;
}
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c
index 63409c122ae8..0d7b20d4285d 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/atmel_lcdfb.c
@@ -100,8 +100,11 @@ static int atmel_bl_update_status(struct backlight_device *bl)
brightness = 0;
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, brightness);
- lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR,
+ if (contrast_ctr & ATMEL_LCDC_POL_POSITIVE)
+ lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR,
brightness ? contrast_ctr : 0);
+ else
+ lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
bl->props.fb_blank = bl->props.power = sinfo->bl_power = power;
@@ -682,14 +685,30 @@ static int atmel_lcdfb_setcolreg(unsigned int regno, unsigned int red,
case FB_VISUAL_PSEUDOCOLOR:
if (regno < 256) {
- val = ((red >> 11) & 0x001f);
- val |= ((green >> 6) & 0x03e0);
- val |= ((blue >> 1) & 0x7c00);
-
- /*
- * TODO: intensity bit. Maybe something like
- * ~(red[10] ^ green[10] ^ blue[10]) & 1
- */
+ if (cpu_is_at91sam9261() || cpu_is_at91sam9263()
+ || cpu_is_at91sam9rl()) {
+ /* old style I+BGR:555 */
+ val = ((red >> 11) & 0x001f);
+ val |= ((green >> 6) & 0x03e0);
+ val |= ((blue >> 1) & 0x7c00);
+
+ /*
+ * TODO: intensity bit. Maybe something like
+ * ~(red[10] ^ green[10] ^ blue[10]) & 1
+ */
+ } else {
+ /* new style BGR:565 / RGB:565 */
+ if (sinfo->lcd_wiring_mode ==
+ ATMEL_LCDC_WIRING_RGB) {
+ val = ((blue >> 11) & 0x001f);
+ val |= ((red >> 0) & 0xf800);
+ } else {
+ val = ((red >> 11) & 0x001f);
+ val |= ((blue >> 0) & 0xf800);
+ }
+
+ val |= ((green >> 5) & 0x07e0);
+ }
lcdc_writel(sinfo, ATMEL_LCDC_LUT(regno), val);
ret = 0;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index 44bdce4242ad..622f12b62a47 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -301,9 +301,9 @@ static struct fb_ops atyfb_ops = {
.fb_sync = atyfb_sync,
};
-static int noaccel;
+static bool noaccel;
#ifdef CONFIG_MTRR
-static int nomtrr;
+static bool nomtrr;
#endif
static int vram;
static int pll;
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 150684882ef7..ce1506b75adf 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -263,19 +263,19 @@ static reg_val common_regs[] = {
static char *mode_option;
static char *monitor_layout;
-static int noaccel = 0;
+static bool noaccel = 0;
static int default_dynclk = -2;
-static int nomodeset = 0;
-static int ignore_edid = 0;
-static int mirror = 0;
+static bool nomodeset = 0;
+static bool ignore_edid = 0;
+static bool mirror = 0;
static int panel_yres = 0;
-static int force_dfp = 0;
-static int force_measure_pll = 0;
+static bool force_dfp = 0;
+static bool force_measure_pll = 0;
#ifdef CONFIG_MTRR
-static int nomtrr = 0;
+static bool nomtrr = 0;
#endif
-static int force_sleep;
-static int ignore_devlist;
+static bool force_sleep;
+static bool ignore_devlist;
#ifdef CONFIG_PMAC_BACKLIGHT
static int backlight = 1;
#else
diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c
index 649cb35de4ed..de9da6774fd9 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/au1100fb.c
@@ -60,18 +60,6 @@
#include "au1100fb.h"
-/*
- * Sanity check. If this is a new Au1100 based board, search for
- * the PB1100 ifdefs to make sure you modify the code accordingly.
- */
-#if defined(CONFIG_MIPS_PB1100)
- #include <asm/mach-pb1x00/pb1100.h>
-#elif defined(CONFIG_MIPS_DB1100)
- #include <asm/mach-db1x00/db1x00.h>
-#else
- #error "Unknown Au1100 board, Au1100 FB driver not supported"
-#endif
-
#define DRIVER_NAME "au1100fb"
#define DRIVER_DESC "LCD controller driver for AU1100 processors"
diff --git a/drivers/video/au1200fb.c b/drivers/video/au1200fb.c
index 72005598040f..04e4479d5afd 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/au1200fb.c
@@ -44,6 +44,7 @@
#include <linux/slab.h>
#include <asm/mach-au1x00/au1000.h>
+#include <asm/mach-au1x00/au1200fb.h> /* platform_data */
#include "au1200fb.h"
#define DRIVER_NAME "au1200fb"
@@ -143,6 +144,7 @@ struct au1200_lcd_iodata_t {
/* Private, per-framebuffer management information (independent of the panel itself) */
struct au1200fb_device {
struct fb_info *fb_info; /* FB driver info record */
+ struct au1200fb_platdata *pd;
int plane;
unsigned char* fb_mem; /* FrameBuffer memory map */
@@ -201,9 +203,6 @@ struct window_settings {
#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01
#endif
-extern int board_au1200fb_panel_init (void);
-extern int board_au1200fb_panel_shutdown (void);
-
/*
* Default window configurations
*/
@@ -334,8 +333,6 @@ struct panel_settings
uint32 mode_toyclksrc;
uint32 mode_backlight;
uint32 mode_auxpll;
- int (*device_init)(void);
- int (*device_shutdown)(void);
#define Xres min_xres
#define Yres min_yres
u32 min_xres; /* Minimum horizontal resolution */
@@ -385,8 +382,6 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
320, 320,
240, 240,
},
@@ -415,8 +410,6 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
640, 480,
640, 480,
},
@@ -445,8 +438,6 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
800, 800,
600, 600,
},
@@ -475,8 +466,6 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 6, /* 72MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
1024, 1024,
768, 768,
},
@@ -505,8 +494,6 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 10, /* 120MHz AUXPLL */
- .device_init = NULL,
- .device_shutdown = NULL,
1280, 1280,
1024, 1024,
},
@@ -535,8 +522,6 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = board_au1200fb_panel_init,
- .device_shutdown = board_au1200fb_panel_shutdown,
1024, 1024,
768, 768,
},
@@ -568,8 +553,6 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = board_au1200fb_panel_init,
- .device_shutdown = board_au1200fb_panel_shutdown,
640, 480,
640, 480,
},
@@ -601,8 +584,6 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = board_au1200fb_panel_init,
- .device_shutdown = board_au1200fb_panel_shutdown,
320, 320,
240, 240,
},
@@ -634,11 +615,43 @@ static struct panel_settings known_lcd_panels[] =
.mode_toyclksrc = 0x00000004, /* AUXPLL directly */
.mode_backlight = 0x00000000,
.mode_auxpll = 8, /* 96MHz AUXPLL */
- .device_init = board_au1200fb_panel_init,
- .device_shutdown = board_au1200fb_panel_shutdown,
856, 856,
480, 480,
},
+ [9] = {
+ .name = "DB1300_800x480",
+ .monspecs = {
+ .modedb = NULL,
+ .modedb_len = 0,
+ .hfmin = 30000,
+ .hfmax = 70000,
+ .vfmin = 60,
+ .vfmax = 60,
+ .dclkmin = 6000000,
+ .dclkmax = 28000000,
+ .input = FB_DISP_RGB,
+ },
+ .mode_screen = LCD_SCREEN_SX_N(800) |
+ LCD_SCREEN_SY_N(480),
+ .mode_horztiming = LCD_HORZTIMING_HPW_N(5) |
+ LCD_HORZTIMING_HND1_N(16) |
+ LCD_HORZTIMING_HND2_N(8),
+ .mode_verttiming = LCD_VERTTIMING_VPW_N(4) |
+ LCD_VERTTIMING_VND1_N(8) |
+ LCD_VERTTIMING_VND2_N(5),
+ .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(1) |
+ LCD_CLKCONTROL_IV |
+ LCD_CLKCONTROL_IH,
+ .mode_pwmdiv = 0x00000000,
+ .mode_pwmhi = 0x00000000,
+ .mode_outmask = 0x00FFFFFF,
+ .mode_fifoctrl = 0x2f2f2f2f,
+ .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
+ .mode_backlight = 0x00000000,
+ .mode_auxpll = (48/12) * 2,
+ 800, 800,
+ 480, 480,
+ },
};
#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))
@@ -764,7 +777,8 @@ static int au1200_setlocation (struct au1200fb_device *fbdev, int plane,
return 0;
}
-static void au1200_setpanel (struct panel_settings *newpanel)
+static void au1200_setpanel(struct panel_settings *newpanel,
+ struct au1200fb_platdata *pd)
{
/*
* Perform global setup/init of LCD controller
@@ -798,8 +812,8 @@ static void au1200_setpanel (struct panel_settings *newpanel)
the controller, the clock cannot be turned off before first
shutting down the controller.
*/
- if (panel->device_shutdown != NULL)
- panel->device_shutdown();
+ if (pd->panel_shutdown)
+ pd->panel_shutdown();
}
/* Newpanel == NULL indicates a shutdown operation only */
@@ -852,7 +866,8 @@ static void au1200_setpanel (struct panel_settings *newpanel)
au_sync();
/* Call init of panel */
- if (panel->device_init != NULL) panel->device_init();
+ if (pd->panel_init)
+ pd->panel_init();
/* FIX!!!! not appropriate on panel change!!! Global setup/init */
lcd->intenable = 0;
@@ -1185,6 +1200,8 @@ static int au1200fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green,
*/
static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
{
+ struct au1200fb_device *fbdev = fbi->par;
+
/* Short-circuit screen blanking */
if (noblanking)
return 0;
@@ -1194,13 +1211,13 @@ static int au1200fb_fb_blank(int blank_mode, struct fb_info *fbi)
case FB_BLANK_UNBLANK:
case FB_BLANK_NORMAL:
/* printk("turn on panel\n"); */
- au1200_setpanel(panel);
+ au1200_setpanel(panel, fbdev->pd);
break;
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_POWERDOWN:
/* printk("turn off panel\n"); */
- au1200_setpanel(NULL);
+ au1200_setpanel(NULL, fbdev->pd);
break;
default:
break;
@@ -1428,6 +1445,7 @@ static void get_window(unsigned int plane,
static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
unsigned long arg)
{
+ struct au1200fb_device *fbdev = info->par;
int plane;
int val;
@@ -1472,7 +1490,7 @@ static int au1200fb_ioctl(struct fb_info *info, unsigned int cmd,
struct panel_settings *newpanel;
panel_index = iodata.global.panel_choice;
newpanel = &known_lcd_panels[panel_index];
- au1200_setpanel(newpanel);
+ au1200_setpanel(newpanel, fbdev->pd);
}
break;
@@ -1588,22 +1606,102 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
/*-------------------------------------------------------------------------*/
-/* AU1200 LCD controller device driver */
+static int au1200fb_setup(struct au1200fb_platdata *pd)
+{
+ char *options = NULL;
+ char *this_opt, *endptr;
+ int num_panels = ARRAY_SIZE(known_lcd_panels);
+ int panel_idx = -1;
+
+ fb_get_options(DRIVER_NAME, &options);
+
+ if (!options)
+ goto out;
+
+ while ((this_opt = strsep(&options, ",")) != NULL) {
+ /* Panel option - can be panel name,
+ * "bs" for board-switch, or number/index */
+ if (!strncmp(this_opt, "panel:", 6)) {
+ int i;
+ long int li;
+ char *endptr;
+ this_opt += 6;
+ /* First check for index, which allows
+ * to short circuit this mess */
+ li = simple_strtol(this_opt, &endptr, 0);
+ if (*endptr == '\0')
+ panel_idx = (int)li;
+ else if (strcmp(this_opt, "bs") == 0)
+ panel_idx = pd->panel_index();
+ else {
+ for (i = 0; i < num_panels; i++) {
+ if (!strcmp(this_opt,
+ known_lcd_panels[i].name)) {
+ panel_idx = i;
+ break;
+ }
+ }
+ }
+ if ((panel_idx < 0) || (panel_idx >= num_panels))
+ print_warn("Panel %s not supported!", this_opt);
+ else
+ panel_index = panel_idx;
+
+ } else if (strncmp(this_opt, "nohwcursor", 10) == 0)
+ nohwcursor = 1;
+ else if (strncmp(this_opt, "devices:", 8) == 0) {
+ this_opt += 8;
+ device_count = simple_strtol(this_opt, &endptr, 0);
+ if ((device_count < 0) ||
+ (device_count > MAX_DEVICE_COUNT))
+ device_count = MAX_DEVICE_COUNT;
+ } else if (strncmp(this_opt, "wincfg:", 7) == 0) {
+ this_opt += 7;
+ window_index = simple_strtol(this_opt, &endptr, 0);
+ if ((window_index < 0) ||
+ (window_index >= ARRAY_SIZE(windows)))
+ window_index = DEFAULT_WINDOW_INDEX;
+ } else if (strncmp(this_opt, "off", 3) == 0)
+ return 1;
+ else
+ print_warn("Unsupported option \"%s\"", this_opt);
+ }
+
+out:
+ return 0;
+}
+
+/* AU1200 LCD controller device driver */
static int __devinit au1200fb_drv_probe(struct platform_device *dev)
{
struct au1200fb_device *fbdev;
+ struct au1200fb_platdata *pd;
struct fb_info *fbi = NULL;
unsigned long page;
int bpp, plane, ret, irq;
+ print_info("" DRIVER_DESC "");
+
+ pd = dev->dev.platform_data;
+ if (!pd)
+ return -ENODEV;
+
+ /* Setup driver with options */
+ if (au1200fb_setup(pd))
+ return -ENODEV;
+
+ /* Point to the panel selected */
+ panel = &known_lcd_panels[panel_index];
+ win = &windows[window_index];
+
+ printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
+ printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
+
/* shut gcc up */
ret = 0;
fbdev = NULL;
- /* Kickstart the panel */
- au1200_setpanel(panel);
-
for (plane = 0; plane < device_count; ++plane) {
bpp = winbpp(win->w[plane].mode_winctrl1);
if (win->w[plane].xres == 0)
@@ -1619,6 +1717,7 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
_au1200fb_infos[plane] = fbi;
fbdev = fbi->par;
fbdev->fb_info = fbi;
+ fbdev->pd = pd;
fbdev->plane = plane;
@@ -1680,6 +1779,11 @@ static int __devinit au1200fb_drv_probe(struct platform_device *dev)
goto failed;
}
+ platform_set_drvdata(dev, pd);
+
+ /* Kickstart the panel */
+ au1200_setpanel(panel, pd);
+
return 0;
failed:
@@ -1699,12 +1803,13 @@ failed:
static int __devexit au1200fb_drv_remove(struct platform_device *dev)
{
+ struct au1200fb_platdata *pd = platform_get_drvdata(dev);
struct au1200fb_device *fbdev;
struct fb_info *fbi;
int plane;
/* Turn off the panel */
- au1200_setpanel(NULL);
+ au1200_setpanel(NULL, pd);
for (plane = 0; plane < device_count; ++plane) {
fbi = _au1200fb_infos[plane];
@@ -1732,7 +1837,8 @@ static int __devexit au1200fb_drv_remove(struct platform_device *dev)
#ifdef CONFIG_PM
static int au1200fb_drv_suspend(struct device *dev)
{
- au1200_setpanel(NULL);
+ struct au1200fb_platdata *pd = dev_get_drvdata(dev);
+ au1200_setpanel(NULL, pd);
lcd->outmask = 0;
au_sync();
@@ -1742,11 +1848,12 @@ static int au1200fb_drv_suspend(struct device *dev)
static int au1200fb_drv_resume(struct device *dev)
{
+ struct au1200fb_platdata *pd = dev_get_drvdata(dev);
struct fb_info *fbi;
int i;
/* Kickstart the panel */
- au1200_setpanel(panel);
+ au1200_setpanel(panel, pd);
for (i = 0; i < device_count; i++) {
fbi = _au1200fb_infos[i];
@@ -1781,100 +1888,8 @@ static struct platform_driver au1200fb_driver = {
/*-------------------------------------------------------------------------*/
-/* Kernel driver */
-
-static int au1200fb_setup(void)
-{
- char *options = NULL;
- char *this_opt, *endptr;
- int num_panels = ARRAY_SIZE(known_lcd_panels);
- int panel_idx = -1;
-
- fb_get_options(DRIVER_NAME, &options);
-
- if (options) {
- while ((this_opt = strsep(&options,",")) != NULL) {
- /* Panel option - can be panel name,
- * "bs" for board-switch, or number/index */
- if (!strncmp(this_opt, "panel:", 6)) {
- int i;
- long int li;
- char *endptr;
- this_opt += 6;
- /* First check for index, which allows
- * to short circuit this mess */
- li = simple_strtol(this_opt, &endptr, 0);
- if (*endptr == '\0') {
- panel_idx = (int)li;
- }
- else if (strcmp(this_opt, "bs") == 0) {
- extern int board_au1200fb_panel(void);
- panel_idx = board_au1200fb_panel();
- }
-
- else
- for (i = 0; i < num_panels; i++) {
- if (!strcmp(this_opt, known_lcd_panels[i].name)) {
- panel_idx = i;
- break;
- }
- }
-
- if ((panel_idx < 0) || (panel_idx >= num_panels)) {
- print_warn("Panel %s not supported!", this_opt);
- }
- else
- panel_index = panel_idx;
- }
-
- else if (strncmp(this_opt, "nohwcursor", 10) == 0) {
- nohwcursor = 1;
- }
-
- else if (strncmp(this_opt, "devices:", 8) == 0) {
- this_opt += 8;
- device_count = simple_strtol(this_opt,
- &endptr, 0);
- if ((device_count < 0) ||
- (device_count > MAX_DEVICE_COUNT))
- device_count = MAX_DEVICE_COUNT;
- }
-
- else if (strncmp(this_opt, "wincfg:", 7) == 0) {
- this_opt += 7;
- window_index = simple_strtol(this_opt,
- &endptr, 0);
- if ((window_index < 0) ||
- (window_index >= ARRAY_SIZE(windows)))
- window_index = DEFAULT_WINDOW_INDEX;
- }
-
- else if (strncmp(this_opt, "off", 3) == 0)
- return 1;
- /* Unsupported option */
- else {
- print_warn("Unsupported option \"%s\"", this_opt);
- }
- }
- }
- return 0;
-}
-
static int __init au1200fb_init(void)
{
- print_info("" DRIVER_DESC "");
-
- /* Setup driver with options */
- if (au1200fb_setup())
- return -ENODEV;
-
- /* Point to the panel selected */
- panel = &known_lcd_panels[panel_index];
- win = &windows[window_index];
-
- printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
- printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
-
return platform_driver_register(&au1200fb_driver);
}
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 6df7c54db0a3..738c8ce7d132 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -280,52 +280,74 @@ MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
#endif /* CONFIG_PCI */
#ifdef CONFIG_ZORRO
-static const struct zorro_device_id cirrusfb_zorro_table[] = {
+struct zorrocl {
+ enum cirrus_board type; /* Board type */
+ u32 regoffset; /* Offset of registers in first Zorro device */
+ u32 ramsize; /* Size of video RAM in first Zorro device */
+ /* If zero, use autoprobe on RAM device */
+ u32 ramoffset; /* Offset of video RAM in first Zorro device */
+ zorro_id ramid; /* Zorro ID of RAM device */
+ zorro_id ramid2; /* Zorro ID of optional second RAM device */
+};
+
+static const struct zorrocl zcl_sd64 __devinitconst = {
+ .type = BT_SD64,
+ .ramid = ZORRO_PROD_HELFRICH_SD64_RAM,
+};
+
+static const struct zorrocl zcl_piccolo __devinitconst = {
+ .type = BT_PICCOLO,
+ .ramid = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
+};
+
+static const struct zorrocl zcl_picasso __devinitconst = {
+ .type = BT_PICASSO,
+ .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
+};
+
+static const struct zorrocl zcl_spectrum __devinitconst = {
+ .type = BT_SPECTRUM,
+ .ramid = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
+};
+
+static const struct zorrocl zcl_picasso4_z3 __devinitconst = {
+ .type = BT_PICASSO4,
+ .regoffset = 0x00600000,
+ .ramsize = 4 * MB_,
+ .ramoffset = 0x01000000, /* 0x02000000 for 64 MiB boards */
+};
+
+static const struct zorrocl zcl_picasso4_z2 __devinitconst = {
+ .type = BT_PICASSO4,
+ .regoffset = 0x10000,
+ .ramid = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1,
+ .ramid2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2,
+};
+
+
+static const struct zorro_device_id cirrusfb_zorro_table[] __devinitconst = {
{
- .id = ZORRO_PROD_HELFRICH_SD64_RAM,
- .driver_data = BT_SD64,
+ .id = ZORRO_PROD_HELFRICH_SD64_REG,
+ .driver_data = (unsigned long)&zcl_sd64,
}, {
- .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
- .driver_data = BT_PICCOLO,
+ .id = ZORRO_PROD_HELFRICH_PICCOLO_REG,
+ .driver_data = (unsigned long)&zcl_piccolo,
}, {
- .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
- .driver_data = BT_PICASSO,
+ .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
+ .driver_data = (unsigned long)&zcl_picasso,
}, {
- .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
- .driver_data = BT_SPECTRUM,
+ .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
+ .driver_data = (unsigned long)&zcl_spectrum,
}, {
.id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
- .driver_data = BT_PICASSO4,
+ .driver_data = (unsigned long)&zcl_picasso4_z3,
+ }, {
+ .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG,
+ .driver_data = (unsigned long)&zcl_picasso4_z2,
},
{ 0 }
};
MODULE_DEVICE_TABLE(zorro, cirrusfb_zorro_table);
-
-static const struct {
- zorro_id id2;
- unsigned long size;
-} cirrusfb_zorro_table2[] = {
- [BT_SD64] = {
- .id2 = ZORRO_PROD_HELFRICH_SD64_REG,
- .size = 0x400000
- },
- [BT_PICCOLO] = {
- .id2 = ZORRO_PROD_HELFRICH_PICCOLO_REG,
- .size = 0x200000
- },
- [BT_PICASSO] = {
- .id2 = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG,
- .size = 0x200000
- },
- [BT_SPECTRUM] = {
- .id2 = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG,
- .size = 0x200000
- },
- [BT_PICASSO4] = {
- .id2 = 0,
- .size = 0x400000
- }
-};
#endif /* CONFIG_ZORRO */
#ifdef CIRRUSFB_DEBUG
@@ -350,7 +372,7 @@ struct cirrusfb_info {
void (*unmap)(struct fb_info *info);
};
-static int noaccel __devinitdata;
+static bool noaccel __devinitdata;
static char *mode_option __devinitdata = "640x480@60";
/****************************************************************************/
@@ -1956,16 +1978,12 @@ static void cirrusfb_zorro_unmap(struct fb_info *info)
struct cirrusfb_info *cinfo = info->par;
struct zorro_dev *zdev = to_zorro_dev(info->device);
- zorro_release_device(zdev);
-
- if (cinfo->btype == BT_PICASSO4) {
- cinfo->regbase -= 0x600000;
- iounmap((void *)cinfo->regbase);
+ if (info->fix.smem_start > 16 * MB_)
iounmap(info->screen_base);
- } else {
- if (zorro_resource_start(zdev) > 0x01000000)
- iounmap(info->screen_base);
- }
+ if (info->fix.mmio_start > 16 * MB_)
+ iounmap(cinfo->regbase);
+
+ zorro_release_device(zdev);
}
#endif /* CONFIG_ZORRO */
@@ -2222,115 +2240,116 @@ static struct pci_driver cirrusfb_pci_driver = {
static int __devinit cirrusfb_zorro_register(struct zorro_dev *z,
const struct zorro_device_id *ent)
{
- struct cirrusfb_info *cinfo;
struct fb_info *info;
+ int error;
+ const struct zorrocl *zcl;
enum cirrus_board btype;
- struct zorro_dev *z2 = NULL;
- unsigned long board_addr, board_size, size;
- int ret;
-
- btype = ent->driver_data;
- if (cirrusfb_zorro_table2[btype].id2)
- z2 = zorro_find_device(cirrusfb_zorro_table2[btype].id2, NULL);
- size = cirrusfb_zorro_table2[btype].size;
+ unsigned long regbase, ramsize, rambase;
+ struct cirrusfb_info *cinfo;
info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
if (!info) {
printk(KERN_ERR "cirrusfb: could not allocate memory\n");
- ret = -ENOMEM;
- goto err_out;
+ return -ENOMEM;
+ }
+
+ zcl = (const struct zorrocl *)ent->driver_data;
+ btype = zcl->type;
+ regbase = zorro_resource_start(z) + zcl->regoffset;
+ ramsize = zcl->ramsize;
+ if (ramsize) {
+ rambase = zorro_resource_start(z) + zcl->ramoffset;
+ if (zorro_resource_len(z) == 64 * MB_) {
+ /* Quirk for 64 MiB Picasso IV */
+ rambase += zcl->ramoffset;
+ }
+ } else {
+ struct zorro_dev *ram = zorro_find_device(zcl->ramid, NULL);
+ if (!ram || !zorro_resource_len(ram)) {
+ dev_err(info->device, "No video RAM found\n");
+ error = -ENODEV;
+ goto err_release_fb;
+ }
+ rambase = zorro_resource_start(ram);
+ ramsize = zorro_resource_len(ram);
+ if (zcl->ramid2 &&
+ (ram = zorro_find_device(zcl->ramid2, NULL))) {
+ if (zorro_resource_start(ram) != rambase + ramsize) {
+ dev_warn(info->device,
+ "Skipping non-contiguous RAM at %pR\n",
+ &ram->resource);
+ } else {
+ ramsize += zorro_resource_len(ram);
+ }
+ }
}
- dev_info(info->device, "%s board detected\n",
- cirrusfb_board_info[btype].name);
-
- cinfo = info->par;
- cinfo->btype = btype;
-
- assert(z);
- assert(btype != BT_NONE);
-
- board_addr = zorro_resource_start(z);
- board_size = zorro_resource_len(z);
- info->screen_size = size;
+ dev_info(info->device,
+ "%s board detected, REG at 0x%lx, %lu MiB RAM at 0x%lx\n",
+ cirrusfb_board_info[btype].name, regbase, ramsize / MB_,
+ rambase);
if (!zorro_request_device(z, "cirrusfb")) {
- dev_err(info->device, "cannot reserve region 0x%lx, abort\n",
- board_addr);
- ret = -EBUSY;
+ dev_err(info->device, "Cannot reserve %pR\n", &z->resource);
+ error = -EBUSY;
goto err_release_fb;
}
- ret = -EIO;
-
- if (btype == BT_PICASSO4) {
- dev_info(info->device, " REG at $%lx\n", board_addr + 0x600000);
-
- /* To be precise, for the P4 this is not the */
- /* begin of the board, but the begin of RAM. */
- /* for P4, map in its address space in 2 chunks (### TEST! ) */
- /* (note the ugly hardcoded 16M number) */
- cinfo->regbase = ioremap(board_addr, 16777216);
- if (!cinfo->regbase)
- goto err_release_region;
-
- dev_dbg(info->device, "Virtual address for board set to: $%p\n",
- cinfo->regbase);
- cinfo->regbase += 0x600000;
- info->fix.mmio_start = board_addr + 0x600000;
-
- info->fix.smem_start = board_addr + 16777216;
- info->screen_base = ioremap(info->fix.smem_start, 16777216);
- if (!info->screen_base)
- goto err_unmap_regbase;
- } else {
- dev_info(info->device, " REG at $%lx\n",
- (unsigned long) z2->resource.start);
-
- info->fix.smem_start = board_addr;
- if (board_addr > 0x01000000)
- info->screen_base = ioremap(board_addr, board_size);
- else
- info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
- if (!info->screen_base)
- goto err_release_region;
+ cinfo = info->par;
+ cinfo->btype = btype;
- /* set address for REG area of board */
- cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
- info->fix.mmio_start = z2->resource.start;
+ info->fix.mmio_start = regbase;
+ cinfo->regbase = regbase > 16 * MB_ ? ioremap(regbase, 64 * 1024)
+ : (caddr_t)ZTWO_VADDR(regbase);
+ if (!cinfo->regbase) {
+ dev_err(info->device, "Cannot map registers\n");
+ error = -EIO;
+ goto err_release_dev;
+ }
- dev_dbg(info->device, "Virtual address for board set to: $%p\n",
- cinfo->regbase);
+ info->fix.smem_start = rambase;
+ info->screen_size = ramsize;
+ info->screen_base = rambase > 16 * MB_ ? ioremap(rambase, ramsize)
+ : (caddr_t)ZTWO_VADDR(rambase);
+ if (!info->screen_base) {
+ dev_err(info->device, "Cannot map video RAM\n");
+ error = -EIO;
+ goto err_unmap_reg;
}
+
cinfo->unmap = cirrusfb_zorro_unmap;
dev_info(info->device,
- "Cirrus Logic chipset on Zorro bus, RAM (%lu MB) at $%lx\n",
- board_size / MB_, board_addr);
-
- zorro_set_drvdata(z, info);
+ "Cirrus Logic chipset on Zorro bus, RAM (%lu MiB) at 0x%lx\n",
+ ramsize / MB_, rambase);
/* MCLK select etc. */
if (cirrusfb_board_info[btype].init_sr1f)
vga_wseq(cinfo->regbase, CL_SEQR1F,
cirrusfb_board_info[btype].sr1f);
- ret = cirrusfb_register(info);
- if (!ret)
- return 0;
+ error = cirrusfb_register(info);
+ if (error) {
+ dev_err(info->device, "Failed to register device, error %d\n",
+ error);
+ goto err_unmap_ram;
+ }
- if (btype == BT_PICASSO4 || board_addr > 0x01000000)
+ zorro_set_drvdata(z, info);
+ return 0;
+
+err_unmap_ram:
+ if (rambase > 16 * MB_)
iounmap(info->screen_base);
-err_unmap_regbase:
- if (btype == BT_PICASSO4)
- iounmap(cinfo->regbase - 0x600000);
-err_release_region:
- release_region(board_addr, board_size);
+err_unmap_reg:
+ if (regbase > 16 * MB_)
+ iounmap(cinfo->regbase);
+err_release_dev:
+ zorro_release_device(z);
err_release_fb:
framebuffer_release(info);
-err_out:
- return ret;
+ return error;
}
void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
@@ -2338,6 +2357,7 @@ void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
struct fb_info *info = zorro_get_drvdata(z);
cirrusfb_cleanup(info);
+ zorro_set_drvdata(z, NULL);
}
static struct zorro_driver cirrusfb_zorro_driver = {
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index 93317b5b8740..a122d9287d16 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -25,14 +25,13 @@
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
+#include <asm/gio_device.h>
+
#include <video/newport.h>
#include <linux/linux_logo.h>
#include <linux/font.h>
-
-extern unsigned long sgi_gfxaddr;
-
#define FONT_DATA ((unsigned char *)font_vga_8x16.data)
/* borrowed from fbcon.c */
@@ -304,12 +303,6 @@ static const char *newport_startup(void)
{
int i;
- if (!sgi_gfxaddr)
- return NULL;
-
- if (!npregs)
- npregs = (struct newport_regs *)/* ioremap cannot fail */
- ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
npregs->cset.config = NPORT_CFG_GD0;
if (newport_wait(npregs))
@@ -743,26 +736,58 @@ const struct consw newport_con = {
.con_save_screen = DUMMY
};
-#ifdef MODULE
-static int __init newport_console_init(void)
+static int newport_probe(struct gio_device *dev,
+ const struct gio_device_id *id)
{
- if (!sgi_gfxaddr)
- return 0;
+ unsigned long newport_addr;
- if (!npregs)
- npregs = (struct newport_regs *)/* ioremap cannot fail */
- ioremap(sgi_gfxaddr, sizeof(struct newport_regs));
+ if (!dev->resource.start)
+ return -EINVAL;
+
+ if (npregs)
+ return -EBUSY; /* we only support one Newport as console */
+
+ newport_addr = dev->resource.start + 0xF0000;
+ if (!request_mem_region(newport_addr, 0x10000, "Newport"))
+ return -ENODEV;
+
+ npregs = (struct newport_regs *)/* ioremap cannot fail */
+ ioremap(newport_addr, sizeof(struct newport_regs));
return take_over_console(&newport_con, 0, MAX_NR_CONSOLES - 1, 1);
}
-module_init(newport_console_init);
-static void __exit newport_console_exit(void)
+static void newport_remove(struct gio_device *dev)
{
give_up_console(&newport_con);
iounmap((void *)npregs);
}
+
+static struct gio_device_id newport_ids[] = {
+ { .id = 0x7e },
+ { .id = 0xff }
+};
+
+MODULE_ALIAS("gio:7e");
+
+static struct gio_driver newport_driver = {
+ .name = "newport",
+ .id_table = newport_ids,
+ .probe = newport_probe,
+ .remove = newport_remove,
+};
+
+int __init newport_console_init(void)
+{
+ return gio_register_driver(&newport_driver);
+}
+
+void __exit newport_console_exit(void)
+{
+ gio_unregister_driver(&newport_driver);
+}
+
+module_init(newport_console_init);
module_exit(newport_console_exit);
-#endif
MODULE_LICENSE("GPL");
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 7b2c40abae15..0c189b32a4c5 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -420,7 +420,7 @@ static int __init init_control(struct fb_info_control *p)
/* Try to pick a video mode out of NVRAM if we have one. */
#ifdef CONFIG_NVRAM
- if (default_cmode == CMODE_NVRAM){
+ if (default_cmode == CMODE_NVRAM) {
cmode = nvram_read_byte(NV_CMODE);
if(cmode < CMODE_8 || cmode > CMODE_32)
cmode = CMODE_8;
diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig
deleted file mode 100644
index f99af931d4f8..000000000000
--- a/drivers/video/display/Kconfig
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# Display drivers configuration
-#
-
-menu "Display device support"
-
-config DISPLAY_SUPPORT
- tristate "Display panel/monitor support"
- ---help---
- This framework adds support for low-level control of a display.
- This includes support for power.
-
- Enable this to be able to choose the drivers for controlling the
- physical display panel/monitor on some platforms. This not only
- covers LCD displays for PDAs but also other types of displays
- such as CRT, TVout etc.
-
- To have support for your specific display panel you will have to
- select the proper drivers which depend on this option.
-
-comment "Display hardware drivers"
- depends on DISPLAY_SUPPORT
-
-endmenu
diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile
deleted file mode 100644
index c0ea832bf171..000000000000
--- a/drivers/video/display/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-# Display drivers
-
-display-objs := display-sysfs.o
-
-obj-$(CONFIG_DISPLAY_SUPPORT) += display.o
-
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
deleted file mode 100644
index 0c647d7af0ee..000000000000
--- a/drivers/video/display/display-sysfs.c
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * display-sysfs.c - Display output driver sysfs interface
- *
- * Copyright (C) 2007 James Simmons <jsimmons@infradead.org>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, 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/module.h>
-#include <linux/display.h>
-#include <linux/ctype.h>
-#include <linux/idr.h>
-#include <linux/err.h>
-#include <linux/kdev_t.h>
-#include <linux/slab.h>
-
-static ssize_t display_show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
-}
-
-static ssize_t display_show_type(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
-}
-
-static ssize_t display_show_contrast(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- ssize_t rc = -ENXIO;
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver) && dsp->driver->get_contrast)
- rc = sprintf(buf, "%d\n", dsp->driver->get_contrast(dsp));
- mutex_unlock(&dsp->lock);
- return rc;
-}
-
-static ssize_t display_store_contrast(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- ssize_t ret = -EINVAL, size;
- int contrast;
- char *endp;
-
- contrast = simple_strtoul(buf, &endp, 0);
- size = endp - buf;
-
- if (isspace(*endp))
- size++;
-
- if (size != count)
- return ret;
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver && dsp->driver->set_contrast)) {
- pr_debug("display: set contrast to %d\n", contrast);
- dsp->driver->set_contrast(dsp, contrast);
- ret = count;
- }
- mutex_unlock(&dsp->lock);
- return ret;
-}
-
-static ssize_t display_show_max_contrast(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
- ssize_t rc = -ENXIO;
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver))
- rc = sprintf(buf, "%d\n", dsp->driver->max_contrast);
- mutex_unlock(&dsp->lock);
- return rc;
-}
-
-static struct device_attribute display_attrs[] = {
- __ATTR(name, S_IRUGO, display_show_name, NULL),
- __ATTR(type, S_IRUGO, display_show_type, NULL),
- __ATTR(contrast, S_IRUGO | S_IWUSR, display_show_contrast, display_store_contrast),
- __ATTR(max_contrast, S_IRUGO, display_show_max_contrast, NULL),
-};
-
-static int display_suspend(struct device *dev, pm_message_t state)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver->suspend))
- dsp->driver->suspend(dsp, state);
- mutex_unlock(&dsp->lock);
- return 0;
-};
-
-static int display_resume(struct device *dev)
-{
- struct display_device *dsp = dev_get_drvdata(dev);
-
- mutex_lock(&dsp->lock);
- if (likely(dsp->driver->resume))
- dsp->driver->resume(dsp);
- mutex_unlock(&dsp->lock);
- return 0;
-};
-
-static struct mutex allocated_dsp_lock;
-static DEFINE_IDR(allocated_dsp);
-static struct class *display_class;
-
-struct display_device *display_device_register(struct display_driver *driver,
- struct device *parent, void *devdata)
-{
- struct display_device *new_dev = NULL;
- int ret = -EINVAL;
-
- if (unlikely(!driver))
- return ERR_PTR(ret);
-
- mutex_lock(&allocated_dsp_lock);
- ret = idr_pre_get(&allocated_dsp, GFP_KERNEL);
- mutex_unlock(&allocated_dsp_lock);
- if (!ret)
- return ERR_PTR(ret);
-
- new_dev = kzalloc(sizeof(struct display_device), GFP_KERNEL);
- if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
- // Reserve the index for this display
- mutex_lock(&allocated_dsp_lock);
- ret = idr_get_new(&allocated_dsp, new_dev, &new_dev->idx);
- mutex_unlock(&allocated_dsp_lock);
-
- if (!ret) {
- new_dev->dev = device_create(display_class, parent,
- MKDEV(0, 0), new_dev,
- "display%d", new_dev->idx);
- if (!IS_ERR(new_dev->dev)) {
- new_dev->parent = parent;
- new_dev->driver = driver;
- mutex_init(&new_dev->lock);
- return new_dev;
- }
- mutex_lock(&allocated_dsp_lock);
- idr_remove(&allocated_dsp, new_dev->idx);
- mutex_unlock(&allocated_dsp_lock);
- ret = -EINVAL;
- }
- }
- kfree(new_dev);
- return ERR_PTR(ret);
-}
-EXPORT_SYMBOL(display_device_register);
-
-void display_device_unregister(struct display_device *ddev)
-{
- if (!ddev)
- return;
- // Free device
- mutex_lock(&ddev->lock);
- device_unregister(ddev->dev);
- mutex_unlock(&ddev->lock);
- // Mark device index as available
- mutex_lock(&allocated_dsp_lock);
- idr_remove(&allocated_dsp, ddev->idx);
- mutex_unlock(&allocated_dsp_lock);
- kfree(ddev);
-}
-EXPORT_SYMBOL(display_device_unregister);
-
-static int __init display_class_init(void)
-{
- display_class = class_create(THIS_MODULE, "display");
- if (IS_ERR(display_class)) {
- printk(KERN_ERR "Failed to create display class\n");
- display_class = NULL;
- return -EINVAL;
- }
- display_class->dev_attrs = display_attrs;
- display_class->suspend = display_suspend;
- display_class->resume = display_resume;
- mutex_init(&allocated_dsp_lock);
- return 0;
-}
-
-static void __exit display_class_exit(void)
-{
- class_destroy(display_class);
-}
-
-module_init(display_class_init);
-module_exit(display_class_exit);
-
-MODULE_DESCRIPTION("Display Hardware handling");
-MODULE_AUTHOR("James Simmons <jsimmons@infradead.org>");
-MODULE_LICENSE("GPL");
-
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index ad936295d8f4..ac9141b85356 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -967,6 +967,20 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var)
memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
u32 activate = var->activate;
+ /* When using FOURCC mode, make sure the red, green, blue and
+ * transp fields are set to 0.
+ */
+ if ((info->fix.capabilities & FB_CAP_FOURCC) &&
+ var->grayscale > 1) {
+ if (var->red.offset || var->green.offset ||
+ var->blue.offset || var->transp.offset ||
+ var->red.length || var->green.length ||
+ var->blue.length || var->transp.length ||
+ var->red.msb_right || var->green.msb_right ||
+ var->blue.msb_right || var->transp.msb_right)
+ return -EINVAL;
+ }
+
if (!info->fbops->fb_check_var) {
*var = info->var;
goto done;
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fsl-diu-fb.c
index a16beeb5f548..acf292bfba02 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fsl-diu-fb.c
@@ -36,8 +36,7 @@
#include <linux/fsl-diu-fb.h>
#include "edid.h"
-#define FSL_AOI_NUM 6 /* 5 AOIs and one dummy AOI */
- /* 1 for plane 0, 2 for plane 1&2 each */
+#define NUM_AOIS 5 /* 1 for plane 0, 2 for planes 1 & 2 each */
/* HW cursor parameters */
#define MAX_CURS 32
@@ -49,12 +48,6 @@
#define INT_PARERR 0x08 /* Display parameters error interrupt */
#define INT_LS_BF_VS 0x10 /* Lines before vsync. interrupt */
-struct diu_addr {
- void *vaddr; /* Virtual address */
- dma_addr_t paddr; /* Physical address */
- __u32 offset;
-};
-
/*
* List of supported video modes
*
@@ -330,23 +323,6 @@ static unsigned int d_cache_line_size;
static DEFINE_SPINLOCK(diu_lock);
-struct fsl_diu_data {
- struct fb_info *fsl_diu_info[FSL_AOI_NUM - 1];
- /*FSL_AOI_NUM has one dummy AOI */
- struct device_attribute dev_attr;
- struct diu_ad *dummy_ad;
- void *dummy_aoi_virt;
- unsigned int irq;
- int fb_enabled;
- enum fsl_diu_monitor_port monitor_port;
- struct diu __iomem *diu_reg;
- spinlock_t reg_lock;
- struct diu_addr ad;
- struct diu_addr gamma;
- struct diu_addr pallete;
- struct diu_addr cursor;
-};
-
enum mfb_index {
PLANE0 = 0, /* Plane 0, only one AOI that fills the screen */
PLANE1_AOI0, /* Plane 1, first AOI */
@@ -370,6 +346,42 @@ struct mfb_info {
u8 *edid_data;
};
+/**
+ * struct fsl_diu_data - per-DIU data structure
+ * @dma_addr: DMA address of this structure
+ * @fsl_diu_info: fb_info objects, one per AOI
+ * @dev_attr: sysfs structure
+ * @irq: IRQ
+ * @monitor_port: the monitor port this DIU is connected to
+ * @diu_reg: pointer to the DIU hardware registers
+ * @reg_lock: spinlock for register access
+ * @dummy_aoi: video buffer for the 4x4 32-bit dummy AOI
+ * dummy_ad: DIU Area Descriptor for the dummy AOI
+ * @ad[]: Area Descriptors for each real AOI
+ * @gamma: gamma color table
+ * @cursor: hardware cursor data
+ *
+ * This data structure must be allocated with 32-byte alignment, so that the
+ * internal fields can be aligned properly.
+ */
+struct fsl_diu_data {
+ dma_addr_t dma_addr;
+ struct fb_info fsl_diu_info[NUM_AOIS];
+ struct mfb_info mfb[NUM_AOIS];
+ struct device_attribute dev_attr;
+ unsigned int irq;
+ enum fsl_diu_monitor_port monitor_port;
+ struct diu __iomem *diu_reg;
+ spinlock_t reg_lock;
+ u8 dummy_aoi[4 * 4 * 4];
+ struct diu_ad dummy_ad __aligned(8);
+ struct diu_ad ad[NUM_AOIS] __aligned(8);
+ u8 gamma[256 * 3] __aligned(32);
+ u8 cursor[MAX_CURS * MAX_CURS * 2] __aligned(32);
+} __aligned(32);
+
+/* Determine the DMA address of a member of the fsl_diu_data structure */
+#define DMA_ADDR(p, f) ((p)->dma_addr + offsetof(struct fsl_diu_data, f))
static struct mfb_info mfb_template[] = {
{
@@ -449,37 +461,6 @@ static enum fsl_diu_monitor_port fsl_diu_name_to_port(const char *s)
return diu_ops.valid_monitor_port(port);
}
-/**
- * fsl_diu_alloc - allocate memory for the DIU
- * @size: number of bytes to allocate
- * @param: returned physical address of memory
- *
- * This function allocates a physically-contiguous block of memory.
- */
-static void *fsl_diu_alloc(size_t size, phys_addr_t *phys)
-{
- void *virt;
-
- virt = alloc_pages_exact(size, GFP_DMA | __GFP_ZERO);
- if (virt)
- *phys = virt_to_phys(virt);
-
- return virt;
-}
-
-/**
- * fsl_diu_free - release DIU memory
- * @virt: pointer returned by fsl_diu_alloc()
- * @size: number of bytes allocated by fsl_diu_alloc()
- *
- * This function releases memory allocated by fsl_diu_alloc().
- */
-static void fsl_diu_free(void *virt, size_t size)
-{
- if (virt && size)
- free_pages_exact(virt, size);
-}
-
/*
* Workaround for failed writing desc register of planes.
* Needed with MPC5121 DIU rev 2.0 silicon.
@@ -495,8 +476,8 @@ static void fsl_diu_enable_panel(struct fb_info *info)
{
struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par;
struct diu_ad *ad = mfbi->ad;
- struct fsl_diu_data *machine_data = mfbi->parent;
- struct diu __iomem *hw = machine_data->diu_reg;
+ struct fsl_diu_data *data = mfbi->parent;
+ struct diu __iomem *hw = data->diu_reg;
switch (mfbi->index) {
case PLANE0:
@@ -504,7 +485,7 @@ static void fsl_diu_enable_panel(struct fb_info *info)
wr_reg_wa(&hw->desc[0], ad->paddr);
break;
case PLANE1_AOI0:
- cmfbi = machine_data->fsl_diu_info[2]->par;
+ cmfbi = &data->mfb[2];
if (hw->desc[1] != ad->paddr) { /* AOI0 closed */
if (cmfbi->count > 0) /* AOI1 open */
ad->next_ad =
@@ -515,7 +496,7 @@ static void fsl_diu_enable_panel(struct fb_info *info)
}
break;
case PLANE2_AOI0:
- cmfbi = machine_data->fsl_diu_info[4]->par;
+ cmfbi = &data->mfb[4];
if (hw->desc[2] != ad->paddr) { /* AOI0 closed */
if (cmfbi->count > 0) /* AOI1 open */
ad->next_ad =
@@ -526,17 +507,17 @@ static void fsl_diu_enable_panel(struct fb_info *info)
}
break;
case PLANE1_AOI1:
- pmfbi = machine_data->fsl_diu_info[1]->par;
+ pmfbi = &data->mfb[1];
ad->next_ad = 0;
- if (hw->desc[1] == machine_data->dummy_ad->paddr)
+ if (hw->desc[1] == data->dummy_ad.paddr)
wr_reg_wa(&hw->desc[1], ad->paddr);
else /* AOI0 open */
pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
break;
case PLANE2_AOI1:
- pmfbi = machine_data->fsl_diu_info[3]->par;
+ pmfbi = &data->mfb[3];
ad->next_ad = 0;
- if (hw->desc[2] == machine_data->dummy_ad->paddr)
+ if (hw->desc[2] == data->dummy_ad.paddr)
wr_reg_wa(&hw->desc[2], ad->paddr);
else /* AOI0 was open */
pmfbi->ad->next_ad = cpu_to_le32(ad->paddr);
@@ -548,52 +529,52 @@ static void fsl_diu_disable_panel(struct fb_info *info)
{
struct mfb_info *pmfbi, *cmfbi, *mfbi = info->par;
struct diu_ad *ad = mfbi->ad;
- struct fsl_diu_data *machine_data = mfbi->parent;
- struct diu __iomem *hw = machine_data->diu_reg;
+ struct fsl_diu_data *data = mfbi->parent;
+ struct diu __iomem *hw = data->diu_reg;
switch (mfbi->index) {
case PLANE0:
- if (hw->desc[0] != machine_data->dummy_ad->paddr)
- wr_reg_wa(&hw->desc[0], machine_data->dummy_ad->paddr);
+ if (hw->desc[0] != data->dummy_ad.paddr)
+ wr_reg_wa(&hw->desc[0], data->dummy_ad.paddr);
break;
case PLANE1_AOI0:
- cmfbi = machine_data->fsl_diu_info[2]->par;
+ cmfbi = &data->mfb[2];
if (cmfbi->count > 0) /* AOI1 is open */
wr_reg_wa(&hw->desc[1], cmfbi->ad->paddr);
/* move AOI1 to the first */
else /* AOI1 was closed */
- wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr);
+ wr_reg_wa(&hw->desc[1], data->dummy_ad.paddr);
/* close AOI 0 */
break;
case PLANE2_AOI0:
- cmfbi = machine_data->fsl_diu_info[4]->par;
+ cmfbi = &data->mfb[4];
if (cmfbi->count > 0) /* AOI1 is open */
wr_reg_wa(&hw->desc[2], cmfbi->ad->paddr);
/* move AOI1 to the first */
else /* AOI1 was closed */
- wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr);
+ wr_reg_wa(&hw->desc[2], data->dummy_ad.paddr);
/* close AOI 0 */
break;
case PLANE1_AOI1:
- pmfbi = machine_data->fsl_diu_info[1]->par;
+ pmfbi = &data->mfb[1];
if (hw->desc[1] != ad->paddr) {
/* AOI1 is not the first in the chain */
if (pmfbi->count > 0)
/* AOI0 is open, must be the first */
pmfbi->ad->next_ad = 0;
} else /* AOI1 is the first in the chain */
- wr_reg_wa(&hw->desc[1], machine_data->dummy_ad->paddr);
+ wr_reg_wa(&hw->desc[1], data->dummy_ad.paddr);
/* close AOI 1 */
break;
case PLANE2_AOI1:
- pmfbi = machine_data->fsl_diu_info[3]->par;
+ pmfbi = &data->mfb[3];
if (hw->desc[2] != ad->paddr) {
/* AOI1 is not the first in the chain */
if (pmfbi->count > 0)
/* AOI0 is open, must be the first */
pmfbi->ad->next_ad = 0;
} else /* AOI1 is the first in the chain */
- wr_reg_wa(&hw->desc[2], machine_data->dummy_ad->paddr);
+ wr_reg_wa(&hw->desc[2], data->dummy_ad.paddr);
/* close AOI 1 */
break;
}
@@ -602,39 +583,33 @@ static void fsl_diu_disable_panel(struct fb_info *info)
static void enable_lcdc(struct fb_info *info)
{
struct mfb_info *mfbi = info->par;
- struct fsl_diu_data *machine_data = mfbi->parent;
- struct diu __iomem *hw = machine_data->diu_reg;
+ struct fsl_diu_data *data = mfbi->parent;
+ struct diu __iomem *hw = data->diu_reg;
- if (!machine_data->fb_enabled) {
- out_be32(&hw->diu_mode, MFB_MODE1);
- machine_data->fb_enabled++;
- }
+ out_be32(&hw->diu_mode, MFB_MODE1);
}
static void disable_lcdc(struct fb_info *info)
{
struct mfb_info *mfbi = info->par;
- struct fsl_diu_data *machine_data = mfbi->parent;
- struct diu __iomem *hw = machine_data->diu_reg;
+ struct fsl_diu_data *data = mfbi->parent;
+ struct diu __iomem *hw = data->diu_reg;
- if (machine_data->fb_enabled) {
- out_be32(&hw->diu_mode, 0);
- machine_data->fb_enabled = 0;
- }
+ out_be32(&hw->diu_mode, 0);
}
static void adjust_aoi_size_position(struct fb_var_screeninfo *var,
struct fb_info *info)
{
struct mfb_info *lower_aoi_mfbi, *upper_aoi_mfbi, *mfbi = info->par;
- struct fsl_diu_data *machine_data = mfbi->parent;
+ struct fsl_diu_data *data = mfbi->parent;
int available_height, upper_aoi_bottom;
enum mfb_index index = mfbi->index;
int lower_aoi_is_open, upper_aoi_is_open;
__u32 base_plane_width, base_plane_height, upper_aoi_height;
- base_plane_width = machine_data->fsl_diu_info[0]->var.xres;
- base_plane_height = machine_data->fsl_diu_info[0]->var.yres;
+ base_plane_width = data->fsl_diu_info[0].var.xres;
+ base_plane_height = data->fsl_diu_info[0].var.yres;
if (mfbi->x_aoi_d < 0)
mfbi->x_aoi_d = 0;
@@ -649,7 +624,7 @@ static void adjust_aoi_size_position(struct fb_var_screeninfo *var,
break;
case PLANE1_AOI0:
case PLANE2_AOI0:
- lower_aoi_mfbi = machine_data->fsl_diu_info[index+1]->par;
+ lower_aoi_mfbi = data->fsl_diu_info[index+1].par;
lower_aoi_is_open = lower_aoi_mfbi->count > 0 ? 1 : 0;
if (var->xres > base_plane_width)
var->xres = base_plane_width;
@@ -667,9 +642,8 @@ static void adjust_aoi_size_position(struct fb_var_screeninfo *var,
break;
case PLANE1_AOI1:
case PLANE2_AOI1:
- upper_aoi_mfbi = machine_data->fsl_diu_info[index-1]->par;
- upper_aoi_height =
- machine_data->fsl_diu_info[index-1]->var.yres;
+ upper_aoi_mfbi = data->fsl_diu_info[index-1].par;
+ upper_aoi_height = data->fsl_diu_info[index-1].var.yres;
upper_aoi_bottom = upper_aoi_mfbi->y_aoi_d + upper_aoi_height;
upper_aoi_is_open = upper_aoi_mfbi->count > 0 ? 1 : 0;
if (var->xres > base_plane_width)
@@ -809,33 +783,33 @@ static void update_lcdc(struct fb_info *info)
{
struct fb_var_screeninfo *var = &info->var;
struct mfb_info *mfbi = info->par;
- struct fsl_diu_data *machine_data = mfbi->parent;
+ struct fsl_diu_data *data = mfbi->parent;
struct diu __iomem *hw;
int i, j;
- char __iomem *cursor_base, *gamma_table_base;
+ u8 *gamma_table_base;
u32 temp;
- hw = machine_data->diu_reg;
+ hw = data->diu_reg;
+
+ diu_ops.set_monitor_port(data->monitor_port);
+ gamma_table_base = data->gamma;
- diu_ops.set_monitor_port(machine_data->monitor_port);
- gamma_table_base = machine_data->gamma.vaddr;
- cursor_base = machine_data->cursor.vaddr;
/* Prep for DIU init - gamma table, cursor table */
for (i = 0; i <= 2; i++)
for (j = 0; j <= 255; j++)
*gamma_table_base++ = j;
- diu_ops.set_gamma_table(machine_data->monitor_port,
- machine_data->gamma.vaddr);
+ if (diu_ops.set_gamma_table)
+ diu_ops.set_gamma_table(data->monitor_port, data->gamma);
disable_lcdc(info);
/* Program DIU registers */
- out_be32(&hw->gamma, machine_data->gamma.paddr);
- out_be32(&hw->cursor, machine_data->cursor.paddr);
+ out_be32(&hw->gamma, DMA_ADDR(data, gamma));
+ out_be32(&hw->cursor, DMA_ADDR(data, cursor));
out_be32(&hw->bgnd, 0x007F7F7F); /* BGND */
out_be32(&hw->bgnd_wb, 0); /* BGND_WB */
@@ -870,16 +844,17 @@ static void update_lcdc(struct fb_info *info)
static int map_video_memory(struct fb_info *info)
{
- phys_addr_t phys;
u32 smem_len = info->fix.line_length * info->var.yres_virtual;
+ void *p;
- info->screen_base = fsl_diu_alloc(smem_len, &phys);
- if (info->screen_base == NULL) {
+ p = alloc_pages_exact(smem_len, GFP_DMA | __GFP_ZERO);
+ if (!p) {
dev_err(info->dev, "unable to allocate fb memory\n");
return -ENOMEM;
}
mutex_lock(&info->mm_lock);
- info->fix.smem_start = (unsigned long) phys;
+ info->screen_base = p;
+ info->fix.smem_start = virt_to_phys(info->screen_base);
info->fix.smem_len = smem_len;
mutex_unlock(&info->mm_lock);
info->screen_size = info->fix.smem_len;
@@ -889,12 +864,17 @@ static int map_video_memory(struct fb_info *info)
static void unmap_video_memory(struct fb_info *info)
{
- fsl_diu_free(info->screen_base, info->fix.smem_len);
+ void *p = info->screen_base;
+ size_t l = info->fix.smem_len;
+
mutex_lock(&info->mm_lock);
info->screen_base = NULL;
info->fix.smem_start = 0;
info->fix.smem_len = 0;
mutex_unlock(&info->mm_lock);
+
+ if (p)
+ free_pages_exact(p, l);
}
/*
@@ -913,6 +893,59 @@ static int fsl_diu_set_aoi(struct fb_info *info)
return 0;
}
+/**
+ * fsl_diu_get_pixel_format: return the pixel format for a given color depth
+ *
+ * The pixel format is a 32-bit value that determine which bits in each
+ * pixel are to be used for each color. This is the default function used
+ * if the platform does not define its own version.
+ */
+static u32 fsl_diu_get_pixel_format(unsigned int bits_per_pixel)
+{
+#define PF_BYTE_F 0x10000000
+#define PF_ALPHA_C_MASK 0x0E000000
+#define PF_ALPHA_C_SHIFT 25
+#define PF_BLUE_C_MASK 0x01800000
+#define PF_BLUE_C_SHIFT 23
+#define PF_GREEN_C_MASK 0x00600000
+#define PF_GREEN_C_SHIFT 21
+#define PF_RED_C_MASK 0x00180000
+#define PF_RED_C_SHIFT 19
+#define PF_PALETTE 0x00040000
+#define PF_PIXEL_S_MASK 0x00030000
+#define PF_PIXEL_S_SHIFT 16
+#define PF_COMP_3_MASK 0x0000F000
+#define PF_COMP_3_SHIFT 12
+#define PF_COMP_2_MASK 0x00000F00
+#define PF_COMP_2_SHIFT 8
+#define PF_COMP_1_MASK 0x000000F0
+#define PF_COMP_1_SHIFT 4
+#define PF_COMP_0_MASK 0x0000000F
+#define PF_COMP_0_SHIFT 0
+
+#define MAKE_PF(alpha, red, blue, green, size, c0, c1, c2, c3) \
+ cpu_to_le32(PF_BYTE_F | (alpha << PF_ALPHA_C_SHIFT) | \
+ (blue << PF_BLUE_C_SHIFT) | (green << PF_GREEN_C_SHIFT) | \
+ (red << PF_RED_C_SHIFT) | (c3 << PF_COMP_3_SHIFT) | \
+ (c2 << PF_COMP_2_SHIFT) | (c1 << PF_COMP_1_SHIFT) | \
+ (c0 << PF_COMP_0_SHIFT) | (size << PF_PIXEL_S_SHIFT))
+
+ switch (bits_per_pixel) {
+ case 32:
+ /* 0x88883316 */
+ return MAKE_PF(3, 2, 0, 1, 3, 8, 8, 8, 8);
+ case 24:
+ /* 0x88082219 */
+ return MAKE_PF(4, 0, 1, 2, 2, 0, 8, 8, 8);
+ case 16:
+ /* 0x65053118 */
+ return MAKE_PF(4, 2, 1, 0, 1, 5, 6, 5, 0);
+ default:
+ pr_err("fsl-diu: unsupported color depth %u\n", bits_per_pixel);
+ return 0;
+ }
+}
+
/*
* Using the fb_var_screeninfo in fb_info we set the resolution of this
* particular framebuffer. This function alters the fb_fix_screeninfo stored
@@ -926,11 +959,11 @@ static int fsl_diu_set_par(struct fb_info *info)
unsigned long len;
struct fb_var_screeninfo *var = &info->var;
struct mfb_info *mfbi = info->par;
- struct fsl_diu_data *machine_data = mfbi->parent;
+ struct fsl_diu_data *data = mfbi->parent;
struct diu_ad *ad = mfbi->ad;
struct diu __iomem *hw;
- hw = machine_data->diu_reg;
+ hw = data->diu_reg;
set_fix(info);
mfbi->cursor_reset = 1;
@@ -948,8 +981,12 @@ static int fsl_diu_set_par(struct fb_info *info)
}
}
- ad->pix_fmt = diu_ops.get_pixel_format(machine_data->monitor_port,
- var->bits_per_pixel);
+ if (diu_ops.get_pixel_format)
+ ad->pix_fmt = diu_ops.get_pixel_format(data->monitor_port,
+ var->bits_per_pixel);
+ else
+ ad->pix_fmt = fsl_diu_get_pixel_format(var->bits_per_pixel);
+
ad->addr = cpu_to_le32(info->fix.smem_start);
ad->src_size_g_alpha = cpu_to_le32((var->yres_virtual << 12) |
var->xres_virtual) | mfbi->g_alpha;
@@ -1208,21 +1245,6 @@ static struct fb_ops fsl_diu_ops = {
.fb_release = fsl_diu_release,
};
-static int init_fbinfo(struct fb_info *info)
-{
- struct mfb_info *mfbi = info->par;
-
- info->device = NULL;
- info->var.activate = FB_ACTIVATE_NOW;
- info->fbops = &fsl_diu_ops;
- info->flags = FBINFO_FLAG_DEFAULT;
- info->pseudo_palette = &mfbi->pseudo_palette;
-
- /* Allocate colormap */
- fb_alloc_cmap(&info->cmap, 16, 0);
- return 0;
-}
-
static int __devinit install_fb(struct fb_info *info)
{
int rc;
@@ -1232,8 +1254,15 @@ static int __devinit install_fb(struct fb_info *info)
unsigned int dbsize = ARRAY_SIZE(fsl_diu_mode_db);
int has_default_mode = 1;
- if (init_fbinfo(info))
- return -EINVAL;
+ info->var.activate = FB_ACTIVATE_NOW;
+ info->fbops = &fsl_diu_ops;
+ info->flags = FBINFO_DEFAULT | FBINFO_VIRTFB | FBINFO_PARTIAL_PAN_OK |
+ FBINFO_READS_FAST;
+ info->pseudo_palette = mfbi->pseudo_palette;
+
+ rc = fb_alloc_cmap(&info->cmap, 16, 0);
+ if (rc)
+ return rc;
if (mfbi->index == PLANE0) {
if (mfbi->edid_data) {
@@ -1359,16 +1388,16 @@ static irqreturn_t fsl_diu_isr(int irq, void *dev_id)
return IRQ_NONE;
}
-static int request_irq_local(struct fsl_diu_data *machine_data)
+static int request_irq_local(struct fsl_diu_data *data)
{
- struct diu __iomem *hw = machine_data->diu_reg;
+ struct diu __iomem *hw = data->diu_reg;
u32 ints;
int ret;
/* Read to clear the status */
in_be32(&hw->int_status);
- ret = request_irq(machine_data->irq, fsl_diu_isr, 0, "fsl-diu-fb", hw);
+ ret = request_irq(data->irq, fsl_diu_isr, 0, "fsl-diu-fb", hw);
if (!ret) {
ints = INT_PARERR | INT_LS_BF_VS;
#if !defined(CONFIG_NOT_COHERENT_CACHE)
@@ -1383,14 +1412,14 @@ static int request_irq_local(struct fsl_diu_data *machine_data)
return ret;
}
-static void free_irq_local(struct fsl_diu_data *machine_data)
+static void free_irq_local(struct fsl_diu_data *data)
{
- struct diu __iomem *hw = machine_data->diu_reg;
+ struct diu __iomem *hw = data->diu_reg;
/* Disable all LCDC interrupt */
out_be32(&hw->int_mask, 0x1f);
- free_irq(machine_data->irq, NULL);
+ free_irq(data->irq, NULL);
}
#ifdef CONFIG_PM
@@ -1400,20 +1429,20 @@ static void free_irq_local(struct fsl_diu_data *machine_data)
*/
static int fsl_diu_suspend(struct platform_device *ofdev, pm_message_t state)
{
- struct fsl_diu_data *machine_data;
+ struct fsl_diu_data *data;
- machine_data = dev_get_drvdata(&ofdev->dev);
- disable_lcdc(machine_data->fsl_diu_info[0]);
+ data = dev_get_drvdata(&ofdev->dev);
+ disable_lcdc(data->fsl_diu_info[0]);
return 0;
}
static int fsl_diu_resume(struct platform_device *ofdev)
{
- struct fsl_diu_data *machine_data;
+ struct fsl_diu_data *data;
- machine_data = dev_get_drvdata(&ofdev->dev);
- enable_lcdc(machine_data->fsl_diu_info[0]);
+ data = dev_get_drvdata(&ofdev->dev);
+ enable_lcdc(data->fsl_diu_info[0]);
return 0;
}
@@ -1423,56 +1452,24 @@ static int fsl_diu_resume(struct platform_device *ofdev)
#define fsl_diu_resume NULL
#endif /* CONFIG_PM */
-/* Align to 64-bit(8-byte), 32-byte, etc. */
-static int allocate_buf(struct device *dev, struct diu_addr *buf, u32 size,
- u32 bytes_align)
-{
- u32 offset;
- dma_addr_t mask;
-
- buf->vaddr =
- dma_alloc_coherent(dev, size + bytes_align, &buf->paddr,
- GFP_DMA | __GFP_ZERO);
- if (!buf->vaddr)
- return -ENOMEM;
-
- mask = bytes_align - 1;
- offset = buf->paddr & mask;
- if (offset) {
- buf->offset = bytes_align - offset;
- buf->paddr = buf->paddr + offset;
- } else
- buf->offset = 0;
-
- return 0;
-}
-
-static void free_buf(struct device *dev, struct diu_addr *buf, u32 size,
- u32 bytes_align)
-{
- dma_free_coherent(dev, size + bytes_align, buf->vaddr,
- buf->paddr - buf->offset);
-}
-
static ssize_t store_monitor(struct device *device,
struct device_attribute *attr, const char *buf, size_t count)
{
enum fsl_diu_monitor_port old_monitor_port;
- struct fsl_diu_data *machine_data =
+ struct fsl_diu_data *data =
container_of(attr, struct fsl_diu_data, dev_attr);
- old_monitor_port = machine_data->monitor_port;
- machine_data->monitor_port = fsl_diu_name_to_port(buf);
+ old_monitor_port = data->monitor_port;
+ data->monitor_port = fsl_diu_name_to_port(buf);
- if (old_monitor_port != machine_data->monitor_port) {
+ if (old_monitor_port != data->monitor_port) {
/* All AOIs need adjust pixel format
* fsl_diu_set_par only change the pixsel format here
* unlikely to fail. */
- fsl_diu_set_par(machine_data->fsl_diu_info[0]);
- fsl_diu_set_par(machine_data->fsl_diu_info[1]);
- fsl_diu_set_par(machine_data->fsl_diu_info[2]);
- fsl_diu_set_par(machine_data->fsl_diu_info[3]);
- fsl_diu_set_par(machine_data->fsl_diu_info[4]);
+ unsigned int i;
+
+ for (i=0; i < NUM_AOIS; i++)
+ fsl_diu_set_par(&data->fsl_diu_info[i]);
}
return count;
}
@@ -1480,10 +1477,10 @@ static ssize_t store_monitor(struct device *device,
static ssize_t show_monitor(struct device *device,
struct device_attribute *attr, char *buf)
{
- struct fsl_diu_data *machine_data =
+ struct fsl_diu_data *data =
container_of(attr, struct fsl_diu_data, dev_attr);
- switch (machine_data->monitor_port) {
+ switch (data->monitor_port) {
case FSL_DIU_PORT_DVI:
return sprintf(buf, "DVI\n");
case FSL_DIU_PORT_LVDS:
@@ -1499,28 +1496,52 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct mfb_info *mfbi;
- phys_addr_t dummy_ad_addr = 0;
- int ret, i, error = 0;
- struct fsl_diu_data *machine_data;
+ struct fsl_diu_data *data;
int diu_mode;
+ dma_addr_t dma_addr; /* DMA addr of fsl_diu_data struct */
+ unsigned int i;
+ int ret;
- machine_data = kzalloc(sizeof(struct fsl_diu_data), GFP_KERNEL);
- if (!machine_data)
+ data = dma_alloc_coherent(&pdev->dev, sizeof(struct fsl_diu_data),
+ &dma_addr, GFP_DMA | __GFP_ZERO);
+ if (!data)
return -ENOMEM;
+ data->dma_addr = dma_addr;
+
+ /*
+ * dma_alloc_coherent() uses a page allocator, so the address is
+ * always page-aligned. We need the memory to be 32-byte aligned,
+ * so that's good. However, if one day the allocator changes, we
+ * need to catch that. It's not worth the effort to handle unaligned
+ * alloctions now because it's highly unlikely to ever be a problem.
+ */
+ if ((unsigned long)data & 31) {
+ dev_err(&pdev->dev, "misaligned allocation");
+ ret = -ENOMEM;
+ goto error;
+ }
- spin_lock_init(&machine_data->reg_lock);
+ spin_lock_init(&data->reg_lock);
- for (i = 0; i < ARRAY_SIZE(machine_data->fsl_diu_info); i++) {
- machine_data->fsl_diu_info[i] =
- framebuffer_alloc(sizeof(struct mfb_info), &pdev->dev);
- if (!machine_data->fsl_diu_info[i]) {
- dev_err(&pdev->dev, "cannot allocate memory\n");
- ret = -ENOMEM;
- goto error2;
- }
- mfbi = machine_data->fsl_diu_info[i]->par;
+ for (i = 0; i < NUM_AOIS; i++) {
+ struct fb_info *info = &data->fsl_diu_info[i];
+
+ info->device = &pdev->dev;
+ info->par = &data->mfb[i];
+
+ /*
+ * We store the physical address of the AD in the reserved
+ * 'paddr' field of the AD itself.
+ */
+ data->ad[i].paddr = DMA_ADDR(data, ad[i]);
+
+ info->fix.smem_start = 0;
+
+ /* Initialize the AOI data structure */
+ mfbi = info->par;
memcpy(mfbi, &mfb_template[i], sizeof(struct mfb_info));
- mfbi->parent = machine_data;
+ mfbi->parent = data;
+ mfbi->ad = &data->ad[i];
if (mfbi->index == PLANE0) {
const u8 *prop;
@@ -1534,158 +1555,102 @@ static int __devinit fsl_diu_probe(struct platform_device *pdev)
}
}
- machine_data->diu_reg = of_iomap(np, 0);
- if (!machine_data->diu_reg) {
+ data->diu_reg = of_iomap(np, 0);
+ if (!data->diu_reg) {
dev_err(&pdev->dev, "cannot map DIU registers\n");
ret = -EFAULT;
- goto error2;
+ goto error;
}
- diu_mode = in_be32(&machine_data->diu_reg->diu_mode);
+ diu_mode = in_be32(&data->diu_reg->diu_mode);
if (diu_mode == MFB_MODE0)
- out_be32(&machine_data->diu_reg->diu_mode, 0); /* disable DIU */
+ out_be32(&data->diu_reg->diu_mode, 0); /* disable DIU */
/* Get the IRQ of the DIU */
- machine_data->irq = irq_of_parse_and_map(np, 0);
+ data->irq = irq_of_parse_and_map(np, 0);
- if (!machine_data->irq) {
+ if (!data->irq) {
dev_err(&pdev->dev, "could not get DIU IRQ\n");
ret = -EINVAL;
goto error;
}
- machine_data->monitor_port = monitor_port;
-
- /* Area descriptor memory pool aligns to 64-bit boundary */
- if (allocate_buf(&pdev->dev, &machine_data->ad,
- sizeof(struct diu_ad) * FSL_AOI_NUM, 8))
- return -ENOMEM;
-
- /* Get memory for Gamma Table - 32-byte aligned memory */
- if (allocate_buf(&pdev->dev, &machine_data->gamma, 768, 32)) {
- ret = -ENOMEM;
- goto error;
- }
-
- /* For performance, cursor bitmap buffer aligns to 32-byte boundary */
- if (allocate_buf(&pdev->dev, &machine_data->cursor,
- MAX_CURS * MAX_CURS * 2, 32)) {
- ret = -ENOMEM;
- goto error;
- }
-
- i = ARRAY_SIZE(machine_data->fsl_diu_info);
- machine_data->dummy_ad = (struct diu_ad *)((u32)machine_data->ad.vaddr +
- machine_data->ad.offset) + i;
- machine_data->dummy_ad->paddr = machine_data->ad.paddr +
- i * sizeof(struct diu_ad);
- machine_data->dummy_aoi_virt = fsl_diu_alloc(64, &dummy_ad_addr);
- if (!machine_data->dummy_aoi_virt) {
- ret = -ENOMEM;
- goto error;
- }
- machine_data->dummy_ad->addr = cpu_to_le32(dummy_ad_addr);
- machine_data->dummy_ad->pix_fmt = 0x88882317;
- machine_data->dummy_ad->src_size_g_alpha = cpu_to_le32((4 << 12) | 4);
- machine_data->dummy_ad->aoi_size = cpu_to_le32((4 << 16) | 2);
- machine_data->dummy_ad->offset_xyi = 0;
- machine_data->dummy_ad->offset_xyd = 0;
- machine_data->dummy_ad->next_ad = 0;
+ data->monitor_port = monitor_port;
+
+ /* Initialize the dummy Area Descriptor */
+ data->dummy_ad.addr = cpu_to_le32(DMA_ADDR(data, dummy_aoi));
+ data->dummy_ad.pix_fmt = 0x88882317;
+ data->dummy_ad.src_size_g_alpha = cpu_to_le32((4 << 12) | 4);
+ data->dummy_ad.aoi_size = cpu_to_le32((4 << 16) | 2);
+ data->dummy_ad.offset_xyi = 0;
+ data->dummy_ad.offset_xyd = 0;
+ data->dummy_ad.next_ad = 0;
+ data->dummy_ad.paddr = DMA_ADDR(data, dummy_ad);
/*
* Let DIU display splash screen if it was pre-initialized
* by the bootloader, set dummy area descriptor otherwise.
*/
if (diu_mode == MFB_MODE0)
- out_be32(&machine_data->diu_reg->desc[0],
- machine_data->dummy_ad->paddr);
-
- out_be32(&machine_data->diu_reg->desc[1], machine_data->dummy_ad->paddr);
- out_be32(&machine_data->diu_reg->desc[2], machine_data->dummy_ad->paddr);
-
- for (i = 0; i < ARRAY_SIZE(machine_data->fsl_diu_info); i++) {
- machine_data->fsl_diu_info[i]->fix.smem_start = 0;
- mfbi = machine_data->fsl_diu_info[i]->par;
- mfbi->ad = (struct diu_ad *)((u32)machine_data->ad.vaddr
- + machine_data->ad.offset) + i;
- mfbi->ad->paddr =
- machine_data->ad.paddr + i * sizeof(struct diu_ad);
- ret = install_fb(machine_data->fsl_diu_info[i]);
+ out_be32(&data->diu_reg->desc[0], data->dummy_ad.paddr);
+
+ out_be32(&data->diu_reg->desc[1], data->dummy_ad.paddr);
+ out_be32(&data->diu_reg->desc[2], data->dummy_ad.paddr);
+
+ for (i = 0; i < NUM_AOIS; i++) {
+ ret = install_fb(&data->fsl_diu_info[i]);
if (ret) {
dev_err(&pdev->dev, "could not register fb %d\n", i);
goto error;
}
}
- if (request_irq_local(machine_data)) {
+ if (request_irq_local(data)) {
dev_err(&pdev->dev, "could not claim irq\n");
goto error;
}
- sysfs_attr_init(&machine_data->dev_attr.attr);
- machine_data->dev_attr.attr.name = "monitor";
- machine_data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
- machine_data->dev_attr.show = show_monitor;
- machine_data->dev_attr.store = store_monitor;
- error = device_create_file(machine_data->fsl_diu_info[0]->dev,
- &machine_data->dev_attr);
- if (error) {
+ sysfs_attr_init(&data->dev_attr.attr);
+ data->dev_attr.attr.name = "monitor";
+ data->dev_attr.attr.mode = S_IRUGO|S_IWUSR;
+ data->dev_attr.show = show_monitor;
+ data->dev_attr.store = store_monitor;
+ ret = device_create_file(&pdev->dev, &data->dev_attr);
+ if (ret) {
dev_err(&pdev->dev, "could not create sysfs file %s\n",
- machine_data->dev_attr.attr.name);
+ data->dev_attr.attr.name);
}
- dev_set_drvdata(&pdev->dev, machine_data);
+ dev_set_drvdata(&pdev->dev, data);
return 0;
error:
- for (i = 0; i < ARRAY_SIZE(machine_data->fsl_diu_info); i++)
- uninstall_fb(machine_data->fsl_diu_info[i]);
-
- if (machine_data->ad.vaddr)
- free_buf(&pdev->dev, &machine_data->ad,
- sizeof(struct diu_ad) * FSL_AOI_NUM, 8);
- if (machine_data->gamma.vaddr)
- free_buf(&pdev->dev, &machine_data->gamma, 768, 32);
- if (machine_data->cursor.vaddr)
- free_buf(&pdev->dev, &machine_data->cursor,
- MAX_CURS * MAX_CURS * 2, 32);
- if (machine_data->dummy_aoi_virt)
- fsl_diu_free(machine_data->dummy_aoi_virt, 64);
- iounmap(machine_data->diu_reg);
-
-error2:
- for (i = 0; i < ARRAY_SIZE(machine_data->fsl_diu_info); i++)
- if (machine_data->fsl_diu_info[i])
- framebuffer_release(machine_data->fsl_diu_info[i]);
- kfree(machine_data);
+ for (i = 0; i < NUM_AOIS; i++)
+ uninstall_fb(&data->fsl_diu_info[i]);
+
+ iounmap(data->diu_reg);
+
+ dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data,
+ data->dma_addr);
return ret;
}
static int fsl_diu_remove(struct platform_device *pdev)
{
- struct fsl_diu_data *machine_data;
+ struct fsl_diu_data *data;
int i;
- machine_data = dev_get_drvdata(&pdev->dev);
- disable_lcdc(machine_data->fsl_diu_info[0]);
- free_irq_local(machine_data);
- for (i = 0; i < ARRAY_SIZE(machine_data->fsl_diu_info); i++)
- uninstall_fb(machine_data->fsl_diu_info[i]);
- if (machine_data->ad.vaddr)
- free_buf(&pdev->dev, &machine_data->ad,
- sizeof(struct diu_ad) * FSL_AOI_NUM, 8);
- if (machine_data->gamma.vaddr)
- free_buf(&pdev->dev, &machine_data->gamma, 768, 32);
- if (machine_data->cursor.vaddr)
- free_buf(&pdev->dev, &machine_data->cursor,
- MAX_CURS * MAX_CURS * 2, 32);
- if (machine_data->dummy_aoi_virt)
- fsl_diu_free(machine_data->dummy_aoi_virt, 64);
- iounmap(machine_data->diu_reg);
- for (i = 0; i < ARRAY_SIZE(machine_data->fsl_diu_info); i++)
- if (machine_data->fsl_diu_info[i])
- framebuffer_release(machine_data->fsl_diu_info[i]);
- kfree(machine_data);
+ data = dev_get_drvdata(&pdev->dev);
+ disable_lcdc(&data->fsl_diu_info[0]);
+ free_irq_local(data);
+
+ for (i = 0; i < NUM_AOIS; i++)
+ uninstall_fb(&data->fsl_diu_info[i]);
+
+ iounmap(data->diu_reg);
+
+ dma_free_coherent(&pdev->dev, sizeof(struct fsl_diu_data), data,
+ data->dma_addr);
return 0;
}
diff --git a/drivers/video/grvga.c b/drivers/video/grvga.c
index f37e02538203..da066c210923 100644
--- a/drivers/video/grvga.c
+++ b/drivers/video/grvga.c
@@ -70,7 +70,7 @@ static const struct fb_videomode grvga_modedb[] = {
}
};
-static struct fb_fix_screeninfo grvga_fix __initdata = {
+static struct fb_fix_screeninfo grvga_fix __devinitdata = {
.id = "AG SVGACTRL",
.type = FB_TYPE_PACKED_PIXELS,
.visual = FB_VISUAL_PSEUDOCOLOR,
@@ -267,7 +267,7 @@ static struct fb_ops grvga_ops = {
.fb_imageblit = cfb_imageblit
};
-static int __init grvga_parse_custom(char *options,
+static int __devinit grvga_parse_custom(char *options,
struct fb_var_screeninfo *screendata)
{
char *this_opt;
diff --git a/drivers/video/hgafb.c b/drivers/video/hgafb.c
index 4394389caf68..c645f9282650 100644
--- a/drivers/video/hgafb.c
+++ b/drivers/video/hgafb.c
@@ -133,7 +133,7 @@ static struct fb_fix_screeninfo hga_fix __devinitdata = {
/* Don't assume that tty1 will be the initial current console. */
static int release_io_port = 0;
static int release_io_ports = 0;
-static int nologo = 0;
+static bool nologo = 0;
/* -------------------------------------------------------------------------
*
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c
index 318f6fb895b2..b83f36190cae 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/i810/i810_main.c
@@ -135,8 +135,8 @@ static struct pci_driver i810fb_driver = {
static char *mode_option __devinitdata = NULL;
static int vram __devinitdata = 4;
static int bpp __devinitdata = 8;
-static int mtrr __devinitdata;
-static int accel __devinitdata;
+static bool mtrr __devinitdata;
+static bool accel __devinitdata;
static int hsync1 __devinitdata;
static int hsync2 __devinitdata;
static int vsync1 __devinitdata;
@@ -144,10 +144,10 @@ static int vsync2 __devinitdata;
static int xres __devinitdata;
static int yres;
static int vyres __devinitdata;
-static int sync __devinitdata;
-static int extvga __devinitdata;
-static int dcolor __devinitdata;
-static int ddc3 __devinitdata = 2;
+static bool sync __devinitdata;
+static bool extvga __devinitdata;
+static bool dcolor __devinitdata;
+static bool ddc3 __devinitdata;
/*------------------------------------------------------------*/
@@ -1776,7 +1776,7 @@ static void __devinit i810_init_defaults(struct i810fb_par *par,
if (sync)
par->dev_flags |= ALWAYS_SYNC;
- par->ddc_num = ddc3;
+ par->ddc_num = (ddc3 ? 3 : 2);
if (bpp < 8)
bpp = 8;
@@ -1999,7 +1999,7 @@ static int __devinit i810fb_setup(char *options)
else if (!strncmp(this_opt, "dcolor", 6))
dcolor = 1;
else if (!strncmp(this_opt, "ddc3", 4))
- ddc3 = 3;
+ ddc3 = true;
else
mode_option = this_opt;
}
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index 5ba399991050..c6afa33a4532 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -230,15 +230,15 @@ MODULE_DESCRIPTION("Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS
MODULE_LICENSE("Dual BSD/GPL");
MODULE_DEVICE_TABLE(pci, intelfb_pci_table);
-static int accel = 1;
+static bool accel = 1;
static int vram = 4;
-static int hwcursor = 0;
-static int mtrr = 1;
-static int fixed = 0;
-static int noinit = 0;
-static int noregister = 0;
-static int probeonly = 0;
-static int idonly = 0;
+static bool hwcursor = 0;
+static bool mtrr = 1;
+static bool fixed = 0;
+static bool noinit = 0;
+static bool noregister = 0;
+static bool probeonly = 0;
+static bool idonly = 0;
static int bailearly = 0;
static int voffset = 48;
static char *mode = NULL;
@@ -263,7 +263,7 @@ module_param(probeonly, bool, 0);
MODULE_PARM_DESC(probeonly, "Do a minimal probe (debug)");
module_param(idonly, bool, 0);
MODULE_PARM_DESC(idonly, "Just identify without doing anything else (debug)");
-module_param(bailearly, bool, 0);
+module_param(bailearly, int, 0);
MODULE_PARM_DESC(bailearly, "Bail out early, depending on value (debug)");
module_param(mode, charp, S_IRUGO);
MODULE_PARM_DESC(mode,
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index ea7a8ccc830c..080c35b34bbb 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -21,7 +21,7 @@
#include <asm/bootinfo.h>
#endif
-static int nologo;
+static bool nologo;
module_param(nologo, bool, 0);
MODULE_PARM_DESC(nologo, "Disables startup logo");
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 44bf8d4a216b..401a56e250bd 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -147,7 +147,6 @@ static struct fb_var_screeninfo vesafb_defined = {
39721L,48L,16L,33L,10L,
96L,2L,~0, /* No sync info */
FB_VMODE_NONINTERLACED,
- 0, {0,0,0,0,0}
};
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index d7112c39614b..02796a4317a9 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -593,7 +593,6 @@ static struct fb_var_screeninfo matroxfb_dh_defined = {
39721L,48L,16L,33L,10L,
96L,2,0, /* no sync info */
FB_VMODE_NONINTERLACED,
- 0, {0,0,0,0,0}
};
static int matroxfb_dh_regit(const struct matrox_fb_info *minfo,
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 6ce34160da78..55bf6196b7a0 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -1053,18 +1053,7 @@ static struct platform_driver mbxfb_driver = {
},
};
-int __devinit mbxfb_init(void)
-{
- return platform_driver_register(&mbxfb_driver);
-}
-
-static void __devexit mbxfb_exit(void)
-{
- platform_driver_unregister(&mbxfb_driver);
-}
-
-module_init(mbxfb_init);
-module_exit(mbxfb_exit);
+module_platform_driver(mbxfb_driver);
MODULE_DESCRIPTION("loadable framebuffer driver for Marathon device");
MODULE_AUTHOR("Mike Rapoport, Compulab");
diff --git a/drivers/video/mxsfb.c b/drivers/video/mxsfb.c
index eb3c5eea1a0f..4a89f889852d 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/mxsfb.c
@@ -902,18 +902,7 @@ static struct platform_driver mxsfb_driver = {
},
};
-static int __init mxsfb_init(void)
-{
- return platform_driver_register(&mxsfb_driver);
-}
-
-static void __exit mxsfb_exit(void)
-{
- platform_driver_unregister(&mxsfb_driver);
-}
-
-module_init(mxsfb_init);
-module_exit(mxsfb_exit);
+module_platform_driver(mxsfb_driver);
MODULE_DESCRIPTION("Freescale mxs framebuffer driver");
MODULE_AUTHOR("Sascha Hauer, Pengutronix");
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index feea7b1dc386..fb3f67391105 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -84,11 +84,11 @@
/* --------------------------------------------------------------------- */
-static int internal;
-static int external;
-static int libretto;
-static int nostretch;
-static int nopciburst;
+static bool internal;
+static bool external;
+static bool libretto;
+static bool nostretch;
+static bool nopciburst;
static char *mode_option __devinitdata = NULL;
#ifdef MODULE
diff --git a/drivers/video/nuc900fb.c b/drivers/video/nuc900fb.c
index d1fbbd888cf4..e10f551ade21 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/nuc900fb.c
@@ -762,18 +762,7 @@ static struct platform_driver nuc900fb_driver = {
},
};
-int __devinit nuc900fb_init(void)
-{
- return platform_driver_register(&nuc900fb_driver);
-}
-
-static void __exit nuc900fb_cleanup(void)
-{
- platform_driver_unregister(&nuc900fb_driver);
-}
-
-module_init(nuc900fb_init);
-module_exit(nuc900fb_cleanup);
+module_platform_driver(nuc900fb_driver);
MODULE_DESCRIPTION("Framebuffer driver for the NUC900");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
index 6978ae4ef83a..0fdd6f6873bf 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/omap/lcd_ams_delta.c
@@ -198,7 +198,7 @@ static int ams_delta_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver ams_delta_panel_driver = {
+static struct platform_driver ams_delta_panel_driver = {
.probe = ams_delta_panel_probe,
.remove = ams_delta_panel_remove,
.suspend = ams_delta_panel_suspend,
@@ -209,15 +209,4 @@ struct platform_driver ams_delta_panel_driver = {
},
};
-static int __init ams_delta_panel_drv_init(void)
-{
- return platform_driver_register(&ams_delta_panel_driver);
-}
-
-static void __exit ams_delta_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&ams_delta_panel_driver);
-}
-
-module_init(ams_delta_panel_drv_init);
-module_exit(ams_delta_panel_drv_cleanup);
+module_platform_driver(ams_delta_panel_driver);
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c
index 622ad839fd9d..49bdeca81e50 100644
--- a/drivers/video/omap/lcd_h3.c
+++ b/drivers/video/omap/lcd_h3.c
@@ -113,7 +113,7 @@ static int h3_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver h3_panel_driver = {
+static struct platform_driver h3_panel_driver = {
.probe = h3_panel_probe,
.remove = h3_panel_remove,
.suspend = h3_panel_suspend,
@@ -124,16 +124,4 @@ struct platform_driver h3_panel_driver = {
},
};
-static int __init h3_panel_drv_init(void)
-{
- return platform_driver_register(&h3_panel_driver);
-}
-
-static void __exit h3_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&h3_panel_driver);
-}
-
-module_init(h3_panel_drv_init);
-module_exit(h3_panel_drv_cleanup);
-
+module_platform_driver(h3_panel_driver);
diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/omap/lcd_htcherald.c
index 4802419da83b..20f477851d54 100644
--- a/drivers/video/omap/lcd_htcherald.c
+++ b/drivers/video/omap/lcd_htcherald.c
@@ -104,7 +104,7 @@ static int htcherald_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver htcherald_panel_driver = {
+static struct platform_driver htcherald_panel_driver = {
.probe = htcherald_panel_probe,
.remove = htcherald_panel_remove,
.suspend = htcherald_panel_suspend,
@@ -115,16 +115,4 @@ struct platform_driver htcherald_panel_driver = {
},
};
-static int __init htcherald_panel_drv_init(void)
-{
- return platform_driver_register(&htcherald_panel_driver);
-}
-
-static void __exit htcherald_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&htcherald_panel_driver);
-}
-
-module_init(htcherald_panel_drv_init);
-module_exit(htcherald_panel_drv_cleanup);
-
+module_platform_driver(htcherald_panel_driver);
diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c
index 3271f1643b26..b38b1dd15ce3 100644
--- a/drivers/video/omap/lcd_inn1510.c
+++ b/drivers/video/omap/lcd_inn1510.c
@@ -98,7 +98,7 @@ static int innovator1510_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver innovator1510_panel_driver = {
+static struct platform_driver innovator1510_panel_driver = {
.probe = innovator1510_panel_probe,
.remove = innovator1510_panel_remove,
.suspend = innovator1510_panel_suspend,
@@ -109,16 +109,4 @@ struct platform_driver innovator1510_panel_driver = {
},
};
-static int __init innovator1510_panel_drv_init(void)
-{
- return platform_driver_register(&innovator1510_panel_driver);
-}
-
-static void __exit innovator1510_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&innovator1510_panel_driver);
-}
-
-module_init(innovator1510_panel_drv_init);
-module_exit(innovator1510_panel_drv_cleanup);
-
+module_platform_driver(innovator1510_panel_driver);
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
index 12cc52a70f96..7e8bd8e08a98 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/omap/lcd_inn1610.c
@@ -122,7 +122,7 @@ static int innovator1610_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver innovator1610_panel_driver = {
+static struct platform_driver innovator1610_panel_driver = {
.probe = innovator1610_panel_probe,
.remove = innovator1610_panel_remove,
.suspend = innovator1610_panel_suspend,
@@ -133,16 +133,4 @@ struct platform_driver innovator1610_panel_driver = {
},
};
-static int __init innovator1610_panel_drv_init(void)
-{
- return platform_driver_register(&innovator1610_panel_driver);
-}
-
-static void __exit innovator1610_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&innovator1610_panel_driver);
-}
-
-module_init(innovator1610_panel_drv_init);
-module_exit(innovator1610_panel_drv_cleanup);
-
+module_platform_driver(innovator1610_panel_driver);
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
index eb381db7fe51..8d546dd55e81 100644
--- a/drivers/video/omap/lcd_mipid.c
+++ b/drivers/video/omap/lcd_mipid.c
@@ -603,7 +603,6 @@ static int mipid_spi_remove(struct spi_device *spi)
static struct spi_driver mipid_spi_driver = {
.driver = {
.name = MIPID_MODULE_NAME,
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = mipid_spi_probe,
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
index 6f8d13c41202..5914220dfa9c 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/omap/lcd_osk.c
@@ -116,7 +116,7 @@ static int osk_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver osk_panel_driver = {
+static struct platform_driver osk_panel_driver = {
.probe = osk_panel_probe,
.remove = osk_panel_remove,
.suspend = osk_panel_suspend,
@@ -127,16 +127,4 @@ struct platform_driver osk_panel_driver = {
},
};
-static int __init osk_panel_drv_init(void)
-{
- return platform_driver_register(&osk_panel_driver);
-}
-
-static void __exit osk_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&osk_panel_driver);
-}
-
-module_init(osk_panel_drv_init);
-module_exit(osk_panel_drv_cleanup);
-
+module_platform_driver(osk_panel_driver);
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
index 4cb301750d02..88c31eb0cd6c 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/omap/lcd_palmte.c
@@ -97,7 +97,7 @@ static int palmte_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver palmte_panel_driver = {
+static struct platform_driver palmte_panel_driver = {
.probe = palmte_panel_probe,
.remove = palmte_panel_remove,
.suspend = palmte_panel_suspend,
@@ -108,16 +108,4 @@ struct platform_driver palmte_panel_driver = {
},
};
-static int __init palmte_panel_drv_init(void)
-{
- return platform_driver_register(&palmte_panel_driver);
-}
-
-static void __exit palmte_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&palmte_panel_driver);
-}
-
-module_init(palmte_panel_drv_init);
-module_exit(palmte_panel_drv_cleanup);
-
+module_platform_driver(palmte_panel_driver);
diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c
index b51b332e5a2b..aaf3c8ba1243 100644
--- a/drivers/video/omap/lcd_palmtt.c
+++ b/drivers/video/omap/lcd_palmtt.c
@@ -102,7 +102,7 @@ static int palmtt_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver palmtt_panel_driver = {
+static struct platform_driver palmtt_panel_driver = {
.probe = palmtt_panel_probe,
.remove = palmtt_panel_remove,
.suspend = palmtt_panel_suspend,
@@ -113,15 +113,4 @@ struct platform_driver palmtt_panel_driver = {
},
};
-static int __init palmtt_panel_drv_init(void)
-{
- return platform_driver_register(&palmtt_panel_driver);
-}
-
-static void __exit palmtt_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&palmtt_panel_driver);
-}
-
-module_init(palmtt_panel_drv_init);
-module_exit(palmtt_panel_drv_cleanup);
+module_platform_driver(palmtt_panel_driver);
diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c
index 2334e56536bc..3b7d8aa1cf34 100644
--- a/drivers/video/omap/lcd_palmz71.c
+++ b/drivers/video/omap/lcd_palmz71.c
@@ -98,7 +98,7 @@ static int palmz71_panel_resume(struct platform_device *pdev)
return 0;
}
-struct platform_driver palmz71_panel_driver = {
+static struct platform_driver palmz71_panel_driver = {
.probe = palmz71_panel_probe,
.remove = palmz71_panel_remove,
.suspend = palmz71_panel_suspend,
@@ -109,15 +109,4 @@ struct platform_driver palmz71_panel_driver = {
},
};
-static int __init palmz71_panel_drv_init(void)
-{
- return platform_driver_register(&palmz71_panel_driver);
-}
-
-static void __exit palmz71_panel_drv_cleanup(void)
-{
- platform_driver_unregister(&palmz71_panel_driver);
-}
-
-module_init(palmz71_panel_drv_init);
-module_exit(palmz71_panel_drv_cleanup);
+module_platform_driver(palmz71_panel_driver);
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
index 25d8e5103193..b291bfaac80e 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/omap/omapfb_main.c
@@ -47,9 +47,9 @@ static unsigned int def_rotate;
static unsigned int def_mirror;
#ifdef CONFIG_FB_OMAP_MANUAL_UPDATE
-static int manual_update = 1;
+static bool manual_update = 1;
#else
-static int manual_update;
+static bool manual_update;
#endif
static struct platform_device *fbdev_pdev;
diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
index 8d8e1fe1901c..74d29b552901 100644
--- a/drivers/video/omap2/displays/Kconfig
+++ b/drivers/video/omap2/displays/Kconfig
@@ -41,7 +41,7 @@ config PANEL_NEC_NL8048HL11_01B
config PANEL_PICODLP
tristate "TI PICO DLP mini-projector"
- depends on OMAP2_DSS && I2C
+ depends on OMAP2_DSS_DPI && I2C
help
A mini-projector used in TI's SDP4430 and EVM boards
For more info please visit http://www.dlp.com/projector/
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index dbd59b8e5b36..51a87e149e24 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -803,7 +803,6 @@ static int acx565akm_spi_remove(struct spi_device *spi)
static struct spi_driver acx565akm_spi_driver = {
.driver = {
.name = "acx565akm",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = acx565akm_spi_probe,
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index 519c47d2057f..28b9a6d61b0f 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -297,6 +297,72 @@ static struct panel_config generic_dpi_panels[] = {
.name = "apollon",
},
+ /* FocalTech ETM070003DH6 */
+ {
+ {
+ .x_res = 800,
+ .y_res = 480,
+
+ .pixel_clock = 28000,
+
+ .hsw = 48,
+ .hfp = 40,
+ .hbp = 40,
+
+ .vsw = 3,
+ .vfp = 13,
+ .vbp = 29,
+ },
+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS,
+ .name = "focaltech_etm070003dh6",
+ },
+
+ /* Microtips Technologies - UMSH-8173MD */
+ {
+ {
+ .x_res = 800,
+ .y_res = 480,
+
+ .pixel_clock = 34560,
+
+ .hsw = 13,
+ .hfp = 101,
+ .hbp = 101,
+
+ .vsw = 23,
+ .vfp = 1,
+ .vbp = 1,
+ },
+ .acbi = 0x0,
+ .acb = 0x0,
+ .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS |
+ OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IPC,
+ .power_on_delay = 0,
+ .power_off_delay = 0,
+ .name = "microtips_umsh_8173md",
+ },
+
+ /* OrtusTech COM43H4M10XTC */
+ {
+ {
+ .x_res = 480,
+ .y_res = 272,
+
+ .pixel_clock = 8000,
+
+ .hsw = 41,
+ .hfp = 8,
+ .hbp = 4,
+
+ .vsw = 10,
+ .vfp = 4,
+ .vbp = 2,
+ },
+ .config = OMAP_DSS_LCD_TFT,
+
+ .name = "ortustech_com43h4m10xtc",
+ },
};
struct panel_drv_data {
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index 150e8bae35a1..dc9408dc93d1 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -708,7 +708,6 @@ static int mipid_spi_remove(struct spi_device *spi)
static struct spi_driver mipid_spi_driver = {
.driver = {
.name = "lcd_mipid",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = mipid_spi_probe,
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index 2ba9d0ca187c..0eb31caddca8 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -163,50 +163,93 @@ static void nec_8048_panel_remove(struct omap_dss_device *dssdev)
kfree(necd);
}
-static int nec_8048_panel_enable(struct omap_dss_device *dssdev)
+static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
{
- int r = 0;
+ int r;
struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
struct backlight_device *bl = necd->bl;
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+ r = omapdss_dpi_display_enable(dssdev);
+ if (r)
+ goto err0;
+
if (dssdev->platform_enable) {
r = dssdev->platform_enable(dssdev);
if (r)
- return r;
+ goto err1;
}
r = nec_8048_bl_update_status(bl);
if (r < 0)
dev_err(&dssdev->dev, "failed to set lcd brightness\n");
- r = omapdss_dpi_display_enable(dssdev);
-
+ return 0;
+err1:
+ omapdss_dpi_display_disable(dssdev);
+err0:
return r;
}
-static void nec_8048_panel_disable(struct omap_dss_device *dssdev)
+static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
{
struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
struct backlight_device *bl = necd->bl;
- omapdss_dpi_display_disable(dssdev);
+ if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return;
bl->props.brightness = 0;
nec_8048_bl_update_status(bl);
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
+
+ omapdss_dpi_display_disable(dssdev);
+}
+
+static int nec_8048_panel_enable(struct omap_dss_device *dssdev)
+{
+ int r;
+
+ r = nec_8048_panel_power_on(dssdev);
+ if (r)
+ return r;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
+}
+
+static void nec_8048_panel_disable(struct omap_dss_device *dssdev)
+{
+ nec_8048_panel_power_off(dssdev);
+
+ dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
}
static int nec_8048_panel_suspend(struct omap_dss_device *dssdev)
{
- nec_8048_panel_disable(dssdev);
+ nec_8048_panel_power_off(dssdev);
+
+ dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
return 0;
}
static int nec_8048_panel_resume(struct omap_dss_device *dssdev)
{
- return nec_8048_panel_enable(dssdev);
+ int r;
+
+ r = nec_8048_panel_power_on(dssdev);
+ if (r)
+ return r;
+
+ dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+ return 0;
}
static int nec_8048_recommended_bpp(struct omap_dss_device *dssdev)
@@ -303,7 +346,6 @@ static struct spi_driver nec_8048_spi_driver = {
.resume = nec_8048_spi_resume,
.driver = {
.name = "nec_8048_spi",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
},
};
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index 80c3f6ab1a94..00c5c615585f 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -198,12 +198,6 @@ struct taal_data {
bool te_enabled;
atomic_t do_update;
- struct {
- u16 x;
- u16 y;
- u16 w;
- u16 h;
- } update_region;
int channel;
struct delayed_work te_timeout_work;
@@ -1188,6 +1182,10 @@ static int taal_power_on(struct omap_dss_device *dssdev)
if (r)
goto err;
+ r = dsi_enable_video_output(dssdev, td->channel);
+ if (r)
+ goto err;
+
td->enabled = 1;
if (!td->intro_printed) {
@@ -1217,6 +1215,8 @@ static void taal_power_off(struct omap_dss_device *dssdev)
struct taal_data *td = dev_get_drvdata(&dssdev->dev);
int r;
+ dsi_disable_video_output(dssdev, td->channel);
+
r = taal_dcs_write_0(td, MIPI_DCS_SET_DISPLAY_OFF);
if (!r)
r = taal_sleep_in(td);
@@ -1394,12 +1394,8 @@ static irqreturn_t taal_te_isr(int irq, void *data)
if (old) {
cancel_delayed_work(&td->te_timeout_work);
- r = omap_dsi_update(dssdev, td->channel,
- td->update_region.x,
- td->update_region.y,
- td->update_region.w,
- td->update_region.h,
- taal_framedone_cb, dssdev);
+ r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
+ dssdev);
if (r)
goto err;
}
@@ -1444,26 +1440,20 @@ static int taal_update(struct omap_dss_device *dssdev,
goto err;
}
- r = omap_dsi_prepare_update(dssdev, &x, &y, &w, &h, true);
- if (r)
- goto err;
-
- r = taal_set_update_window(td, x, y, w, h);
+ /* XXX no need to send this every frame, but dsi break if not done */
+ r = taal_set_update_window(td, 0, 0,
+ td->panel_config->timings.x_res,
+ td->panel_config->timings.y_res);
if (r)
goto err;
if (td->te_enabled && panel_data->use_ext_te) {
- td->update_region.x = x;
- td->update_region.y = y;
- td->update_region.w = w;
- td->update_region.h = h;
- barrier();
schedule_delayed_work(&td->te_timeout_work,
msecs_to_jiffies(250));
atomic_set(&td->do_update, 1);
} else {
- r = omap_dsi_update(dssdev, td->channel, x, y, w, h,
- taal_framedone_cb, dssdev);
+ r = omap_dsi_update(dssdev, td->channel, taal_framedone_cb,
+ dssdev);
if (r)
goto err;
}
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index 2462b9ec6662..e6649aa89591 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -512,7 +512,6 @@ static int __devexit tpo_td043_spi_remove(struct spi_device *spi)
static struct spi_driver tpo_td043_spi_driver = {
.driver = {
.name = "tpo_td043mtea1_panel_spi",
- .bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = tpo_td043_spi_probe,
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index bd34ac5b2026..5c450b0f94d0 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,5 +1,6 @@
obj-$(CONFIG_OMAP2_DSS) += omapdss.o
-omapdss-y := core.o dss.o dss_features.o dispc.o display.o manager.o overlay.o
+omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
+ manager.o overlay.o apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
new file mode 100644
index 000000000000..052dc874cd3d
--- /dev/null
+++ b/drivers/video/omap2/dss/apply.c
@@ -0,0 +1,1324 @@
+/*
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DSS_SUBSYS_NAME "APPLY"
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/jiffies.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+
+/*
+ * We have 4 levels of cache for the dispc settings. First two are in SW and
+ * the latter two in HW.
+ *
+ * set_info()
+ * v
+ * +--------------------+
+ * | user_info |
+ * +--------------------+
+ * v
+ * apply()
+ * v
+ * +--------------------+
+ * | info |
+ * +--------------------+
+ * v
+ * write_regs()
+ * v
+ * +--------------------+
+ * | shadow registers |
+ * +--------------------+
+ * v
+ * VFP or lcd/digit_enable
+ * v
+ * +--------------------+
+ * | registers |
+ * +--------------------+
+ */
+
+struct ovl_priv_data {
+
+ bool user_info_dirty;
+ struct omap_overlay_info user_info;
+
+ bool info_dirty;
+ struct omap_overlay_info info;
+
+ bool shadow_info_dirty;
+
+ bool extra_info_dirty;
+ bool shadow_extra_info_dirty;
+
+ bool enabled;
+ enum omap_channel channel;
+ u32 fifo_low, fifo_high;
+
+ /*
+ * True if overlay is to be enabled. Used to check and calculate configs
+ * for the overlay before it is enabled in the HW.
+ */
+ bool enabling;
+};
+
+struct mgr_priv_data {
+
+ bool user_info_dirty;
+ struct omap_overlay_manager_info user_info;
+
+ bool info_dirty;
+ struct omap_overlay_manager_info info;
+
+ bool shadow_info_dirty;
+
+ /* If true, GO bit is up and shadow registers cannot be written.
+ * Never true for manual update displays */
+ bool busy;
+
+ /* If true, dispc output is enabled */
+ bool updating;
+
+ /* If true, a display is enabled using this manager */
+ bool enabled;
+};
+
+static struct {
+ struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
+ struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
+
+ bool irq_enabled;
+} dss_data;
+
+/* protects dss_data */
+static spinlock_t data_lock;
+/* lock for blocking functions */
+static DEFINE_MUTEX(apply_lock);
+static DECLARE_COMPLETION(extra_updated_completion);
+
+static void dss_register_vsync_isr(void);
+
+static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
+{
+ return &dss_data.ovl_priv_data_array[ovl->id];
+}
+
+static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
+{
+ return &dss_data.mgr_priv_data_array[mgr->id];
+}
+
+void dss_apply_init(void)
+{
+ const int num_ovls = dss_feat_get_num_ovls();
+ int i;
+
+ spin_lock_init(&data_lock);
+
+ for (i = 0; i < num_ovls; ++i) {
+ struct ovl_priv_data *op;
+
+ op = &dss_data.ovl_priv_data_array[i];
+
+ op->info.global_alpha = 255;
+
+ switch (i) {
+ case 0:
+ op->info.zorder = 0;
+ break;
+ case 1:
+ op->info.zorder =
+ dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
+ break;
+ case 2:
+ op->info.zorder =
+ dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
+ break;
+ case 3:
+ op->info.zorder =
+ dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
+ break;
+ }
+
+ op->user_info = op->info;
+ }
+}
+
+static bool ovl_manual_update(struct omap_overlay *ovl)
+{
+ return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+}
+
+static bool mgr_manual_update(struct omap_overlay_manager *mgr)
+{
+ return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+}
+
+static int dss_check_settings_low(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev, bool applying)
+{
+ struct omap_overlay_info *oi;
+ struct omap_overlay_manager_info *mi;
+ struct omap_overlay *ovl;
+ struct omap_overlay_info *ois[MAX_DSS_OVERLAYS];
+ struct ovl_priv_data *op;
+ struct mgr_priv_data *mp;
+
+ mp = get_mgr_priv(mgr);
+
+ if (applying && mp->user_info_dirty)
+ mi = &mp->user_info;
+ else
+ mi = &mp->info;
+
+ /* collect the infos to be tested into the array */
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ op = get_ovl_priv(ovl);
+
+ if (!op->enabled && !op->enabling)
+ oi = NULL;
+ else if (applying && op->user_info_dirty)
+ oi = &op->user_info;
+ else
+ oi = &op->info;
+
+ ois[ovl->id] = oi;
+ }
+
+ return dss_mgr_check(mgr, dssdev, mi, ois);
+}
+
+/*
+ * check manager and overlay settings using overlay_info from data->info
+ */
+static int dss_check_settings(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev)
+{
+ return dss_check_settings_low(mgr, dssdev, false);
+}
+
+/*
+ * check manager and overlay settings using overlay_info from ovl->info if
+ * dirty and from data->info otherwise
+ */
+static int dss_check_settings_apply(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev)
+{
+ return dss_check_settings_low(mgr, dssdev, true);
+}
+
+static bool need_isr(void)
+{
+ const int num_mgrs = dss_feat_get_num_mgrs();
+ int i;
+
+ for (i = 0; i < num_mgrs; ++i) {
+ struct omap_overlay_manager *mgr;
+ struct mgr_priv_data *mp;
+ struct omap_overlay *ovl;
+
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ if (!mp->enabled)
+ continue;
+
+ if (mgr_manual_update(mgr)) {
+ /* to catch FRAMEDONE */
+ if (mp->updating)
+ return true;
+ } else {
+ /* to catch GO bit going down */
+ if (mp->busy)
+ return true;
+
+ /* to write new values to registers */
+ if (mp->info_dirty)
+ return true;
+
+ /* to set GO bit */
+ if (mp->shadow_info_dirty)
+ return true;
+
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ struct ovl_priv_data *op;
+
+ op = get_ovl_priv(ovl);
+
+ /*
+ * NOTE: we check extra_info flags even for
+ * disabled overlays, as extra_infos need to be
+ * always written.
+ */
+
+ /* to write new values to registers */
+ if (op->extra_info_dirty)
+ return true;
+
+ /* to set GO bit */
+ if (op->shadow_extra_info_dirty)
+ return true;
+
+ if (!op->enabled)
+ continue;
+
+ /* to write new values to registers */
+ if (op->info_dirty)
+ return true;
+
+ /* to set GO bit */
+ if (op->shadow_info_dirty)
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+static bool need_go(struct omap_overlay_manager *mgr)
+{
+ struct omap_overlay *ovl;
+ struct mgr_priv_data *mp;
+ struct ovl_priv_data *op;
+
+ mp = get_mgr_priv(mgr);
+
+ if (mp->shadow_info_dirty)
+ return true;
+
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ op = get_ovl_priv(ovl);
+ if (op->shadow_info_dirty || op->shadow_extra_info_dirty)
+ return true;
+ }
+
+ return false;
+}
+
+/* returns true if an extra_info field is currently being updated */
+static bool extra_info_update_ongoing(void)
+{
+ const int num_ovls = omap_dss_get_num_overlays();
+ struct ovl_priv_data *op;
+ struct omap_overlay *ovl;
+ struct mgr_priv_data *mp;
+ int i;
+
+ for (i = 0; i < num_ovls; ++i) {
+ ovl = omap_dss_get_overlay(i);
+ op = get_ovl_priv(ovl);
+
+ if (!ovl->manager)
+ continue;
+
+ mp = get_mgr_priv(ovl->manager);
+
+ if (!mp->enabled)
+ continue;
+
+ if (!mp->updating)
+ continue;
+
+ if (op->extra_info_dirty || op->shadow_extra_info_dirty)
+ return true;
+ }
+
+ return false;
+}
+
+/* wait until no extra_info updates are pending */
+static void wait_pending_extra_info_updates(void)
+{
+ bool updating;
+ unsigned long flags;
+ unsigned long t;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ updating = extra_info_update_ongoing();
+
+ if (!updating) {
+ spin_unlock_irqrestore(&data_lock, flags);
+ return;
+ }
+
+ init_completion(&extra_updated_completion);
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ t = msecs_to_jiffies(500);
+ wait_for_completion_timeout(&extra_updated_completion, t);
+
+ updating = extra_info_update_ongoing();
+
+ WARN_ON(updating);
+}
+
+int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
+{
+ unsigned long timeout = msecs_to_jiffies(500);
+ struct mgr_priv_data *mp;
+ u32 irq;
+ int r;
+ int i;
+ struct omap_dss_device *dssdev = mgr->device;
+
+ if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+ if (mgr_manual_update(mgr))
+ return 0;
+
+ irq = dispc_mgr_get_vsync_irq(mgr->id);
+
+ mp = get_mgr_priv(mgr);
+ i = 0;
+ while (1) {
+ unsigned long flags;
+ bool shadow_dirty, dirty;
+
+ spin_lock_irqsave(&data_lock, flags);
+ dirty = mp->info_dirty;
+ shadow_dirty = mp->shadow_info_dirty;
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ if (!dirty && !shadow_dirty) {
+ r = 0;
+ break;
+ }
+
+ /* 4 iterations is the worst case:
+ * 1 - initial iteration, dirty = true (between VFP and VSYNC)
+ * 2 - first VSYNC, dirty = true
+ * 3 - dirty = false, shadow_dirty = true
+ * 4 - shadow_dirty = false */
+ if (i++ == 3) {
+ DSSERR("mgr(%d)->wait_for_go() not finishing\n",
+ mgr->id);
+ r = 0;
+ break;
+ }
+
+ r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+ if (r == -ERESTARTSYS)
+ break;
+
+ if (r) {
+ DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
+ break;
+ }
+ }
+
+ return r;
+}
+
+int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
+{
+ unsigned long timeout = msecs_to_jiffies(500);
+ struct ovl_priv_data *op;
+ struct omap_dss_device *dssdev;
+ u32 irq;
+ int r;
+ int i;
+
+ if (!ovl->manager)
+ return 0;
+
+ dssdev = ovl->manager->device;
+
+ if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+ return 0;
+
+ if (ovl_manual_update(ovl))
+ return 0;
+
+ irq = dispc_mgr_get_vsync_irq(ovl->manager->id);
+
+ op = get_ovl_priv(ovl);
+ i = 0;
+ while (1) {
+ unsigned long flags;
+ bool shadow_dirty, dirty;
+
+ spin_lock_irqsave(&data_lock, flags);
+ dirty = op->info_dirty;
+ shadow_dirty = op->shadow_info_dirty;
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ if (!dirty && !shadow_dirty) {
+ r = 0;
+ break;
+ }
+
+ /* 4 iterations is the worst case:
+ * 1 - initial iteration, dirty = true (between VFP and VSYNC)
+ * 2 - first VSYNC, dirty = true
+ * 3 - dirty = false, shadow_dirty = true
+ * 4 - shadow_dirty = false */
+ if (i++ == 3) {
+ DSSERR("ovl(%d)->wait_for_go() not finishing\n",
+ ovl->id);
+ r = 0;
+ break;
+ }
+
+ r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
+ if (r == -ERESTARTSYS)
+ break;
+
+ if (r) {
+ DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
+ break;
+ }
+ }
+
+ return r;
+}
+
+static void dss_ovl_write_regs(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ struct omap_overlay_info *oi;
+ bool ilace, replication;
+ struct mgr_priv_data *mp;
+ int r;
+
+ DSSDBGF("%d", ovl->id);
+
+ if (!op->enabled || !op->info_dirty)
+ return;
+
+ oi = &op->info;
+
+ replication = dss_use_replication(ovl->manager->device, oi->color_mode);
+
+ ilace = ovl->manager->device->type == OMAP_DISPLAY_TYPE_VENC;
+
+ r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
+ if (r) {
+ /*
+ * We can't do much here, as this function can be called from
+ * vsync interrupt.
+ */
+ DSSERR("dispc_ovl_setup failed for ovl %d\n", ovl->id);
+
+ /* This will leave fifo configurations in a nonoptimal state */
+ op->enabled = false;
+ dispc_ovl_enable(ovl->id, false);
+ return;
+ }
+
+ mp = get_mgr_priv(ovl->manager);
+
+ op->info_dirty = false;
+ if (mp->updating)
+ op->shadow_info_dirty = true;
+}
+
+static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ struct mgr_priv_data *mp;
+
+ DSSDBGF("%d", ovl->id);
+
+ if (!op->extra_info_dirty)
+ return;
+
+ /* note: write also when op->enabled == false, so that the ovl gets
+ * disabled */
+
+ dispc_ovl_enable(ovl->id, op->enabled);
+ dispc_ovl_set_channel_out(ovl->id, op->channel);
+ dispc_ovl_set_fifo_threshold(ovl->id, op->fifo_low, op->fifo_high);
+
+ mp = get_mgr_priv(ovl->manager);
+
+ op->extra_info_dirty = false;
+ if (mp->updating)
+ op->shadow_extra_info_dirty = true;
+}
+
+static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ struct omap_overlay *ovl;
+
+ DSSDBGF("%d", mgr->id);
+
+ if (!mp->enabled)
+ return;
+
+ WARN_ON(mp->busy);
+
+ /* Commit overlay settings */
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ dss_ovl_write_regs(ovl);
+ dss_ovl_write_regs_extra(ovl);
+ }
+
+ if (mp->info_dirty) {
+ dispc_mgr_setup(mgr->id, &mp->info);
+
+ mp->info_dirty = false;
+ if (mp->updating)
+ mp->shadow_info_dirty = true;
+ }
+}
+
+static void dss_write_regs(void)
+{
+ const int num_mgrs = omap_dss_get_num_overlay_managers();
+ int i;
+
+ for (i = 0; i < num_mgrs; ++i) {
+ struct omap_overlay_manager *mgr;
+ struct mgr_priv_data *mp;
+ int r;
+
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
+ continue;
+
+ r = dss_check_settings(mgr, mgr->device);
+ if (r) {
+ DSSERR("cannot write registers for manager %s: "
+ "illegal configuration\n", mgr->name);
+ continue;
+ }
+
+ dss_mgr_write_regs(mgr);
+ }
+}
+
+static void dss_set_go_bits(void)
+{
+ const int num_mgrs = omap_dss_get_num_overlay_managers();
+ int i;
+
+ for (i = 0; i < num_mgrs; ++i) {
+ struct omap_overlay_manager *mgr;
+ struct mgr_priv_data *mp;
+
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
+ continue;
+
+ if (!need_go(mgr))
+ continue;
+
+ mp->busy = true;
+
+ if (!dss_data.irq_enabled && need_isr())
+ dss_register_vsync_isr();
+
+ dispc_mgr_go(mgr->id);
+ }
+
+}
+
+void dss_mgr_start_update(struct omap_overlay_manager *mgr)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+ int r;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ WARN_ON(mp->updating);
+
+ r = dss_check_settings(mgr, mgr->device);
+ if (r) {
+ DSSERR("cannot start manual update: illegal configuration\n");
+ spin_unlock_irqrestore(&data_lock, flags);
+ return;
+ }
+
+ dss_mgr_write_regs(mgr);
+
+ mp->updating = true;
+
+ if (!dss_data.irq_enabled && need_isr())
+ dss_register_vsync_isr();
+
+ dispc_mgr_enable(mgr->id, true);
+
+ spin_unlock_irqrestore(&data_lock, flags);
+}
+
+static void dss_apply_irq_handler(void *data, u32 mask);
+
+static void dss_register_vsync_isr(void)
+{
+ const int num_mgrs = dss_feat_get_num_mgrs();
+ u32 mask;
+ int r, i;
+
+ mask = 0;
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_vsync_irq(i);
+
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_framedone_irq(i);
+
+ r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
+ WARN_ON(r);
+
+ dss_data.irq_enabled = true;
+}
+
+static void dss_unregister_vsync_isr(void)
+{
+ const int num_mgrs = dss_feat_get_num_mgrs();
+ u32 mask;
+ int r, i;
+
+ mask = 0;
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_vsync_irq(i);
+
+ for (i = 0; i < num_mgrs; ++i)
+ mask |= dispc_mgr_get_framedone_irq(i);
+
+ r = omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, mask);
+ WARN_ON(r);
+
+ dss_data.irq_enabled = false;
+}
+
+static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
+{
+ struct omap_overlay *ovl;
+ struct mgr_priv_data *mp;
+ struct ovl_priv_data *op;
+
+ mp = get_mgr_priv(mgr);
+ mp->shadow_info_dirty = false;
+
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ op = get_ovl_priv(ovl);
+ op->shadow_info_dirty = false;
+ op->shadow_extra_info_dirty = false;
+ }
+}
+
+static void dss_apply_irq_handler(void *data, u32 mask)
+{
+ const int num_mgrs = dss_feat_get_num_mgrs();
+ int i;
+ bool extra_updating;
+
+ spin_lock(&data_lock);
+
+ /* clear busy, updating flags, shadow_dirty flags */
+ for (i = 0; i < num_mgrs; i++) {
+ struct omap_overlay_manager *mgr;
+ struct mgr_priv_data *mp;
+ bool was_updating;
+
+ mgr = omap_dss_get_overlay_manager(i);
+ mp = get_mgr_priv(mgr);
+
+ if (!mp->enabled)
+ continue;
+
+ was_updating = mp->updating;
+ mp->updating = dispc_mgr_is_enabled(i);
+
+ if (!mgr_manual_update(mgr)) {
+ bool was_busy = mp->busy;
+ mp->busy = dispc_mgr_go_busy(i);
+
+ if (was_busy && !mp->busy)
+ mgr_clear_shadow_dirty(mgr);
+ } else {
+ if (was_updating && !mp->updating)
+ mgr_clear_shadow_dirty(mgr);
+ }
+ }
+
+ dss_write_regs();
+ dss_set_go_bits();
+
+ extra_updating = extra_info_update_ongoing();
+ if (!extra_updating)
+ complete_all(&extra_updated_completion);
+
+ if (!need_isr())
+ dss_unregister_vsync_isr();
+
+ spin_unlock(&data_lock);
+}
+
+static void omap_dss_mgr_apply_ovl(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op;
+
+ op = get_ovl_priv(ovl);
+
+ if (!op->user_info_dirty)
+ return;
+
+ op->user_info_dirty = false;
+ op->info_dirty = true;
+ op->info = op->user_info;
+}
+
+static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
+{
+ struct mgr_priv_data *mp;
+
+ mp = get_mgr_priv(mgr);
+
+ if (!mp->user_info_dirty)
+ return;
+
+ mp->user_info_dirty = false;
+ mp->info_dirty = true;
+ mp->info = mp->user_info;
+}
+
+int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+{
+ unsigned long flags;
+ struct omap_overlay *ovl;
+ int r;
+
+ DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ r = dss_check_settings_apply(mgr, mgr->device);
+ if (r) {
+ spin_unlock_irqrestore(&data_lock, flags);
+ DSSERR("failed to apply settings: illegal configuration.\n");
+ return r;
+ }
+
+ /* Configure overlays */
+ list_for_each_entry(ovl, &mgr->overlays, list)
+ omap_dss_mgr_apply_ovl(ovl);
+
+ /* Configure manager */
+ omap_dss_mgr_apply_mgr(mgr);
+
+ dss_write_regs();
+ dss_set_go_bits();
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ return 0;
+}
+
+static void dss_apply_ovl_enable(struct omap_overlay *ovl, bool enable)
+{
+ struct ovl_priv_data *op;
+
+ op = get_ovl_priv(ovl);
+
+ if (op->enabled == enable)
+ return;
+
+ op->enabled = enable;
+ op->extra_info_dirty = true;
+}
+
+static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
+ u32 fifo_low, u32 fifo_high)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+
+ if (op->fifo_low == fifo_low && op->fifo_high == fifo_high)
+ return;
+
+ op->fifo_low = fifo_low;
+ op->fifo_high = fifo_high;
+ op->extra_info_dirty = true;
+}
+
+static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ struct omap_dss_device *dssdev;
+ u32 size, burst_size;
+ u32 fifo_low, fifo_high;
+
+ if (!op->enabled && !op->enabling)
+ return;
+
+ dssdev = ovl->manager->device;
+
+ size = dispc_ovl_get_fifo_size(ovl->id);
+
+ burst_size = dispc_ovl_get_burst_size(ovl->id);
+
+ switch (dssdev->type) {
+ case OMAP_DISPLAY_TYPE_DPI:
+ case OMAP_DISPLAY_TYPE_DBI:
+ case OMAP_DISPLAY_TYPE_SDI:
+ case OMAP_DISPLAY_TYPE_VENC:
+ case OMAP_DISPLAY_TYPE_HDMI:
+ default_get_overlay_fifo_thresholds(ovl->id, size,
+ burst_size, &fifo_low, &fifo_high);
+ break;
+#ifdef CONFIG_OMAP2_DSS_DSI
+ case OMAP_DISPLAY_TYPE_DSI:
+ dsi_get_overlay_fifo_thresholds(ovl->id, size,
+ burst_size, &fifo_low, &fifo_high);
+ break;
+#endif
+ default:
+ BUG();
+ }
+
+ dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
+}
+
+static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
+{
+ struct omap_overlay *ovl;
+ struct mgr_priv_data *mp;
+
+ mp = get_mgr_priv(mgr);
+
+ if (!mp->enabled)
+ return;
+
+ list_for_each_entry(ovl, &mgr->overlays, list)
+ dss_ovl_setup_fifo(ovl);
+}
+
+static void dss_setup_fifos(void)
+{
+ const int num_mgrs = omap_dss_get_num_overlay_managers();
+ struct omap_overlay_manager *mgr;
+ int i;
+
+ for (i = 0; i < num_mgrs; ++i) {
+ mgr = omap_dss_get_overlay_manager(i);
+ dss_mgr_setup_fifos(mgr);
+ }
+}
+
+int dss_mgr_enable(struct omap_overlay_manager *mgr)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (mp->enabled)
+ goto out;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ mp->enabled = true;
+
+ r = dss_check_settings(mgr, mgr->device);
+ if (r) {
+ DSSERR("failed to enable manager %d: check_settings failed\n",
+ mgr->id);
+ goto err;
+ }
+
+ dss_setup_fifos();
+
+ dss_write_regs();
+ dss_set_go_bits();
+
+ if (!mgr_manual_update(mgr))
+ mp->updating = true;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ if (!mgr_manual_update(mgr))
+ dispc_mgr_enable(mgr->id, true);
+
+out:
+ mutex_unlock(&apply_lock);
+
+ return 0;
+
+err:
+ mp->enabled = false;
+ spin_unlock_irqrestore(&data_lock, flags);
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+void dss_mgr_disable(struct omap_overlay_manager *mgr)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+
+ mutex_lock(&apply_lock);
+
+ if (!mp->enabled)
+ goto out;
+
+ if (!mgr_manual_update(mgr))
+ dispc_mgr_enable(mgr->id, false);
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ mp->updating = false;
+ mp->enabled = false;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+out:
+ mutex_unlock(&apply_lock);
+}
+
+int dss_mgr_set_info(struct omap_overlay_manager *mgr,
+ struct omap_overlay_manager_info *info)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+ int r;
+
+ r = dss_mgr_simple_check(mgr, info);
+ if (r)
+ return r;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ mp->user_info = *info;
+ mp->user_info_dirty = true;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ return 0;
+}
+
+void dss_mgr_get_info(struct omap_overlay_manager *mgr,
+ struct omap_overlay_manager_info *info)
+{
+ struct mgr_priv_data *mp = get_mgr_priv(mgr);
+ unsigned long flags;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ *info = mp->user_info;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+}
+
+int dss_mgr_set_device(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev)
+{
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (dssdev->manager) {
+ DSSERR("display '%s' already has a manager '%s'\n",
+ dssdev->name, dssdev->manager->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ if ((mgr->supported_displays & dssdev->type) == 0) {
+ DSSERR("display '%s' does not support manager '%s'\n",
+ dssdev->name, mgr->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ dssdev->manager = mgr;
+ mgr->device = dssdev;
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
+{
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (!mgr->device) {
+ DSSERR("failed to unset display, display not set.\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ /*
+ * Don't allow currently enabled displays to have the overlay manager
+ * pulled out from underneath them
+ */
+ if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+ r = -EINVAL;
+ goto err;
+ }
+
+ mgr->device->manager = NULL;
+ mgr->device = NULL;
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+
+int dss_ovl_set_info(struct omap_overlay *ovl,
+ struct omap_overlay_info *info)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ int r;
+
+ r = dss_ovl_simple_check(ovl, info);
+ if (r)
+ return r;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ op->user_info = *info;
+ op->user_info_dirty = true;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ return 0;
+}
+
+void dss_ovl_get_info(struct omap_overlay *ovl,
+ struct omap_overlay_info *info)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ *info = op->user_info;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+}
+
+int dss_ovl_set_manager(struct omap_overlay *ovl,
+ struct omap_overlay_manager *mgr)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ int r;
+
+ if (!mgr)
+ return -EINVAL;
+
+ mutex_lock(&apply_lock);
+
+ if (ovl->manager) {
+ DSSERR("overlay '%s' already has a manager '%s'\n",
+ ovl->name, ovl->manager->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ if (op->enabled) {
+ spin_unlock_irqrestore(&data_lock, flags);
+ DSSERR("overlay has to be disabled to change the manager\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ op->channel = mgr->id;
+ op->extra_info_dirty = true;
+
+ ovl->manager = mgr;
+ list_add_tail(&ovl->list, &mgr->overlays);
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ /* XXX: When there is an overlay on a DSI manual update display, and
+ * the overlay is first disabled, then moved to tv, and enabled, we
+ * seem to get SYNC_LOST_DIGIT error.
+ *
+ * Waiting doesn't seem to help, but updating the manual update display
+ * after disabling the overlay seems to fix this. This hints that the
+ * overlay is perhaps somehow tied to the LCD output until the output
+ * is updated.
+ *
+ * Userspace workaround for this is to update the LCD after disabling
+ * the overlay, but before moving the overlay to TV.
+ */
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+int dss_ovl_unset_manager(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (!ovl->manager) {
+ DSSERR("failed to detach overlay: manager not set\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ if (op->enabled) {
+ spin_unlock_irqrestore(&data_lock, flags);
+ DSSERR("overlay has to be disabled to unset the manager\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ op->channel = -1;
+
+ ovl->manager = NULL;
+ list_del(&ovl->list);
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+bool dss_ovl_is_enabled(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ bool e;
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ e = op->enabled;
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ return e;
+}
+
+int dss_ovl_enable(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (op->enabled) {
+ r = 0;
+ goto err1;
+ }
+
+ if (ovl->manager == NULL || ovl->manager->device == NULL) {
+ r = -EINVAL;
+ goto err1;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ op->enabling = true;
+
+ r = dss_check_settings(ovl->manager, ovl->manager->device);
+ if (r) {
+ DSSERR("failed to enable overlay %d: check_settings failed\n",
+ ovl->id);
+ goto err2;
+ }
+
+ dss_setup_fifos();
+
+ op->enabling = false;
+ dss_apply_ovl_enable(ovl, true);
+
+ dss_write_regs();
+ dss_set_go_bits();
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+err2:
+ op->enabling = false;
+ spin_unlock_irqrestore(&data_lock, flags);
+err1:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
+int dss_ovl_disable(struct omap_overlay *ovl)
+{
+ struct ovl_priv_data *op = get_ovl_priv(ovl);
+ unsigned long flags;
+ int r;
+
+ mutex_lock(&apply_lock);
+
+ if (!op->enabled) {
+ r = 0;
+ goto err;
+ }
+
+ if (ovl->manager == NULL || ovl->manager->device == NULL) {
+ r = -EINVAL;
+ goto err;
+ }
+
+ spin_lock_irqsave(&data_lock, flags);
+
+ dss_apply_ovl_enable(ovl, false);
+ dss_write_regs();
+ dss_set_go_bits();
+
+ spin_unlock_irqrestore(&data_lock, flags);
+
+ mutex_unlock(&apply_lock);
+
+ return 0;
+
+err:
+ mutex_unlock(&apply_lock);
+ return r;
+}
+
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 86ec12e16c7c..8613f86fb56d 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -50,7 +50,7 @@ module_param_named(def_disp, def_disp_name, charp, 0);
MODULE_PARM_DESC(def_disp, "default display name");
#ifdef DEBUG
-unsigned int dss_debug;
+bool dss_debug;
module_param_named(debug, dss_debug, bool, 0644);
#endif
@@ -178,6 +178,8 @@ static int omap_dss_probe(struct platform_device *pdev)
dss_features_init();
+ dss_apply_init();
+
dss_init_overlay_managers(pdev);
dss_init_overlays(pdev);
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 5c81533eacaa..a5ec7f37c185 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -64,22 +64,6 @@ struct omap_dispc_isr_data {
u32 mask;
};
-struct dispc_h_coef {
- s8 hc4;
- s8 hc3;
- u8 hc2;
- s8 hc1;
- s8 hc0;
-};
-
-struct dispc_v_coef {
- s8 vc22;
- s8 vc2;
- u8 vc1;
- s8 vc0;
- s8 vc00;
-};
-
enum omap_burst_size {
BURST_SIZE_X2 = 0,
BURST_SIZE_X4 = 1,
@@ -438,6 +422,34 @@ static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
return mgr ? mgr->device : NULL;
}
+u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
+{
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD:
+ return DISPC_IRQ_VSYNC;
+ case OMAP_DSS_CHANNEL_LCD2:
+ return DISPC_IRQ_VSYNC2;
+ case OMAP_DSS_CHANNEL_DIGIT:
+ return DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
+ default:
+ BUG();
+ }
+}
+
+u32 dispc_mgr_get_framedone_irq(enum omap_channel channel)
+{
+ switch (channel) {
+ case OMAP_DSS_CHANNEL_LCD:
+ return DISPC_IRQ_FRAMEDONE;
+ case OMAP_DSS_CHANNEL_LCD2:
+ return DISPC_IRQ_FRAMEDONE2;
+ case OMAP_DSS_CHANNEL_DIGIT:
+ return 0;
+ default:
+ BUG();
+ }
+}
+
bool dispc_mgr_go_busy(enum omap_channel channel)
{
int bit;
@@ -533,105 +545,27 @@ static void dispc_ovl_write_firv2_reg(enum omap_plane plane, int reg, u32 value)
dispc_write_reg(DISPC_OVL_FIR_COEF_V2(plane, reg), value);
}
-static void dispc_ovl_set_scale_coef(enum omap_plane plane, int hscaleup,
- int vscaleup, int five_taps,
- enum omap_color_component color_comp)
-{
- /* Coefficients for horizontal up-sampling */
- static const struct dispc_h_coef coef_hup[8] = {
- { 0, 0, 128, 0, 0 },
- { -1, 13, 124, -8, 0 },
- { -2, 30, 112, -11, -1 },
- { -5, 51, 95, -11, -2 },
- { 0, -9, 73, 73, -9 },
- { -2, -11, 95, 51, -5 },
- { -1, -11, 112, 30, -2 },
- { 0, -8, 124, 13, -1 },
- };
-
- /* Coefficients for vertical up-sampling */
- static const struct dispc_v_coef coef_vup_3tap[8] = {
- { 0, 0, 128, 0, 0 },
- { 0, 3, 123, 2, 0 },
- { 0, 12, 111, 5, 0 },
- { 0, 32, 89, 7, 0 },
- { 0, 0, 64, 64, 0 },
- { 0, 7, 89, 32, 0 },
- { 0, 5, 111, 12, 0 },
- { 0, 2, 123, 3, 0 },
- };
-
- static const struct dispc_v_coef coef_vup_5tap[8] = {
- { 0, 0, 128, 0, 0 },
- { -1, 13, 124, -8, 0 },
- { -2, 30, 112, -11, -1 },
- { -5, 51, 95, -11, -2 },
- { 0, -9, 73, 73, -9 },
- { -2, -11, 95, 51, -5 },
- { -1, -11, 112, 30, -2 },
- { 0, -8, 124, 13, -1 },
- };
-
- /* Coefficients for horizontal down-sampling */
- static const struct dispc_h_coef coef_hdown[8] = {
- { 0, 36, 56, 36, 0 },
- { 4, 40, 55, 31, -2 },
- { 8, 44, 54, 27, -5 },
- { 12, 48, 53, 22, -7 },
- { -9, 17, 52, 51, 17 },
- { -7, 22, 53, 48, 12 },
- { -5, 27, 54, 44, 8 },
- { -2, 31, 55, 40, 4 },
- };
-
- /* Coefficients for vertical down-sampling */
- static const struct dispc_v_coef coef_vdown_3tap[8] = {
- { 0, 36, 56, 36, 0 },
- { 0, 40, 57, 31, 0 },
- { 0, 45, 56, 27, 0 },
- { 0, 50, 55, 23, 0 },
- { 0, 18, 55, 55, 0 },
- { 0, 23, 55, 50, 0 },
- { 0, 27, 56, 45, 0 },
- { 0, 31, 57, 40, 0 },
- };
-
- static const struct dispc_v_coef coef_vdown_5tap[8] = {
- { 0, 36, 56, 36, 0 },
- { 4, 40, 55, 31, -2 },
- { 8, 44, 54, 27, -5 },
- { 12, 48, 53, 22, -7 },
- { -9, 17, 52, 51, 17 },
- { -7, 22, 53, 48, 12 },
- { -5, 27, 54, 44, 8 },
- { -2, 31, 55, 40, 4 },
- };
-
- const struct dispc_h_coef *h_coef;
- const struct dispc_v_coef *v_coef;
+static void dispc_ovl_set_scale_coef(enum omap_plane plane, int fir_hinc,
+ int fir_vinc, int five_taps,
+ enum omap_color_component color_comp)
+{
+ const struct dispc_coef *h_coef, *v_coef;
int i;
- if (hscaleup)
- h_coef = coef_hup;
- else
- h_coef = coef_hdown;
-
- if (vscaleup)
- v_coef = five_taps ? coef_vup_5tap : coef_vup_3tap;
- else
- v_coef = five_taps ? coef_vdown_5tap : coef_vdown_3tap;
+ h_coef = dispc_ovl_get_scale_coef(fir_hinc, true);
+ v_coef = dispc_ovl_get_scale_coef(fir_vinc, five_taps);
for (i = 0; i < 8; i++) {
u32 h, hv;
- h = FLD_VAL(h_coef[i].hc0, 7, 0)
- | FLD_VAL(h_coef[i].hc1, 15, 8)
- | FLD_VAL(h_coef[i].hc2, 23, 16)
- | FLD_VAL(h_coef[i].hc3, 31, 24);
- hv = FLD_VAL(h_coef[i].hc4, 7, 0)
- | FLD_VAL(v_coef[i].vc0, 15, 8)
- | FLD_VAL(v_coef[i].vc1, 23, 16)
- | FLD_VAL(v_coef[i].vc2, 31, 24);
+ h = FLD_VAL(h_coef[i].hc0_vc00, 7, 0)
+ | FLD_VAL(h_coef[i].hc1_vc0, 15, 8)
+ | FLD_VAL(h_coef[i].hc2_vc1, 23, 16)
+ | FLD_VAL(h_coef[i].hc3_vc2, 31, 24);
+ hv = FLD_VAL(h_coef[i].hc4_vc22, 7, 0)
+ | FLD_VAL(v_coef[i].hc1_vc0, 15, 8)
+ | FLD_VAL(v_coef[i].hc2_vc1, 23, 16)
+ | FLD_VAL(v_coef[i].hc3_vc2, 31, 24);
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y) {
dispc_ovl_write_firh_reg(plane, i, h);
@@ -646,8 +580,8 @@ static void dispc_ovl_set_scale_coef(enum omap_plane plane, int hscaleup,
if (five_taps) {
for (i = 0; i < 8; i++) {
u32 v;
- v = FLD_VAL(v_coef[i].vc00, 7, 0)
- | FLD_VAL(v_coef[i].vc22, 15, 8);
+ v = FLD_VAL(v_coef[i].hc0_vc00, 7, 0)
+ | FLD_VAL(v_coef[i].hc4_vc22, 15, 8);
if (color_comp == DISPC_COLOR_COMPONENT_RGB_Y)
dispc_ovl_write_firv_reg(plane, i, v);
else
@@ -875,8 +809,7 @@ static void dispc_ovl_set_color_mode(enum omap_plane plane,
REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), m, 4, 1);
}
-static void dispc_ovl_set_channel_out(enum omap_plane plane,
- enum omap_channel channel)
+void dispc_ovl_set_channel_out(enum omap_plane plane, enum omap_channel channel)
{
int shift;
u32 val;
@@ -923,6 +856,39 @@ static void dispc_ovl_set_channel_out(enum omap_plane plane,
dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
}
+static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
+{
+ int shift;
+ u32 val;
+ enum omap_channel channel;
+
+ switch (plane) {
+ case OMAP_DSS_GFX:
+ shift = 8;
+ break;
+ case OMAP_DSS_VIDEO1:
+ case OMAP_DSS_VIDEO2:
+ case OMAP_DSS_VIDEO3:
+ shift = 16;
+ break;
+ default:
+ BUG();
+ }
+
+ val = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
+
+ if (dss_has_feature(FEAT_MGR_LCD2)) {
+ if (FLD_GET(val, 31, 30) == 0)
+ channel = FLD_GET(val, shift, shift);
+ else
+ channel = OMAP_DSS_CHANNEL_LCD2;
+ } else {
+ channel = FLD_GET(val, shift, shift);
+ }
+
+ return channel;
+}
+
static void dispc_ovl_set_burst_size(enum omap_plane plane,
enum omap_burst_size burst_size)
{
@@ -964,7 +930,7 @@ void dispc_enable_gamma_table(bool enable)
REG_FLD_MOD(DISPC_CONFIG, enable, 9, 9);
}
-void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
+static void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
{
u16 reg;
@@ -978,7 +944,7 @@ void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable)
REG_FLD_MOD(reg, enable, 15, 15);
}
-void dispc_mgr_set_cpr_coef(enum omap_channel channel,
+static void dispc_mgr_set_cpr_coef(enum omap_channel channel,
struct omap_dss_cpr_coefs *coefs)
{
u32 coef_r, coef_g, coef_b;
@@ -1057,8 +1023,7 @@ u32 dispc_ovl_get_fifo_size(enum omap_plane plane)
return dispc.fifo_size[plane];
}
-static void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low,
- u32 high)
+void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high)
{
u8 hi_start, hi_end, lo_start, lo_end;
u32 unit;
@@ -1169,17 +1134,12 @@ static void dispc_ovl_set_scale_param(enum omap_plane plane,
enum omap_color_component color_comp)
{
int fir_hinc, fir_vinc;
- int hscaleup, vscaleup;
-
- hscaleup = orig_width <= out_width;
- vscaleup = orig_height <= out_height;
-
- dispc_ovl_set_scale_coef(plane, hscaleup, vscaleup, five_taps,
- color_comp);
fir_hinc = 1024 * orig_width / out_width;
fir_vinc = 1024 * orig_height / out_height;
+ dispc_ovl_set_scale_coef(plane, fir_hinc, fir_vinc, five_taps,
+ color_comp);
dispc_ovl_set_fir(plane, fir_hinc, fir_vinc, color_comp);
}
@@ -1654,6 +1614,9 @@ static unsigned long calc_fclk_five_taps(enum omap_channel channel, u16 width,
u32 fclk = 0;
u64 tmp, pclk = dispc_mgr_pclk_rate(channel);
+ if (height <= out_height && width <= out_width)
+ return (unsigned long) pclk;
+
if (height > out_height) {
struct omap_dss_device *dssdev = dispc_mgr_get_device(channel);
unsigned int ppl = dssdev->panel.timings.x_res;
@@ -1708,7 +1671,16 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
else
vf = 1;
- return dispc_mgr_pclk_rate(channel) * vf * hf;
+ if (cpu_is_omap24xx()) {
+ if (vf > 1 && hf > 1)
+ return dispc_mgr_pclk_rate(channel) * 4;
+ else
+ return dispc_mgr_pclk_rate(channel) * 2;
+ } else if (cpu_is_omap34xx()) {
+ return dispc_mgr_pclk_rate(channel) * vf * hf;
+ } else {
+ return dispc_mgr_pclk_rate(channel) * hf;
+ }
}
static int dispc_ovl_calc_scaling(enum omap_plane plane,
@@ -1718,6 +1690,8 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
+ const int maxsinglelinewidth =
+ dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
unsigned long fclk = 0;
if (width == out_width && height == out_height)
@@ -1734,28 +1708,40 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
out_height > height * 8)
return -EINVAL;
- /* Must use 5-tap filter? */
- *five_taps = height > out_height * 2;
-
- if (!*five_taps) {
+ if (cpu_is_omap24xx()) {
+ if (width > maxsinglelinewidth)
+ DSSERR("Cannot scale max input width exceeded");
+ *five_taps = false;
+ fclk = calc_fclk(channel, width, height, out_width,
+ out_height);
+ } else if (cpu_is_omap34xx()) {
+ if (width > (maxsinglelinewidth * 2)) {
+ DSSERR("Cannot setup scaling");
+ DSSERR("width exceeds maximum width possible");
+ return -EINVAL;
+ }
+ fclk = calc_fclk_five_taps(channel, width, height, out_width,
+ out_height, color_mode);
+ if (width > maxsinglelinewidth) {
+ if (height > out_height && height < out_height * 2)
+ *five_taps = false;
+ else {
+ DSSERR("cannot setup scaling with five taps");
+ return -EINVAL;
+ }
+ }
+ if (!*five_taps)
+ fclk = calc_fclk(channel, width, height, out_width,
+ out_height);
+ } else {
+ if (width > maxsinglelinewidth) {
+ DSSERR("Cannot scale width exceeds max line width");
+ return -EINVAL;
+ }
fclk = calc_fclk(channel, width, height, out_width,
out_height);
-
- /* Try 5-tap filter if 3-tap fclk is too high */
- if (cpu_is_omap34xx() && height > out_height &&
- fclk > dispc_fclk_rate())
- *five_taps = true;
- }
-
- if (width > (2048 >> *five_taps)) {
- DSSERR("failed to set up scaling, fclk too low\n");
- return -EINVAL;
}
- if (*five_taps)
- fclk = calc_fclk_five_taps(channel, width, height,
- out_width, out_height, color_mode);
-
DSSDBG("required fclk rate = %lu Hz\n", fclk);
DSSDBG("current fclk rate = %lu Hz\n", dispc_fclk_rate());
@@ -1771,11 +1757,10 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
}
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
- bool ilace, enum omap_channel channel, bool replication,
- u32 fifo_low, u32 fifo_high)
+ bool ilace, bool replication)
{
struct omap_overlay *ovl = omap_dss_get_overlay(plane);
- bool five_taps = false;
+ bool five_taps = true;
bool fieldmode = 0;
int r, cconv = 0;
unsigned offset0, offset1;
@@ -1783,36 +1768,43 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
s32 pix_inc;
u16 frame_height = oi->height;
unsigned int field_offset = 0;
+ u16 outw, outh;
+ enum omap_channel channel;
+
+ channel = dispc_ovl_get_channel_out(plane);
DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
- "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d "
- "fifo_low %d fifo high %d\n", plane, oi->paddr, oi->p_uv_addr,
+ "%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
+ plane, oi->paddr, oi->p_uv_addr,
oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
- oi->mirror, ilace, channel, replication, fifo_low, fifo_high);
+ oi->mirror, ilace, channel, replication);
if (oi->paddr == 0)
return -EINVAL;
- if (ilace && oi->height == oi->out_height)
+ outw = oi->out_width == 0 ? oi->width : oi->out_width;
+ outh = oi->out_height == 0 ? oi->height : oi->out_height;
+
+ if (ilace && oi->height == outh)
fieldmode = 1;
if (ilace) {
if (fieldmode)
oi->height /= 2;
oi->pos_y /= 2;
- oi->out_height /= 2;
+ outh /= 2;
DSSDBG("adjusting for ilace: height %d, pos_y %d, "
"out_height %d\n",
- oi->height, oi->pos_y, oi->out_height);
+ oi->height, oi->pos_y, outh);
}
if (!dss_feat_color_mode_supported(plane, oi->color_mode))
return -EINVAL;
r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height,
- oi->out_width, oi->out_height, oi->color_mode,
+ outw, outh, oi->color_mode,
&five_taps);
if (r)
return r;
@@ -1830,10 +1822,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
* so the integer part must be added to the base address of the
* bottom field.
*/
- if (!oi->height || oi->height == oi->out_height)
+ if (!oi->height || oi->height == outh)
field_offset = 0;
else
- field_offset = oi->height / oi->out_height / 2;
+ field_offset = oi->height / outh / 2;
}
/* Fields are independent but interleaved in memory. */
@@ -1869,7 +1861,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
dispc_ovl_set_pix_inc(plane, pix_inc);
DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width,
- oi->height, oi->out_width, oi->out_height);
+ oi->height, outw, outh);
dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
@@ -1877,10 +1869,10 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
dispc_ovl_set_scaling(plane, oi->width, oi->height,
- oi->out_width, oi->out_height,
+ outw, outh,
ilace, five_taps, fieldmode,
oi->color_mode, oi->rotation);
- dispc_ovl_set_vid_size(plane, oi->out_width, oi->out_height);
+ dispc_ovl_set_vid_size(plane, outw, outh);
dispc_ovl_set_vid_color_conv(plane, cconv);
}
@@ -1891,10 +1883,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
- dispc_ovl_set_channel_out(plane, channel);
-
dispc_ovl_enable_replication(plane, replication);
- dispc_ovl_set_fifo_threshold(plane, fifo_low, fifo_high);
return 0;
}
@@ -1916,10 +1905,14 @@ static void dispc_disable_isr(void *data, u32 mask)
static void _enable_lcd_out(enum omap_channel channel, bool enable)
{
- if (channel == OMAP_DSS_CHANNEL_LCD2)
+ if (channel == OMAP_DSS_CHANNEL_LCD2) {
REG_FLD_MOD(DISPC_CONTROL2, enable ? 1 : 0, 0, 0);
- else
+ /* flush posted write */
+ dispc_read_reg(DISPC_CONTROL2);
+ } else {
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
+ dispc_read_reg(DISPC_CONTROL);
+ }
}
static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
@@ -1967,6 +1960,8 @@ static void dispc_mgr_enable_lcd_out(enum omap_channel channel, bool enable)
static void _enable_digit_out(bool enable)
{
REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
+ /* flush posted write */
+ dispc_read_reg(DISPC_CONTROL);
}
static void dispc_mgr_enable_digit_out(bool enable)
@@ -2124,25 +2119,12 @@ void dispc_set_loadmode(enum omap_dss_load_mode mode)
}
-void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
+static void dispc_mgr_set_default_color(enum omap_channel channel, u32 color)
{
dispc_write_reg(DISPC_DEFAULT_COLOR(channel), color);
}
-u32 dispc_mgr_get_default_color(enum omap_channel channel)
-{
- u32 l;
-
- BUG_ON(channel != OMAP_DSS_CHANNEL_DIGIT &&
- channel != OMAP_DSS_CHANNEL_LCD &&
- channel != OMAP_DSS_CHANNEL_LCD2);
-
- l = dispc_read_reg(DISPC_DEFAULT_COLOR(channel));
-
- return l;
-}
-
-void dispc_mgr_set_trans_key(enum omap_channel ch,
+static void dispc_mgr_set_trans_key(enum omap_channel ch,
enum omap_dss_trans_key_type type,
u32 trans_key)
{
@@ -2156,26 +2138,7 @@ void dispc_mgr_set_trans_key(enum omap_channel ch,
dispc_write_reg(DISPC_TRANS_COLOR(ch), trans_key);
}
-void dispc_mgr_get_trans_key(enum omap_channel ch,
- enum omap_dss_trans_key_type *type,
- u32 *trans_key)
-{
- if (type) {
- if (ch == OMAP_DSS_CHANNEL_LCD)
- *type = REG_GET(DISPC_CONFIG, 11, 11);
- else if (ch == OMAP_DSS_CHANNEL_DIGIT)
- *type = REG_GET(DISPC_CONFIG, 13, 13);
- else if (ch == OMAP_DSS_CHANNEL_LCD2)
- *type = REG_GET(DISPC_CONFIG2, 11, 11);
- else
- BUG();
- }
-
- if (trans_key)
- *trans_key = dispc_read_reg(DISPC_TRANS_COLOR(ch));
-}
-
-void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
+static void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
{
if (ch == OMAP_DSS_CHANNEL_LCD)
REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
@@ -2185,7 +2148,8 @@ void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable)
REG_FLD_MOD(DISPC_CONFIG2, enable, 10, 10);
}
-void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable)
+static void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch,
+ bool enable)
{
if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
return;
@@ -2196,40 +2160,20 @@ void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable)
REG_FLD_MOD(DISPC_CONFIG, enable, 19, 19);
}
-bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch)
-{
- bool enabled;
-
- if (!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER))
- return false;
-
- if (ch == OMAP_DSS_CHANNEL_LCD)
- enabled = REG_GET(DISPC_CONFIG, 18, 18);
- else if (ch == OMAP_DSS_CHANNEL_DIGIT)
- enabled = REG_GET(DISPC_CONFIG, 19, 19);
- else
- BUG();
-
- return enabled;
-}
-
-bool dispc_mgr_trans_key_enabled(enum omap_channel ch)
+void dispc_mgr_setup(enum omap_channel channel,
+ struct omap_overlay_manager_info *info)
{
- bool enabled;
-
- if (ch == OMAP_DSS_CHANNEL_LCD)
- enabled = REG_GET(DISPC_CONFIG, 10, 10);
- else if (ch == OMAP_DSS_CHANNEL_DIGIT)
- enabled = REG_GET(DISPC_CONFIG, 12, 12);
- else if (ch == OMAP_DSS_CHANNEL_LCD2)
- enabled = REG_GET(DISPC_CONFIG2, 10, 10);
- else
- BUG();
-
- return enabled;
+ dispc_mgr_set_default_color(channel, info->default_color);
+ dispc_mgr_set_trans_key(channel, info->trans_key_type, info->trans_key);
+ dispc_mgr_enable_trans_key(channel, info->trans_enabled);
+ dispc_mgr_enable_alpha_fixed_zorder(channel,
+ info->partial_alpha_enabled);
+ if (dss_has_feature(FEAT_CPR)) {
+ dispc_mgr_enable_cpr(channel, info->cpr_enable);
+ dispc_mgr_set_cpr_coef(channel, &info->cpr_coefs);
+ }
}
-
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines)
{
int code;
@@ -3184,7 +3128,8 @@ static void dispc_error_worker(struct work_struct *work)
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
struct omap_overlay_manager *mgr;
mgr = omap_dss_get_overlay_manager(i);
- mgr->device->driver->disable(mgr->device);
+ if (mgr->device && mgr->device->driver)
+ mgr->device->driver->disable(mgr->device);
}
}
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index c06efc38983e..5836bd1650f9 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -97,6 +97,17 @@
#define DISPC_OVL_PRELOAD(n) (DISPC_OVL_BASE(n) + \
DISPC_PRELOAD_OFFSET(n))
+/* DISPC up/downsampling FIR filter coefficient structure */
+struct dispc_coef {
+ s8 hc4_vc22;
+ s8 hc3_vc2;
+ u8 hc2_vc1;
+ s8 hc1_vc0;
+ s8 hc0_vc00;
+};
+
+const struct dispc_coef *dispc_ovl_get_scale_coef(int inc, int five_taps);
+
/* DISPC manager/channel specific registers */
static inline u16 DISPC_DEFAULT_COLOR(enum omap_channel channel)
{
diff --git a/drivers/video/omap2/dss/dispc_coefs.c b/drivers/video/omap2/dss/dispc_coefs.c
new file mode 100644
index 000000000000..069bccbb3f12
--- /dev/null
+++ b/drivers/video/omap2/dss/dispc_coefs.c
@@ -0,0 +1,326 @@
+/*
+ * linux/drivers/video/omap2/dss/dispc_coefs.c
+ *
+ * Copyright (C) 2011 Texas Instruments
+ * Author: Chandrabhanu Mahapatra <cmahapatra@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <video/omapdss.h>
+#include "dispc.h"
+
+#define ARRAY_LEN(array) (sizeof(array) / sizeof(array[0]))
+
+static const struct dispc_coef coef3_M8[8] = {
+ { 0, 0, 128, 0, 0 },
+ { 0, -4, 123, 9, 0 },
+ { 0, -4, 108, 87, 0 },
+ { 0, -2, 87, 43, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 43, 87, -2, 0 },
+ { 0, 24, 108, -4, 0 },
+ { 0, 9, 123, -4, 0 },
+};
+
+static const struct dispc_coef coef3_M9[8] = {
+ { 0, 6, 116, 6, 0 },
+ { 0, 0, 112, 16, 0 },
+ { 0, -2, 100, 30, 0 },
+ { 0, -2, 83, 47, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 47, 83, -2, 0 },
+ { 0, 30, 100, -2, 0 },
+ { 0, 16, 112, 0, 0 },
+};
+
+static const struct dispc_coef coef3_M10[8] = {
+ { 0, 10, 108, 10, 0 },
+ { 0, 3, 104, 21, 0 },
+ { 0, 0, 94, 34, 0 },
+ { 0, -1, 80, 49, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 49, 80, -1, 0 },
+ { 0, 34, 94, 0, 0 },
+ { 0, 21, 104, 3, 0 },
+};
+
+static const struct dispc_coef coef3_M11[8] = {
+ { 0, 14, 100, 14, 0 },
+ { 0, 6, 98, 24, 0 },
+ { 0, 2, 90, 36, 0 },
+ { 0, 0, 78, 50, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 50, 78, 0, 0 },
+ { 0, 36, 90, 2, 0 },
+ { 0, 24, 98, 6, 0 },
+};
+
+static const struct dispc_coef coef3_M12[8] = {
+ { 0, 16, 96, 16, 0 },
+ { 0, 9, 93, 26, 0 },
+ { 0, 4, 86, 38, 0 },
+ { 0, 1, 76, 51, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 51, 76, 1, 0 },
+ { 0, 38, 86, 4, 0 },
+ { 0, 26, 93, 9, 0 },
+};
+
+static const struct dispc_coef coef3_M13[8] = {
+ { 0, 18, 92, 18, 0 },
+ { 0, 10, 90, 28, 0 },
+ { 0, 5, 83, 40, 0 },
+ { 0, 1, 75, 52, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 52, 75, 1, 0 },
+ { 0, 40, 83, 5, 0 },
+ { 0, 28, 90, 10, 0 },
+};
+
+static const struct dispc_coef coef3_M14[8] = {
+ { 0, 20, 88, 20, 0 },
+ { 0, 12, 86, 30, 0 },
+ { 0, 6, 81, 41, 0 },
+ { 0, 2, 74, 52, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 52, 74, 2, 0 },
+ { 0, 41, 81, 6, 0 },
+ { 0, 30, 86, 12, 0 },
+};
+
+static const struct dispc_coef coef3_M16[8] = {
+ { 0, 22, 84, 22, 0 },
+ { 0, 14, 82, 32, 0 },
+ { 0, 8, 78, 42, 0 },
+ { 0, 3, 72, 53, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 53, 72, 3, 0 },
+ { 0, 42, 78, 8, 0 },
+ { 0, 32, 82, 14, 0 },
+};
+
+static const struct dispc_coef coef3_M19[8] = {
+ { 0, 24, 80, 24, 0 },
+ { 0, 16, 79, 33, 0 },
+ { 0, 9, 76, 43, 0 },
+ { 0, 4, 70, 54, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 54, 70, 4, 0 },
+ { 0, 43, 76, 9, 0 },
+ { 0, 33, 79, 16, 0 },
+};
+
+static const struct dispc_coef coef3_M22[8] = {
+ { 0, 25, 78, 25, 0 },
+ { 0, 17, 77, 34, 0 },
+ { 0, 10, 74, 44, 0 },
+ { 0, 5, 69, 54, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 54, 69, 5, 0 },
+ { 0, 44, 74, 10, 0 },
+ { 0, 34, 77, 17, 0 },
+};
+
+static const struct dispc_coef coef3_M26[8] = {
+ { 0, 26, 76, 26, 0 },
+ { 0, 19, 74, 35, 0 },
+ { 0, 11, 72, 45, 0 },
+ { 0, 5, 69, 54, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 54, 69, 5, 0 },
+ { 0, 45, 72, 11, 0 },
+ { 0, 35, 74, 19, 0 },
+};
+
+static const struct dispc_coef coef3_M32[8] = {
+ { 0, 27, 74, 27, 0 },
+ { 0, 19, 73, 36, 0 },
+ { 0, 12, 71, 45, 0 },
+ { 0, 6, 68, 54, 0 },
+ { 0, 64, 64, 0, 0 },
+ { 0, 54, 68, 6, 0 },
+ { 0, 45, 71, 12, 0 },
+ { 0, 36, 73, 19, 0 },
+};
+
+static const struct dispc_coef coef5_M8[8] = {
+ { 0, 0, 128, 0, 0 },
+ { -2, 14, 125, -10, 1 },
+ { -6, 33, 114, -15, 2 },
+ { -10, 55, 98, -16, 1 },
+ { 0, -14, 78, 78, -14 },
+ { 1, -16, 98, 55, -10 },
+ { 2, -15, 114, 33, -6 },
+ { 1, -10, 125, 14, -2 },
+};
+
+static const struct dispc_coef coef5_M9[8] = {
+ { -3, 10, 114, 10, -3 },
+ { -6, 24, 110, 0, -1 },
+ { -8, 40, 103, -7, 0 },
+ { -11, 58, 91, -11, 1 },
+ { 0, -12, 76, 76, -12 },
+ { 1, -11, 91, 58, -11 },
+ { 0, -7, 103, 40, -8 },
+ { -1, 0, 111, 24, -6 },
+};
+
+static const struct dispc_coef coef5_M10[8] = {
+ { -4, 18, 100, 18, -4 },
+ { -6, 30, 99, 8, -3 },
+ { -8, 44, 93, 0, -1 },
+ { -9, 58, 84, -5, 0 },
+ { 0, -8, 72, 72, -8 },
+ { 0, -5, 84, 58, -9 },
+ { -1, 0, 93, 44, -8 },
+ { -3, 8, 99, 30, -6 },
+};
+
+static const struct dispc_coef coef5_M11[8] = {
+ { -5, 23, 92, 23, -5 },
+ { -6, 34, 90, 13, -3 },
+ { -6, 45, 85, 6, -2 },
+ { -6, 57, 78, 0, -1 },
+ { 0, -4, 68, 68, -4 },
+ { -1, 0, 78, 57, -6 },
+ { -2, 6, 85, 45, -6 },
+ { -3, 13, 90, 34, -6 },
+};
+
+static const struct dispc_coef coef5_M12[8] = {
+ { -4, 26, 84, 26, -4 },
+ { -5, 36, 82, 18, -3 },
+ { -4, 46, 78, 10, -2 },
+ { -3, 55, 72, 5, -1 },
+ { 0, 0, 64, 64, 0 },
+ { -1, 5, 72, 55, -3 },
+ { -2, 10, 78, 46, -4 },
+ { -3, 18, 82, 36, -5 },
+};
+
+static const struct dispc_coef coef5_M13[8] = {
+ { -3, 28, 78, 28, -3 },
+ { -3, 37, 76, 21, -3 },
+ { -2, 45, 73, 14, -2 },
+ { 0, 53, 68, 8, -1 },
+ { 0, 3, 61, 61, 3 },
+ { -1, 8, 68, 53, 0 },
+ { -2, 14, 73, 45, -2 },
+ { -3, 21, 76, 37, -3 },
+};
+
+static const struct dispc_coef coef5_M14[8] = {
+ { -2, 30, 72, 30, -2 },
+ { -1, 37, 71, 23, -2 },
+ { 0, 45, 69, 16, -2 },
+ { 3, 52, 64, 10, -1 },
+ { 0, 6, 58, 58, 6 },
+ { -1, 10, 64, 52, 3 },
+ { -2, 16, 69, 45, 0 },
+ { -2, 23, 71, 37, -1 },
+};
+
+static const struct dispc_coef coef5_M16[8] = {
+ { 0, 31, 66, 31, 0 },
+ { 1, 38, 65, 25, -1 },
+ { 3, 44, 62, 20, -1 },
+ { 6, 49, 59, 14, 0 },
+ { 0, 10, 54, 54, 10 },
+ { 0, 14, 59, 49, 6 },
+ { -1, 20, 62, 44, 3 },
+ { -1, 25, 65, 38, 1 },
+};
+
+static const struct dispc_coef coef5_M19[8] = {
+ { 3, 32, 58, 32, 3 },
+ { 4, 38, 58, 27, 1 },
+ { 7, 42, 55, 23, 1 },
+ { 10, 46, 54, 18, 0 },
+ { 0, 14, 50, 50, 14 },
+ { 0, 18, 54, 46, 10 },
+ { 1, 23, 55, 42, 7 },
+ { 1, 27, 58, 38, 4 },
+};
+
+static const struct dispc_coef coef5_M22[8] = {
+ { 4, 33, 54, 33, 4 },
+ { 6, 37, 54, 28, 3 },
+ { 9, 41, 53, 24, 1 },
+ { 12, 45, 51, 20, 0 },
+ { 0, 16, 48, 48, 16 },
+ { 0, 20, 51, 45, 12 },
+ { 1, 24, 53, 41, 9 },
+ { 3, 28, 54, 37, 6 },
+};
+
+static const struct dispc_coef coef5_M26[8] = {
+ { 6, 33, 50, 33, 6 },
+ { 8, 36, 51, 29, 4 },
+ { 11, 40, 50, 25, 2 },
+ { 14, 43, 48, 22, 1 },
+ { 0, 18, 46, 46, 18 },
+ { 1, 22, 48, 43, 14 },
+ { 2, 25, 50, 40, 11 },
+ { 4, 29, 51, 36, 8 },
+};
+
+static const struct dispc_coef coef5_M32[8] = {
+ { 7, 33, 48, 33, 7 },
+ { 10, 36, 48, 29, 5 },
+ { 13, 39, 47, 26, 3 },
+ { 16, 42, 46, 23, 1 },
+ { 0, 19, 45, 45, 19 },
+ { 1, 23, 46, 42, 16 },
+ { 3, 26, 47, 39, 13 },
+ { 5, 29, 48, 36, 10 },
+};
+
+const struct dispc_coef *dispc_ovl_get_scale_coef(int inc, int five_taps)
+{
+ int i;
+ static const struct {
+ int Mmin;
+ int Mmax;
+ const struct dispc_coef *coef_3;
+ const struct dispc_coef *coef_5;
+ } coefs[] = {
+ { 27, 32, coef3_M32, coef5_M32 },
+ { 23, 26, coef3_M26, coef5_M26 },
+ { 20, 22, coef3_M22, coef5_M22 },
+ { 17, 19, coef3_M19, coef5_M19 },
+ { 15, 16, coef3_M16, coef5_M16 },
+ { 14, 14, coef3_M14, coef5_M14 },
+ { 13, 13, coef3_M13, coef5_M13 },
+ { 12, 12, coef3_M12, coef5_M12 },
+ { 11, 11, coef3_M11, coef5_M11 },
+ { 10, 10, coef3_M10, coef5_M10 },
+ { 9, 9, coef3_M9, coef5_M9 },
+ { 4, 8, coef3_M8, coef5_M8 },
+ /*
+ * When upscaling more than two times, blockiness and outlines
+ * around the image are observed when M8 tables are used. M11,
+ * M16 and M19 tables are used to prevent this.
+ */
+ { 3, 3, coef3_M11, coef5_M11 },
+ { 2, 2, coef3_M16, coef5_M16 },
+ { 0, 1, coef3_M19, coef5_M19 },
+ };
+
+ inc /= 128;
+ for (i = 0; i < ARRAY_LEN(coefs); ++i)
+ if (inc >= coefs[i].Mmin && inc <= coefs[i].Mmax)
+ return five_taps ? coefs[i].coef_5 : coefs[i].coef_3;
+ return NULL;
+}
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 976ac23dcd0c..395d658a94fc 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -223,10 +223,13 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
mdelay(2);
- dssdev->manager->enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ goto err_mgr_enable;
return 0;
+err_mgr_enable:
err_set_mode:
if (dpi_use_dsi_pll(dssdev))
dsi_pll_uninit(dpi.dsidev, true);
@@ -249,7 +252,7 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{
- dssdev->manager->disable(dssdev->manager);
+ dss_mgr_disable(dssdev->manager);
if (dpi_use_dsi_pll(dssdev)) {
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 5abf8e7e7456..d4d676c82c12 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -203,6 +203,21 @@ struct dsi_reg { u16 idx; };
typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
#define DSI_MAX_NR_ISRS 2
+#define DSI_MAX_NR_LANES 5
+
+enum dsi_lane_function {
+ DSI_LANE_UNUSED = 0,
+ DSI_LANE_CLK,
+ DSI_LANE_DATA1,
+ DSI_LANE_DATA2,
+ DSI_LANE_DATA3,
+ DSI_LANE_DATA4,
+};
+
+struct dsi_lane_config {
+ enum dsi_lane_function function;
+ u8 polarity;
+};
struct dsi_isr_data {
omap_dsi_isr_t isr;
@@ -223,24 +238,6 @@ enum dsi_vc_source {
DSI_VC_SOURCE_VP,
};
-enum dsi_lane {
- DSI_CLK_P = 1 << 0,
- DSI_CLK_N = 1 << 1,
- DSI_DATA1_P = 1 << 2,
- DSI_DATA1_N = 1 << 3,
- DSI_DATA2_P = 1 << 4,
- DSI_DATA2_N = 1 << 5,
- DSI_DATA3_P = 1 << 6,
- DSI_DATA3_N = 1 << 7,
- DSI_DATA4_P = 1 << 8,
- DSI_DATA4_N = 1 << 9,
-};
-
-struct dsi_update_region {
- u16 x, y, w, h;
- struct omap_dss_device *device;
-};
-
struct dsi_irq_stats {
unsigned long last_reset;
unsigned irq_count;
@@ -290,7 +287,9 @@ struct dsi_data {
struct dsi_isr_tables isr_tables_copy;
int update_channel;
- struct dsi_update_region update_region;
+#ifdef DEBUG
+ unsigned update_bytes;
+#endif
bool te_enabled;
bool ulps_enabled;
@@ -327,7 +326,10 @@ struct dsi_data {
unsigned long fint_min, fint_max;
unsigned long lpdiv_max;
- int num_data_lanes;
+ unsigned num_lanes_supported;
+
+ struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
+ unsigned num_lanes_used;
unsigned scp_clk_refcount;
};
@@ -340,8 +342,8 @@ struct dsi_packet_sent_handler_data {
static struct platform_device *dsi_pdev_map[MAX_NUM_DSI];
#ifdef DEBUG
-static unsigned int dsi_perf;
-module_param_named(dsi_perf, dsi_perf, bool, 0644);
+static bool dsi_perf;
+module_param(dsi_perf, bool, 0644);
#endif
static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dsidev)
@@ -413,14 +415,29 @@ static void dsi_completion_handler(void *data, u32 mask)
static inline int wait_for_bit_change(struct platform_device *dsidev,
const struct dsi_reg idx, int bitnum, int value)
{
- int t = 100000;
+ unsigned long timeout;
+ ktime_t wait;
+ int t;
- while (REG_GET(dsidev, idx, bitnum, bitnum) != value) {
- if (--t == 0)
- return !value;
+ /* first busyloop to see if the bit changes right away */
+ t = 100;
+ while (t-- > 0) {
+ if (REG_GET(dsidev, idx, bitnum, bitnum) == value)
+ return value;
}
- return value;
+ /* then loop for 500ms, sleeping for 1ms in between */
+ timeout = jiffies + msecs_to_jiffies(500);
+ while (time_before(jiffies, timeout)) {
+ if (REG_GET(dsidev, idx, bitnum, bitnum) == value)
+ return value;
+
+ wait = ns_to_ktime(1000 * 1000);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_hrtimeout(&wait, HRTIMER_MODE_REL);
+ }
+
+ return !value;
}
u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt)
@@ -454,7 +471,6 @@ static void dsi_perf_mark_start(struct platform_device *dsidev)
static void dsi_perf_show(struct platform_device *dsidev, const char *name)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- struct omap_dss_device *dssdev = dsi->update_region.device;
ktime_t t, setup_time, trans_time;
u32 total_bytes;
u32 setup_us, trans_us, total_us;
@@ -476,9 +492,7 @@ static void dsi_perf_show(struct platform_device *dsidev, const char *name)
total_us = setup_us + trans_us;
- total_bytes = dsi->update_region.w *
- dsi->update_region.h *
- dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
+ total_bytes = dsi->update_bytes;
printk(KERN_INFO "DSI(%s): %u us + %u us = %u us (%uHz), "
"%u bytes, %u kbytes/sec\n",
@@ -1720,17 +1734,19 @@ static void dsi_dump_dsidev_clocks(struct platform_device *dsidev,
seq_printf(s, "CLKIN4DDR\t%-16luregm %u\n",
cinfo->clkin4ddr, cinfo->regm);
- seq_printf(s, "%s (%s)\t%-16luregm_dispc %u\t(%s)\n",
- dss_get_generic_clk_source_name(dispc_clk_src),
- dss_feat_get_clk_source_name(dispc_clk_src),
+ seq_printf(s, "DSI_PLL_HSDIV_DISPC (%s)\t%-16luregm_dispc %u\t(%s)\n",
+ dss_feat_get_clk_source_name(dsi_module == 0 ?
+ OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
+ OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC),
cinfo->dsi_pll_hsdiv_dispc_clk,
cinfo->regm_dispc,
dispc_clk_src == OMAP_DSS_CLK_SRC_FCK ?
"off" : "on");
- seq_printf(s, "%s (%s)\t%-16luregm_dsi %u\t(%s)\n",
- dss_get_generic_clk_source_name(dsi_clk_src),
- dss_feat_get_clk_source_name(dsi_clk_src),
+ seq_printf(s, "DSI_PLL_HSDIV_DSI (%s)\t%-16luregm_dsi %u\t(%s)\n",
+ dss_feat_get_clk_source_name(dsi_module == 0 ?
+ OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
+ OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI),
cinfo->dsi_pll_hsdiv_dsi_clk,
cinfo->regm_dsi,
dsi_clk_src == OMAP_DSS_CLK_SRC_FCK ?
@@ -2029,34 +2045,6 @@ static int dsi_cio_power(struct platform_device *dsidev,
return 0;
}
-/* Number of data lanes present on DSI interface */
-static inline int dsi_get_num_data_lanes(struct platform_device *dsidev)
-{
- /* DSI on OMAP3 doesn't have register DSI_GNQ, set number
- * of data lanes as 2 by default */
- if (dss_has_feature(FEAT_DSI_GNQ))
- return REG_GET(dsidev, DSI_GNQ, 11, 9); /* NB_DATA_LANES */
- else
- return 2;
-}
-
-/* Number of data lanes used by the dss device */
-static inline int dsi_get_num_data_lanes_dssdev(struct omap_dss_device *dssdev)
-{
- int num_data_lanes = 0;
-
- if (dssdev->phy.dsi.data1_lane != 0)
- num_data_lanes++;
- if (dssdev->phy.dsi.data2_lane != 0)
- num_data_lanes++;
- if (dssdev->phy.dsi.data3_lane != 0)
- num_data_lanes++;
- if (dssdev->phy.dsi.data4_lane != 0)
- num_data_lanes++;
-
- return num_data_lanes;
-}
-
static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
{
int val;
@@ -2088,59 +2076,112 @@ static unsigned dsi_get_line_buf_size(struct platform_device *dsidev)
}
}
-static void dsi_set_lane_config(struct omap_dss_device *dssdev)
+static int dsi_parse_lane_config(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- u32 r;
- int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ u8 lanes[DSI_MAX_NR_LANES];
+ u8 polarities[DSI_MAX_NR_LANES];
+ int num_lanes, i;
+
+ static const enum dsi_lane_function functions[] = {
+ DSI_LANE_CLK,
+ DSI_LANE_DATA1,
+ DSI_LANE_DATA2,
+ DSI_LANE_DATA3,
+ DSI_LANE_DATA4,
+ };
+
+ lanes[0] = dssdev->phy.dsi.clk_lane;
+ lanes[1] = dssdev->phy.dsi.data1_lane;
+ lanes[2] = dssdev->phy.dsi.data2_lane;
+ lanes[3] = dssdev->phy.dsi.data3_lane;
+ lanes[4] = dssdev->phy.dsi.data4_lane;
+ polarities[0] = dssdev->phy.dsi.clk_pol;
+ polarities[1] = dssdev->phy.dsi.data1_pol;
+ polarities[2] = dssdev->phy.dsi.data2_pol;
+ polarities[3] = dssdev->phy.dsi.data3_pol;
+ polarities[4] = dssdev->phy.dsi.data4_pol;
- int clk_lane = dssdev->phy.dsi.clk_lane;
- int data1_lane = dssdev->phy.dsi.data1_lane;
- int data2_lane = dssdev->phy.dsi.data2_lane;
- int clk_pol = dssdev->phy.dsi.clk_pol;
- int data1_pol = dssdev->phy.dsi.data1_pol;
- int data2_pol = dssdev->phy.dsi.data2_pol;
+ num_lanes = 0;
+
+ for (i = 0; i < dsi->num_lanes_supported; ++i)
+ dsi->lanes[i].function = DSI_LANE_UNUSED;
+
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ int num;
+
+ if (lanes[i] == DSI_LANE_UNUSED)
+ break;
+
+ num = lanes[i] - 1;
+
+ if (num >= dsi->num_lanes_supported)
+ return -EINVAL;
+
+ if (dsi->lanes[num].function != DSI_LANE_UNUSED)
+ return -EINVAL;
+
+ dsi->lanes[num].function = functions[i];
+ dsi->lanes[num].polarity = polarities[i];
+ num_lanes++;
+ }
+
+ if (num_lanes < 2 || num_lanes > dsi->num_lanes_supported)
+ return -EINVAL;
+
+ dsi->num_lanes_used = num_lanes;
+
+ return 0;
+}
+
+static int dsi_set_lane_config(struct omap_dss_device *dssdev)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ static const u8 offsets[] = { 0, 4, 8, 12, 16 };
+ static const enum dsi_lane_function functions[] = {
+ DSI_LANE_CLK,
+ DSI_LANE_DATA1,
+ DSI_LANE_DATA2,
+ DSI_LANE_DATA3,
+ DSI_LANE_DATA4,
+ };
+ u32 r;
+ int i;
r = dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG1);
- r = FLD_MOD(r, clk_lane, 2, 0);
- r = FLD_MOD(r, clk_pol, 3, 3);
- r = FLD_MOD(r, data1_lane, 6, 4);
- r = FLD_MOD(r, data1_pol, 7, 7);
- r = FLD_MOD(r, data2_lane, 10, 8);
- r = FLD_MOD(r, data2_pol, 11, 11);
- if (num_data_lanes_dssdev > 2) {
- int data3_lane = dssdev->phy.dsi.data3_lane;
- int data3_pol = dssdev->phy.dsi.data3_pol;
-
- r = FLD_MOD(r, data3_lane, 14, 12);
- r = FLD_MOD(r, data3_pol, 15, 15);
+
+ for (i = 0; i < dsi->num_lanes_used; ++i) {
+ unsigned offset = offsets[i];
+ unsigned polarity, lane_number;
+ unsigned t;
+
+ for (t = 0; t < dsi->num_lanes_supported; ++t)
+ if (dsi->lanes[t].function == functions[i])
+ break;
+
+ if (t == dsi->num_lanes_supported)
+ return -EINVAL;
+
+ lane_number = t;
+ polarity = dsi->lanes[t].polarity;
+
+ r = FLD_MOD(r, lane_number + 1, offset + 2, offset);
+ r = FLD_MOD(r, polarity, offset + 3, offset + 3);
}
- if (num_data_lanes_dssdev > 3) {
- int data4_lane = dssdev->phy.dsi.data4_lane;
- int data4_pol = dssdev->phy.dsi.data4_pol;
- r = FLD_MOD(r, data4_lane, 18, 16);
- r = FLD_MOD(r, data4_pol, 19, 19);
+ /* clear the unused lanes */
+ for (; i < dsi->num_lanes_supported; ++i) {
+ unsigned offset = offsets[i];
+
+ r = FLD_MOD(r, 0, offset + 2, offset);
+ r = FLD_MOD(r, 0, offset + 3, offset + 3);
}
- dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
- /* The configuration of the DSI complex I/O (number of data lanes,
- position, differential order) should not be changed while
- DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. In order for
- the hardware to take into account a new configuration of the complex
- I/O (done in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to
- follow this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1,
- then reset the DSS.DSI_CTRL[0] IF_EN to 0, then set
- DSS.DSI_CLK_CTRL[20] LP_CLK_ENABLE to 1 and finally set again the
- DSS.DSI_CTRL[0] IF_EN bit to 1. If the sequence is not followed, the
- DSI complex I/O configuration is unknown. */
+ dsi_write_reg(dsidev, DSI_COMPLEXIO_CFG1, r);
- /*
- REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
- REG_FLD_MOD(dsidev, DSI_CTRL, 0, 0, 0);
- REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 1, 20, 20);
- REG_FLD_MOD(dsidev, DSI_CTRL, 1, 0, 0);
- */
+ return 0;
}
static inline unsigned ns2ddr(struct platform_device *dsidev, unsigned ns)
@@ -2230,49 +2271,28 @@ static void dsi_cio_timings(struct platform_device *dsidev)
dsi_write_reg(dsidev, DSI_DSIPHY_CFG2, r);
}
+/* lane masks have lane 0 at lsb. mask_p for positive lines, n for negative */
static void dsi_cio_enable_lane_override(struct omap_dss_device *dssdev,
- enum dsi_lane lanes)
+ unsigned mask_p, unsigned mask_n)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- int clk_lane = dssdev->phy.dsi.clk_lane;
- int data1_lane = dssdev->phy.dsi.data1_lane;
- int data2_lane = dssdev->phy.dsi.data2_lane;
- int data3_lane = dssdev->phy.dsi.data3_lane;
- int data4_lane = dssdev->phy.dsi.data4_lane;
- int clk_pol = dssdev->phy.dsi.clk_pol;
- int data1_pol = dssdev->phy.dsi.data1_pol;
- int data2_pol = dssdev->phy.dsi.data2_pol;
- int data3_pol = dssdev->phy.dsi.data3_pol;
- int data4_pol = dssdev->phy.dsi.data4_pol;
-
- u32 l = 0;
- u8 lptxscp_start = dsi->num_data_lanes == 2 ? 22 : 26;
-
- if (lanes & DSI_CLK_P)
- l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 0 : 1));
- if (lanes & DSI_CLK_N)
- l |= 1 << ((clk_lane - 1) * 2 + (clk_pol ? 1 : 0));
-
- if (lanes & DSI_DATA1_P)
- l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 0 : 1));
- if (lanes & DSI_DATA1_N)
- l |= 1 << ((data1_lane - 1) * 2 + (data1_pol ? 1 : 0));
-
- if (lanes & DSI_DATA2_P)
- l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 0 : 1));
- if (lanes & DSI_DATA2_N)
- l |= 1 << ((data2_lane - 1) * 2 + (data2_pol ? 1 : 0));
-
- if (lanes & DSI_DATA3_P)
- l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 0 : 1));
- if (lanes & DSI_DATA3_N)
- l |= 1 << ((data3_lane - 1) * 2 + (data3_pol ? 1 : 0));
-
- if (lanes & DSI_DATA4_P)
- l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 0 : 1));
- if (lanes & DSI_DATA4_N)
- l |= 1 << ((data4_lane - 1) * 2 + (data4_pol ? 1 : 0));
+ int i;
+ u32 l;
+ u8 lptxscp_start = dsi->num_lanes_supported == 3 ? 22 : 26;
+
+ l = 0;
+
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ unsigned p = dsi->lanes[i].polarity;
+
+ if (mask_p & (1 << i))
+ l |= 1 << (i * 2 + (p ? 0 : 1));
+
+ if (mask_n & (1 << i))
+ l |= 1 << (i * 2 + (p ? 1 : 0));
+ }
+
/*
* Bits in REGLPTXSCPDAT4TO0DXDY:
* 17: DY0 18: DX0
@@ -2305,51 +2325,40 @@ static void dsi_cio_disable_lane_override(struct platform_device *dsidev)
static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- int t;
- int bits[3];
- bool in_use[3];
-
- if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC)) {
- bits[0] = 28;
- bits[1] = 27;
- bits[2] = 26;
- } else {
- bits[0] = 24;
- bits[1] = 25;
- bits[2] = 26;
- }
-
- in_use[0] = false;
- in_use[1] = false;
- in_use[2] = false;
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ int t, i;
+ bool in_use[DSI_MAX_NR_LANES];
+ static const u8 offsets_old[] = { 28, 27, 26 };
+ static const u8 offsets_new[] = { 24, 25, 26, 27, 28 };
+ const u8 *offsets;
+
+ if (dss_has_feature(FEAT_DSI_REVERSE_TXCLKESC))
+ offsets = offsets_old;
+ else
+ offsets = offsets_new;
- if (dssdev->phy.dsi.clk_lane != 0)
- in_use[dssdev->phy.dsi.clk_lane - 1] = true;
- if (dssdev->phy.dsi.data1_lane != 0)
- in_use[dssdev->phy.dsi.data1_lane - 1] = true;
- if (dssdev->phy.dsi.data2_lane != 0)
- in_use[dssdev->phy.dsi.data2_lane - 1] = true;
+ for (i = 0; i < dsi->num_lanes_supported; ++i)
+ in_use[i] = dsi->lanes[i].function != DSI_LANE_UNUSED;
t = 100000;
while (true) {
u32 l;
- int i;
int ok;
l = dsi_read_reg(dsidev, DSI_DSIPHY_CFG5);
ok = 0;
- for (i = 0; i < 3; ++i) {
- if (!in_use[i] || (l & (1 << bits[i])))
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (!in_use[i] || (l & (1 << offsets[i])))
ok++;
}
- if (ok == 3)
+ if (ok == dsi->num_lanes_supported)
break;
if (--t == 0) {
- for (i = 0; i < 3; ++i) {
- if (!in_use[i] || (l & (1 << bits[i])))
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (!in_use[i] || (l & (1 << offsets[i])))
continue;
DSSERR("CIO TXCLKESC%d domain not coming " \
@@ -2362,22 +2371,20 @@ static int dsi_cio_wait_tx_clk_esc_reset(struct omap_dss_device *dssdev)
return 0;
}
+/* return bitmask of enabled lanes, lane0 being the lsb */
static unsigned dsi_get_lane_mask(struct omap_dss_device *dssdev)
{
- unsigned lanes = 0;
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
+ unsigned mask = 0;
+ int i;
- if (dssdev->phy.dsi.clk_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.clk_lane - 1);
- if (dssdev->phy.dsi.data1_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.data1_lane - 1);
- if (dssdev->phy.dsi.data2_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.data2_lane - 1);
- if (dssdev->phy.dsi.data3_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.data3_lane - 1);
- if (dssdev->phy.dsi.data4_lane != 0)
- lanes |= 1 << (dssdev->phy.dsi.data4_lane - 1);
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (dsi->lanes[i].function != DSI_LANE_UNUSED)
+ mask |= 1 << i;
+ }
- return lanes;
+ return mask;
}
static int dsi_cio_init(struct omap_dss_device *dssdev)
@@ -2385,7 +2392,6 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
int r;
- int num_data_lanes_dssdev = dsi_get_num_data_lanes_dssdev(dssdev);
u32 l;
DSSDBGF();
@@ -2407,7 +2413,9 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
goto err_scp_clk_dom;
}
- dsi_set_lane_config(dssdev);
+ r = dsi_set_lane_config(dssdev);
+ if (r)
+ goto err_scp_clk_dom;
/* set TX STOP MODE timer to maximum for this operation */
l = dsi_read_reg(dsidev, DSI_TIMING1);
@@ -2418,7 +2426,8 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
dsi_write_reg(dsidev, DSI_TIMING1, l);
if (dsi->ulps_enabled) {
- u32 lane_mask = DSI_CLK_P | DSI_DATA1_P | DSI_DATA2_P;
+ unsigned mask_p;
+ int i;
DSSDBG("manual ulps exit\n");
@@ -2427,16 +2436,19 @@ static int dsi_cio_init(struct omap_dss_device *dssdev)
* ULPS exit sequence, as after reset the DSS HW thinks
* that we are not in ULPS mode, and refuses to send the
* sequence. So we need to send the ULPS exit sequence
- * manually.
+ * manually by setting positive lines high and negative lines
+ * low for 1ms.
*/
- if (num_data_lanes_dssdev > 2)
- lane_mask |= DSI_DATA3_P;
+ mask_p = 0;
- if (num_data_lanes_dssdev > 3)
- lane_mask |= DSI_DATA4_P;
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (dsi->lanes[i].function == DSI_LANE_UNUSED)
+ continue;
+ mask_p |= 1 << i;
+ }
- dsi_cio_enable_lane_override(dssdev, lane_mask);
+ dsi_cio_enable_lane_override(dssdev, mask_p, 0);
}
r = dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ON);
@@ -2913,6 +2925,9 @@ static int dsi_vc_send_bta(struct platform_device *dsidev, int channel)
REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
+ /* flush posted write */
+ dsi_read_reg(dsidev, DSI_VC_CTRL(channel));
+
return 0;
}
@@ -3513,7 +3528,8 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
DECLARE_COMPLETION_ONSTACK(completion);
- int r;
+ int r, i;
+ unsigned mask;
DSSDBGF();
@@ -3524,9 +3540,11 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
if (dsi->ulps_enabled)
return 0;
+ /* DDR_CLK_ALWAYS_ON */
if (REG_GET(dsidev, DSI_CLK_CTRL, 13, 13)) {
- DSSERR("DDR_CLK_ALWAYS_ON enabled when entering ULPS\n");
- return -EIO;
+ dsi_if_enable(dsidev, 0);
+ REG_FLD_MOD(dsidev, DSI_CLK_CTRL, 0, 13, 13);
+ dsi_if_enable(dsidev, 1);
}
dsi_sync_vc(dsidev, 0);
@@ -3556,10 +3574,19 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
if (r)
return r;
+ mask = 0;
+
+ for (i = 0; i < dsi->num_lanes_supported; ++i) {
+ if (dsi->lanes[i].function == DSI_LANE_UNUSED)
+ continue;
+ mask |= 1 << i;
+ }
/* Assert TxRequestEsc for data lanes and TxUlpsClk for clk lane */
/* LANEx_ULPS_SIG2 */
- REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (1 << 0) | (1 << 1) | (1 << 2),
- 7, 5);
+ REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, mask, 9, 5);
+
+ /* flush posted write and wait for SCP interface to finish the write */
+ dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2);
if (wait_for_completion_timeout(&completion,
msecs_to_jiffies(1000)) == 0) {
@@ -3572,8 +3599,10 @@ static int dsi_enter_ulps(struct platform_device *dsidev)
DSI_CIO_IRQ_ULPSACTIVENOT_ALL0);
/* Reset LANEx_ULPS_SIG2 */
- REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, (0 << 0) | (0 << 1) | (0 << 2),
- 7, 5);
+ REG_FLD_MOD(dsidev, DSI_COMPLEXIO_CFG2, 0, 9, 5);
+
+ /* flush posted write and wait for SCP interface to finish the write */
+ dsi_read_reg(dsidev, DSI_COMPLEXIO_CFG2);
dsi_cio_power(dsidev, DSI_COMPLEXIO_POWER_ULPS);
@@ -3836,6 +3865,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
static void dsi_proto_timings(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
unsigned tlpx, tclk_zero, tclk_prepare, tclk_trail;
unsigned tclk_pre, tclk_post;
unsigned ths_prepare, ths_prepare_ths_zero, ths_zero;
@@ -3843,7 +3873,7 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
unsigned ddr_clk_pre, ddr_clk_post;
unsigned enter_hs_mode_lat, exit_hs_mode_lat;
unsigned ths_eot;
- int ndl = dsi_get_num_data_lanes_dssdev(dssdev);
+ int ndl = dsi->num_lanes_used - 1;
u32 r;
r = dsi_read_reg(dsidev, DSI_DSIPHY_CFG0);
@@ -3945,68 +3975,82 @@ static void dsi_proto_timings(struct omap_dss_device *dssdev)
}
}
-int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel)
+int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
u8 data_type;
u16 word_count;
+ int r;
- switch (dssdev->panel.dsi_pix_fmt) {
- case OMAP_DSS_DSI_FMT_RGB888:
- data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
- break;
- case OMAP_DSS_DSI_FMT_RGB666:
- data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
- break;
- case OMAP_DSS_DSI_FMT_RGB666_PACKED:
- data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
- break;
- case OMAP_DSS_DSI_FMT_RGB565:
- data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
- break;
- default:
- BUG();
- };
+ if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ switch (dssdev->panel.dsi_pix_fmt) {
+ case OMAP_DSS_DSI_FMT_RGB888:
+ data_type = MIPI_DSI_PACKED_PIXEL_STREAM_24;
+ break;
+ case OMAP_DSS_DSI_FMT_RGB666:
+ data_type = MIPI_DSI_PIXEL_STREAM_3BYTE_18;
+ break;
+ case OMAP_DSS_DSI_FMT_RGB666_PACKED:
+ data_type = MIPI_DSI_PACKED_PIXEL_STREAM_18;
+ break;
+ case OMAP_DSS_DSI_FMT_RGB565:
+ data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
+ break;
+ default:
+ BUG();
+ };
- dsi_if_enable(dsidev, false);
- dsi_vc_enable(dsidev, channel, false);
+ dsi_if_enable(dsidev, false);
+ dsi_vc_enable(dsidev, channel, false);
- /* MODE, 1 = video mode */
- REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
+ /* MODE, 1 = video mode */
+ REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 1, 4, 4);
- word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
+ word_count = DIV_ROUND_UP(dssdev->panel.timings.x_res * bpp, 8);
- dsi_vc_write_long_header(dsidev, channel, data_type, word_count, 0);
+ dsi_vc_write_long_header(dsidev, channel, data_type,
+ word_count, 0);
- dsi_vc_enable(dsidev, channel, true);
- dsi_if_enable(dsidev, true);
+ dsi_vc_enable(dsidev, channel, true);
+ dsi_if_enable(dsidev, true);
+ }
- dssdev->manager->enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r) {
+ if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ dsi_if_enable(dsidev, false);
+ dsi_vc_enable(dsidev, channel, false);
+ }
+
+ return r;
+ }
return 0;
}
-EXPORT_SYMBOL(dsi_video_mode_enable);
+EXPORT_SYMBOL(dsi_enable_video_output);
-void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel)
+void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- dsi_if_enable(dsidev, false);
- dsi_vc_enable(dsidev, channel, false);
+ if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_VIDEO_MODE) {
+ dsi_if_enable(dsidev, false);
+ dsi_vc_enable(dsidev, channel, false);
- /* MODE, 0 = command mode */
- REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4);
+ /* MODE, 0 = command mode */
+ REG_FLD_MOD(dsidev, DSI_VC_CTRL(channel), 0, 4, 4);
- dsi_vc_enable(dsidev, channel, true);
- dsi_if_enable(dsidev, true);
+ dsi_vc_enable(dsidev, channel, true);
+ dsi_if_enable(dsidev, true);
+ }
- dssdev->manager->disable(dssdev->manager);
+ dss_mgr_disable(dssdev->manager);
}
-EXPORT_SYMBOL(dsi_video_mode_disable);
+EXPORT_SYMBOL(dsi_disable_video_output);
static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
- u16 x, u16 y, u16 w, u16 h)
+ u16 w, u16 h)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
@@ -4021,8 +4065,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
const unsigned channel = dsi->update_channel;
const unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
- DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
- x, y, w, h);
+ DSSDBG("dsi_update_screen_dispc(%dx%d)\n", w, h);
dsi_vc_config_source(dsidev, channel, DSI_VC_SOURCE_VP);
@@ -4070,7 +4113,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev,
msecs_to_jiffies(250));
BUG_ON(r == 0);
- dss_start_update(dssdev);
+ dss_mgr_start_update(dssdev->manager);
if (dsi->te_enabled) {
/* disable LP_RX_TO, so that we can receive TE. Time to wait
@@ -4146,66 +4189,27 @@ static void dsi_framedone_irq_callback(void *data, u32 mask)
#endif
}
-int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h,
- bool enlarge_update_area)
+int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
+ void (*callback)(int, void *), void *data)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
u16 dw, dh;
- dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
- if (*x > dw || *y > dh)
- return -EINVAL;
-
- if (*x + *w > dw)
- return -EINVAL;
-
- if (*y + *h > dh)
- return -EINVAL;
-
- if (*w == 1)
- return -EINVAL;
-
- if (*w == 0 || *h == 0)
- return -EINVAL;
-
dsi_perf_mark_setup(dsidev);
- dss_setup_partial_planes(dssdev, x, y, w, h,
- enlarge_update_area);
- dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
-
- return 0;
-}
-EXPORT_SYMBOL(omap_dsi_prepare_update);
-
-int omap_dsi_update(struct omap_dss_device *dssdev,
- int channel,
- u16 x, u16 y, u16 w, u16 h,
- void (*callback)(int, void *), void *data)
-{
- struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
- struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
-
dsi->update_channel = channel;
- /* OMAP DSS cannot send updates of odd widths.
- * omap_dsi_prepare_update() makes the widths even, but add a BUG_ON
- * here to make sure we catch erroneous updates. Otherwise we'll only
- * see rather obscure HW error happening, as DSS halts. */
- BUG_ON(x % 2 == 1);
-
dsi->framedone_callback = callback;
dsi->framedone_data = data;
- dsi->update_region.x = x;
- dsi->update_region.y = y;
- dsi->update_region.w = w;
- dsi->update_region.h = h;
- dsi->update_region.device = dssdev;
+ dssdev->driver->get_resolution(dssdev, &dw, &dh);
- dsi_update_screen_dispc(dssdev, x, y, w, h);
+#ifdef DEBUG
+ dsi->update_bytes = dw * dh *
+ dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) / 8;
+#endif
+ dsi_update_screen_dispc(dssdev, dw, dh);
return 0;
}
@@ -4218,6 +4222,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
int r;
if (dssdev->panel.dsi_mode == OMAP_DSS_DSI_CMD_MODE) {
+ u16 dw, dh;
u32 irq;
struct omap_video_timings timings = {
.hsw = 1,
@@ -4228,6 +4233,10 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
.vbp = 0,
};
+ dssdev->driver->get_resolution(dssdev, &dw, &dh);
+ timings.x_res = dw;
+ timings.y_res = dh;
+
irq = dssdev->manager->id == OMAP_DSS_CHANNEL_LCD ?
DISPC_IRQ_FRAMEDONE : DISPC_IRQ_FRAMEDONE2;
@@ -4330,6 +4339,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
int dsi_module = dsi_get_dsidev_id(dsidev);
int r;
+ r = dsi_parse_lane_config(dssdev);
+ if (r) {
+ DSSERR("illegal lane config");
+ goto err0;
+ }
+
r = dsi_pll_init(dsidev, true, true);
if (r)
goto err0;
@@ -4521,7 +4536,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
{
struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- int dsi_module = dsi_get_dsidev_id(dsidev);
DSSDBG("DSI init\n");
@@ -4543,12 +4557,6 @@ int dsi_init_display(struct omap_dss_device *dssdev)
dsi->vdds_dsi_reg = vdds_dsi;
}
- if (dsi_get_num_data_lanes_dssdev(dssdev) > dsi->num_data_lanes) {
- DSSERR("DSI%d can't support more than %d data lanes\n",
- dsi_module + 1, dsi->num_data_lanes);
- return -EINVAL;
- }
-
return 0;
}
@@ -4771,7 +4779,13 @@ static int omap_dsihw_probe(struct platform_device *dsidev)
dev_dbg(&dsidev->dev, "OMAP DSI rev %d.%d\n",
FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
- dsi->num_data_lanes = dsi_get_num_data_lanes(dsidev);
+ /* DSI on OMAP3 doesn't have register DSI_GNQ, set number
+ * of data to 3 by default */
+ if (dss_has_feature(FEAT_DSI_GNQ))
+ /* NB_DATA_LANES */
+ dsi->num_lanes_supported = 1 + REG_GET(dsidev, DSI_GNQ, 11, 9);
+ else
+ dsi->num_lanes_supported = 3;
dsi_runtime_put(dsidev);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 6308fc59fc9e..32ff69fb3333 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -28,7 +28,7 @@
#endif
#ifdef DEBUG
-extern unsigned int dss_debug;
+extern bool dss_debug;
#ifdef DSS_SUBSYS_NAME
#define DSSDBG(format, ...) \
if (dss_debug) \
@@ -163,6 +163,34 @@ struct bus_type *dss_get_bus(void);
struct regulator *dss_get_vdds_dsi(void);
struct regulator *dss_get_vdds_sdi(void);
+/* apply */
+void dss_apply_init(void);
+int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr);
+int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
+void dss_mgr_start_update(struct omap_overlay_manager *mgr);
+int omap_dss_mgr_apply(struct omap_overlay_manager *mgr);
+
+int dss_mgr_enable(struct omap_overlay_manager *mgr);
+void dss_mgr_disable(struct omap_overlay_manager *mgr);
+int dss_mgr_set_info(struct omap_overlay_manager *mgr,
+ struct omap_overlay_manager_info *info);
+void dss_mgr_get_info(struct omap_overlay_manager *mgr,
+ struct omap_overlay_manager_info *info);
+int dss_mgr_set_device(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev);
+int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
+
+bool dss_ovl_is_enabled(struct omap_overlay *ovl);
+int dss_ovl_enable(struct omap_overlay *ovl);
+int dss_ovl_disable(struct omap_overlay *ovl);
+int dss_ovl_set_info(struct omap_overlay *ovl,
+ struct omap_overlay_info *info);
+void dss_ovl_get_info(struct omap_overlay *ovl,
+ struct omap_overlay_info *info);
+int dss_ovl_set_manager(struct omap_overlay *ovl,
+ struct omap_overlay_manager *mgr);
+int dss_ovl_unset_manager(struct omap_overlay *ovl);
+
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
@@ -181,21 +209,22 @@ void default_get_overlay_fifo_thresholds(enum omap_plane plane,
/* manager */
int dss_init_overlay_managers(struct platform_device *pdev);
void dss_uninit_overlay_managers(struct platform_device *pdev);
-int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl);
-void dss_setup_partial_planes(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h,
- bool enlarge_update_area);
-void dss_start_update(struct omap_dss_device *dssdev);
+int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
+ const struct omap_overlay_manager_info *info);
+int dss_mgr_check(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev,
+ struct omap_overlay_manager_info *info,
+ struct omap_overlay_info **overlay_infos);
/* overlay */
void dss_init_overlays(struct platform_device *pdev);
void dss_uninit_overlays(struct platform_device *pdev);
-int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev);
void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
-#ifdef L4_EXAMPLE
-void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr);
-#endif
void dss_recheck_connections(struct omap_dss_device *dssdev, bool force);
+int dss_ovl_simple_check(struct omap_overlay *ovl,
+ const struct omap_overlay_info *info);
+int dss_ovl_check(struct omap_overlay *ovl,
+ struct omap_overlay_info *info, struct omap_dss_device *dssdev);
/* DSS */
int dss_init_platform_driver(void);
@@ -399,21 +428,22 @@ int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
struct dispc_clock_info *cinfo);
+void dispc_ovl_set_fifo_threshold(enum omap_plane plane, u32 low, u32 high);
u32 dispc_ovl_get_fifo_size(enum omap_plane plane);
u32 dispc_ovl_get_burst_size(enum omap_plane plane);
int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
- bool ilace, enum omap_channel channel, bool replication,
- u32 fifo_low, u32 fifo_high);
+ bool ilace, bool replication);
int dispc_ovl_enable(enum omap_plane plane, bool enable);
-
+void dispc_ovl_set_channel_out(enum omap_plane plane,
+ enum omap_channel channel);
void dispc_mgr_enable_fifohandcheck(enum omap_channel channel, bool enable);
void dispc_mgr_set_lcd_size(enum omap_channel channel, u16 width, u16 height);
-void dispc_mgr_enable_cpr(enum omap_channel channel, bool enable);
-void dispc_mgr_set_cpr_coef(enum omap_channel channel,
- struct omap_dss_cpr_coefs *coefs);
+u32 dispc_mgr_get_vsync_irq(enum omap_channel channel);
+u32 dispc_mgr_get_framedone_irq(enum omap_channel channel);
bool dispc_mgr_go_busy(enum omap_channel channel);
void dispc_mgr_go(enum omap_channel channel);
+bool dispc_mgr_is_enabled(enum omap_channel channel);
void dispc_mgr_enable(enum omap_channel channel, bool enable);
bool dispc_mgr_is_channel_enabled(enum omap_channel channel);
void dispc_mgr_set_io_pad_mode(enum dss_io_pad_mode mode);
@@ -421,18 +451,6 @@ void dispc_mgr_enable_stallmode(enum omap_channel channel, bool enable);
void dispc_mgr_set_tft_data_lines(enum omap_channel channel, u8 data_lines);
void dispc_mgr_set_lcd_display_type(enum omap_channel channel,
enum omap_lcd_display_type type);
-void dispc_mgr_set_default_color(enum omap_channel channel, u32 color);
-u32 dispc_mgr_get_default_color(enum omap_channel channel);
-void dispc_mgr_set_trans_key(enum omap_channel ch,
- enum omap_dss_trans_key_type type,
- u32 trans_key);
-void dispc_mgr_get_trans_key(enum omap_channel ch,
- enum omap_dss_trans_key_type *type,
- u32 *trans_key);
-void dispc_mgr_enable_trans_key(enum omap_channel ch, bool enable);
-void dispc_mgr_enable_alpha_fixed_zorder(enum omap_channel ch, bool enable);
-bool dispc_mgr_trans_key_enabled(enum omap_channel ch);
-bool dispc_mgr_alpha_fixed_zorder_enabled(enum omap_channel ch);
void dispc_mgr_set_lcd_timings(enum omap_channel channel,
struct omap_video_timings *timings);
void dispc_mgr_set_pol_freq(enum omap_channel channel,
@@ -443,6 +461,8 @@ int dispc_mgr_set_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
+void dispc_mgr_setup(enum omap_channel channel,
+ struct omap_overlay_manager_info *info);
/* VENC */
#ifdef CONFIG_OMAP2_DSS_VENC
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index b402699168a5..afcb59301c37 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -304,6 +304,11 @@ static const struct dss_param_range omap2_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 0, 0 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, 0 },
[FEAT_PARAM_DOWNSCALE] = { 1, 2 },
+ /*
+ * Assuming the line width buffer to be 768 pixels as OMAP2 DISPC
+ * scaler cannot scale a image with width more than 768.
+ */
+ [FEAT_PARAM_LINEWIDTH] = { 1, 768 },
};
static const struct dss_param_range omap3_dss_param_range[] = {
@@ -316,6 +321,7 @@ static const struct dss_param_range omap3_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 750000, 2100000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 1, (1 << 13) - 1},
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
+ [FEAT_PARAM_LINEWIDTH] = { 1, 1024 },
};
static const struct dss_param_range omap4_dss_param_range[] = {
@@ -328,6 +334,7 @@ static const struct dss_param_range omap4_dss_param_range[] = {
[FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 },
[FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
[FEAT_PARAM_DOWNSCALE] = { 1, 4 },
+ [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
};
/* OMAP2 DSS Features */
@@ -465,6 +472,10 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
.dump_core = ti_hdmi_4xxx_core_dump,
.dump_pll = ti_hdmi_4xxx_pll_dump,
.dump_phy = ti_hdmi_4xxx_phy_dump,
+#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
+ defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
+ .audio_enable = ti_hdmi_4xxx_wp_audio_enable,
+#endif
};
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 6a6c05dd45ce..cd833bbaac3d 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -86,6 +86,7 @@ enum dss_range_param {
FEAT_PARAM_DSIPLL_FINT,
FEAT_PARAM_DSIPLL_LPDIV,
FEAT_PARAM_DOWNSCALE,
+ FEAT_PARAM_LINEWIDTH,
};
/* DSS Feature Functions */
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index c56378c555b0..b4c270edb915 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -333,7 +333,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
if (r)
return r;
- dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0);
+ dss_mgr_disable(dssdev->manager);
p = &dssdev->panel.timings;
@@ -387,9 +387,16 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 1);
- dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 1);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ goto err_mgr_enable;
return 0;
+
+err_mgr_enable:
+ hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
+ hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
+ hdmi.ip_data.ops->pll_disable(&hdmi.ip_data);
err:
hdmi_runtime_put();
return -EIO;
@@ -397,7 +404,7 @@ err:
static void hdmi_power_off(struct omap_dss_device *dssdev)
{
- dispc_mgr_enable(OMAP_DSS_CHANNEL_DIGIT, 0);
+ dss_mgr_disable(dssdev->manager);
hdmi.ip_data.ops->video_enable(&hdmi.ip_data, 0);
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
@@ -554,11 +561,44 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
-static int hdmi_audio_hw_params(struct hdmi_ip_data *ip_data,
- struct snd_pcm_substream *substream,
+static int hdmi_audio_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct platform_device *pdev = to_platform_device(codec->dev);
+ struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec);
+ int err = 0;
+
+ if (!(ip_data->ops) && !(ip_data->ops->audio_enable)) {
+ dev_err(&pdev->dev, "Cannot enable/disable audio\n");
+ return -ENODEV;
+ }
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+ ip_data->ops->audio_enable(ip_data, true);
+ break;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+ ip_data->ops->audio_enable(ip_data, false);
+ break;
+ default:
+ err = -EINVAL;
+ }
+ return err;
+}
+
+static int hdmi_audio_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_codec *codec = rtd->codec;
+ struct hdmi_ip_data *ip_data = snd_soc_codec_get_drvdata(codec);
struct hdmi_audio_format audio_format;
struct hdmi_audio_dma audio_dma;
struct hdmi_core_audio_config core_cfg;
@@ -698,7 +738,16 @@ static int hdmi_audio_startup(struct snd_pcm_substream *substream,
return 0;
}
+static int hdmi_audio_codec_probe(struct snd_soc_codec *codec)
+{
+ struct hdmi_ip_data *priv = &hdmi.ip_data;
+
+ snd_soc_codec_set_drvdata(codec, priv);
+ return 0;
+}
+
static struct snd_soc_codec_driver hdmi_audio_codec_drv = {
+ .probe = hdmi_audio_codec_probe,
};
static struct snd_soc_dai_ops hdmi_audio_codec_ops = {
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 6e63845cc7d7..d1858e71c64e 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -26,17 +26,15 @@
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/spinlock.h>
#include <linux/jiffies.h>
#include <video/omapdss.h>
-#include <plat/cpu.h>
#include "dss.h"
#include "dss_features.h"
static int num_managers;
-static struct list_head manager_list;
+static struct omap_overlay_manager *managers;
static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
{
@@ -106,7 +104,11 @@ put_device:
static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.default_color);
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%#x\n", info.default_color);
}
static ssize_t manager_default_color_store(struct omap_overlay_manager *mgr,
@@ -144,8 +146,11 @@ static ssize_t manager_trans_key_type_show(struct omap_overlay_manager *mgr,
char *buf)
{
enum omap_dss_trans_key_type key_type;
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
- key_type = mgr->info.trans_key_type;
+ key_type = info.trans_key_type;
BUG_ON(key_type >= ARRAY_SIZE(trans_key_type_str));
return snprintf(buf, PAGE_SIZE, "%s\n", trans_key_type_str[key_type]);
@@ -185,7 +190,11 @@ static ssize_t manager_trans_key_type_store(struct omap_overlay_manager *mgr,
static ssize_t manager_trans_key_value_show(struct omap_overlay_manager *mgr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%#x\n", mgr->info.trans_key);
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%#x\n", info.trans_key);
}
static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
@@ -217,7 +226,11 @@ static ssize_t manager_trans_key_value_store(struct omap_overlay_manager *mgr,
static ssize_t manager_trans_key_enabled_show(struct omap_overlay_manager *mgr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.trans_enabled);
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.trans_enabled);
}
static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
@@ -249,10 +262,14 @@ static ssize_t manager_trans_key_enabled_store(struct omap_overlay_manager *mgr,
static ssize_t manager_alpha_blending_enabled_show(
struct omap_overlay_manager *mgr, char *buf)
{
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
WARN_ON(!dss_has_feature(FEAT_ALPHA_FIXED_ZORDER));
return snprintf(buf, PAGE_SIZE, "%d\n",
- mgr->info.partial_alpha_enabled);
+ info.partial_alpha_enabled);
}
static ssize_t manager_alpha_blending_enabled_store(
@@ -287,7 +304,11 @@ static ssize_t manager_alpha_blending_enabled_store(
static ssize_t manager_cpr_enable_show(struct omap_overlay_manager *mgr,
char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", mgr->info.cpr_enable);
+ struct omap_overlay_manager_info info;
+
+ mgr->get_manager_info(mgr, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.cpr_enable);
}
static ssize_t manager_cpr_enable_store(struct omap_overlay_manager *mgr,
@@ -469,143 +490,6 @@ static struct kobj_type manager_ktype = {
.default_attrs = manager_sysfs_attrs,
};
-/*
- * We have 4 levels of cache for the dispc settings. First two are in SW and
- * the latter two in HW.
- *
- * +--------------------+
- * |overlay/manager_info|
- * +--------------------+
- * v
- * apply()
- * v
- * +--------------------+
- * | dss_cache |
- * +--------------------+
- * v
- * configure()
- * v
- * +--------------------+
- * | shadow registers |
- * +--------------------+
- * v
- * VFP or lcd/digit_enable
- * v
- * +--------------------+
- * | registers |
- * +--------------------+
- */
-
-struct overlay_cache_data {
- /* If true, cache changed, but not written to shadow registers. Set
- * in apply(), cleared when registers written. */
- bool dirty;
- /* If true, shadow registers contain changed values not yet in real
- * registers. Set when writing to shadow registers, cleared at
- * VSYNC/EVSYNC */
- bool shadow_dirty;
-
- bool enabled;
-
- struct omap_overlay_info info;
-
- enum omap_channel channel;
- bool replication;
- bool ilace;
-
- u32 fifo_low;
- u32 fifo_high;
-};
-
-struct manager_cache_data {
- /* If true, cache changed, but not written to shadow registers. Set
- * in apply(), cleared when registers written. */
- bool dirty;
- /* If true, shadow registers contain changed values not yet in real
- * registers. Set when writing to shadow registers, cleared at
- * VSYNC/EVSYNC */
- bool shadow_dirty;
-
- struct omap_overlay_manager_info info;
-
- bool manual_update;
- bool do_manual_update;
-
- /* manual update region */
- u16 x, y, w, h;
-
- /* enlarge the update area if the update area contains scaled
- * overlays */
- bool enlarge_update_area;
-};
-
-static struct {
- spinlock_t lock;
- struct overlay_cache_data overlay_cache[MAX_DSS_OVERLAYS];
- struct manager_cache_data manager_cache[MAX_DSS_MANAGERS];
-
- bool irq_enabled;
-} dss_cache;
-
-
-
-static int omap_dss_set_device(struct omap_overlay_manager *mgr,
- struct omap_dss_device *dssdev)
-{
- int i;
- int r;
-
- if (dssdev->manager) {
- DSSERR("display '%s' already has a manager '%s'\n",
- dssdev->name, dssdev->manager->name);
- return -EINVAL;
- }
-
- if ((mgr->supported_displays & dssdev->type) == 0) {
- DSSERR("display '%s' does not support manager '%s'\n",
- dssdev->name, mgr->name);
- return -EINVAL;
- }
-
- for (i = 0; i < mgr->num_overlays; i++) {
- struct omap_overlay *ovl = mgr->overlays[i];
-
- if (ovl->manager != mgr || !ovl->info.enabled)
- continue;
-
- r = dss_check_overlay(ovl, dssdev);
- if (r)
- return r;
- }
-
- dssdev->manager = mgr;
- mgr->device = dssdev;
- mgr->device_changed = true;
-
- return 0;
-}
-
-static int omap_dss_unset_device(struct omap_overlay_manager *mgr)
-{
- if (!mgr->device) {
- DSSERR("failed to unset display, display not set.\n");
- return -EINVAL;
- }
-
- /*
- * Don't allow currently enabled displays to have the overlay manager
- * pulled out from underneath them
- */
- if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED)
- return -EINVAL;
-
- mgr->device->manager = NULL;
- mgr->device = NULL;
- mgr->device_changed = true;
-
- return 0;
-}
-
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{
unsigned long timeout = msecs_to_jiffies(500);
@@ -624,1022 +508,169 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
}
-static int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
-{
- unsigned long timeout = msecs_to_jiffies(500);
- struct manager_cache_data *mc;
- u32 irq;
- int r;
- int i;
- struct omap_dss_device *dssdev = mgr->device;
-
- if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
- return 0;
-
- if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
- return 0;
-
- if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
- || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
- irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
- } else {
- irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
- DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
- }
-
- mc = &dss_cache.manager_cache[mgr->id];
- i = 0;
- while (1) {
- unsigned long flags;
- bool shadow_dirty, dirty;
-
- spin_lock_irqsave(&dss_cache.lock, flags);
- dirty = mc->dirty;
- shadow_dirty = mc->shadow_dirty;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
-
- if (!dirty && !shadow_dirty) {
- r = 0;
- break;
- }
-
- /* 4 iterations is the worst case:
- * 1 - initial iteration, dirty = true (between VFP and VSYNC)
- * 2 - first VSYNC, dirty = true
- * 3 - dirty = false, shadow_dirty = true
- * 4 - shadow_dirty = false */
- if (i++ == 3) {
- DSSERR("mgr(%d)->wait_for_go() not finishing\n",
- mgr->id);
- r = 0;
- break;
- }
-
- r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
- if (r == -ERESTARTSYS)
- break;
-
- if (r) {
- DSSERR("mgr(%d)->wait_for_go() timeout\n", mgr->id);
- break;
- }
- }
-
- return r;
-}
-
-int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
-{
- unsigned long timeout = msecs_to_jiffies(500);
- struct overlay_cache_data *oc;
- struct omap_dss_device *dssdev;
- u32 irq;
- int r;
- int i;
-
- if (!ovl->manager)
- return 0;
-
- dssdev = ovl->manager->device;
-
- if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
- return 0;
-
- if (dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
- return 0;
-
- if (dssdev->type == OMAP_DISPLAY_TYPE_VENC
- || dssdev->type == OMAP_DISPLAY_TYPE_HDMI) {
- irq = DISPC_IRQ_EVSYNC_ODD | DISPC_IRQ_EVSYNC_EVEN;
- } else {
- irq = (dssdev->manager->id == OMAP_DSS_CHANNEL_LCD) ?
- DISPC_IRQ_VSYNC : DISPC_IRQ_VSYNC2;
- }
-
- oc = &dss_cache.overlay_cache[ovl->id];
- i = 0;
- while (1) {
- unsigned long flags;
- bool shadow_dirty, dirty;
-
- spin_lock_irqsave(&dss_cache.lock, flags);
- dirty = oc->dirty;
- shadow_dirty = oc->shadow_dirty;
- spin_unlock_irqrestore(&dss_cache.lock, flags);
-
- if (!dirty && !shadow_dirty) {
- r = 0;
- break;
- }
-
- /* 4 iterations is the worst case:
- * 1 - initial iteration, dirty = true (between VFP and VSYNC)
- * 2 - first VSYNC, dirty = true
- * 3 - dirty = false, shadow_dirty = true
- * 4 - shadow_dirty = false */
- if (i++ == 3) {
- DSSERR("ovl(%d)->wait_for_go() not finishing\n",
- ovl->id);
- r = 0;
- break;
- }
-
- r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
- if (r == -ERESTARTSYS)
- break;
-
- if (r) {
- DSSERR("ovl(%d)->wait_for_go() timeout\n", ovl->id);
- break;
- }
- }
-
- return r;
-}
-
-static int overlay_enabled(struct omap_overlay *ovl)
-{
- return ovl->info.enabled && ovl->manager && ovl->manager->device;
-}
-
-/* Is rect1 a subset of rect2? */
-static bool rectangle_subset(int x1, int y1, int w1, int h1,
- int x2, int y2, int w2, int h2)
-{
- if (x1 < x2 || y1 < y2)
- return false;
-
- if (x1 + w1 > x2 + w2)
- return false;
-
- if (y1 + h1 > y2 + h2)
- return false;
-
- return true;
-}
-
-/* Do rect1 and rect2 overlap? */
-static bool rectangle_intersects(int x1, int y1, int w1, int h1,
- int x2, int y2, int w2, int h2)
-{
- if (x1 >= x2 + w2)
- return false;
-
- if (x2 >= x1 + w1)
- return false;
-
- if (y1 >= y2 + h2)
- return false;
-
- if (y2 >= y1 + h1)
- return false;
-
- return true;
-}
-
-static bool dispc_is_overlay_scaled(struct overlay_cache_data *oc)
-{
- struct omap_overlay_info *oi = &oc->info;
-
- if (oi->out_width != 0 && oi->width != oi->out_width)
- return true;
-
- if (oi->out_height != 0 && oi->height != oi->out_height)
- return true;
-
- return false;
-}
-
-static int configure_overlay(enum omap_plane plane)
+int dss_init_overlay_managers(struct platform_device *pdev)
{
- struct overlay_cache_data *c;
- struct manager_cache_data *mc;
- struct omap_overlay_info *oi, new_oi;
- struct omap_overlay_manager_info *mi;
- u16 outw, outh;
- u16 x, y, w, h;
- u32 paddr;
- int r;
- u16 orig_w, orig_h, orig_outw, orig_outh;
+ int i, r;
- DSSDBGF("%d", plane);
+ num_managers = dss_feat_get_num_mgrs();
- c = &dss_cache.overlay_cache[plane];
- oi = &c->info;
+ managers = kzalloc(sizeof(struct omap_overlay_manager) * num_managers,
+ GFP_KERNEL);
- if (!c->enabled) {
- dispc_ovl_enable(plane, 0);
- return 0;
- }
+ BUG_ON(managers == NULL);
- mc = &dss_cache.manager_cache[c->channel];
- mi = &mc->info;
-
- x = oi->pos_x;
- y = oi->pos_y;
- w = oi->width;
- h = oi->height;
- outw = oi->out_width == 0 ? oi->width : oi->out_width;
- outh = oi->out_height == 0 ? oi->height : oi->out_height;
- paddr = oi->paddr;
-
- orig_w = w;
- orig_h = h;
- orig_outw = outw;
- orig_outh = outh;
-
- if (mc->manual_update && mc->do_manual_update) {
- unsigned bpp;
- unsigned scale_x_m = w, scale_x_d = outw;
- unsigned scale_y_m = h, scale_y_d = outh;
-
- /* If the overlay is outside the update region, disable it */
- if (!rectangle_intersects(mc->x, mc->y, mc->w, mc->h,
- x, y, outw, outh)) {
- dispc_ovl_enable(plane, 0);
- return 0;
- }
+ for (i = 0; i < num_managers; ++i) {
+ struct omap_overlay_manager *mgr = &managers[i];
- switch (oi->color_mode) {
- case OMAP_DSS_COLOR_NV12:
- bpp = 8;
- break;
- case OMAP_DSS_COLOR_RGB16:
- case OMAP_DSS_COLOR_ARGB16:
- case OMAP_DSS_COLOR_YUV2:
- case OMAP_DSS_COLOR_UYVY:
- case OMAP_DSS_COLOR_RGBA16:
- case OMAP_DSS_COLOR_RGBX16:
- case OMAP_DSS_COLOR_ARGB16_1555:
- case OMAP_DSS_COLOR_XRGB16_1555:
- bpp = 16;
+ switch (i) {
+ case 0:
+ mgr->name = "lcd";
+ mgr->id = OMAP_DSS_CHANNEL_LCD;
break;
-
- case OMAP_DSS_COLOR_RGB24P:
- bpp = 24;
+ case 1:
+ mgr->name = "tv";
+ mgr->id = OMAP_DSS_CHANNEL_DIGIT;
break;
-
- case OMAP_DSS_COLOR_RGB24U:
- case OMAP_DSS_COLOR_ARGB32:
- case OMAP_DSS_COLOR_RGBA32:
- case OMAP_DSS_COLOR_RGBX32:
- bpp = 32;
+ case 2:
+ mgr->name = "lcd2";
+ mgr->id = OMAP_DSS_CHANNEL_LCD2;
break;
-
- default:
- BUG();
}
- if (mc->x > oi->pos_x) {
- x = 0;
- outw -= (mc->x - oi->pos_x);
- paddr += (mc->x - oi->pos_x) *
- scale_x_m / scale_x_d * bpp / 8;
- } else {
- x = oi->pos_x - mc->x;
- }
-
- if (mc->y > oi->pos_y) {
- y = 0;
- outh -= (mc->y - oi->pos_y);
- paddr += (mc->y - oi->pos_y) *
- scale_y_m / scale_y_d *
- oi->screen_width * bpp / 8;
- } else {
- y = oi->pos_y - mc->y;
- }
-
- if (mc->w < (x + outw))
- outw -= (x + outw) - (mc->w);
-
- if (mc->h < (y + outh))
- outh -= (y + outh) - (mc->h);
-
- w = w * outw / orig_outw;
- h = h * outh / orig_outh;
-
- /* YUV mode overlay's input width has to be even and the
- * algorithm above may adjust the width to be odd.
- *
- * Here we adjust the width if needed, preferring to increase
- * the width if the original width was bigger.
- */
- if ((w & 1) &&
- (oi->color_mode == OMAP_DSS_COLOR_YUV2 ||
- oi->color_mode == OMAP_DSS_COLOR_UYVY)) {
- if (orig_w > w)
- w += 1;
- else
- w -= 1;
- }
- }
-
- new_oi = *oi;
-
- /* update new_oi members which could have been possibly updated */
- new_oi.pos_x = x;
- new_oi.pos_y = y;
- new_oi.width = w;
- new_oi.height = h;
- new_oi.out_width = outw;
- new_oi.out_height = outh;
- new_oi.paddr = paddr;
-
- r = dispc_ovl_setup(plane, &new_oi, c->ilace, c->channel,
- c->replication, c->fifo_low, c->fifo_high);
- if (r) {
- /* this shouldn't happen */
- DSSERR("dispc_ovl_setup failed for ovl %d\n", plane);
- dispc_ovl_enable(plane, 0);
- return r;
- }
-
- dispc_ovl_enable(plane, 1);
-
- return 0;
-}
-
-static void configure_manager(enum omap_channel channel)
-{
- struct omap_overlay_manager_info *mi;
-
- DSSDBGF("%d", channel);
-
- /* picking info from the cache */
- mi = &dss_cache.manager_cache[channel].info;
-
- dispc_mgr_set_default_color(channel, mi->default_color);
- dispc_mgr_set_trans_key(channel, mi->trans_key_type, mi->trans_key);
- dispc_mgr_enable_trans_key(channel, mi->trans_enabled);
- dispc_mgr_enable_alpha_fixed_zorder(channel, mi->partial_alpha_enabled);
- if (dss_has_feature(FEAT_CPR)) {
- dispc_mgr_enable_cpr(channel, mi->cpr_enable);
- dispc_mgr_set_cpr_coef(channel, &mi->cpr_coefs);
- }
-}
-
-/* configure_dispc() tries to write values from cache to shadow registers.
- * It writes only to those managers/overlays that are not busy.
- * returns 0 if everything could be written to shadow registers.
- * returns 1 if not everything could be written to shadow registers. */
-static int configure_dispc(void)
-{
- struct overlay_cache_data *oc;
- struct manager_cache_data *mc;
- const int num_ovls = dss_feat_get_num_ovls();
- const int num_mgrs = dss_feat_get_num_mgrs();
- int i;
- int r;
- bool mgr_busy[MAX_DSS_MANAGERS];
- bool mgr_go[MAX_DSS_MANAGERS];
- bool busy;
-
- r = 0;
- busy = false;
-
- for (i = 0; i < num_mgrs; i++) {
- mgr_busy[i] = dispc_mgr_go_busy(i);
- mgr_go[i] = false;
- }
-
- /* Commit overlay settings */
- for (i = 0; i < num_ovls; ++i) {
- oc = &dss_cache.overlay_cache[i];
- mc = &dss_cache.manager_cache[oc->channel];
+ mgr->set_device = &dss_mgr_set_device;
+ mgr->unset_device = &dss_mgr_unset_device;
+ mgr->apply = &omap_dss_mgr_apply;
+ mgr->set_manager_info = &dss_mgr_set_info;
+ mgr->get_manager_info = &dss_mgr_get_info;
+ mgr->wait_for_go = &dss_mgr_wait_for_go;
+ mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
- if (!oc->dirty)
- continue;
+ mgr->caps = 0;
+ mgr->supported_displays =
+ dss_feat_get_supported_displays(mgr->id);
- if (mc->manual_update && !mc->do_manual_update)
- continue;
+ INIT_LIST_HEAD(&mgr->overlays);
- if (mgr_busy[oc->channel]) {
- busy = true;
- continue;
- }
+ r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
+ &pdev->dev.kobj, "manager%d", i);
- r = configure_overlay(i);
if (r)
- DSSERR("configure_overlay %d failed\n", i);
-
- oc->dirty = false;
- oc->shadow_dirty = true;
- mgr_go[oc->channel] = true;
- }
-
- /* Commit manager settings */
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
-
- if (!mc->dirty)
- continue;
-
- if (mc->manual_update && !mc->do_manual_update)
- continue;
-
- if (mgr_busy[i]) {
- busy = true;
- continue;
- }
-
- configure_manager(i);
- mc->dirty = false;
- mc->shadow_dirty = true;
- mgr_go[i] = true;
- }
-
- /* set GO */
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
-
- if (!mgr_go[i])
- continue;
-
- /* We don't need GO with manual update display. LCD iface will
- * always be turned off after frame, and new settings will be
- * taken in to use at next update */
- if (!mc->manual_update)
- dispc_mgr_go(i);
- }
-
- if (busy)
- r = 1;
- else
- r = 0;
-
- return r;
-}
-
-/* Make the coordinates even. There are some strange problems with OMAP and
- * partial DSI update when the update widths are odd. */
-static void make_even(u16 *x, u16 *w)
-{
- u16 x1, x2;
-
- x1 = *x;
- x2 = *x + *w;
-
- x1 &= ~1;
- x2 = ALIGN(x2, 2);
-
- *x = x1;
- *w = x2 - x1;
-}
-
-/* Configure dispc for partial update. Return possibly modified update
- * area */
-void dss_setup_partial_planes(struct omap_dss_device *dssdev,
- u16 *xi, u16 *yi, u16 *wi, u16 *hi, bool enlarge_update_area)
-{
- struct overlay_cache_data *oc;
- struct manager_cache_data *mc;
- struct omap_overlay_info *oi;
- const int num_ovls = dss_feat_get_num_ovls();
- struct omap_overlay_manager *mgr;
- int i;
- u16 x, y, w, h;
- unsigned long flags;
- bool area_changed;
-
- x = *xi;
- y = *yi;
- w = *wi;
- h = *hi;
-
- DSSDBG("dispc_setup_partial_planes %d,%d %dx%d\n",
- *xi, *yi, *wi, *hi);
-
- mgr = dssdev->manager;
-
- if (!mgr) {
- DSSDBG("no manager\n");
- return;
+ DSSERR("failed to create sysfs file\n");
}
- make_even(&x, &w);
-
- spin_lock_irqsave(&dss_cache.lock, flags);
-
- /*
- * Execute the outer loop until the inner loop has completed
- * once without increasing the update area. This will ensure that
- * all scaled overlays end up completely within the update area.
- */
- do {
- area_changed = false;
-
- /* We need to show the whole overlay if it is scaled. So look
- * for those, and make the update area larger if found.
- * Also mark the overlay cache dirty */
- for (i = 0; i < num_ovls; ++i) {
- unsigned x1, y1, x2, y2;
- unsigned outw, outh;
-
- oc = &dss_cache.overlay_cache[i];
- oi = &oc->info;
-
- if (oc->channel != mgr->id)
- continue;
-
- oc->dirty = true;
-
- if (!enlarge_update_area)
- continue;
-
- if (!oc->enabled)
- continue;
-
- if (!dispc_is_overlay_scaled(oc))
- continue;
-
- outw = oi->out_width == 0 ?
- oi->width : oi->out_width;
- outh = oi->out_height == 0 ?
- oi->height : oi->out_height;
-
- /* is the overlay outside the update region? */
- if (!rectangle_intersects(x, y, w, h,
- oi->pos_x, oi->pos_y,
- outw, outh))
- continue;
-
- /* if the overlay totally inside the update region? */
- if (rectangle_subset(oi->pos_x, oi->pos_y, outw, outh,
- x, y, w, h))
- continue;
-
- if (x > oi->pos_x)
- x1 = oi->pos_x;
- else
- x1 = x;
-
- if (y > oi->pos_y)
- y1 = oi->pos_y;
- else
- y1 = y;
-
- if ((x + w) < (oi->pos_x + outw))
- x2 = oi->pos_x + outw;
- else
- x2 = x + w;
-
- if ((y + h) < (oi->pos_y + outh))
- y2 = oi->pos_y + outh;
- else
- y2 = y + h;
-
- x = x1;
- y = y1;
- w = x2 - x1;
- h = y2 - y1;
-
- make_even(&x, &w);
-
- DSSDBG("changing upd area due to ovl(%d) "
- "scaling %d,%d %dx%d\n",
- i, x, y, w, h);
-
- area_changed = true;
- }
- } while (area_changed);
-
- mc = &dss_cache.manager_cache[mgr->id];
- mc->do_manual_update = true;
- mc->enlarge_update_area = enlarge_update_area;
- mc->x = x;
- mc->y = y;
- mc->w = w;
- mc->h = h;
-
- configure_dispc();
-
- mc->do_manual_update = false;
-
- spin_unlock_irqrestore(&dss_cache.lock, flags);
-
- *xi = x;
- *yi = y;
- *wi = w;
- *hi = h;
+ return 0;
}
-void dss_start_update(struct omap_dss_device *dssdev)
+void dss_uninit_overlay_managers(struct platform_device *pdev)
{
- struct manager_cache_data *mc;
- struct overlay_cache_data *oc;
- const int num_ovls = dss_feat_get_num_ovls();
- const int num_mgrs = dss_feat_get_num_mgrs();
- struct omap_overlay_manager *mgr;
int i;
- mgr = dssdev->manager;
+ for (i = 0; i < num_managers; ++i) {
+ struct omap_overlay_manager *mgr = &managers[i];
- for (i = 0; i < num_ovls; ++i) {
- oc = &dss_cache.overlay_cache[i];
- if (oc->channel != mgr->id)
- continue;
-
- oc->shadow_dirty = false;
- }
-
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
- if (mgr->id != i)
- continue;
-
- mc->shadow_dirty = false;
+ kobject_del(&mgr->kobj);
+ kobject_put(&mgr->kobj);
}
- dssdev->manager->enable(dssdev->manager);
+ kfree(managers);
+ managers = NULL;
+ num_managers = 0;
}
-static void dss_apply_irq_handler(void *data, u32 mask)
+int omap_dss_get_num_overlay_managers(void)
{
- struct manager_cache_data *mc;
- struct overlay_cache_data *oc;
- const int num_ovls = dss_feat_get_num_ovls();
- const int num_mgrs = dss_feat_get_num_mgrs();
- int i, r;
- bool mgr_busy[MAX_DSS_MANAGERS];
- u32 irq_mask;
-
- for (i = 0; i < num_mgrs; i++)
- mgr_busy[i] = dispc_mgr_go_busy(i);
-
- spin_lock(&dss_cache.lock);
-
- for (i = 0; i < num_ovls; ++i) {
- oc = &dss_cache.overlay_cache[i];
- if (!mgr_busy[oc->channel])
- oc->shadow_dirty = false;
- }
-
- for (i = 0; i < num_mgrs; ++i) {
- mc = &dss_cache.manager_cache[i];
- if (!mgr_busy[i])
- mc->shadow_dirty = false;
- }
-
- r = configure_dispc();
- if (r == 1)
- goto end;
-
- /* re-read busy flags */
- for (i = 0; i < num_mgrs; i++)
- mgr_busy[i] = dispc_mgr_go_busy(i);
-
- /* keep running as long as there are busy managers, so that
- * we can collect overlay-applied information */
- for (i = 0; i < num_mgrs; ++i) {
- if (mgr_busy[i])
- goto end;
- }
-
- irq_mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- irq_mask |= DISPC_IRQ_VSYNC2;
-
- omap_dispc_unregister_isr(dss_apply_irq_handler, NULL, irq_mask);
- dss_cache.irq_enabled = false;
-
-end:
- spin_unlock(&dss_cache.lock);
+ return num_managers;
}
+EXPORT_SYMBOL(omap_dss_get_num_overlay_managers);
-static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
+struct omap_overlay_manager *omap_dss_get_overlay_manager(int num)
{
- struct overlay_cache_data *oc;
- struct manager_cache_data *mc;
- int i;
- struct omap_overlay *ovl;
- int num_planes_enabled = 0;
- bool use_fifomerge;
- unsigned long flags;
- int r;
-
- DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
-
- r = dispc_runtime_get();
- if (r)
- return r;
-
- spin_lock_irqsave(&dss_cache.lock, flags);
-
- /* Configure overlays */
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
- struct omap_dss_device *dssdev;
-
- ovl = omap_dss_get_overlay(i);
-
- oc = &dss_cache.overlay_cache[ovl->id];
-
- if (ovl->manager_changed) {
- ovl->manager_changed = false;
- ovl->info_dirty = true;
- }
-
- if (!overlay_enabled(ovl)) {
- if (oc->enabled) {
- oc->enabled = false;
- oc->dirty = true;
- }
- continue;
- }
-
- if (!ovl->info_dirty) {
- if (oc->enabled)
- ++num_planes_enabled;
- continue;
- }
-
- dssdev = ovl->manager->device;
-
- if (dss_check_overlay(ovl, dssdev)) {
- if (oc->enabled) {
- oc->enabled = false;
- oc->dirty = true;
- }
- continue;
- }
-
- ovl->info_dirty = false;
- oc->dirty = true;
- oc->info = ovl->info;
-
- oc->replication =
- dss_use_replication(dssdev, ovl->info.color_mode);
-
- oc->ilace = dssdev->type == OMAP_DISPLAY_TYPE_VENC;
-
- oc->channel = ovl->manager->id;
-
- oc->enabled = true;
-
- ++num_planes_enabled;
- }
-
- /* Configure managers */
- list_for_each_entry(mgr, &manager_list, list) {
- struct omap_dss_device *dssdev;
+ if (num >= num_managers)
+ return NULL;
- mc = &dss_cache.manager_cache[mgr->id];
-
- if (mgr->device_changed) {
- mgr->device_changed = false;
- mgr->info_dirty = true;
- }
-
- if (!mgr->info_dirty)
- continue;
-
- if (!mgr->device)
- continue;
-
- dssdev = mgr->device;
-
- mgr->info_dirty = false;
- mc->dirty = true;
- mc->info = mgr->info;
-
- mc->manual_update =
- dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
- }
-
- /* XXX TODO: Try to get fifomerge working. The problem is that it
- * affects both managers, not individually but at the same time. This
- * means the change has to be well synchronized. I guess the proper way
- * is to have a two step process for fifo merge:
- * fifomerge enable:
- * 1. disable other planes, leaving one plane enabled
- * 2. wait until the planes are disabled on HW
- * 3. config merged fifo thresholds, enable fifomerge
- * fifomerge disable:
- * 1. config unmerged fifo thresholds, disable fifomerge
- * 2. wait until fifo changes are in HW
- * 3. enable planes
- */
- use_fifomerge = false;
-
- /* Configure overlay fifos */
- for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
- struct omap_dss_device *dssdev;
- u32 size, burst_size;
-
- ovl = omap_dss_get_overlay(i);
-
- oc = &dss_cache.overlay_cache[ovl->id];
-
- if (!oc->enabled)
- continue;
-
- dssdev = ovl->manager->device;
-
- size = dispc_ovl_get_fifo_size(ovl->id);
- if (use_fifomerge)
- size *= 3;
-
- burst_size = dispc_ovl_get_burst_size(ovl->id);
-
- switch (dssdev->type) {
- case OMAP_DISPLAY_TYPE_DPI:
- case OMAP_DISPLAY_TYPE_DBI:
- case OMAP_DISPLAY_TYPE_SDI:
- case OMAP_DISPLAY_TYPE_VENC:
- case OMAP_DISPLAY_TYPE_HDMI:
- default_get_overlay_fifo_thresholds(ovl->id, size,
- burst_size, &oc->fifo_low,
- &oc->fifo_high);
- break;
-#ifdef CONFIG_OMAP2_DSS_DSI
- case OMAP_DISPLAY_TYPE_DSI:
- dsi_get_overlay_fifo_thresholds(ovl->id, size,
- burst_size, &oc->fifo_low,
- &oc->fifo_high);
- break;
-#endif
- default:
- BUG();
- }
- }
-
- r = 0;
- if (!dss_cache.irq_enabled) {
- u32 mask;
-
- mask = DISPC_IRQ_VSYNC | DISPC_IRQ_EVSYNC_ODD |
- DISPC_IRQ_EVSYNC_EVEN;
- if (dss_has_feature(FEAT_MGR_LCD2))
- mask |= DISPC_IRQ_VSYNC2;
-
- r = omap_dispc_register_isr(dss_apply_irq_handler, NULL, mask);
- dss_cache.irq_enabled = true;
- }
- configure_dispc();
-
- spin_unlock_irqrestore(&dss_cache.lock, flags);
-
- dispc_runtime_put();
-
- return r;
+ return &managers[num];
}
+EXPORT_SYMBOL(omap_dss_get_overlay_manager);
-static int dss_check_manager(struct omap_overlay_manager *mgr)
+int dss_mgr_simple_check(struct omap_overlay_manager *mgr,
+ const struct omap_overlay_manager_info *info)
{
if (dss_has_feature(FEAT_ALPHA_FIXED_ZORDER)) {
/*
* OMAP3 supports only graphics source transparency color key
* and alpha blending simultaneously. See TRM 15.4.2.4.2.2
- * Alpha Mode
+ * Alpha Mode.
*/
- if (mgr->info.partial_alpha_enabled && mgr->info.trans_enabled
- && mgr->info.trans_key_type !=
- OMAP_DSS_COLOR_KEY_GFX_DST)
+ if (info->partial_alpha_enabled && info->trans_enabled
+ && info->trans_key_type != OMAP_DSS_COLOR_KEY_GFX_DST) {
+ DSSERR("check_manager: illegal transparency key\n");
return -EINVAL;
+ }
}
return 0;
}
-static int omap_dss_mgr_set_info(struct omap_overlay_manager *mgr,
- struct omap_overlay_manager_info *info)
-{
- int r;
- struct omap_overlay_manager_info old_info;
-
- old_info = mgr->info;
- mgr->info = *info;
-
- r = dss_check_manager(mgr);
- if (r) {
- mgr->info = old_info;
- return r;
- }
-
- mgr->info_dirty = true;
-
- return 0;
-}
-
-static void omap_dss_mgr_get_info(struct omap_overlay_manager *mgr,
- struct omap_overlay_manager_info *info)
+static int dss_mgr_check_zorder(struct omap_overlay_manager *mgr,
+ struct omap_overlay_info **overlay_infos)
{
- *info = mgr->info;
-}
+ struct omap_overlay *ovl1, *ovl2;
+ struct omap_overlay_info *info1, *info2;
-static int dss_mgr_enable(struct omap_overlay_manager *mgr)
-{
- dispc_mgr_enable(mgr->id, 1);
- return 0;
-}
+ list_for_each_entry(ovl1, &mgr->overlays, list) {
+ info1 = overlay_infos[ovl1->id];
-static int dss_mgr_disable(struct omap_overlay_manager *mgr)
-{
- dispc_mgr_enable(mgr->id, 0);
- return 0;
-}
-
-static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
-{
- ++num_managers;
- list_add_tail(&manager->list, &manager_list);
-}
-
-int dss_init_overlay_managers(struct platform_device *pdev)
-{
- int i, r;
-
- spin_lock_init(&dss_cache.lock);
-
- INIT_LIST_HEAD(&manager_list);
-
- num_managers = 0;
-
- for (i = 0; i < dss_feat_get_num_mgrs(); ++i) {
- struct omap_overlay_manager *mgr;
- mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
-
- BUG_ON(mgr == NULL);
-
- switch (i) {
- case 0:
- mgr->name = "lcd";
- mgr->id = OMAP_DSS_CHANNEL_LCD;
- break;
- case 1:
- mgr->name = "tv";
- mgr->id = OMAP_DSS_CHANNEL_DIGIT;
- break;
- case 2:
- mgr->name = "lcd2";
- mgr->id = OMAP_DSS_CHANNEL_LCD2;
- break;
- }
-
- mgr->set_device = &omap_dss_set_device;
- mgr->unset_device = &omap_dss_unset_device;
- mgr->apply = &omap_dss_mgr_apply;
- mgr->set_manager_info = &omap_dss_mgr_set_info;
- mgr->get_manager_info = &omap_dss_mgr_get_info;
- mgr->wait_for_go = &dss_mgr_wait_for_go;
- mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
-
- mgr->enable = &dss_mgr_enable;
- mgr->disable = &dss_mgr_disable;
-
- mgr->caps = 0;
- mgr->supported_displays =
- dss_feat_get_supported_displays(mgr->id);
+ if (info1 == NULL)
+ continue;
- dss_overlay_setup_dispc_manager(mgr);
+ list_for_each_entry(ovl2, &mgr->overlays, list) {
+ if (ovl1 == ovl2)
+ continue;
- omap_dss_add_overlay_manager(mgr);
+ info2 = overlay_infos[ovl2->id];
- r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
- &pdev->dev.kobj, "manager%d", i);
+ if (info2 == NULL)
+ continue;
- if (r) {
- DSSERR("failed to create sysfs file\n");
- continue;
+ if (info1->zorder == info2->zorder) {
+ DSSERR("overlays %d and %d have the same "
+ "zorder %d\n",
+ ovl1->id, ovl2->id, info1->zorder);
+ return -EINVAL;
+ }
}
}
return 0;
}
-void dss_uninit_overlay_managers(struct platform_device *pdev)
+int dss_mgr_check(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dssdev,
+ struct omap_overlay_manager_info *info,
+ struct omap_overlay_info **overlay_infos)
{
- struct omap_overlay_manager *mgr;
+ struct omap_overlay *ovl;
+ int r;
- while (!list_empty(&manager_list)) {
- mgr = list_first_entry(&manager_list,
- struct omap_overlay_manager, list);
- list_del(&mgr->list);
- kobject_del(&mgr->kobj);
- kobject_put(&mgr->kobj);
- kfree(mgr);
+ if (dss_has_feature(FEAT_ALPHA_FREE_ZORDER)) {
+ r = dss_mgr_check_zorder(mgr, overlay_infos);
+ if (r)
+ return r;
}
- num_managers = 0;
-}
+ list_for_each_entry(ovl, &mgr->overlays, list) {
+ struct omap_overlay_info *oi;
+ int r;
-int omap_dss_get_num_overlay_managers(void)
-{
- return num_managers;
-}
-EXPORT_SYMBOL(omap_dss_get_num_overlay_managers);
+ oi = overlay_infos[ovl->id];
-struct omap_overlay_manager *omap_dss_get_overlay_manager(int num)
-{
- int i = 0;
- struct omap_overlay_manager *mgr;
+ if (oi == NULL)
+ continue;
- list_for_each_entry(mgr, &manager_list, list) {
- if (i++ == num)
- return mgr;
+ r = dss_ovl_check(ovl, oi, dssdev);
+ if (r)
+ return r;
}
- return NULL;
+ return 0;
}
-EXPORT_SYMBOL(omap_dss_get_overlay_manager);
-
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index ab8e40e48759..6e821810deec 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -38,7 +38,7 @@
#include "dss_features.h"
static int num_overlays;
-static struct list_head overlay_list;
+static struct omap_overlay *overlays;
static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
{
@@ -124,19 +124,31 @@ err:
static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- ovl->info.width, ovl->info.height);
+ info.width, info.height);
}
static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.screen_width);
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.screen_width);
}
static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- ovl->info.pos_x, ovl->info.pos_y);
+ info.pos_x, info.pos_y);
}
static ssize_t overlay_position_store(struct omap_overlay *ovl,
@@ -170,8 +182,12 @@ static ssize_t overlay_position_store(struct omap_overlay *ovl,
static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d,%d\n",
- ovl->info.out_width, ovl->info.out_height);
+ info.out_width, info.out_height);
}
static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
@@ -205,7 +221,7 @@ static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.enabled);
+ return snprintf(buf, PAGE_SIZE, "%d\n", ovl->is_enabled(ovl));
}
static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
@@ -213,33 +229,30 @@ static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf,
{
int r;
bool enable;
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
r = strtobool(buf, &enable);
if (r)
return r;
- info.enabled = enable;
+ if (enable)
+ r = ovl->enable(ovl);
+ else
+ r = ovl->disable(ovl);
- r = ovl->set_overlay_info(ovl, &info);
if (r)
return r;
- if (ovl->manager) {
- r = ovl->manager->apply(ovl->manager);
- if (r)
- return r;
- }
-
return size;
}
static ssize_t overlay_global_alpha_show(struct omap_overlay *ovl, char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d\n",
- ovl->info.global_alpha);
+ info.global_alpha);
}
static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
@@ -276,8 +289,12 @@ static ssize_t overlay_global_alpha_store(struct omap_overlay *ovl,
static ssize_t overlay_pre_mult_alpha_show(struct omap_overlay *ovl,
char *buf)
{
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
return snprintf(buf, PAGE_SIZE, "%d\n",
- ovl->info.pre_mult_alpha);
+ info.pre_mult_alpha);
}
static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
@@ -313,7 +330,11 @@ static ssize_t overlay_pre_mult_alpha_store(struct omap_overlay *ovl,
static ssize_t overlay_zorder_show(struct omap_overlay *ovl, char *buf)
{
- return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.zorder);
+ struct omap_overlay_info info;
+
+ ovl->get_overlay_info(ovl, &info);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", info.zorder);
}
static ssize_t overlay_zorder_store(struct omap_overlay *ovl,
@@ -430,183 +451,6 @@ static struct kobj_type overlay_ktype = {
.default_attrs = overlay_sysfs_attrs,
};
-/* Check if overlay parameters are compatible with display */
-int dss_check_overlay(struct omap_overlay *ovl, struct omap_dss_device *dssdev)
-{
- struct omap_overlay_info *info;
- u16 outw, outh;
- u16 dw, dh;
- int i;
-
- if (!dssdev)
- return 0;
-
- if (!ovl->info.enabled)
- return 0;
-
- info = &ovl->info;
-
- if (info->paddr == 0) {
- DSSDBG("check_overlay failed: paddr 0\n");
- return -EINVAL;
- }
-
- dssdev->driver->get_resolution(dssdev, &dw, &dh);
-
- DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
- ovl->id,
- info->pos_x, info->pos_y,
- info->width, info->height,
- info->out_width, info->out_height,
- dw, dh);
-
- if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
- outw = info->width;
- outh = info->height;
- } else {
- if (info->out_width == 0)
- outw = info->width;
- else
- outw = info->out_width;
-
- if (info->out_height == 0)
- outh = info->height;
- else
- outh = info->out_height;
- }
-
- if (dw < info->pos_x + outw) {
- DSSDBG("check_overlay failed 1: %d < %d + %d\n",
- dw, info->pos_x, outw);
- return -EINVAL;
- }
-
- if (dh < info->pos_y + outh) {
- DSSDBG("check_overlay failed 2: %d < %d + %d\n",
- dh, info->pos_y, outh);
- return -EINVAL;
- }
-
- if ((ovl->supported_modes & info->color_mode) == 0) {
- DSSERR("overlay doesn't support mode %d\n", info->color_mode);
- return -EINVAL;
- }
-
- if (ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) {
- if (info->zorder < 0 || info->zorder > 3) {
- DSSERR("zorder out of range: %d\n",
- info->zorder);
- return -EINVAL;
- }
- /*
- * Check that zorder doesn't match with zorder of any other
- * overlay which is enabled and is also connected to the same
- * manager
- */
- for (i = 0; i < omap_dss_get_num_overlays(); i++) {
- struct omap_overlay *tmp_ovl = omap_dss_get_overlay(i);
-
- if (tmp_ovl->id != ovl->id &&
- tmp_ovl->manager == ovl->manager &&
- tmp_ovl->info.enabled == true &&
- tmp_ovl->info.zorder == info->zorder) {
- DSSERR("%s and %s have same zorder: %d\n",
- ovl->name, tmp_ovl->name, info->zorder);
- return -EINVAL;
- }
- }
- }
-
- return 0;
-}
-
-static int dss_ovl_set_overlay_info(struct omap_overlay *ovl,
- struct omap_overlay_info *info)
-{
- int r;
- struct omap_overlay_info old_info;
-
- old_info = ovl->info;
- ovl->info = *info;
-
- if (ovl->manager) {
- r = dss_check_overlay(ovl, ovl->manager->device);
- if (r) {
- ovl->info = old_info;
- return r;
- }
- }
-
- ovl->info_dirty = true;
-
- return 0;
-}
-
-static void dss_ovl_get_overlay_info(struct omap_overlay *ovl,
- struct omap_overlay_info *info)
-{
- *info = ovl->info;
-}
-
-static int dss_ovl_wait_for_go(struct omap_overlay *ovl)
-{
- return dss_mgr_wait_for_go_ovl(ovl);
-}
-
-static int omap_dss_set_manager(struct omap_overlay *ovl,
- struct omap_overlay_manager *mgr)
-{
- if (!mgr)
- return -EINVAL;
-
- if (ovl->manager) {
- DSSERR("overlay '%s' already has a manager '%s'\n",
- ovl->name, ovl->manager->name);
- return -EINVAL;
- }
-
- if (ovl->info.enabled) {
- DSSERR("overlay has to be disabled to change the manager\n");
- return -EINVAL;
- }
-
- ovl->manager = mgr;
- ovl->manager_changed = true;
-
- /* XXX: When there is an overlay on a DSI manual update display, and
- * the overlay is first disabled, then moved to tv, and enabled, we
- * seem to get SYNC_LOST_DIGIT error.
- *
- * Waiting doesn't seem to help, but updating the manual update display
- * after disabling the overlay seems to fix this. This hints that the
- * overlay is perhaps somehow tied to the LCD output until the output
- * is updated.
- *
- * Userspace workaround for this is to update the LCD after disabling
- * the overlay, but before moving the overlay to TV.
- */
-
- return 0;
-}
-
-static int omap_dss_unset_manager(struct omap_overlay *ovl)
-{
- if (!ovl->manager) {
- DSSERR("failed to detach overlay: manager not set\n");
- return -EINVAL;
- }
-
- if (ovl->info.enabled) {
- DSSERR("overlay has to be disabled to unset the manager\n");
- return -EINVAL;
- }
-
- ovl->manager = NULL;
- ovl->manager_changed = true;
-
- return 0;
-}
-
int omap_dss_get_num_overlays(void)
{
return num_overlays;
@@ -615,134 +459,65 @@ EXPORT_SYMBOL(omap_dss_get_num_overlays);
struct omap_overlay *omap_dss_get_overlay(int num)
{
- int i = 0;
- struct omap_overlay *ovl;
+ if (num >= num_overlays)
+ return NULL;
- list_for_each_entry(ovl, &overlay_list, list) {
- if (i++ == num)
- return ovl;
- }
-
- return NULL;
+ return &overlays[num];
}
EXPORT_SYMBOL(omap_dss_get_overlay);
-static void omap_dss_add_overlay(struct omap_overlay *overlay)
-{
- ++num_overlays;
- list_add_tail(&overlay->list, &overlay_list);
-}
-
-static struct omap_overlay *dispc_overlays[MAX_DSS_OVERLAYS];
-
-void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
-{
- mgr->num_overlays = dss_feat_get_num_ovls();
- mgr->overlays = dispc_overlays;
-}
-
-#ifdef L4_EXAMPLE
-static struct omap_overlay *l4_overlays[1];
-void dss_overlay_setup_l4_manager(struct omap_overlay_manager *mgr)
-{
- mgr->num_overlays = 1;
- mgr->overlays = l4_overlays;
-}
-#endif
-
void dss_init_overlays(struct platform_device *pdev)
{
int i, r;
- INIT_LIST_HEAD(&overlay_list);
+ num_overlays = dss_feat_get_num_ovls();
- num_overlays = 0;
+ overlays = kzalloc(sizeof(struct omap_overlay) * num_overlays,
+ GFP_KERNEL);
- for (i = 0; i < dss_feat_get_num_ovls(); ++i) {
- struct omap_overlay *ovl;
- ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
+ BUG_ON(overlays == NULL);
- BUG_ON(ovl == NULL);
+ for (i = 0; i < num_overlays; ++i) {
+ struct omap_overlay *ovl = &overlays[i];
switch (i) {
case 0:
ovl->name = "gfx";
ovl->id = OMAP_DSS_GFX;
- ovl->info.global_alpha = 255;
- ovl->info.zorder = 0;
break;
case 1:
ovl->name = "vid1";
ovl->id = OMAP_DSS_VIDEO1;
- ovl->info.global_alpha = 255;
- ovl->info.zorder =
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 3 : 0;
break;
case 2:
ovl->name = "vid2";
ovl->id = OMAP_DSS_VIDEO2;
- ovl->info.global_alpha = 255;
- ovl->info.zorder =
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 2 : 0;
break;
case 3:
ovl->name = "vid3";
ovl->id = OMAP_DSS_VIDEO3;
- ovl->info.global_alpha = 255;
- ovl->info.zorder =
- dss_has_feature(FEAT_ALPHA_FREE_ZORDER) ? 1 : 0;
break;
}
- ovl->set_manager = &omap_dss_set_manager;
- ovl->unset_manager = &omap_dss_unset_manager;
- ovl->set_overlay_info = &dss_ovl_set_overlay_info;
- ovl->get_overlay_info = &dss_ovl_get_overlay_info;
- ovl->wait_for_go = &dss_ovl_wait_for_go;
+ ovl->is_enabled = &dss_ovl_is_enabled;
+ ovl->enable = &dss_ovl_enable;
+ ovl->disable = &dss_ovl_disable;
+ ovl->set_manager = &dss_ovl_set_manager;
+ ovl->unset_manager = &dss_ovl_unset_manager;
+ ovl->set_overlay_info = &dss_ovl_set_info;
+ ovl->get_overlay_info = &dss_ovl_get_info;
+ ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
ovl->caps = dss_feat_get_overlay_caps(ovl->id);
ovl->supported_modes =
dss_feat_get_supported_color_modes(ovl->id);
- omap_dss_add_overlay(ovl);
-
r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
&pdev->dev.kobj, "overlay%d", i);
- if (r) {
- DSSERR("failed to create sysfs file\n");
- continue;
- }
-
- dispc_overlays[i] = ovl;
- }
-
-#ifdef L4_EXAMPLE
- {
- struct omap_overlay *ovl;
- ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
-
- BUG_ON(ovl == NULL);
-
- ovl->name = "l4";
- ovl->supported_modes = OMAP_DSS_COLOR_RGB24U;
-
- ovl->set_manager = &omap_dss_set_manager;
- ovl->unset_manager = &omap_dss_unset_manager;
- ovl->set_overlay_info = &dss_ovl_set_overlay_info;
- ovl->get_overlay_info = &dss_ovl_get_overlay_info;
-
- omap_dss_add_overlay(ovl);
-
- r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
- &pdev->dev.kobj, "overlayl4");
-
if (r)
DSSERR("failed to create sysfs file\n");
-
- l4_overlays[0] = ovl;
}
-#endif
}
/* connect overlays to the new device, if not already connected. if force
@@ -795,8 +570,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
ovl = omap_dss_get_overlay(i);
if (!ovl->manager || force) {
if (ovl->manager)
- omap_dss_unset_manager(ovl);
- omap_dss_set_manager(ovl, mgr);
+ ovl->unset_manager(ovl);
+ ovl->set_manager(ovl, mgr);
}
}
@@ -806,17 +581,95 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
void dss_uninit_overlays(struct platform_device *pdev)
{
- struct omap_overlay *ovl;
+ int i;
+
+ for (i = 0; i < num_overlays; ++i) {
+ struct omap_overlay *ovl = &overlays[i];
- while (!list_empty(&overlay_list)) {
- ovl = list_first_entry(&overlay_list,
- struct omap_overlay, list);
- list_del(&ovl->list);
kobject_del(&ovl->kobj);
kobject_put(&ovl->kobj);
- kfree(ovl);
}
+ kfree(overlays);
+ overlays = NULL;
num_overlays = 0;
}
+int dss_ovl_simple_check(struct omap_overlay *ovl,
+ const struct omap_overlay_info *info)
+{
+ if (info->paddr == 0) {
+ DSSERR("check_overlay: paddr cannot be 0\n");
+ return -EINVAL;
+ }
+
+ if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
+ if (info->out_width != 0 && info->width != info->out_width) {
+ DSSERR("check_overlay: overlay %d doesn't support "
+ "scaling\n", ovl->id);
+ return -EINVAL;
+ }
+
+ if (info->out_height != 0 && info->height != info->out_height) {
+ DSSERR("check_overlay: overlay %d doesn't support "
+ "scaling\n", ovl->id);
+ return -EINVAL;
+ }
+ }
+
+ if ((ovl->supported_modes & info->color_mode) == 0) {
+ DSSERR("check_overlay: overlay %d doesn't support mode %d\n",
+ ovl->id, info->color_mode);
+ return -EINVAL;
+ }
+
+ if (info->zorder >= omap_dss_get_num_overlays()) {
+ DSSERR("check_overlay: zorder %d too high\n", info->zorder);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int dss_ovl_check(struct omap_overlay *ovl,
+ struct omap_overlay_info *info, struct omap_dss_device *dssdev)
+{
+ u16 outw, outh;
+ u16 dw, dh;
+
+ if (dssdev == NULL)
+ return 0;
+
+ dssdev->driver->get_resolution(dssdev, &dw, &dh);
+
+ if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
+ outw = info->width;
+ outh = info->height;
+ } else {
+ if (info->out_width == 0)
+ outw = info->width;
+ else
+ outw = info->out_width;
+
+ if (info->out_height == 0)
+ outh = info->height;
+ else
+ outh = info->out_height;
+ }
+
+ if (dw < info->pos_x + outw) {
+ DSSERR("overlay %d horizontally not inside the display area "
+ "(%d + %d >= %d)\n",
+ ovl->id, info->pos_x, outw, dw);
+ return -EINVAL;
+ }
+
+ if (dh < info->pos_y + outh) {
+ DSSERR("overlay %d vertically not inside the display area "
+ "(%d + %d >= %d)\n",
+ ovl->id, info->pos_y, outh, dh);
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 1130c608a561..814bb9500dca 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -784,7 +784,6 @@ int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
if (*w == 0 || *h == 0)
return -EINVAL;
- dss_setup_partial_planes(dssdev, x, y, w, h, true);
dispc_mgr_set_lcd_size(dssdev->manager->id, *w, *h);
return 0;
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 40305ad7841e..8266ca0d666b 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -123,10 +123,14 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
goto err_sdi_enable;
mdelay(2);
- dssdev->manager->enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ goto err_mgr_enable;
return 0;
+err_mgr_enable:
+ dss_sdi_disable();
err_sdi_enable:
err_set_dispc_clock_div:
err_set_dss_clock_div:
@@ -145,7 +149,7 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
{
- dssdev->manager->disable(dssdev->manager);
+ dss_mgr_disable(dssdev->manager);
dss_sdi_disable();
diff --git a/drivers/video/omap2/dss/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index 2c3443dabb14..7503f7f619a7 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -110,6 +110,11 @@ struct ti_hdmi_ip_ops {
void (*dump_phy)(struct hdmi_ip_data *ip_data, struct seq_file *s);
+#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
+ defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
+ void (*audio_enable)(struct hdmi_ip_data *ip_data, bool start);
+#endif
+
};
struct hdmi_ip_data {
@@ -134,5 +139,8 @@ void ti_hdmi_4xxx_wp_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
void ti_hdmi_4xxx_pll_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
void ti_hdmi_4xxx_core_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
void ti_hdmi_4xxx_phy_dump(struct hdmi_ip_data *ip_data, struct seq_file *s);
-
+#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
+ defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
+void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable);
+#endif
#endif
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index e1a6ce518af6..9af81f18f163 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -1204,36 +1204,13 @@ int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
return 0;
}
-int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
- struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai)
+void ti_hdmi_4xxx_wp_audio_enable(struct hdmi_ip_data *ip_data, bool enable)
{
- int err = 0;
- switch (cmd) {
- case SNDRV_PCM_TRIGGER_START:
- case SNDRV_PCM_TRIGGER_RESUME:
- case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- REG_FLD_MOD(hdmi_av_base(ip_data),
- HDMI_CORE_AV_AUD_MODE, 1, 0, 0);
- REG_FLD_MOD(hdmi_wp_base(ip_data),
- HDMI_WP_AUDIO_CTRL, 1, 31, 31);
- REG_FLD_MOD(hdmi_wp_base(ip_data),
- HDMI_WP_AUDIO_CTRL, 1, 30, 30);
- break;
-
- case SNDRV_PCM_TRIGGER_STOP:
- case SNDRV_PCM_TRIGGER_SUSPEND:
- case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- REG_FLD_MOD(hdmi_av_base(ip_data),
- HDMI_CORE_AV_AUD_MODE, 0, 0, 0);
- REG_FLD_MOD(hdmi_wp_base(ip_data),
- HDMI_WP_AUDIO_CTRL, 0, 30, 30);
- REG_FLD_MOD(hdmi_wp_base(ip_data),
- HDMI_WP_AUDIO_CTRL, 0, 31, 31);
- break;
- default:
- err = -EINVAL;
- }
- return err;
+ REG_FLD_MOD(hdmi_av_base(ip_data),
+ HDMI_CORE_AV_AUD_MODE, enable, 0, 0);
+ REG_FLD_MOD(hdmi_wp_base(ip_data),
+ HDMI_WP_AUDIO_CTRL, enable, 31, 31);
+ REG_FLD_MOD(hdmi_wp_base(ip_data),
+ HDMI_WP_AUDIO_CTRL, enable, 30, 30);
}
#endif
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
index 204095632d27..a442998980f1 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
@@ -576,9 +576,6 @@ struct hdmi_core_audio_config {
#if defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI) || \
defined(CONFIG_SND_OMAP_SOC_OMAP4_HDMI_MODULE)
-int hdmi_audio_trigger(struct hdmi_ip_data *ip_data,
- struct snd_pcm_substream *substream, int cmd,
- struct snd_soc_dai *dai);
int hdmi_config_audio_acr(struct hdmi_ip_data *ip_data,
u32 sample_freq, u32 *n, u32 *cts);
void hdmi_core_audio_infoframe_config(struct hdmi_ip_data *ip_data,
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 7533458ba4d2..b3e9f9091581 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -417,9 +417,10 @@ static const struct venc_config *venc_timings_to_config(
BUG();
}
-static void venc_power_on(struct omap_dss_device *dssdev)
+static int venc_power_on(struct omap_dss_device *dssdev)
{
u32 l;
+ int r;
venc_reset();
venc_write_config(venc_timings_to_config(&dssdev->panel.timings));
@@ -447,7 +448,22 @@ static void venc_power_on(struct omap_dss_device *dssdev)
if (dssdev->platform_enable)
dssdev->platform_enable(dssdev);
- dssdev->manager->enable(dssdev->manager);
+ r = dss_mgr_enable(dssdev->manager);
+ if (r)
+ goto err;
+
+ return 0;
+
+err:
+ venc_write_reg(VENC_OUTPUT_CONTROL, 0);
+ dss_set_dac_pwrdn_bgz(0);
+
+ if (dssdev->platform_disable)
+ dssdev->platform_disable(dssdev);
+
+ regulator_disable(venc.vdda_dac_reg);
+
+ return r;
}
static void venc_power_off(struct omap_dss_device *dssdev)
@@ -455,7 +471,7 @@ static void venc_power_off(struct omap_dss_device *dssdev)
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0);
- dssdev->manager->disable(dssdev->manager);
+ dss_mgr_disable(dssdev->manager);
if (dssdev->platform_disable)
dssdev->platform_disable(dssdev);
@@ -504,7 +520,9 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
if (r)
goto err1;
- venc_power_on(dssdev);
+ r = venc_power_on(dssdev);
+ if (r)
+ goto err2;
venc.wss_data = 0;
@@ -512,6 +530,8 @@ static int venc_panel_enable(struct omap_dss_device *dssdev)
mutex_unlock(&venc.venc_lock);
return 0;
+err2:
+ venc_runtime_put();
err1:
omap_dss_stop_device(dssdev);
err0:
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index df7bcce5b107..16ba6196f330 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -111,28 +111,22 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
set_fb_fix(fbi);
}
- if (pi->enabled) {
- struct omap_overlay_info info;
+ if (!pi->enabled) {
+ r = ovl->disable(ovl);
+ if (r)
+ goto undo;
+ }
+ if (pi->enabled) {
r = omapfb_setup_overlay(fbi, ovl, pi->pos_x, pi->pos_y,
pi->out_width, pi->out_height);
if (r)
goto undo;
-
- ovl->get_overlay_info(ovl, &info);
-
- if (!info.enabled) {
- info.enabled = pi->enabled;
- r = ovl->set_overlay_info(ovl, &info);
- if (r)
- goto undo;
- }
} else {
struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info);
- info.enabled = pi->enabled;
info.pos_x = pi->pos_x;
info.pos_y = pi->pos_y;
info.out_width = pi->out_width;
@@ -146,6 +140,12 @@ static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
if (ovl->manager)
ovl->manager->apply(ovl->manager);
+ if (pi->enabled) {
+ r = ovl->enable(ovl);
+ if (r)
+ goto undo;
+ }
+
/* Release the locks in a specific order to keep lockdep happy */
if (old_rg->id > new_rg->id) {
omapfb_put_mem_region(old_rg);
@@ -189,19 +189,19 @@ static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
memset(pi, 0, sizeof(*pi));
} else {
struct omap_overlay *ovl;
- struct omap_overlay_info *ovli;
+ struct omap_overlay_info ovli;
ovl = ofbi->overlays[0];
- ovli = &ovl->info;
+ ovl->get_overlay_info(ovl, &ovli);
- pi->pos_x = ovli->pos_x;
- pi->pos_y = ovli->pos_y;
- pi->enabled = ovli->enabled;
+ pi->pos_x = ovli.pos_x;
+ pi->pos_y = ovli.pos_y;
+ pi->enabled = ovl->is_enabled(ovl);
pi->channel_out = 0; /* xxx */
pi->mirror = 0;
pi->mem_idx = get_mem_idx(ofbi);
- pi->out_width = ovli->out_width;
- pi->out_height = ovli->out_height;
+ pi->out_width = ovli.out_width;
+ pi->out_height = ovli.out_height;
}
return 0;
@@ -238,7 +238,9 @@ static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
continue;
for (j = 0; j < ofbi2->num_overlays; j++) {
- if (ofbi2->overlays[j]->info.enabled) {
+ struct omap_overlay *ovl;
+ ovl = ofbi2->overlays[j];
+ if (ovl->is_enabled(ovl)) {
r = -EBUSY;
goto out;
}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 70aa47de7146..ce158311ff59 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -43,18 +43,18 @@
static char *def_mode;
static char *def_vram;
-static int def_vrfb;
+static bool def_vrfb;
static int def_rotate;
-static int def_mirror;
+static bool def_mirror;
static bool auto_update;
static unsigned int auto_update_freq;
module_param(auto_update, bool, 0);
module_param(auto_update_freq, uint, 0644);
#ifdef DEBUG
-unsigned int omapfb_debug;
+bool omapfb_debug;
module_param_named(debug, omapfb_debug, bool, 0644);
-static unsigned int omapfb_test_pattern;
+static bool omapfb_test_pattern;
module_param_named(test, omapfb_test_pattern, bool, 0644);
#endif
@@ -970,16 +970,20 @@ int omapfb_apply_changes(struct fb_info *fbi, int init)
outh = var->yres;
}
} else {
- outw = ovl->info.out_width;
- outh = ovl->info.out_height;
+ struct omap_overlay_info info;
+ ovl->get_overlay_info(ovl, &info);
+ outw = info.out_width;
+ outh = info.out_height;
}
if (init) {
posx = 0;
posy = 0;
} else {
- posx = ovl->info.pos_x;
- posy = ovl->info.pos_y;
+ struct omap_overlay_info info;
+ ovl->get_overlay_info(ovl, &info);
+ posx = info.pos_x;
+ posy = info.pos_y;
}
r = omapfb_setup_overlay(fbi, ovl, posx, posy, outw, outh);
@@ -2067,6 +2071,8 @@ static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
if (ofbi->num_overlays > 0) {
struct omap_overlay *ovl = ofbi->overlays[0];
+ ovl->manager->apply(ovl->manager);
+
r = omapfb_overlay_enable(ovl, 1);
if (r) {
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 1694d5148f32..e8d8cc76a435 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -473,7 +473,9 @@ static ssize_t store_size(struct device *dev, struct device_attribute *attr,
continue;
for (j = 0; j < ofbi2->num_overlays; j++) {
- if (ofbi2->overlays[j]->info.enabled) {
+ struct omap_overlay *ovl;
+ ovl = ofbi2->overlays[j];
+ if (ovl->is_enabled(ovl)) {
r = -EBUSY;
goto out;
}
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index fdf0edeccf4e..c0bdc9b54ecf 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -32,7 +32,7 @@
#include <video/omapdss.h>
#ifdef DEBUG
-extern unsigned int omapfb_debug;
+extern bool omapfb_debug;
#define DBG(format, ...) \
do { \
if (omapfb_debug) \
@@ -181,13 +181,10 @@ static inline void omapfb_unlock(struct omapfb2_device *fbdev)
static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
int enable)
{
- struct omap_overlay_info info;
-
- ovl->get_overlay_info(ovl, &info);
- if (info.enabled == enable)
- return 0;
- info.enabled = enable;
- return ovl->set_overlay_info(ovl, &info);
+ if (enable)
+ return ovl->enable(ovl);
+ else
+ return ovl->disable(ovl);
}
static inline struct omapfb2_mem_region *
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index dc7bfa91e57a..df31a24a5026 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -78,12 +78,12 @@ static char *mode_option __devinitdata;
* these flags allow the user to specify that requests for +ve sync
* should be silently turned in -ve sync.
*/
-static int lowhsync;
-static int lowvsync;
-static int noaccel __devinitdata;
+static bool lowhsync;
+static bool lowvsync;
+static bool noaccel __devinitdata;
/* mtrr option */
#ifdef CONFIG_MTRR
-static int nomtrr __devinitdata;
+static bool nomtrr __devinitdata;
#endif
/*
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 6632ee5ecb7e..055e527a8e45 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -57,11 +57,11 @@
*/
static int hwcursor = 1;
static char *mode_option __devinitdata;
-static int noaccel __devinitdata;
+static bool noaccel __devinitdata;
/* mtrr option */
#ifdef CONFIG_MTRR
-static int nomtrr __devinitdata;
+static bool nomtrr __devinitdata;
#endif
/*
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
index b2252fea2858..6d30428e9cf9 100644
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -193,17 +193,6 @@ static struct platform_driver rgbfb_driver = {
.remove = rgbfb_remove,
};
-static int __init rgbfb_init(void)
-{
- return platform_driver_register(&rgbfb_driver);
-}
-
-static void __exit rgbfb_exit(void)
-{
- platform_driver_unregister(&rgbfb_driver);
-}
-
-module_init(rgbfb_init);
-module_exit(rgbfb_exit);
+module_platform_driver(rgbfb_driver);
MODULE_LICENSE("GPL");
diff --git a/drivers/video/pnx4008/sdum.c b/drivers/video/pnx4008/sdum.c
index 50e00395240f..c5c741452cac 100644
--- a/drivers/video/pnx4008/sdum.c
+++ b/drivers/video/pnx4008/sdum.c
@@ -856,17 +856,6 @@ static struct platform_driver sdum_driver = {
.resume = sdum_resume,
};
-int __init sdum_init(void)
-{
- return platform_driver_register(&sdum_driver);
-}
-
-static void __exit sdum_exit(void)
-{
- platform_driver_unregister(&sdum_driver);
-};
-
-module_init(sdum_init);
-module_exit(sdum_exit);
+module_platform_driver(sdum_driver);
MODULE_LICENSE("GPL");
diff --git a/drivers/video/pxa168fb.c b/drivers/video/pxa168fb.c
index 18ead6f0184d..8384b941f6ba 100644
--- a/drivers/video/pxa168fb.c
+++ b/drivers/video/pxa168fb.c
@@ -832,17 +832,7 @@ static struct platform_driver pxa168fb_driver = {
.remove = __devexit_p(pxa168fb_remove),
};
-static int __init pxa168fb_init(void)
-{
- return platform_driver_register(&pxa168fb_driver);
-}
-module_init(pxa168fb_init);
-
-static void __exit pxa168fb_exit(void)
-{
- platform_driver_unregister(&pxa168fb_driver);
-}
-module_exit(pxa168fb_exit);
+module_platform_driver(pxa168fb_driver);
MODULE_AUTHOR("Lennert Buytenhek <buytenh@marvell.com> "
"Green Wan <gwan@marvell.com>");
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/pxa3xx-gcu.c
index 1ed8b366618d..1d71c08a818f 100644
--- a/drivers/video/pxa3xx-gcu.c
+++ b/drivers/video/pxa3xx-gcu.c
@@ -747,20 +747,7 @@ static struct platform_driver pxa3xx_gcu_driver = {
},
};
-static int __init
-pxa3xx_gcu_init(void)
-{
- return platform_driver_register(&pxa3xx_gcu_driver);
-}
-
-static void __exit
-pxa3xx_gcu_exit(void)
-{
- platform_driver_unregister(&pxa3xx_gcu_driver);
-}
-
-module_init(pxa3xx_gcu_init);
-module_exit(pxa3xx_gcu_exit);
+module_platform_driver(pxa3xx_gcu_driver);
MODULE_DESCRIPTION("PXA3xx graphics controller unit driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c
index d8ab7be4fd6b..2f58cf9c813b 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/riva/fbdev.c
@@ -207,9 +207,9 @@ MODULE_DEVICE_TABLE(pci, rivafb_pci_tbl);
/* command line data, set in rivafb_setup() */
static int flatpanel __devinitdata = -1; /* Autodetect later */
static int forceCRTC __devinitdata = -1;
-static int noaccel __devinitdata = 0;
+static bool noaccel __devinitdata = 0;
#ifdef CONFIG_MTRR
-static int nomtrr __devinitdata = 0;
+static bool nomtrr __devinitdata = 0;
#endif
#ifdef CONFIG_PMAC_BACKLIGHT
static int backlight __devinitdata = 1;
@@ -218,7 +218,7 @@ static int backlight __devinitdata = 0;
#endif
static char *mode_option __devinitdata = NULL;
-static int strictmode = 0;
+static bool strictmode = 0;
static struct fb_fix_screeninfo __devinitdata rivafb_fix = {
.type = FB_TYPE_PACKED_PIXELS,
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c
index 0753b1cfcb8b..0c63b69b6340 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/s3c-fb.c
@@ -192,6 +192,7 @@ struct s3c_fb_vsync {
* @regs: The mapped hardware registers.
* @variant: Variant information for this hardware.
* @enabled: A bitmask of enabled hardware windows.
+ * @output_on: Flag if the physical output is enabled.
* @pdata: The platform configuration data passed with the device.
* @windows: The hardware windows that have been claimed.
* @irq_no: IRQ line number
@@ -208,6 +209,7 @@ struct s3c_fb {
struct s3c_fb_variant variant;
unsigned char enabled;
+ bool output_on;
struct s3c_fb_platdata *pdata;
struct s3c_fb_win *windows[S3C_FB_MAX_WIN];
@@ -441,6 +443,39 @@ static void shadow_protect_win(struct s3c_fb_win *win, bool protect)
}
/**
+ * s3c_fb_enable() - Set the state of the main LCD output
+ * @sfb: The main framebuffer state.
+ * @enable: The state to set.
+ */
+static void s3c_fb_enable(struct s3c_fb *sfb, int enable)
+{
+ u32 vidcon0 = readl(sfb->regs + VIDCON0);
+
+ if (enable && !sfb->output_on)
+ pm_runtime_get_sync(sfb->dev);
+
+ if (enable) {
+ vidcon0 |= VIDCON0_ENVID | VIDCON0_ENVID_F;
+ } else {
+ /* see the note in the framebuffer datasheet about
+ * why you cannot take both of these bits down at the
+ * same time. */
+
+ if (vidcon0 & VIDCON0_ENVID) {
+ vidcon0 |= VIDCON0_ENVID;
+ vidcon0 &= ~VIDCON0_ENVID_F;
+ }
+ }
+
+ writel(vidcon0, sfb->regs + VIDCON0);
+
+ if (!enable && sfb->output_on)
+ pm_runtime_put_sync(sfb->dev);
+
+ sfb->output_on = enable;
+}
+
+/**
* s3c_fb_set_par() - framebuffer request to set new framebuffer state.
* @info: The framebuffer to change.
*
@@ -461,6 +496,8 @@ static int s3c_fb_set_par(struct fb_info *info)
dev_dbg(sfb->dev, "setting framebuffer parameters\n");
+ pm_runtime_get_sync(sfb->dev);
+
shadow_protect_win(win, 1);
switch (var->bits_per_pixel) {
@@ -510,9 +547,10 @@ static int s3c_fb_set_par(struct fb_info *info)
if (sfb->variant.is_2443)
data |= (1 << 5);
- data |= VIDCON0_ENVID | VIDCON0_ENVID_F;
writel(data, regs + VIDCON0);
+ s3c_fb_enable(sfb, 1);
+
data = VIDTCON0_VBPD(var->upper_margin - 1) |
VIDTCON0_VFPD(var->lower_margin - 1) |
VIDTCON0_VSPW(var->vsync_len - 1);
@@ -574,6 +612,7 @@ static int s3c_fb_set_par(struct fb_info *info)
}
data = WINCONx_ENWIN;
+ sfb->enabled |= (1 << win->index);
/* note, since we have to round up the bits-per-pixel, we end up
* relying on the bitfield information for r/g/b/a to work out
@@ -621,7 +660,8 @@ static int s3c_fb_set_par(struct fb_info *info)
} else if (var->transp.length == 1)
data |= WINCON1_BPPMODE_25BPP_A1888
| WINCON1_BLD_PIX;
- else if (var->transp.length == 4)
+ else if ((var->transp.length == 4) ||
+ (var->transp.length == 8))
data |= WINCON1_BPPMODE_28BPP_A4888
| WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
else
@@ -654,6 +694,8 @@ static int s3c_fb_set_par(struct fb_info *info)
shadow_protect_win(win, 0);
+ pm_runtime_put_sync(sfb->dev);
+
return 0;
}
@@ -725,6 +767,8 @@ static int s3c_fb_setcolreg(unsigned regno,
dev_dbg(sfb->dev, "%s: win %d: %d => rgb=%d/%d/%d\n",
__func__, win->index, regno, red, green, blue);
+ pm_runtime_get_sync(sfb->dev);
+
switch (info->fix.visual) {
case FB_VISUAL_TRUECOLOR:
/* true-colour, use pseudo-palette */
@@ -752,39 +796,15 @@ static int s3c_fb_setcolreg(unsigned regno,
break;
default:
+ pm_runtime_put_sync(sfb->dev);
return 1; /* unknown type */
}
+ pm_runtime_put_sync(sfb->dev);
return 0;
}
/**
- * s3c_fb_enable() - Set the state of the main LCD output
- * @sfb: The main framebuffer state.
- * @enable: The state to set.
- */
-static void s3c_fb_enable(struct s3c_fb *sfb, int enable)
-{
- u32 vidcon0 = readl(sfb->regs + VIDCON0);
-
- if (enable)
- vidcon0 |= VIDCON0_ENVID | VIDCON0_ENVID_F;
- else {
- /* see the note in the framebuffer datasheet about
- * why you cannot take both of these bits down at the
- * same time. */
-
- if (!(vidcon0 & VIDCON0_ENVID))
- return;
-
- vidcon0 |= VIDCON0_ENVID;
- vidcon0 &= ~VIDCON0_ENVID_F;
- }
-
- writel(vidcon0, sfb->regs + VIDCON0);
-}
-
-/**
* s3c_fb_blank() - blank or unblank the given window
* @blank_mode: The blank state from FB_BLANK_*
* @info: The framebuffer to blank.
@@ -800,6 +820,8 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
dev_dbg(sfb->dev, "blank mode %d\n", blank_mode);
+ pm_runtime_get_sync(sfb->dev);
+
wincon = readl(sfb->regs + sfb->variant.wincon + (index * 4));
switch (blank_mode) {
@@ -810,12 +832,16 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
case FB_BLANK_NORMAL:
/* disable the DMA and display 0x0 (black) */
+ shadow_protect_win(win, 1);
writel(WINxMAP_MAP | WINxMAP_MAP_COLOUR(0x0),
sfb->regs + sfb->variant.winmap + (index * 4));
+ shadow_protect_win(win, 0);
break;
case FB_BLANK_UNBLANK:
+ shadow_protect_win(win, 1);
writel(0x0, sfb->regs + sfb->variant.winmap + (index * 4));
+ shadow_protect_win(win, 0);
wincon |= WINCONx_ENWIN;
sfb->enabled |= (1 << index);
break;
@@ -823,10 +849,13 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
default:
+ pm_runtime_put_sync(sfb->dev);
return 1;
}
+ shadow_protect_win(win, 1);
writel(wincon, sfb->regs + sfb->variant.wincon + (index * 4));
+ shadow_protect_win(win, 0);
/* Check the enabled state to see if we need to be running the
* main LCD interface, as if there are no active windows then
@@ -845,8 +874,13 @@ static int s3c_fb_blank(int blank_mode, struct fb_info *info)
/* we're stuck with this until we can do something about overriding
* the power control using the blanking event for a single fb.
*/
- if (index == sfb->pdata->default_win)
+ if (index == sfb->pdata->default_win) {
+ shadow_protect_win(win, 1);
s3c_fb_enable(sfb, blank_mode != FB_BLANK_POWERDOWN ? 1 : 0);
+ shadow_protect_win(win, 0);
+ }
+
+ pm_runtime_put_sync(sfb->dev);
return 0;
}
@@ -870,6 +904,8 @@ static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
void __iomem *buf = sfb->regs + win->index * 8;
unsigned int start_boff, end_boff;
+ pm_runtime_get_sync(sfb->dev);
+
/* Offset in bytes to the start of the displayed area */
start_boff = var->yoffset * info->fix.line_length;
/* X offset depends on the current bpp */
@@ -888,6 +924,7 @@ static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
break;
default:
dev_err(sfb->dev, "invalid bpp\n");
+ pm_runtime_put_sync(sfb->dev);
return -EINVAL;
}
}
@@ -903,6 +940,7 @@ static int s3c_fb_pan_display(struct fb_var_screeninfo *var,
shadow_protect_win(win, 0);
+ pm_runtime_put_sync(sfb->dev);
return 0;
}
@@ -992,11 +1030,16 @@ static int s3c_fb_wait_for_vsync(struct s3c_fb *sfb, u32 crtc)
if (crtc != 0)
return -ENODEV;
+ pm_runtime_get_sync(sfb->dev);
+
count = sfb->vsync_info.count;
s3c_fb_enable_irq(sfb);
ret = wait_event_interruptible_timeout(sfb->vsync_info.wait,
count != sfb->vsync_info.count,
msecs_to_jiffies(VSYNC_TIMEOUT_MSEC));
+
+ pm_runtime_put_sync(sfb->dev);
+
if (ret == 0)
return -ETIMEDOUT;
@@ -1027,30 +1070,8 @@ static int s3c_fb_ioctl(struct fb_info *info, unsigned int cmd,
return ret;
}
-static int s3c_fb_open(struct fb_info *info, int user)
-{
- struct s3c_fb_win *win = info->par;
- struct s3c_fb *sfb = win->parent;
-
- pm_runtime_get_sync(sfb->dev);
-
- return 0;
-}
-
-static int s3c_fb_release(struct fb_info *info, int user)
-{
- struct s3c_fb_win *win = info->par;
- struct s3c_fb *sfb = win->parent;
-
- pm_runtime_put_sync(sfb->dev);
-
- return 0;
-}
-
static struct fb_ops s3c_fb_ops = {
.owner = THIS_MODULE,
- .fb_open = s3c_fb_open,
- .fb_release = s3c_fb_release,
.fb_check_var = s3c_fb_check_var,
.fb_set_par = s3c_fb_set_par,
.fb_blank = s3c_fb_blank,
@@ -1452,7 +1473,7 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
dev_err(dev, "failed to create window %d\n", win);
for (; win >= 0; win--)
s3c_fb_release_win(sfb, sfb->windows[win]);
- goto err_irq;
+ goto err_pm_runtime;
}
}
@@ -1461,7 +1482,8 @@ static int __devinit s3c_fb_probe(struct platform_device *pdev)
return 0;
-err_irq:
+err_pm_runtime:
+ pm_runtime_put_sync(sfb->dev);
free_irq(sfb->irq_no, sfb);
err_ioremap:
@@ -1471,6 +1493,8 @@ err_req_region:
release_mem_region(sfb->regs_res->start, resource_size(sfb->regs_res));
err_lcd_clk:
+ pm_runtime_disable(sfb->dev);
+
if (!sfb->variant.has_clksel) {
clk_disable(sfb->lcd_clk);
clk_put(sfb->lcd_clk);
@@ -1524,7 +1548,7 @@ static int __devexit s3c_fb_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
+#ifdef CONFIG_PM_SLEEP
static int s3c_fb_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -1571,10 +1595,15 @@ static int s3c_fb_resume(struct device *dev)
for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) {
void __iomem *regs = sfb->regs + sfb->variant.keycon;
+ win = sfb->windows[win_no];
+ if (!win)
+ continue;
+ shadow_protect_win(win, 1);
regs += (win_no * 8);
writel(0xffffff, regs + WKEYCON0);
writel(0xffffff, regs + WKEYCON1);
+ shadow_protect_win(win, 0);
}
/* restore framebuffers */
@@ -1589,27 +1618,19 @@ static int s3c_fb_resume(struct device *dev)
return 0;
}
+#endif
+#ifdef CONFIG_PM_RUNTIME
static int s3c_fb_runtime_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct s3c_fb *sfb = platform_get_drvdata(pdev);
- struct s3c_fb_win *win;
- int win_no;
-
- for (win_no = S3C_FB_MAX_WIN - 1; win_no >= 0; win_no--) {
- win = sfb->windows[win_no];
- if (!win)
- continue;
-
- /* use the blank function to push into power-down */
- s3c_fb_blank(FB_BLANK_POWERDOWN, win->fbinfo);
- }
if (!sfb->variant.has_clksel)
clk_disable(sfb->lcd_clk);
clk_disable(sfb->bus_clk);
+
return 0;
}
@@ -1618,8 +1639,6 @@ static int s3c_fb_runtime_resume(struct device *dev)
struct platform_device *pdev = to_platform_device(dev);
struct s3c_fb *sfb = platform_get_drvdata(pdev);
struct s3c_fb_platdata *pd = sfb->pdata;
- struct s3c_fb_win *win;
- int win_no;
clk_enable(sfb->bus_clk);
@@ -1630,39 +1649,10 @@ static int s3c_fb_runtime_resume(struct device *dev)
pd->setup_gpio();
writel(pd->vidcon1, sfb->regs + VIDCON1);
- /* zero all windows before we do anything */
- for (win_no = 0; win_no < sfb->variant.nr_windows; win_no++)
- s3c_fb_clear_win(sfb, win_no);
-
- for (win_no = 0; win_no < sfb->variant.nr_windows - 1; win_no++) {
- void __iomem *regs = sfb->regs + sfb->variant.keycon;
-
- regs += (win_no * 8);
- writel(0xffffff, regs + WKEYCON0);
- writel(0xffffff, regs + WKEYCON1);
- }
-
- /* restore framebuffers */
- for (win_no = 0; win_no < S3C_FB_MAX_WIN; win_no++) {
- win = sfb->windows[win_no];
- if (!win)
- continue;
-
- dev_dbg(&pdev->dev, "resuming window %d\n", win_no);
- s3c_fb_set_par(win->fbinfo);
- }
-
return 0;
}
-
-#else
-#define s3c_fb_suspend NULL
-#define s3c_fb_resume NULL
-#define s3c_fb_runtime_suspend NULL
-#define s3c_fb_runtime_resume NULL
#endif
-
#define VALID_BPP124 (VALID_BPP(1) | VALID_BPP(2) | VALID_BPP(4))
#define VALID_BPP1248 (VALID_BPP124 | VALID_BPP(8))
@@ -1985,10 +1975,9 @@ static struct platform_device_id s3c_fb_driver_ids[] = {
MODULE_DEVICE_TABLE(platform, s3c_fb_driver_ids);
static const struct dev_pm_ops s3cfb_pm_ops = {
- .suspend = s3c_fb_suspend,
- .resume = s3c_fb_resume,
- .runtime_suspend = s3c_fb_runtime_suspend,
- .runtime_resume = s3c_fb_runtime_resume,
+ SET_SYSTEM_SLEEP_PM_OPS(s3c_fb_suspend, s3c_fb_resume)
+ SET_RUNTIME_PM_OPS(s3c_fb_runtime_suspend, s3c_fb_runtime_resume,
+ NULL)
};
static struct platform_driver s3c_fb_driver = {
@@ -2002,18 +1991,7 @@ static struct platform_driver s3c_fb_driver = {
},
};
-static int __init s3c_fb_init(void)
-{
- return platform_driver_register(&s3c_fb_driver);
-}
-
-static void __exit s3c_fb_cleanup(void)
-{
- platform_driver_unregister(&s3c_fb_driver);
-}
-
-module_init(s3c_fb_init);
-module_exit(s3c_fb_cleanup);
+module_platform_driver(s3c_fb_driver);
MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
MODULE_DESCRIPTION("Samsung S3C SoC Framebuffer driver");
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index ee4c0df217f7..77f34c614c86 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -26,8 +26,8 @@
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
+#include <linux/io.h>
-#include <asm/io.h>
#include <asm/div64.h>
#include <asm/mach/map.h>
@@ -45,10 +45,10 @@
#ifdef CONFIG_FB_S3C2410_DEBUG
static int debug = 1;
#else
-static int debug = 0;
+static int debug;
#endif
-#define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); }
+#define dprintk(msg...) if (debug) printk(KERN_DEBUG "s3c2410fb: " msg);
/* useful functions */
@@ -567,11 +567,10 @@ static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL;
- if (blank_mode == FB_BLANK_POWERDOWN) {
+ if (blank_mode == FB_BLANK_POWERDOWN)
s3c2410fb_lcd_enable(fbi, 0);
- } else {
+ else
s3c2410fb_lcd_enable(fbi, 1);
- }
if (blank_mode == FB_BLANK_UNBLANK)
writel(0x0, tpal_reg);
@@ -812,7 +811,7 @@ static inline void s3c2410fb_cpufreq_deregister(struct s3c2410fb_info *info)
#endif
-static char driver_name[] = "s3c2410fb";
+static const char driver_name[] = "s3c2410fb";
static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
enum s3c_drv_type drv_type)
@@ -881,7 +880,10 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
goto release_mem;
}
- info->irq_base = info->io + ((drv_type == DRV_S3C2412) ? S3C2412_LCDINTBASE : S3C2410_LCDINTBASE);
+ if (drv_type == DRV_S3C2412)
+ info->irq_base = info->io + S3C2412_LCDINTBASE;
+ else
+ info->irq_base = info->io + S3C2410_LCDINTBASE;
dprintk("devinit\n");
@@ -927,7 +929,7 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
clk_enable(info->clk);
dprintk("got and enabled clock\n");
- msleep(1);
+ usleep_range(1000, 1000);
info->clk_rate = clk_get_rate(info->clk);
@@ -975,9 +977,8 @@ static int __devinit s3c24xxfb_probe(struct platform_device *pdev,
/* create device files */
ret = device_create_file(&pdev->dev, &dev_attr_debug);
- if (ret) {
+ if (ret)
printk(KERN_ERR "failed to add debug attribute\n");
- }
printk(KERN_INFO "fb%d: %s frame buffer device\n",
fbinfo->node, fbinfo->fix.id);
@@ -1027,7 +1028,7 @@ static int __devexit s3c2410fb_remove(struct platform_device *pdev)
s3c2410fb_cpufreq_deregister(info);
s3c2410fb_lcd_enable(info, 0);
- msleep(1);
+ usleep_range(1000, 1000);
s3c2410fb_unmap_video_memory(fbinfo);
@@ -1064,7 +1065,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
* the LCD DMA engine is not going to get back on the bus
* before the clock goes off again (bjd) */
- msleep(1);
+ usleep_range(1000, 1000);
clk_disable(info->clk);
return 0;
@@ -1076,7 +1077,7 @@ static int s3c2410fb_resume(struct platform_device *dev)
struct s3c2410fb_info *info = fbinfo->par;
clk_enable(info->clk);
- msleep(1);
+ usleep_range(1000, 1000);
s3c2410fb_init_registers(fbinfo);
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index 946a949f4c7d..2c80246b18b8 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -727,7 +727,7 @@ static int s3fb_set_par(struct fb_info *info)
if (par->chip == CHIP_988_VIRGE_VX) {
vga_wcrt(par->state.vgabase, 0x50, 0x00);
vga_wcrt(par->state.vgabase, 0x67, 0x50);
-
+ msleep(10); /* screen remains blank sometimes without this */
vga_wcrt(par->state.vgabase, 0x63, (mode <= 2) ? 0x90 : 0x09);
vga_wcrt(par->state.vgabase, 0x66, 0x90);
}
@@ -901,7 +901,8 @@ static int s3fb_set_par(struct fb_info *info)
/* Set Data Transfer Position */
hsstart = ((info->var.xres + info->var.right_margin) * hmul) / 8;
- value = clamp((htotal + hsstart + 1) / 2, hsstart + 4, htotal + 1);
+ /* + 2 is needed for Virge/VX, does no harm on other cards */
+ value = clamp((htotal + hsstart + 1) / 2 + 2, hsstart + 4, htotal + 1);
svga_wcrt_multi(par->state.vgabase, s3_dtpc_regs, value);
memset_io(info->screen_base, 0x00, screen_size);
@@ -1216,6 +1217,31 @@ static int __devinit s3_pci_probe(struct pci_dev *dev, const struct pci_device_i
info->screen_size = 2 << 20;
break;
}
+ } else if (par->chip == CHIP_988_VIRGE_VX) {
+ switch ((regval & 0x60) >> 5) {
+ case 0: /* 2MB */
+ info->screen_size = 2 << 20;
+ break;
+ case 1: /* 4MB */
+ info->screen_size = 4 << 20;
+ break;
+ case 2: /* 6MB */
+ info->screen_size = 6 << 20;
+ break;
+ case 3: /* 8MB */
+ info->screen_size = 8 << 20;
+ break;
+ }
+ /* off-screen memory */
+ regval = vga_rcrt(par->state.vgabase, 0x37);
+ switch ((regval & 0x60) >> 5) {
+ case 1: /* 4MB */
+ info->screen_size -= 4 << 20;
+ break;
+ case 2: /* 2MB */
+ info->screen_size -= 2 << 20;
+ break;
+ }
} else
info->screen_size = s3_memsizes[regval >> 5] << 10;
info->fix.smem_len = info->screen_size;
diff --git a/drivers/video/sbuslib.c b/drivers/video/sbuslib.c
index 37d764ad56b0..3c1de981a18c 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/sbuslib.c
@@ -76,7 +76,7 @@ int sbusfb_mmap_helper(struct sbus_mmap_map *map,
map_offset = (physbase + map[i].poff) & POFF_MASK;
break;
}
- if (!map_size){
+ if (!map_size) {
page += PAGE_SIZE;
continue;
}
diff --git a/drivers/video/sh7760fb.c b/drivers/video/sh7760fb.c
index 45e47d847163..83b16e237a0e 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/sh7760fb.c
@@ -585,18 +585,7 @@ static struct platform_driver sh7760_lcdc_driver = {
.remove = __devexit_p(sh7760fb_remove),
};
-static int __init sh7760fb_init(void)
-{
- return platform_driver_register(&sh7760_lcdc_driver);
-}
-
-static void __exit sh7760fb_exit(void)
-{
- platform_driver_unregister(&sh7760_lcdc_driver);
-}
-
-module_init(sh7760fb_init);
-module_exit(sh7760fb_exit);
+module_platform_driver(sh7760_lcdc_driver);
MODULE_AUTHOR("Nobuhiro Iwamatsu, Manuel Lauss");
MODULE_DESCRIPTION("FBdev for SH7760/63 integrated LCD Controller");
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/sh_mipi_dsi.c
index 72ee96bc6b3e..05151b82f40f 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/sh_mipi_dsi.c
@@ -8,6 +8,7 @@
* published by the Free Software Foundation.
*/
+#include <linux/bitmap.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/init.h>
@@ -41,6 +42,7 @@
#define VMCTR1 0x0020
#define VMCTR2 0x0024
#define VMLEN1 0x0028
+#define VMLEN2 0x002c
#define CMTSRTREQ 0x0070
#define CMTSRTCTR 0x00d0
@@ -51,8 +53,7 @@ struct sh_mipi {
void __iomem *base;
void __iomem *linkbase;
struct clk *dsit_clk;
- struct clk *dsip_clk;
- struct device *dev;
+ struct platform_device *pdev;
void *next_board_data;
void (*next_display_on)(void *board_data, struct fb_info *info);
@@ -124,35 +125,15 @@ static void sh_mipi_shutdown(struct platform_device *pdev)
sh_mipi_dsi_enable(mipi, false);
}
-static void mipi_display_on(void *arg, struct fb_info *info)
-{
- struct sh_mipi *mipi = arg;
-
- pm_runtime_get_sync(mipi->dev);
- sh_mipi_dsi_enable(mipi, true);
-
- if (mipi->next_display_on)
- mipi->next_display_on(mipi->next_board_data, info);
-}
-
-static void mipi_display_off(void *arg)
-{
- struct sh_mipi *mipi = arg;
-
- if (mipi->next_display_off)
- mipi->next_display_off(mipi->next_board_data);
-
- sh_mipi_dsi_enable(mipi, false);
- pm_runtime_put(mipi->dev);
-}
-
static int __init sh_mipi_setup(struct sh_mipi *mipi,
struct sh_mipi_dsi_info *pdata)
{
void __iomem *base = mipi->base;
struct sh_mobile_lcdc_chan_cfg *ch = pdata->lcd_chan;
- u32 pctype, datatype, pixfmt, linelength, vmctr2 = 0x00e00000;
+ u32 pctype, datatype, pixfmt, linelength, vmctr2;
+ u32 tmp, top, bottom, delay, div;
bool yuv;
+ int bpp;
/*
* Select data format. MIPI DSI is not hot-pluggable, so, we just use
@@ -253,6 +234,9 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
(!yuv && ch->interface_type != RGB24))
return -EINVAL;
+ if (!pdata->lane)
+ return -EINVAL;
+
/* reset DSI link */
iowrite32(0x00000001, base + SYSCTRL);
/* Hold reset for 100 cycles of the slowest of bus, HS byte and LP clock */
@@ -262,15 +246,6 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
/* setup DSI link */
/*
- * Default = ULPS enable |
- * Contention detection enabled |
- * EoT packet transmission enable |
- * CRC check enable |
- * ECC check enable
- * additionally enable first two lanes
- */
- iowrite32(0x00003703, base + SYSCONF);
- /*
* T_wakeup = 0x7000
* T_hs-trail = 3
* T_hs-prepare = 3
@@ -290,15 +265,24 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
iowrite32(0x0fffffff, base + TATOVSET);
/* Peripheral reset timeout, default 0xffffffff */
iowrite32(0x0fffffff, base + PRTOVSET);
- /* Enable timeout counters */
- iowrite32(0x00000f00, base + DSICTRL);
/* Interrupts not used, disable all */
iowrite32(0, base + DSIINTE);
/* DSI-Tx bias on */
iowrite32(0x00000001, base + PHYCTRL);
udelay(200);
- /* Deassert resets, power on, set multiplier */
- iowrite32(0x03070b01, base + PHYCTRL);
+ /* Deassert resets, power on */
+ iowrite32(0x03070001, base + PHYCTRL);
+
+ /*
+ * Default = ULPS enable |
+ * Contention detection enabled |
+ * EoT packet transmission enable |
+ * CRC check enable |
+ * ECC check enable
+ */
+ bitmap_fill((unsigned long *)&tmp, pdata->lane);
+ tmp |= 0x00003700;
+ iowrite32(tmp, base + SYSCONF);
/* setup l-bridge */
@@ -316,18 +300,68 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
* Non-burst mode with sync pulses: VSE and HSE are output,
* HSA period allowed, no commands in LP
*/
+ vmctr2 = 0;
+ if (pdata->flags & SH_MIPI_DSI_VSEE)
+ vmctr2 |= 1 << 23;
+ if (pdata->flags & SH_MIPI_DSI_HSEE)
+ vmctr2 |= 1 << 22;
+ if (pdata->flags & SH_MIPI_DSI_HSAE)
+ vmctr2 |= 1 << 21;
+ if (pdata->flags & SH_MIPI_DSI_BL2E)
+ vmctr2 |= 1 << 17;
if (pdata->flags & SH_MIPI_DSI_HSABM)
- vmctr2 |= 0x20;
- if (pdata->flags & SH_MIPI_DSI_HSPBM)
- vmctr2 |= 0x10;
+ vmctr2 |= 1 << 5;
+ if (pdata->flags & SH_MIPI_DSI_HBPBM)
+ vmctr2 |= 1 << 4;
+ if (pdata->flags & SH_MIPI_DSI_HFPBM)
+ vmctr2 |= 1 << 3;
iowrite32(vmctr2, mipi->linkbase + VMCTR2);
/*
- * 0x660 = 1632 bytes per line (RGB24, 544 pixels: see
- * sh_mobile_lcdc_info.ch[0].lcd_cfg[0].xres), HSALEN = 1 - default
- * (unused if VMCTR2[HSABM] = 0)
+ * VMLEN1 = RGBLEN | HSALEN
+ *
+ * see
+ * Video mode - Blanking Packet setting
+ */
+ top = linelength << 16; /* RGBLEN */
+ bottom = 0x00000001;
+ if (pdata->flags & SH_MIPI_DSI_HSABM) /* HSALEN */
+ bottom = (pdata->lane * ch->lcd_cfg[0].hsync_len) - 10;
+ iowrite32(top | bottom , mipi->linkbase + VMLEN1);
+
+ /*
+ * VMLEN2 = HBPLEN | HFPLEN
+ *
+ * see
+ * Video mode - Blanking Packet setting
*/
- iowrite32(1 | (linelength << 16), mipi->linkbase + VMLEN1);
+ top = 0x00010000;
+ bottom = 0x00000001;
+ delay = 0;
+
+ div = 1; /* HSbyteCLK is calculation base
+ * HS4divCLK = HSbyteCLK/2
+ * HS6divCLK is not supported for now */
+ if (pdata->flags & SH_MIPI_DSI_HS4divCLK)
+ div = 2;
+
+ if (pdata->flags & SH_MIPI_DSI_HFPBM) { /* HBPLEN */
+ top = ch->lcd_cfg[0].hsync_len + ch->lcd_cfg[0].left_margin;
+ top = ((pdata->lane * top / div) - 10) << 16;
+ }
+ if (pdata->flags & SH_MIPI_DSI_HBPBM) { /* HFPLEN */
+ bottom = ch->lcd_cfg[0].right_margin;
+ bottom = (pdata->lane * bottom / div) - 12;
+ }
+
+ bpp = linelength / ch->lcd_cfg[0].xres; /* byte / pixel */
+ if ((pdata->lane / div) > bpp) {
+ tmp = ch->lcd_cfg[0].xres / bpp; /* output cycle */
+ tmp = ch->lcd_cfg[0].xres - tmp; /* (input - output) cycle */
+ delay = (pdata->lane * tmp);
+ }
+
+ iowrite32(top | (bottom + delay) , mipi->linkbase + VMLEN2);
msleep(5);
@@ -352,9 +386,56 @@ static int __init sh_mipi_setup(struct sh_mipi *mipi,
pixfmt << 4);
sh_mipi_dcs(ch->chan, MIPI_DCS_SET_DISPLAY_ON);
+ /* Enable timeout counters */
+ iowrite32(0x00000f00, base + DSICTRL);
+
return 0;
}
+static void mipi_display_on(void *arg, struct fb_info *info)
+{
+ struct sh_mipi *mipi = arg;
+ struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
+ int ret;
+
+ pm_runtime_get_sync(&mipi->pdev->dev);
+
+ ret = pdata->set_dot_clock(mipi->pdev, mipi->base, 1);
+ if (ret < 0)
+ goto mipi_display_on_fail1;
+
+ ret = sh_mipi_setup(mipi, pdata);
+ if (ret < 0)
+ goto mipi_display_on_fail2;
+
+ sh_mipi_dsi_enable(mipi, true);
+
+ if (mipi->next_display_on)
+ mipi->next_display_on(mipi->next_board_data, info);
+
+ return;
+
+mipi_display_on_fail1:
+ pm_runtime_put_sync(&mipi->pdev->dev);
+mipi_display_on_fail2:
+ pdata->set_dot_clock(mipi->pdev, mipi->base, 0);
+}
+
+static void mipi_display_off(void *arg)
+{
+ struct sh_mipi *mipi = arg;
+ struct sh_mipi_dsi_info *pdata = mipi->pdev->dev.platform_data;
+
+ if (mipi->next_display_off)
+ mipi->next_display_off(mipi->next_board_data);
+
+ sh_mipi_dsi_enable(mipi, false);
+
+ pdata->set_dot_clock(mipi->pdev, mipi->base, 0);
+
+ pm_runtime_put_sync(&mipi->pdev->dev);
+}
+
static int __init sh_mipi_probe(struct platform_device *pdev)
{
struct sh_mipi *mipi;
@@ -363,11 +444,13 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
struct resource *res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
unsigned long rate, f_current;
int idx = pdev->id, ret;
- char dsip_clk[] = "dsi.p_clk";
if (!res || !res2 || idx >= ARRAY_SIZE(mipi_dsi) || !pdata)
return -ENODEV;
+ if (!pdata->set_dot_clock)
+ return -EINVAL;
+
mutex_lock(&array_lock);
if (idx < 0)
for (idx = 0; idx < ARRAY_SIZE(mipi_dsi) && mipi_dsi[idx]; idx++)
@@ -408,7 +491,7 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
goto emap2;
}
- mipi->dev = &pdev->dev;
+ mipi->pdev = pdev;
mipi->dsit_clk = clk_get(&pdev->dev, "dsit_clk");
if (IS_ERR(mipi->dsit_clk)) {
@@ -428,44 +511,15 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
dev_dbg(&pdev->dev, "DSI-T clk %lu -> %lu\n", f_current, rate);
- sprintf(dsip_clk, "dsi%1.1dp_clk", idx);
- mipi->dsip_clk = clk_get(&pdev->dev, dsip_clk);
- if (IS_ERR(mipi->dsip_clk)) {
- ret = PTR_ERR(mipi->dsip_clk);
- goto eclkpget;
- }
-
- f_current = clk_get_rate(mipi->dsip_clk);
- /* Between 10 and 50MHz */
- rate = clk_round_rate(mipi->dsip_clk, 24000000);
- if (rate > 0 && rate != f_current)
- ret = clk_set_rate(mipi->dsip_clk, rate);
- else
- ret = rate;
- if (ret < 0)
- goto esetprate;
-
- dev_dbg(&pdev->dev, "DSI-P clk %lu -> %lu\n", f_current, rate);
-
- msleep(10);
-
ret = clk_enable(mipi->dsit_clk);
if (ret < 0)
goto eclkton;
- ret = clk_enable(mipi->dsip_clk);
- if (ret < 0)
- goto eclkpon;
-
mipi_dsi[idx] = mipi;
pm_runtime_enable(&pdev->dev);
pm_runtime_resume(&pdev->dev);
- ret = sh_mipi_setup(mipi, pdata);
- if (ret < 0)
- goto emipisetup;
-
mutex_unlock(&array_lock);
platform_set_drvdata(pdev, mipi);
@@ -482,16 +536,7 @@ static int __init sh_mipi_probe(struct platform_device *pdev)
return 0;
-emipisetup:
- mipi_dsi[idx] = NULL;
- pm_runtime_disable(&pdev->dev);
- clk_disable(mipi->dsip_clk);
-eclkpon:
- clk_disable(mipi->dsit_clk);
eclkton:
-esetprate:
- clk_put(mipi->dsip_clk);
-eclkpget:
esettrate:
clk_put(mipi->dsit_clk);
eclktget:
@@ -542,10 +587,9 @@ static int __exit sh_mipi_remove(struct platform_device *pdev)
pdata->lcd_chan->board_cfg.board_data = NULL;
pm_runtime_disable(&pdev->dev);
- clk_disable(mipi->dsip_clk);
clk_disable(mipi->dsit_clk);
clk_put(mipi->dsit_clk);
- clk_put(mipi->dsip_clk);
+
iounmap(mipi->linkbase);
if (res2)
release_mem_region(res2->start, resource_size(res2));
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c
index facffc254976..aac5b369d73c 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/sh_mobile_lcdcfb.c
@@ -17,6 +17,7 @@
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
+#include <linux/videodev2.h>
#include <linux/vmalloc.h>
#include <linux/ioctl.h>
#include <linux/slab.h>
@@ -102,7 +103,7 @@ struct sh_mobile_lcdc_priv {
struct sh_mobile_lcdc_chan ch[2];
struct notifier_block notifier;
int started;
- int forced_bpp; /* 2 channel LCDC must share bpp setting */
+ int forced_fourcc; /* 2 channel LCDC must share fourcc setting */
struct sh_mobile_meram_info *meram_dev;
};
@@ -215,6 +216,47 @@ struct sh_mobile_lcdc_sys_bus_ops sh_mobile_lcdc_sys_bus_ops = {
lcdc_sys_read_data,
};
+static int sh_mobile_format_fourcc(const struct fb_var_screeninfo *var)
+{
+ if (var->grayscale > 1)
+ return var->grayscale;
+
+ switch (var->bits_per_pixel) {
+ case 16:
+ return V4L2_PIX_FMT_RGB565;
+ case 24:
+ return V4L2_PIX_FMT_BGR24;
+ case 32:
+ return V4L2_PIX_FMT_BGR32;
+ default:
+ return 0;
+ }
+}
+
+static int sh_mobile_format_is_fourcc(const struct fb_var_screeninfo *var)
+{
+ return var->grayscale > 1;
+}
+
+static bool sh_mobile_format_is_yuv(const struct fb_var_screeninfo *var)
+{
+ if (var->grayscale <= 1)
+ return false;
+
+ switch (var->grayscale) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ case V4L2_PIX_FMT_NV24:
+ case V4L2_PIX_FMT_NV42:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
static void sh_mobile_lcdc_clk_on(struct sh_mobile_lcdc_priv *priv)
{
if (atomic_inc_and_test(&priv->hw_usecnt)) {
@@ -420,7 +462,7 @@ static void sh_mobile_lcdc_geometry(struct sh_mobile_lcdc_chan *ch)
tmp = ((display_var->xres & 7) << 24) |
((display_h_total & 7) << 16) |
((display_var->hsync_len & 7) << 8) |
- hsync_pos;
+ (hsync_pos & 7);
lcdc_write_chan(ch, LDHAJR, tmp);
}
@@ -435,7 +477,6 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
{
struct sh_mobile_lcdc_chan *ch;
unsigned long tmp;
- int bpp = 0;
int k, m;
/* Enable LCDC channels. Read data from external memory, avoid using the
@@ -454,9 +495,6 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
if (!ch->enabled)
continue;
- if (!bpp)
- bpp = ch->info->var.bits_per_pixel;
-
/* Power supply */
lcdc_write_chan(ch, LDPMR, 0);
@@ -487,31 +525,37 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
sh_mobile_lcdc_geometry(ch);
- if (ch->info->var.nonstd) {
- tmp = (ch->info->var.nonstd << 16);
- switch (ch->info->var.bits_per_pixel) {
- case 12:
- tmp |= LDDFR_YF_420;
- break;
- case 16:
- tmp |= LDDFR_YF_422;
- break;
- case 24:
- default:
- tmp |= LDDFR_YF_444;
- break;
- }
- } else {
- switch (ch->info->var.bits_per_pixel) {
- case 16:
- tmp = LDDFR_PKF_RGB16;
- break;
- case 24:
- tmp = LDDFR_PKF_RGB24;
+ switch (sh_mobile_format_fourcc(&ch->info->var)) {
+ case V4L2_PIX_FMT_RGB565:
+ tmp = LDDFR_PKF_RGB16;
+ break;
+ case V4L2_PIX_FMT_BGR24:
+ tmp = LDDFR_PKF_RGB24;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ tmp = LDDFR_PKF_ARGB32;
+ break;
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ tmp = LDDFR_CC | LDDFR_YF_420;
+ break;
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ tmp = LDDFR_CC | LDDFR_YF_422;
+ break;
+ case V4L2_PIX_FMT_NV24:
+ case V4L2_PIX_FMT_NV42:
+ tmp = LDDFR_CC | LDDFR_YF_444;
+ break;
+ }
+
+ if (sh_mobile_format_is_yuv(&ch->info->var)) {
+ switch (ch->info->var.colorspace) {
+ case V4L2_COLORSPACE_REC709:
+ tmp |= LDDFR_CF1;
break;
- case 32:
- default:
- tmp = LDDFR_PKF_ARGB32;
+ case V4L2_COLORSPACE_JPEG:
+ tmp |= LDDFR_CF0;
break;
}
}
@@ -519,7 +563,7 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
lcdc_write_chan(ch, LDDFR, tmp);
lcdc_write_chan(ch, LDMLSR, ch->pitch);
lcdc_write_chan(ch, LDSA1R, ch->base_addr_y);
- if (ch->info->var.nonstd)
+ if (sh_mobile_format_is_yuv(&ch->info->var))
lcdc_write_chan(ch, LDSA2R, ch->base_addr_c);
/* When using deferred I/O mode, configure the LCDC for one-shot
@@ -536,21 +580,23 @@ static void __sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
}
/* Word and long word swap. */
- if (priv->ch[0].info->var.nonstd)
+ switch (sh_mobile_format_fourcc(&priv->ch[0].info->var)) {
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV61:
+ case V4L2_PIX_FMT_NV42:
+ tmp = LDDDSR_LS | LDDDSR_WS;
+ break;
+ case V4L2_PIX_FMT_BGR24:
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV24:
tmp = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS;
- else {
- switch (bpp) {
- case 16:
- tmp = LDDDSR_LS | LDDDSR_WS;
- break;
- case 24:
- tmp = LDDDSR_LS | LDDDSR_WS | LDDDSR_BS;
- break;
- case 32:
- default:
- tmp = LDDDSR_LS;
- break;
- }
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ default:
+ tmp = LDDDSR_LS;
+ break;
}
lcdc_write(priv, _LDDDSR, tmp);
@@ -622,12 +668,24 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
ch->meram_enabled = 0;
}
- if (!ch->info->var.nonstd)
- pixelformat = SH_MOBILE_MERAM_PF_RGB;
- else if (ch->info->var.bits_per_pixel == 24)
- pixelformat = SH_MOBILE_MERAM_PF_NV24;
- else
+ switch (sh_mobile_format_fourcc(&ch->info->var)) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
pixelformat = SH_MOBILE_MERAM_PF_NV;
+ break;
+ case V4L2_PIX_FMT_NV24:
+ case V4L2_PIX_FMT_NV42:
+ pixelformat = SH_MOBILE_MERAM_PF_NV24;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_BGR24:
+ case V4L2_PIX_FMT_BGR32:
+ default:
+ pixelformat = SH_MOBILE_MERAM_PF_RGB;
+ break;
+ }
ret = mdev->ops->meram_register(mdev, cfg, ch->pitch,
ch->info->var.yres, pixelformat,
@@ -845,6 +903,7 @@ static struct fb_fix_screeninfo sh_mobile_lcdc_fix = {
.xpanstep = 0,
.ypanstep = 1,
.ywrapstep = 0,
+ .capabilities = FB_CAP_FOURCC,
};
static void sh_mobile_lcdc_fillrect(struct fb_info *info,
@@ -877,8 +936,9 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
unsigned long new_pan_offset;
unsigned long base_addr_y, base_addr_c;
unsigned long c_offset;
+ bool yuv = sh_mobile_format_is_yuv(&info->var);
- if (!info->var.nonstd)
+ if (!yuv)
new_pan_offset = var->yoffset * info->fix.line_length
+ var->xoffset * (info->var.bits_per_pixel / 8);
else
@@ -892,7 +952,7 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
/* Set the source address for the next refresh */
base_addr_y = ch->dma_handle + new_pan_offset;
- if (info->var.nonstd) {
+ if (yuv) {
/* Set y offset */
c_offset = var->yoffset * info->fix.line_length
* (info->var.bits_per_pixel - 8) / 8;
@@ -900,7 +960,7 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
+ info->var.xres * info->var.yres_virtual
+ c_offset;
/* Set x offset */
- if (info->var.bits_per_pixel == 24)
+ if (sh_mobile_format_fourcc(&info->var) == V4L2_PIX_FMT_NV24)
base_addr_c += 2 * var->xoffset;
else
base_addr_c += var->xoffset;
@@ -924,7 +984,7 @@ static int sh_mobile_fb_pan_display(struct fb_var_screeninfo *var,
ch->base_addr_c = base_addr_c;
lcdc_write_chan_mirror(ch, LDSA1R, base_addr_y);
- if (info->var.nonstd)
+ if (yuv)
lcdc_write_chan_mirror(ch, LDSA2R, base_addr_c);
if (lcdc_chan_is_sublcd(ch))
@@ -1100,51 +1160,84 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in
if (var->yres_virtual < var->yres)
var->yres_virtual = var->yres;
- if (var->bits_per_pixel <= 16) { /* RGB 565 */
- var->bits_per_pixel = 16;
- var->red.offset = 11;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 6;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 0;
- var->transp.length = 0;
- } else if (var->bits_per_pixel <= 24) { /* RGB 888 */
- var->bits_per_pixel = 24;
- var->red.offset = 16;
- var->red.length = 8;
- var->green.offset = 8;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- var->transp.offset = 0;
- var->transp.length = 0;
- } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */
- var->bits_per_pixel = 32;
- var->red.offset = 16;
- var->red.length = 8;
- var->green.offset = 8;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- var->transp.offset = 24;
- var->transp.length = 8;
- } else
- return -EINVAL;
+ if (sh_mobile_format_is_fourcc(var)) {
+ switch (var->grayscale) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV21:
+ var->bits_per_pixel = 12;
+ break;
+ case V4L2_PIX_FMT_RGB565:
+ case V4L2_PIX_FMT_NV16:
+ case V4L2_PIX_FMT_NV61:
+ var->bits_per_pixel = 16;
+ break;
+ case V4L2_PIX_FMT_BGR24:
+ case V4L2_PIX_FMT_NV24:
+ case V4L2_PIX_FMT_NV42:
+ var->bits_per_pixel = 24;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ var->bits_per_pixel = 32;
+ break;
+ default:
+ return -EINVAL;
+ }
- var->red.msb_right = 0;
- var->green.msb_right = 0;
- var->blue.msb_right = 0;
- var->transp.msb_right = 0;
+ /* Default to RGB and JPEG color-spaces for RGB and YUV formats
+ * respectively.
+ */
+ if (!sh_mobile_format_is_yuv(var))
+ var->colorspace = V4L2_COLORSPACE_SRGB;
+ else if (var->colorspace != V4L2_COLORSPACE_REC709)
+ var->colorspace = V4L2_COLORSPACE_JPEG;
+ } else {
+ if (var->bits_per_pixel <= 16) { /* RGB 565 */
+ var->bits_per_pixel = 16;
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ } else if (var->bits_per_pixel <= 24) { /* RGB 888 */
+ var->bits_per_pixel = 24;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ } else if (var->bits_per_pixel <= 32) { /* RGBA 888 */
+ var->bits_per_pixel = 32;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ } else
+ return -EINVAL;
+
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+ var->transp.msb_right = 0;
+ }
/* Make sure we don't exceed our allocated memory. */
if (var->xres_virtual * var->yres_virtual * var->bits_per_pixel / 8 >
info->fix.smem_len)
return -EINVAL;
- /* only accept the forced_bpp for dual channel configurations */
- if (p->forced_bpp && p->forced_bpp != var->bits_per_pixel)
+ /* only accept the forced_fourcc for dual channel configurations */
+ if (p->forced_fourcc &&
+ p->forced_fourcc != sh_mobile_format_fourcc(var))
return -EINVAL;
return 0;
@@ -1158,7 +1251,7 @@ static int sh_mobile_set_par(struct fb_info *info)
sh_mobile_lcdc_stop(ch->lcdc);
- if (info->var.nonstd)
+ if (sh_mobile_format_is_yuv(&info->var))
info->fix.line_length = info->var.xres;
else
info->fix.line_length = info->var.xres
@@ -1170,6 +1263,14 @@ static int sh_mobile_set_par(struct fb_info *info)
info->fix.line_length = line_length;
}
+ if (sh_mobile_format_is_fourcc(&info->var)) {
+ info->fix.type = FB_TYPE_FOURCC;
+ info->fix.visual = FB_VISUAL_FOURCC;
+ } else {
+ info->fix.type = FB_TYPE_PACKED_PIXELS;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ }
+
return ret;
}
@@ -1464,9 +1565,9 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
for (i = 0, mode = cfg->lcd_cfg; i < cfg->num_cfg; i++, mode++) {
unsigned int size = mode->yres * mode->xres;
- /* NV12 buffers must have even number of lines */
- if ((cfg->nonstd) && cfg->bpp == 12 &&
- (mode->yres & 0x1)) {
+ /* NV12/NV21 buffers must have even number of lines */
+ if ((cfg->fourcc == V4L2_PIX_FMT_NV12 ||
+ cfg->fourcc == V4L2_PIX_FMT_NV21) && (mode->yres & 0x1)) {
dev_err(dev, "yres must be multiple of 2 for YCbCr420 "
"mode.\n");
return -EINVAL;
@@ -1484,14 +1585,6 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
dev_dbg(dev, "Found largest videomode %ux%u\n",
max_mode->xres, max_mode->yres);
- /* Initialize fixed screen information. Restrict pan to 2 lines steps
- * for NV12.
- */
- info->fix = sh_mobile_lcdc_fix;
- info->fix.smem_len = max_size * 2 * cfg->bpp / 8;
- if (cfg->nonstd && cfg->bpp == 12)
- info->fix.ypanstep = 2;
-
/* Create the mode list. */
if (cfg->lcd_cfg == NULL) {
mode = &default_720p;
@@ -1509,19 +1602,38 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
*/
var = &info->var;
fb_videomode_to_var(var, mode);
- var->bits_per_pixel = cfg->bpp;
var->width = cfg->lcd_size_cfg.width;
var->height = cfg->lcd_size_cfg.height;
var->yres_virtual = var->yres * 2;
var->activate = FB_ACTIVATE_NOW;
+ switch (cfg->fourcc) {
+ case V4L2_PIX_FMT_RGB565:
+ var->bits_per_pixel = 16;
+ break;
+ case V4L2_PIX_FMT_BGR24:
+ var->bits_per_pixel = 24;
+ break;
+ case V4L2_PIX_FMT_BGR32:
+ var->bits_per_pixel = 32;
+ break;
+ default:
+ var->grayscale = cfg->fourcc;
+ break;
+ }
+
+ /* Make sure the memory size check won't fail. smem_len is initialized
+ * later based on var.
+ */
+ info->fix.smem_len = UINT_MAX;
ret = sh_mobile_check_var(var, info);
if (ret)
return ret;
+ max_size = max_size * var->bits_per_pixel / 8 * 2;
+
/* Allocate frame buffer memory and color map. */
- buf = dma_alloc_coherent(dev, info->fix.smem_len, &ch->dma_handle,
- GFP_KERNEL);
+ buf = dma_alloc_coherent(dev, max_size, &ch->dma_handle, GFP_KERNEL);
if (!buf) {
dev_err(dev, "unable to allocate buffer\n");
return -ENOMEM;
@@ -1530,16 +1642,27 @@ static int __devinit sh_mobile_lcdc_channel_init(struct sh_mobile_lcdc_chan *ch,
ret = fb_alloc_cmap(&info->cmap, PALETTE_NR, 0);
if (ret < 0) {
dev_err(dev, "unable to allocate cmap\n");
- dma_free_coherent(dev, info->fix.smem_len,
- buf, ch->dma_handle);
+ dma_free_coherent(dev, max_size, buf, ch->dma_handle);
return ret;
}
+ /* Initialize fixed screen information. Restrict pan to 2 lines steps
+ * for NV12 and NV21.
+ */
+ info->fix = sh_mobile_lcdc_fix;
info->fix.smem_start = ch->dma_handle;
- if (var->nonstd)
+ info->fix.smem_len = max_size;
+ if (cfg->fourcc == V4L2_PIX_FMT_NV12 ||
+ cfg->fourcc == V4L2_PIX_FMT_NV21)
+ info->fix.ypanstep = 2;
+
+ if (sh_mobile_format_is_yuv(var)) {
info->fix.line_length = var->xres;
- else
- info->fix.line_length = var->xres * (cfg->bpp / 8);
+ info->fix.visual = FB_VISUAL_FOURCC;
+ } else {
+ info->fix.line_length = var->xres * var->bits_per_pixel / 8;
+ info->fix.visual = FB_VISUAL_TRUECOLOR;
+ }
info->screen_base = buf;
info->device = dev;
@@ -1626,9 +1749,9 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
goto err1;
}
- /* for dual channel LCDC (MAIN + SUB) force shared bpp setting */
+ /* for dual channel LCDC (MAIN + SUB) force shared format setting */
if (num_channels == 2)
- priv->forced_bpp = pdata->ch[0].bpp;
+ priv->forced_fourcc = pdata->ch[0].fourcc;
priv->base = ioremap_nocache(res->start, resource_size(res));
if (!priv->base)
@@ -1675,13 +1798,10 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev)
if (error < 0)
goto err1;
- dev_info(info->dev,
- "registered %s/%s as %dx%d %dbpp.\n",
- pdev->name,
- (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
- "mainlcd" : "sublcd",
- info->var.xres, info->var.yres,
- ch->cfg.bpp);
+ dev_info(info->dev, "registered %s/%s as %dx%d %dbpp.\n",
+ pdev->name, (ch->cfg.chan == LCDC_CHAN_MAINLCD) ?
+ "mainlcd" : "sublcd", info->var.xres, info->var.yres,
+ info->var.bits_per_pixel);
/* deferred io mode: disable clock to save power */
if (info->fbdefio || info->state == FBINFO_STATE_SUSPENDED)
@@ -1709,18 +1829,7 @@ static struct platform_driver sh_mobile_lcdc_driver = {
.remove = sh_mobile_lcdc_remove,
};
-static int __init sh_mobile_lcdc_init(void)
-{
- return platform_driver_register(&sh_mobile_lcdc_driver);
-}
-
-static void __exit sh_mobile_lcdc_exit(void)
-{
- platform_driver_unregister(&sh_mobile_lcdc_driver);
-}
-
-module_init(sh_mobile_lcdc_init);
-module_exit(sh_mobile_lcdc_exit);
+module_platform_driver(sh_mobile_lcdc_driver);
MODULE_DESCRIPTION("SuperH Mobile LCDC Framebuffer driver");
MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/sh_mobile_meram.c
index 4d63490209cd..f45d83ecfd21 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/sh_mobile_meram.c
@@ -679,18 +679,7 @@ static struct platform_driver sh_mobile_meram_driver = {
.remove = sh_mobile_meram_remove,
};
-static int __init sh_mobile_meram_init(void)
-{
- return platform_driver_register(&sh_mobile_meram_driver);
-}
-
-static void __exit sh_mobile_meram_exit(void)
-{
- platform_driver_unregister(&sh_mobile_meram_driver);
-}
-
-module_init(sh_mobile_meram_init);
-module_exit(sh_mobile_meram_exit);
+module_platform_driver(sh_mobile_meram_driver);
MODULE_DESCRIPTION("SuperH Mobile MERAM driver");
MODULE_AUTHOR("Damian Hobson-Garcia / Takanari Hayama");
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index a78254cf8e83..3690effbedcc 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -2230,18 +2230,7 @@ static struct platform_driver sm501fb_driver = {
},
};
-static int __devinit sm501fb_init(void)
-{
- return platform_driver_register(&sm501fb_driver);
-}
-
-static void __exit sm501fb_cleanup(void)
-{
- platform_driver_unregister(&sm501fb_driver);
-}
-
-module_init(sm501fb_init);
-module_exit(sm501fb_cleanup);
+module_platform_driver(sm501fb_driver);
module_param_named(mode, fb_mode, charp, 0);
MODULE_PARM_DESC(mode,
diff --git a/drivers/video/smscufx.c b/drivers/video/smscufx.c
index 3c22994ea31a..ccbfef5e828f 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/smscufx.c
@@ -130,8 +130,8 @@ static struct usb_device_id id_table[] = {
MODULE_DEVICE_TABLE(usb, id_table);
/* module options */
-static int console; /* Optionally allow fbcon to consume first framebuffer */
-static int fb_defio = true; /* Optionally enable fb_defio mmap support */
+static bool console; /* Optionally allow fbcon to consume first framebuffer */
+static bool fb_defio = true; /* Optionally enable fb_defio mmap support */
/* ufx keeps a list of urbs for efficient bulk transfers */
static void ufx_urb_completion(struct urb *urb);
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 2301c275d63a..111fb32e8769 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -93,11 +93,11 @@
/* initialized by setup */
-static int vgapass; /* enable VGA passthrough cable */
+static bool vgapass; /* enable VGA passthrough cable */
static int mem; /* mem size in MB, 0 = autodetect */
-static int clipping = 1; /* use clipping (slower, safer) */
+static bool clipping = 1; /* use clipping (slower, safer) */
static int gfxclk; /* force FBI freq in Mhz . Dangerous */
-static int slowpci; /* slow PCI settings */
+static bool slowpci; /* slow PCI settings */
/*
Possible default video modes: 800x600@60, 640x480@75, 1024x768@76, 640x480@60
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index a99b994c9b6b..e026724a3a56 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -169,7 +169,7 @@ static int nowrap = 1; /* not implemented (yet) */
static int hwcursor = 1;
static char *mode_option __devinitdata;
/* mtrr option */
-static int nomtrr __devinitdata;
+static bool nomtrr __devinitdata;
/* -------------------------------------------------------------------------
* Hardware-specific funcions
diff --git a/drivers/video/udlfb.c b/drivers/video/udlfb.c
index 1f868d0187a2..a19773149bd7 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/udlfb.c
@@ -69,9 +69,9 @@ static struct usb_device_id id_table[] = {
MODULE_DEVICE_TABLE(usb, id_table);
/* module options */
-static int console = 1; /* Allow fbcon to open framebuffer */
-static int fb_defio = 1; /* Detect mmap writes using page faults */
-static int shadow = 1; /* Optionally disable shadow framebuffer */
+static bool console = 1; /* Allow fbcon to open framebuffer */
+static bool fb_defio = 1; /* Detect mmap writes using page faults */
+static bool shadow = 1; /* Optionally disable shadow framebuffer */
/* dlfb keeps a list of urbs for efficient bulk transfers */
static void dlfb_urb_completion(struct urb *urb);
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
index 7f8472cc993b..e7f69ef572dc 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/uvesafb.c
@@ -44,11 +44,11 @@ static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
};
static int mtrr __devinitdata = 3; /* enable mtrr by default */
-static int blank = 1; /* enable blanking by default */
+static bool blank = 1; /* enable blanking by default */
static int ypan = 1; /* 0: scroll, 1: ypan, 2: ywrap */
static bool pmi_setpal __devinitdata = true; /* use PMI for palette changes */
-static int nocrtc __devinitdata; /* ignore CRTC settings */
-static int noedid __devinitdata; /* don't try DDC transfers */
+static bool nocrtc __devinitdata; /* ignore CRTC settings */
+static bool noedid __devinitdata; /* don't try DDC transfers */
static int vram_remap __devinitdata; /* set amt. of memory to be used */
static int vram_total __devinitdata; /* set total amount of memory */
static u16 maxclk __devinitdata; /* maximum pixel clock */
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index bf2f78065cf9..501a922aa9dc 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -110,7 +110,7 @@ static struct fb_fix_screeninfo vfb_fix __devinitdata = {
.accel = FB_ACCEL_NONE,
};
-static int vfb_enable __initdata = 0; /* disabled by default */
+static bool vfb_enable __initdata = 0; /* disabled by default */
module_param(vfb_enable, bool, 0);
static int vfb_check_var(struct fb_var_screeninfo *var,
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/vt8500lcdfb.c
index 777c21dd7a6b..2a5fe6ede845 100644
--- a/drivers/video/vt8500lcdfb.c
+++ b/drivers/video/vt8500lcdfb.c
@@ -457,18 +457,7 @@ static struct platform_driver vt8500lcd_driver = {
},
};
-static int __init vt8500lcd_init(void)
-{
- return platform_driver_register(&vt8500lcd_driver);
-}
-
-static void __exit vt8500lcd_exit(void)
-{
- platform_driver_unregister(&vt8500lcd_driver);
-}
-
-module_init(vt8500lcd_init);
-module_exit(vt8500lcd_exit);
+module_platform_driver(vt8500lcd_driver);
MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com>");
MODULE_DESCRIPTION("LCD controller driver for VIA VT8500");
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c
index 2375e5bbf572..90a2e30272ad 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -1620,18 +1620,7 @@ static struct platform_driver w100fb_driver = {
},
};
-int __init w100fb_init(void)
-{
- return platform_driver_register(&w100fb_driver);
-}
-
-void __exit w100fb_cleanup(void)
-{
- platform_driver_unregister(&w100fb_driver);
-}
-
-module_init(w100fb_init);
-module_exit(w100fb_cleanup);
+module_platform_driver(w100fb_driver);
MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/wm8505fb.c b/drivers/video/wm8505fb.c
index 96e34a569169..c8703bd61b74 100644
--- a/drivers/video/wm8505fb.c
+++ b/drivers/video/wm8505fb.c
@@ -404,18 +404,7 @@ static struct platform_driver wm8505fb_driver = {
},
};
-static int __init wm8505fb_init(void)
-{
- return platform_driver_register(&wm8505fb_driver);
-}
-
-static void __exit wm8505fb_exit(void)
-{
- platform_driver_unregister(&wm8505fb_driver);
-}
-
-module_init(wm8505fb_init);
-module_exit(wm8505fb_exit);
+module_platform_driver(wm8505fb_driver);
MODULE_AUTHOR("Ed Spiridonov <edo.rus@gmail.com>");
MODULE_DESCRIPTION("Framebuffer driver for WMT WM8505");
diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/wmt_ge_rops.c
index 45832b7ef7d2..55be3865015b 100644
--- a/drivers/video/wmt_ge_rops.c
+++ b/drivers/video/wmt_ge_rops.c
@@ -167,18 +167,7 @@ static struct platform_driver wmt_ge_rops_driver = {
},
};
-static int __init wmt_ge_rops_init(void)
-{
- return platform_driver_register(&wmt_ge_rops_driver);
-}
-
-static void __exit wmt_ge_rops_exit(void)
-{
- platform_driver_unregister(&wmt_ge_rops_driver);
-}
-
-module_init(wmt_ge_rops_init);
-module_exit(wmt_ge_rops_exit);
+module_platform_driver(wmt_ge_rops_driver);
MODULE_AUTHOR("Alexey Charkov <alchark@gmail.com");
MODULE_DESCRIPTION("Accelerators for raster operations using "
diff --git a/drivers/video/xilinxfb.c b/drivers/video/xilinxfb.c
index fcb6cd90f64d..18084525402a 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/xilinxfb.c
@@ -511,25 +511,7 @@ static struct platform_driver xilinxfb_of_driver = {
},
};
-
-/* ---------------------------------------------------------------------
- * Module setup and teardown
- */
-
-static int __init
-xilinxfb_init(void)
-{
- return platform_driver_register(&xilinxfb_of_driver);
-}
-
-static void __exit
-xilinxfb_cleanup(void)
-{
- platform_driver_unregister(&xilinxfb_of_driver);
-}
-
-module_init(xilinxfb_init);
-module_exit(xilinxfb_cleanup);
+module_platform_driver(xilinxfb_of_driver);
MODULE_AUTHOR("MontaVista Software, Inc. <source@mvista.com>");
MODULE_DESCRIPTION("Xilinx TFT frame buffer driver");
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c
index d4d8d1fdccc4..e45ca2b4bfbe 100644
--- a/drivers/watchdog/f71808e_wdt.c
+++ b/drivers/watchdog/f71808e_wdt.c
@@ -100,7 +100,7 @@ MODULE_PARM_DESC(f71862fg_pin,
"Watchdog f71862fg reset output pin configuration. Choose pin 56 or 63"
" (default=" __MODULE_STRING(WATCHDOG_F71862FG_PIN)")");
-static int nowayout = WATCHDOG_NOWAYOUT;
+static bool nowayout = WATCHDOG_NOWAYOUT;
module_param(nowayout, bool, 0444);
MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close");
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c
index eed5436ffb51..20feb4d3d791 100644
--- a/drivers/watchdog/mpc8xxx_wdt.c
+++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -55,7 +55,7 @@ module_param(timeout, ushort, 0);
MODULE_PARM_DESC(timeout,
"Watchdog timeout in ticks. (0<timeout<65536, default=65535)");
-static int reset = 1;
+static bool reset = 1;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset,
"Watchdog Interrupt/Reset Mode. 0 = interrupt, 1 = reset");
diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c
index 52fed16d8701..30d7be026c18 100644
--- a/drivers/xen/xen-pciback/conf_space.c
+++ b/drivers/xen/xen-pciback/conf_space.c
@@ -16,7 +16,7 @@
#include "conf_space.h"
#include "conf_space_quirks.h"
-static int permissive;
+static bool permissive;
module_param(permissive, bool, 0644);
/* This is where xen_pcibk_read_config_byte, xen_pcibk_read_config_word,
diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c
index 8e1c44d8ab46..d5dcf8d5d3d9 100644
--- a/drivers/xen/xen-pciback/xenbus.c
+++ b/drivers/xen/xen-pciback/xenbus.c
@@ -16,7 +16,7 @@
#define INVALID_EVTCHN_IRQ (-1)
struct workqueue_struct *xen_pcibk_wq;
-static int __read_mostly passthrough;
+static bool __read_mostly passthrough;
module_param(passthrough, bool, S_IRUGO);
MODULE_PARM_DESC(passthrough,
"Option to specify how to export PCI topology to guest:\n"\
diff --git a/fs/aio.c b/fs/aio.c
index 78c514cfd212..969beb0e2231 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -476,14 +476,21 @@ static void kiocb_batch_init(struct kiocb_batch *batch, long total)
batch->count = total;
}
-static void kiocb_batch_free(struct kiocb_batch *batch)
+static void kiocb_batch_free(struct kioctx *ctx, struct kiocb_batch *batch)
{
struct kiocb *req, *n;
+ if (list_empty(&batch->head))
+ return;
+
+ spin_lock_irq(&ctx->ctx_lock);
list_for_each_entry_safe(req, n, &batch->head, ki_batch) {
list_del(&req->ki_batch);
+ list_del(&req->ki_list);
kmem_cache_free(kiocb_cachep, req);
+ ctx->reqs_active--;
}
+ spin_unlock_irq(&ctx->ctx_lock);
}
/*
@@ -1742,7 +1749,7 @@ long do_io_submit(aio_context_t ctx_id, long nr,
}
blk_finish_plug(&plug);
- kiocb_batch_free(&batch);
+ kiocb_batch_free(ctx, &batch);
put_ioctx(ctx);
return i ? i : ret;
}
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
index 88e8a23d0026..376816fcd040 100644
--- a/fs/gfs2/glock.c
+++ b/fs/gfs2/glock.c
@@ -1353,7 +1353,7 @@ void gfs2_glock_complete(struct gfs2_glock *gl, int ret)
spin_lock(&gl->gl_spin);
gl->gl_reply = ret;
- if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))) {
+ if (unlikely(test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))) {
if (gfs2_should_freeze(gl)) {
set_bit(GLF_FROZEN, &gl->gl_flags);
spin_unlock(&gl->gl_spin);
diff --git a/fs/gfs2/glock.h b/fs/gfs2/glock.h
index 2553b858a72e..307ac31df781 100644
--- a/fs/gfs2/glock.h
+++ b/fs/gfs2/glock.h
@@ -121,8 +121,11 @@ enum {
struct lm_lockops {
const char *lm_proto_name;
- int (*lm_mount) (struct gfs2_sbd *sdp, const char *fsname);
- void (*lm_unmount) (struct gfs2_sbd *sdp);
+ int (*lm_mount) (struct gfs2_sbd *sdp, const char *table);
+ void (*lm_first_done) (struct gfs2_sbd *sdp);
+ void (*lm_recovery_result) (struct gfs2_sbd *sdp, unsigned int jid,
+ unsigned int result);
+ void (*lm_unmount) (struct gfs2_sbd *sdp);
void (*lm_withdraw) (struct gfs2_sbd *sdp);
void (*lm_put_lock) (struct gfs2_glock *gl);
int (*lm_lock) (struct gfs2_glock *gl, unsigned int req_state,
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index e1d3bb59945c..97742a7ea9cc 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -139,8 +139,45 @@ struct gfs2_bufdata {
#define GDLM_STRNAME_BYTES 25
#define GDLM_LVB_SIZE 32
+/*
+ * ls_recover_flags:
+ *
+ * DFL_BLOCK_LOCKS: dlm is in recovery and will grant locks that had been
+ * held by failed nodes whose journals need recovery. Those locks should
+ * only be used for journal recovery until the journal recovery is done.
+ * This is set by the dlm recover_prep callback and cleared by the
+ * gfs2_control thread when journal recovery is complete. To avoid
+ * races between recover_prep setting and gfs2_control clearing, recover_spin
+ * is held while changing this bit and reading/writing recover_block
+ * and recover_start.
+ *
+ * DFL_NO_DLM_OPS: dlm lockspace ops/callbacks are not being used.
+ *
+ * DFL_FIRST_MOUNT: this node is the first to mount this fs and is doing
+ * recovery of all journals before allowing other nodes to mount the fs.
+ * This is cleared when FIRST_MOUNT_DONE is set.
+ *
+ * DFL_FIRST_MOUNT_DONE: this node was the first mounter, and has finished
+ * recovery of all journals, and now allows other nodes to mount the fs.
+ *
+ * DFL_MOUNT_DONE: gdlm_mount has completed successfully and cleared
+ * BLOCK_LOCKS for the first time. The gfs2_control thread should now
+ * control clearing BLOCK_LOCKS for further recoveries.
+ *
+ * DFL_UNMOUNT: gdlm_unmount sets to keep sdp off gfs2_control_wq.
+ *
+ * DFL_DLM_RECOVERY: set while dlm is in recovery, between recover_prep()
+ * and recover_done(), i.e. set while recover_block == recover_start.
+ */
+
enum {
DFL_BLOCK_LOCKS = 0,
+ DFL_NO_DLM_OPS = 1,
+ DFL_FIRST_MOUNT = 2,
+ DFL_FIRST_MOUNT_DONE = 3,
+ DFL_MOUNT_DONE = 4,
+ DFL_UNMOUNT = 5,
+ DFL_DLM_RECOVERY = 6,
};
struct lm_lockname {
@@ -392,6 +429,7 @@ struct gfs2_jdesc {
#define JDF_RECOVERY 1
unsigned int jd_jid;
unsigned int jd_blocks;
+ int jd_recover_error;
};
struct gfs2_statfs_change_host {
@@ -461,6 +499,7 @@ enum {
SDF_NORECOVERY = 4,
SDF_DEMOTE = 5,
SDF_NOJOURNALID = 6,
+ SDF_RORECOVERY = 7, /* read only recovery */
};
#define GFS2_FSNAME_LEN 256
@@ -499,14 +538,26 @@ struct gfs2_sb_host {
struct lm_lockstruct {
int ls_jid;
unsigned int ls_first;
- unsigned int ls_first_done;
unsigned int ls_nodir;
const struct lm_lockops *ls_ops;
- unsigned long ls_flags;
dlm_lockspace_t *ls_dlm;
- int ls_recover_jid_done;
- int ls_recover_jid_status;
+ int ls_recover_jid_done; /* These two are deprecated, */
+ int ls_recover_jid_status; /* used previously by gfs_controld */
+
+ struct dlm_lksb ls_mounted_lksb; /* mounted_lock */
+ struct dlm_lksb ls_control_lksb; /* control_lock */
+ char ls_control_lvb[GDLM_LVB_SIZE]; /* control_lock lvb */
+ struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */
+
+ spinlock_t ls_recover_spin; /* protects following fields */
+ unsigned long ls_recover_flags; /* DFL_ */
+ uint32_t ls_recover_mount; /* gen in first recover_done cb */
+ uint32_t ls_recover_start; /* gen in last recover_done cb */
+ uint32_t ls_recover_block; /* copy recover_start in last recover_prep */
+ uint32_t ls_recover_size; /* size of recover_submit, recover_result */
+ uint32_t *ls_recover_submit; /* gen in last recover_slot cb per jid */
+ uint32_t *ls_recover_result; /* result of last jid recovery */
};
struct gfs2_sbd {
@@ -544,6 +595,7 @@ struct gfs2_sbd {
wait_queue_head_t sd_glock_wait;
atomic_t sd_glock_disposal;
struct completion sd_locking_init;
+ struct delayed_work sd_control_work;
/* Inode Stuff */
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 017960cf1d7a..a7d611b93f0f 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -599,9 +599,7 @@ static int link_dinode(struct gfs2_inode *dip, const struct qstr *name,
error = gfs2_meta_inode_buffer(ip, &dibh);
if (error)
goto fail_end_trans;
- inc_nlink(&ip->i_inode);
- if (S_ISDIR(ip->i_inode.i_mode))
- inc_nlink(&ip->i_inode);
+ set_nlink(&ip->i_inode, S_ISDIR(ip->i_inode.i_mode) ? 2 : 1);
gfs2_trans_add_bh(ip->i_gl, dibh, 1);
gfs2_dinode_out(ip, dibh->b_data);
brelse(dibh);
diff --git a/fs/gfs2/lock_dlm.c b/fs/gfs2/lock_dlm.c
index ce85b62bc0a2..8944d1e32ab5 100644
--- a/fs/gfs2/lock_dlm.c
+++ b/fs/gfs2/lock_dlm.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
- * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
+ * Copyright 2004-2011 Red Hat, Inc.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
@@ -11,12 +11,15 @@
#include <linux/dlm.h>
#include <linux/slab.h>
#include <linux/types.h>
+#include <linux/delay.h>
#include <linux/gfs2_ondisk.h>
#include "incore.h"
#include "glock.h"
#include "util.h"
+#include "sys.h"
+extern struct workqueue_struct *gfs2_control_wq;
static void gdlm_ast(void *arg)
{
@@ -185,34 +188,1002 @@ static void gdlm_cancel(struct gfs2_glock *gl)
dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_CANCEL, NULL, gl);
}
-static int gdlm_mount(struct gfs2_sbd *sdp, const char *fsname)
+/*
+ * dlm/gfs2 recovery coordination using dlm_recover callbacks
+ *
+ * 1. dlm_controld sees lockspace members change
+ * 2. dlm_controld blocks dlm-kernel locking activity
+ * 3. dlm_controld within dlm-kernel notifies gfs2 (recover_prep)
+ * 4. dlm_controld starts and finishes its own user level recovery
+ * 5. dlm_controld starts dlm-kernel dlm_recoverd to do kernel recovery
+ * 6. dlm_recoverd notifies gfs2 of failed nodes (recover_slot)
+ * 7. dlm_recoverd does its own lock recovery
+ * 8. dlm_recoverd unblocks dlm-kernel locking activity
+ * 9. dlm_recoverd notifies gfs2 when done (recover_done with new generation)
+ * 10. gfs2_control updates control_lock lvb with new generation and jid bits
+ * 11. gfs2_control enqueues journals for gfs2_recover to recover (maybe none)
+ * 12. gfs2_recover dequeues and recovers journals of failed nodes
+ * 13. gfs2_recover provides recovery results to gfs2_control (recovery_result)
+ * 14. gfs2_control updates control_lock lvb jid bits for recovered journals
+ * 15. gfs2_control unblocks normal locking when all journals are recovered
+ *
+ * - failures during recovery
+ *
+ * recover_prep() may set BLOCK_LOCKS (step 3) again before gfs2_control
+ * clears BLOCK_LOCKS (step 15), e.g. another node fails while still
+ * recovering for a prior failure. gfs2_control needs a way to detect
+ * this so it can leave BLOCK_LOCKS set in step 15. This is managed using
+ * the recover_block and recover_start values.
+ *
+ * recover_done() provides a new lockspace generation number each time it
+ * is called (step 9). This generation number is saved as recover_start.
+ * When recover_prep() is called, it sets BLOCK_LOCKS and sets
+ * recover_block = recover_start. So, while recover_block is equal to
+ * recover_start, BLOCK_LOCKS should remain set. (recover_spin must
+ * be held around the BLOCK_LOCKS/recover_block/recover_start logic.)
+ *
+ * - more specific gfs2 steps in sequence above
+ *
+ * 3. recover_prep sets BLOCK_LOCKS and sets recover_block = recover_start
+ * 6. recover_slot records any failed jids (maybe none)
+ * 9. recover_done sets recover_start = new generation number
+ * 10. gfs2_control sets control_lock lvb = new gen + bits for failed jids
+ * 12. gfs2_recover does journal recoveries for failed jids identified above
+ * 14. gfs2_control clears control_lock lvb bits for recovered jids
+ * 15. gfs2_control checks if recover_block == recover_start (step 3 occured
+ * again) then do nothing, otherwise if recover_start > recover_block
+ * then clear BLOCK_LOCKS.
+ *
+ * - parallel recovery steps across all nodes
+ *
+ * All nodes attempt to update the control_lock lvb with the new generation
+ * number and jid bits, but only the first to get the control_lock EX will
+ * do so; others will see that it's already done (lvb already contains new
+ * generation number.)
+ *
+ * . All nodes get the same recover_prep/recover_slot/recover_done callbacks
+ * . All nodes attempt to set control_lock lvb gen + bits for the new gen
+ * . One node gets control_lock first and writes the lvb, others see it's done
+ * . All nodes attempt to recover jids for which they see control_lock bits set
+ * . One node succeeds for a jid, and that one clears the jid bit in the lvb
+ * . All nodes will eventually see all lvb bits clear and unblock locks
+ *
+ * - is there a problem with clearing an lvb bit that should be set
+ * and missing a journal recovery?
+ *
+ * 1. jid fails
+ * 2. lvb bit set for step 1
+ * 3. jid recovered for step 1
+ * 4. jid taken again (new mount)
+ * 5. jid fails (for step 4)
+ * 6. lvb bit set for step 5 (will already be set)
+ * 7. lvb bit cleared for step 3
+ *
+ * This is not a problem because the failure in step 5 does not
+ * require recovery, because the mount in step 4 could not have
+ * progressed far enough to unblock locks and access the fs. The
+ * control_mount() function waits for all recoveries to be complete
+ * for the latest lockspace generation before ever unblocking locks
+ * and returning. The mount in step 4 waits until the recovery in
+ * step 1 is done.
+ *
+ * - special case of first mounter: first node to mount the fs
+ *
+ * The first node to mount a gfs2 fs needs to check all the journals
+ * and recover any that need recovery before other nodes are allowed
+ * to mount the fs. (Others may begin mounting, but they must wait
+ * for the first mounter to be done before taking locks on the fs
+ * or accessing the fs.) This has two parts:
+ *
+ * 1. The mounted_lock tells a node it's the first to mount the fs.
+ * Each node holds the mounted_lock in PR while it's mounted.
+ * Each node tries to acquire the mounted_lock in EX when it mounts.
+ * If a node is granted the mounted_lock EX it means there are no
+ * other mounted nodes (no PR locks exist), and it is the first mounter.
+ * The mounted_lock is demoted to PR when first recovery is done, so
+ * others will fail to get an EX lock, but will get a PR lock.
+ *
+ * 2. The control_lock blocks others in control_mount() while the first
+ * mounter is doing first mount recovery of all journals.
+ * A mounting node needs to acquire control_lock in EX mode before
+ * it can proceed. The first mounter holds control_lock in EX while doing
+ * the first mount recovery, blocking mounts from other nodes, then demotes
+ * control_lock to NL when it's done (others_may_mount/first_done),
+ * allowing other nodes to continue mounting.
+ *
+ * first mounter:
+ * control_lock EX/NOQUEUE success
+ * mounted_lock EX/NOQUEUE success (no other PR, so no other mounters)
+ * set first=1
+ * do first mounter recovery
+ * mounted_lock EX->PR
+ * control_lock EX->NL, write lvb generation
+ *
+ * other mounter:
+ * control_lock EX/NOQUEUE success (if fail -EAGAIN, retry)
+ * mounted_lock EX/NOQUEUE fail -EAGAIN (expected due to other mounters PR)
+ * mounted_lock PR/NOQUEUE success
+ * read lvb generation
+ * control_lock EX->NL
+ * set first=0
+ *
+ * - mount during recovery
+ *
+ * If a node mounts while others are doing recovery (not first mounter),
+ * the mounting node will get its initial recover_done() callback without
+ * having seen any previous failures/callbacks.
+ *
+ * It must wait for all recoveries preceding its mount to be finished
+ * before it unblocks locks. It does this by repeating the "other mounter"
+ * steps above until the lvb generation number is >= its mount generation
+ * number (from initial recover_done) and all lvb bits are clear.
+ *
+ * - control_lock lvb format
+ *
+ * 4 bytes generation number: the latest dlm lockspace generation number
+ * from recover_done callback. Indicates the jid bitmap has been updated
+ * to reflect all slot failures through that generation.
+ * 4 bytes unused.
+ * GDLM_LVB_SIZE-8 bytes of jid bit map. If bit N is set, it indicates
+ * that jid N needs recovery.
+ */
+
+#define JID_BITMAP_OFFSET 8 /* 4 byte generation number + 4 byte unused */
+
+static void control_lvb_read(struct lm_lockstruct *ls, uint32_t *lvb_gen,
+ char *lvb_bits)
+{
+ uint32_t gen;
+ memcpy(lvb_bits, ls->ls_control_lvb, GDLM_LVB_SIZE);
+ memcpy(&gen, lvb_bits, sizeof(uint32_t));
+ *lvb_gen = le32_to_cpu(gen);
+}
+
+static void control_lvb_write(struct lm_lockstruct *ls, uint32_t lvb_gen,
+ char *lvb_bits)
+{
+ uint32_t gen;
+ memcpy(ls->ls_control_lvb, lvb_bits, GDLM_LVB_SIZE);
+ gen = cpu_to_le32(lvb_gen);
+ memcpy(ls->ls_control_lvb, &gen, sizeof(uint32_t));
+}
+
+static int all_jid_bits_clear(char *lvb)
+{
+ int i;
+ for (i = JID_BITMAP_OFFSET; i < GDLM_LVB_SIZE; i++) {
+ if (lvb[i])
+ return 0;
+ }
+ return 1;
+}
+
+static void sync_wait_cb(void *arg)
+{
+ struct lm_lockstruct *ls = arg;
+ complete(&ls->ls_sync_wait);
+}
+
+static int sync_unlock(struct gfs2_sbd *sdp, struct dlm_lksb *lksb, char *name)
{
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
int error;
- if (fsname == NULL) {
- fs_info(sdp, "no fsname found\n");
- return -EINVAL;
+ error = dlm_unlock(ls->ls_dlm, lksb->sb_lkid, 0, lksb, ls);
+ if (error) {
+ fs_err(sdp, "%s lkid %x error %d\n",
+ name, lksb->sb_lkid, error);
+ return error;
+ }
+
+ wait_for_completion(&ls->ls_sync_wait);
+
+ if (lksb->sb_status != -DLM_EUNLOCK) {
+ fs_err(sdp, "%s lkid %x status %d\n",
+ name, lksb->sb_lkid, lksb->sb_status);
+ return -1;
+ }
+ return 0;
+}
+
+static int sync_lock(struct gfs2_sbd *sdp, int mode, uint32_t flags,
+ unsigned int num, struct dlm_lksb *lksb, char *name)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ char strname[GDLM_STRNAME_BYTES];
+ int error, status;
+
+ memset(strname, 0, GDLM_STRNAME_BYTES);
+ snprintf(strname, GDLM_STRNAME_BYTES, "%8x%16x", LM_TYPE_NONDISK, num);
+
+ error = dlm_lock(ls->ls_dlm, mode, lksb, flags,
+ strname, GDLM_STRNAME_BYTES - 1,
+ 0, sync_wait_cb, ls, NULL);
+ if (error) {
+ fs_err(sdp, "%s lkid %x flags %x mode %d error %d\n",
+ name, lksb->sb_lkid, flags, mode, error);
+ return error;
+ }
+
+ wait_for_completion(&ls->ls_sync_wait);
+
+ status = lksb->sb_status;
+
+ if (status && status != -EAGAIN) {
+ fs_err(sdp, "%s lkid %x flags %x mode %d status %d\n",
+ name, lksb->sb_lkid, flags, mode, status);
+ }
+
+ return status;
+}
+
+static int mounted_unlock(struct gfs2_sbd *sdp)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ return sync_unlock(sdp, &ls->ls_mounted_lksb, "mounted_lock");
+}
+
+static int mounted_lock(struct gfs2_sbd *sdp, int mode, uint32_t flags)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ return sync_lock(sdp, mode, flags, GFS2_MOUNTED_LOCK,
+ &ls->ls_mounted_lksb, "mounted_lock");
+}
+
+static int control_unlock(struct gfs2_sbd *sdp)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ return sync_unlock(sdp, &ls->ls_control_lksb, "control_lock");
+}
+
+static int control_lock(struct gfs2_sbd *sdp, int mode, uint32_t flags)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ return sync_lock(sdp, mode, flags, GFS2_CONTROL_LOCK,
+ &ls->ls_control_lksb, "control_lock");
+}
+
+static void gfs2_control_func(struct work_struct *work)
+{
+ struct gfs2_sbd *sdp = container_of(work, struct gfs2_sbd, sd_control_work.work);
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ char lvb_bits[GDLM_LVB_SIZE];
+ uint32_t block_gen, start_gen, lvb_gen, flags;
+ int recover_set = 0;
+ int write_lvb = 0;
+ int recover_size;
+ int i, error;
+
+ spin_lock(&ls->ls_recover_spin);
+ /*
+ * No MOUNT_DONE means we're still mounting; control_mount()
+ * will set this flag, after which this thread will take over
+ * all further clearing of BLOCK_LOCKS.
+ *
+ * FIRST_MOUNT means this node is doing first mounter recovery,
+ * for which recovery control is handled by
+ * control_mount()/control_first_done(), not this thread.
+ */
+ if (!test_bit(DFL_MOUNT_DONE, &ls->ls_recover_flags) ||
+ test_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags)) {
+ spin_unlock(&ls->ls_recover_spin);
+ return;
+ }
+ block_gen = ls->ls_recover_block;
+ start_gen = ls->ls_recover_start;
+ spin_unlock(&ls->ls_recover_spin);
+
+ /*
+ * Equal block_gen and start_gen implies we are between
+ * recover_prep and recover_done callbacks, which means
+ * dlm recovery is in progress and dlm locking is blocked.
+ * There's no point trying to do any work until recover_done.
+ */
+
+ if (block_gen == start_gen)
+ return;
+
+ /*
+ * Propagate recover_submit[] and recover_result[] to lvb:
+ * dlm_recoverd adds to recover_submit[] jids needing recovery
+ * gfs2_recover adds to recover_result[] journal recovery results
+ *
+ * set lvb bit for jids in recover_submit[] if the lvb has not
+ * yet been updated for the generation of the failure
+ *
+ * clear lvb bit for jids in recover_result[] if the result of
+ * the journal recovery is SUCCESS
+ */
+
+ error = control_lock(sdp, DLM_LOCK_EX, DLM_LKF_CONVERT|DLM_LKF_VALBLK);
+ if (error) {
+ fs_err(sdp, "control lock EX error %d\n", error);
+ return;
+ }
+
+ control_lvb_read(ls, &lvb_gen, lvb_bits);
+
+ spin_lock(&ls->ls_recover_spin);
+ if (block_gen != ls->ls_recover_block ||
+ start_gen != ls->ls_recover_start) {
+ fs_info(sdp, "recover generation %u block1 %u %u\n",
+ start_gen, block_gen, ls->ls_recover_block);
+ spin_unlock(&ls->ls_recover_spin);
+ control_lock(sdp, DLM_LOCK_NL, DLM_LKF_CONVERT);
+ return;
+ }
+
+ recover_size = ls->ls_recover_size;
+
+ if (lvb_gen <= start_gen) {
+ /*
+ * Clear lvb bits for jids we've successfully recovered.
+ * Because all nodes attempt to recover failed journals,
+ * a journal can be recovered multiple times successfully
+ * in succession. Only the first will really do recovery,
+ * the others find it clean, but still report a successful
+ * recovery. So, another node may have already recovered
+ * the jid and cleared the lvb bit for it.
+ */
+ for (i = 0; i < recover_size; i++) {
+ if (ls->ls_recover_result[i] != LM_RD_SUCCESS)
+ continue;
+
+ ls->ls_recover_result[i] = 0;
+
+ if (!test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET))
+ continue;
+
+ __clear_bit_le(i, lvb_bits + JID_BITMAP_OFFSET);
+ write_lvb = 1;
+ }
+ }
+
+ if (lvb_gen == start_gen) {
+ /*
+ * Failed slots before start_gen are already set in lvb.
+ */
+ for (i = 0; i < recover_size; i++) {
+ if (!ls->ls_recover_submit[i])
+ continue;
+ if (ls->ls_recover_submit[i] < lvb_gen)
+ ls->ls_recover_submit[i] = 0;
+ }
+ } else if (lvb_gen < start_gen) {
+ /*
+ * Failed slots before start_gen are not yet set in lvb.
+ */
+ for (i = 0; i < recover_size; i++) {
+ if (!ls->ls_recover_submit[i])
+ continue;
+ if (ls->ls_recover_submit[i] < start_gen) {
+ ls->ls_recover_submit[i] = 0;
+ __set_bit_le(i, lvb_bits + JID_BITMAP_OFFSET);
+ }
+ }
+ /* even if there are no bits to set, we need to write the
+ latest generation to the lvb */
+ write_lvb = 1;
+ } else {
+ /*
+ * we should be getting a recover_done() for lvb_gen soon
+ */
+ }
+ spin_unlock(&ls->ls_recover_spin);
+
+ if (write_lvb) {
+ control_lvb_write(ls, start_gen, lvb_bits);
+ flags = DLM_LKF_CONVERT | DLM_LKF_VALBLK;
+ } else {
+ flags = DLM_LKF_CONVERT;
+ }
+
+ error = control_lock(sdp, DLM_LOCK_NL, flags);
+ if (error) {
+ fs_err(sdp, "control lock NL error %d\n", error);
+ return;
+ }
+
+ /*
+ * Everyone will see jid bits set in the lvb, run gfs2_recover_set(),
+ * and clear a jid bit in the lvb if the recovery is a success.
+ * Eventually all journals will be recovered, all jid bits will
+ * be cleared in the lvb, and everyone will clear BLOCK_LOCKS.
+ */
+
+ for (i = 0; i < recover_size; i++) {
+ if (test_bit_le(i, lvb_bits + JID_BITMAP_OFFSET)) {
+ fs_info(sdp, "recover generation %u jid %d\n",
+ start_gen, i);
+ gfs2_recover_set(sdp, i);
+ recover_set++;
+ }
+ }
+ if (recover_set)
+ return;
+
+ /*
+ * No more jid bits set in lvb, all recovery is done, unblock locks
+ * (unless a new recover_prep callback has occured blocking locks
+ * again while working above)
+ */
+
+ spin_lock(&ls->ls_recover_spin);
+ if (ls->ls_recover_block == block_gen &&
+ ls->ls_recover_start == start_gen) {
+ clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
+ spin_unlock(&ls->ls_recover_spin);
+ fs_info(sdp, "recover generation %u done\n", start_gen);
+ gfs2_glock_thaw(sdp);
+ } else {
+ fs_info(sdp, "recover generation %u block2 %u %u\n",
+ start_gen, block_gen, ls->ls_recover_block);
+ spin_unlock(&ls->ls_recover_spin);
+ }
+}
+
+static int control_mount(struct gfs2_sbd *sdp)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ char lvb_bits[GDLM_LVB_SIZE];
+ uint32_t start_gen, block_gen, mount_gen, lvb_gen;
+ int mounted_mode;
+ int retries = 0;
+ int error;
+
+ memset(&ls->ls_mounted_lksb, 0, sizeof(struct dlm_lksb));
+ memset(&ls->ls_control_lksb, 0, sizeof(struct dlm_lksb));
+ memset(&ls->ls_control_lvb, 0, GDLM_LVB_SIZE);
+ ls->ls_control_lksb.sb_lvbptr = ls->ls_control_lvb;
+ init_completion(&ls->ls_sync_wait);
+
+ set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
+
+ error = control_lock(sdp, DLM_LOCK_NL, DLM_LKF_VALBLK);
+ if (error) {
+ fs_err(sdp, "control_mount control_lock NL error %d\n", error);
+ return error;
+ }
+
+ error = mounted_lock(sdp, DLM_LOCK_NL, 0);
+ if (error) {
+ fs_err(sdp, "control_mount mounted_lock NL error %d\n", error);
+ control_unlock(sdp);
+ return error;
+ }
+ mounted_mode = DLM_LOCK_NL;
+
+restart:
+ if (retries++ && signal_pending(current)) {
+ error = -EINTR;
+ goto fail;
+ }
+
+ /*
+ * We always start with both locks in NL. control_lock is
+ * demoted to NL below so we don't need to do it here.
+ */
+
+ if (mounted_mode != DLM_LOCK_NL) {
+ error = mounted_lock(sdp, DLM_LOCK_NL, DLM_LKF_CONVERT);
+ if (error)
+ goto fail;
+ mounted_mode = DLM_LOCK_NL;
+ }
+
+ /*
+ * Other nodes need to do some work in dlm recovery and gfs2_control
+ * before the recover_done and control_lock will be ready for us below.
+ * A delay here is not required but often avoids having to retry.
+ */
+
+ msleep_interruptible(500);
+
+ /*
+ * Acquire control_lock in EX and mounted_lock in either EX or PR.
+ * control_lock lvb keeps track of any pending journal recoveries.
+ * mounted_lock indicates if any other nodes have the fs mounted.
+ */
+
+ error = control_lock(sdp, DLM_LOCK_EX, DLM_LKF_CONVERT|DLM_LKF_NOQUEUE|DLM_LKF_VALBLK);
+ if (error == -EAGAIN) {
+ goto restart;
+ } else if (error) {
+ fs_err(sdp, "control_mount control_lock EX error %d\n", error);
+ goto fail;
+ }
+
+ error = mounted_lock(sdp, DLM_LOCK_EX, DLM_LKF_CONVERT|DLM_LKF_NOQUEUE);
+ if (!error) {
+ mounted_mode = DLM_LOCK_EX;
+ goto locks_done;
+ } else if (error != -EAGAIN) {
+ fs_err(sdp, "control_mount mounted_lock EX error %d\n", error);
+ goto fail;
+ }
+
+ error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT|DLM_LKF_NOQUEUE);
+ if (!error) {
+ mounted_mode = DLM_LOCK_PR;
+ goto locks_done;
+ } else {
+ /* not even -EAGAIN should happen here */
+ fs_err(sdp, "control_mount mounted_lock PR error %d\n", error);
+ goto fail;
+ }
+
+locks_done:
+ /*
+ * If we got both locks above in EX, then we're the first mounter.
+ * If not, then we need to wait for the control_lock lvb to be
+ * updated by other mounted nodes to reflect our mount generation.
+ *
+ * In simple first mounter cases, first mounter will see zero lvb_gen,
+ * but in cases where all existing nodes leave/fail before mounting
+ * nodes finish control_mount, then all nodes will be mounting and
+ * lvb_gen will be non-zero.
+ */
+
+ control_lvb_read(ls, &lvb_gen, lvb_bits);
+
+ if (lvb_gen == 0xFFFFFFFF) {
+ /* special value to force mount attempts to fail */
+ fs_err(sdp, "control_mount control_lock disabled\n");
+ error = -EINVAL;
+ goto fail;
+ }
+
+ if (mounted_mode == DLM_LOCK_EX) {
+ /* first mounter, keep both EX while doing first recovery */
+ spin_lock(&ls->ls_recover_spin);
+ clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
+ set_bit(DFL_MOUNT_DONE, &ls->ls_recover_flags);
+ set_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags);
+ spin_unlock(&ls->ls_recover_spin);
+ fs_info(sdp, "first mounter control generation %u\n", lvb_gen);
+ return 0;
+ }
+
+ error = control_lock(sdp, DLM_LOCK_NL, DLM_LKF_CONVERT);
+ if (error)
+ goto fail;
+
+ /*
+ * We are not first mounter, now we need to wait for the control_lock
+ * lvb generation to be >= the generation from our first recover_done
+ * and all lvb bits to be clear (no pending journal recoveries.)
+ */
+
+ if (!all_jid_bits_clear(lvb_bits)) {
+ /* journals need recovery, wait until all are clear */
+ fs_info(sdp, "control_mount wait for journal recovery\n");
+ goto restart;
+ }
+
+ spin_lock(&ls->ls_recover_spin);
+ block_gen = ls->ls_recover_block;
+ start_gen = ls->ls_recover_start;
+ mount_gen = ls->ls_recover_mount;
+
+ if (lvb_gen < mount_gen) {
+ /* wait for mounted nodes to update control_lock lvb to our
+ generation, which might include new recovery bits set */
+ fs_info(sdp, "control_mount wait1 block %u start %u mount %u "
+ "lvb %u flags %lx\n", block_gen, start_gen, mount_gen,
+ lvb_gen, ls->ls_recover_flags);
+ spin_unlock(&ls->ls_recover_spin);
+ goto restart;
+ }
+
+ if (lvb_gen != start_gen) {
+ /* wait for mounted nodes to update control_lock lvb to the
+ latest recovery generation */
+ fs_info(sdp, "control_mount wait2 block %u start %u mount %u "
+ "lvb %u flags %lx\n", block_gen, start_gen, mount_gen,
+ lvb_gen, ls->ls_recover_flags);
+ spin_unlock(&ls->ls_recover_spin);
+ goto restart;
+ }
+
+ if (block_gen == start_gen) {
+ /* dlm recovery in progress, wait for it to finish */
+ fs_info(sdp, "control_mount wait3 block %u start %u mount %u "
+ "lvb %u flags %lx\n", block_gen, start_gen, mount_gen,
+ lvb_gen, ls->ls_recover_flags);
+ spin_unlock(&ls->ls_recover_spin);
+ goto restart;
}
- error = dlm_new_lockspace(fsname, NULL,
- DLM_LSFL_FS | DLM_LSFL_NEWEXCL |
- (ls->ls_nodir ? DLM_LSFL_NODIR : 0),
- GDLM_LVB_SIZE, NULL, NULL, NULL, &ls->ls_dlm);
+ clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
+ set_bit(DFL_MOUNT_DONE, &ls->ls_recover_flags);
+ memset(ls->ls_recover_submit, 0, ls->ls_recover_size*sizeof(uint32_t));
+ memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t));
+ spin_unlock(&ls->ls_recover_spin);
+ return 0;
+
+fail:
+ mounted_unlock(sdp);
+ control_unlock(sdp);
+ return error;
+}
+
+static int dlm_recovery_wait(void *word)
+{
+ schedule();
+ return 0;
+}
+
+static int control_first_done(struct gfs2_sbd *sdp)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ char lvb_bits[GDLM_LVB_SIZE];
+ uint32_t start_gen, block_gen;
+ int error;
+
+restart:
+ spin_lock(&ls->ls_recover_spin);
+ start_gen = ls->ls_recover_start;
+ block_gen = ls->ls_recover_block;
+
+ if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags) ||
+ !test_bit(DFL_MOUNT_DONE, &ls->ls_recover_flags) ||
+ !test_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags)) {
+ /* sanity check, should not happen */
+ fs_err(sdp, "control_first_done start %u block %u flags %lx\n",
+ start_gen, block_gen, ls->ls_recover_flags);
+ spin_unlock(&ls->ls_recover_spin);
+ control_unlock(sdp);
+ return -1;
+ }
+
+ if (start_gen == block_gen) {
+ /*
+ * Wait for the end of a dlm recovery cycle to switch from
+ * first mounter recovery. We can ignore any recover_slot
+ * callbacks between the recover_prep and next recover_done
+ * because we are still the first mounter and any failed nodes
+ * have not fully mounted, so they don't need recovery.
+ */
+ spin_unlock(&ls->ls_recover_spin);
+ fs_info(sdp, "control_first_done wait gen %u\n", start_gen);
+
+ wait_on_bit(&ls->ls_recover_flags, DFL_DLM_RECOVERY,
+ dlm_recovery_wait, TASK_UNINTERRUPTIBLE);
+ goto restart;
+ }
+
+ clear_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags);
+ set_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags);
+ memset(ls->ls_recover_submit, 0, ls->ls_recover_size*sizeof(uint32_t));
+ memset(ls->ls_recover_result, 0, ls->ls_recover_size*sizeof(uint32_t));
+ spin_unlock(&ls->ls_recover_spin);
+
+ memset(lvb_bits, 0, sizeof(lvb_bits));
+ control_lvb_write(ls, start_gen, lvb_bits);
+
+ error = mounted_lock(sdp, DLM_LOCK_PR, DLM_LKF_CONVERT);
+ if (error)
+ fs_err(sdp, "control_first_done mounted PR error %d\n", error);
+
+ error = control_lock(sdp, DLM_LOCK_NL, DLM_LKF_CONVERT|DLM_LKF_VALBLK);
if (error)
- printk(KERN_ERR "dlm_new_lockspace error %d", error);
+ fs_err(sdp, "control_first_done control NL error %d\n", error);
return error;
}
+/*
+ * Expand static jid arrays if necessary (by increments of RECOVER_SIZE_INC)
+ * to accomodate the largest slot number. (NB dlm slot numbers start at 1,
+ * gfs2 jids start at 0, so jid = slot - 1)
+ */
+
+#define RECOVER_SIZE_INC 16
+
+static int set_recover_size(struct gfs2_sbd *sdp, struct dlm_slot *slots,
+ int num_slots)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ uint32_t *submit = NULL;
+ uint32_t *result = NULL;
+ uint32_t old_size, new_size;
+ int i, max_jid;
+
+ max_jid = 0;
+ for (i = 0; i < num_slots; i++) {
+ if (max_jid < slots[i].slot - 1)
+ max_jid = slots[i].slot - 1;
+ }
+
+ old_size = ls->ls_recover_size;
+
+ if (old_size >= max_jid + 1)
+ return 0;
+
+ new_size = old_size + RECOVER_SIZE_INC;
+
+ submit = kzalloc(new_size * sizeof(uint32_t), GFP_NOFS);
+ result = kzalloc(new_size * sizeof(uint32_t), GFP_NOFS);
+ if (!submit || !result) {
+ kfree(submit);
+ kfree(result);
+ return -ENOMEM;
+ }
+
+ spin_lock(&ls->ls_recover_spin);
+ memcpy(submit, ls->ls_recover_submit, old_size * sizeof(uint32_t));
+ memcpy(result, ls->ls_recover_result, old_size * sizeof(uint32_t));
+ kfree(ls->ls_recover_submit);
+ kfree(ls->ls_recover_result);
+ ls->ls_recover_submit = submit;
+ ls->ls_recover_result = result;
+ ls->ls_recover_size = new_size;
+ spin_unlock(&ls->ls_recover_spin);
+ return 0;
+}
+
+static void free_recover_size(struct lm_lockstruct *ls)
+{
+ kfree(ls->ls_recover_submit);
+ kfree(ls->ls_recover_result);
+ ls->ls_recover_submit = NULL;
+ ls->ls_recover_result = NULL;
+ ls->ls_recover_size = 0;
+}
+
+/* dlm calls before it does lock recovery */
+
+static void gdlm_recover_prep(void *arg)
+{
+ struct gfs2_sbd *sdp = arg;
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+
+ spin_lock(&ls->ls_recover_spin);
+ ls->ls_recover_block = ls->ls_recover_start;
+ set_bit(DFL_DLM_RECOVERY, &ls->ls_recover_flags);
+
+ if (!test_bit(DFL_MOUNT_DONE, &ls->ls_recover_flags) ||
+ test_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags)) {
+ spin_unlock(&ls->ls_recover_spin);
+ return;
+ }
+ set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
+ spin_unlock(&ls->ls_recover_spin);
+}
+
+/* dlm calls after recover_prep has been completed on all lockspace members;
+ identifies slot/jid of failed member */
+
+static void gdlm_recover_slot(void *arg, struct dlm_slot *slot)
+{
+ struct gfs2_sbd *sdp = arg;
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ int jid = slot->slot - 1;
+
+ spin_lock(&ls->ls_recover_spin);
+ if (ls->ls_recover_size < jid + 1) {
+ fs_err(sdp, "recover_slot jid %d gen %u short size %d",
+ jid, ls->ls_recover_block, ls->ls_recover_size);
+ spin_unlock(&ls->ls_recover_spin);
+ return;
+ }
+
+ if (ls->ls_recover_submit[jid]) {
+ fs_info(sdp, "recover_slot jid %d gen %u prev %u",
+ jid, ls->ls_recover_block, ls->ls_recover_submit[jid]);
+ }
+ ls->ls_recover_submit[jid] = ls->ls_recover_block;
+ spin_unlock(&ls->ls_recover_spin);
+}
+
+/* dlm calls after recover_slot and after it completes lock recovery */
+
+static void gdlm_recover_done(void *arg, struct dlm_slot *slots, int num_slots,
+ int our_slot, uint32_t generation)
+{
+ struct gfs2_sbd *sdp = arg;
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+
+ /* ensure the ls jid arrays are large enough */
+ set_recover_size(sdp, slots, num_slots);
+
+ spin_lock(&ls->ls_recover_spin);
+ ls->ls_recover_start = generation;
+
+ if (!ls->ls_recover_mount) {
+ ls->ls_recover_mount = generation;
+ ls->ls_jid = our_slot - 1;
+ }
+
+ if (!test_bit(DFL_UNMOUNT, &ls->ls_recover_flags))
+ queue_delayed_work(gfs2_control_wq, &sdp->sd_control_work, 0);
+
+ clear_bit(DFL_DLM_RECOVERY, &ls->ls_recover_flags);
+ smp_mb__after_clear_bit();
+ wake_up_bit(&ls->ls_recover_flags, DFL_DLM_RECOVERY);
+ spin_unlock(&ls->ls_recover_spin);
+}
+
+/* gfs2_recover thread has a journal recovery result */
+
+static void gdlm_recovery_result(struct gfs2_sbd *sdp, unsigned int jid,
+ unsigned int result)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+
+ if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags))
+ return;
+
+ /* don't care about the recovery of own journal during mount */
+ if (jid == ls->ls_jid)
+ return;
+
+ spin_lock(&ls->ls_recover_spin);
+ if (test_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags)) {
+ spin_unlock(&ls->ls_recover_spin);
+ return;
+ }
+ if (ls->ls_recover_size < jid + 1) {
+ fs_err(sdp, "recovery_result jid %d short size %d",
+ jid, ls->ls_recover_size);
+ spin_unlock(&ls->ls_recover_spin);
+ return;
+ }
+
+ fs_info(sdp, "recover jid %d result %s\n", jid,
+ result == LM_RD_GAVEUP ? "busy" : "success");
+
+ ls->ls_recover_result[jid] = result;
+
+ /* GAVEUP means another node is recovering the journal; delay our
+ next attempt to recover it, to give the other node a chance to
+ finish before trying again */
+
+ if (!test_bit(DFL_UNMOUNT, &ls->ls_recover_flags))
+ queue_delayed_work(gfs2_control_wq, &sdp->sd_control_work,
+ result == LM_RD_GAVEUP ? HZ : 0);
+ spin_unlock(&ls->ls_recover_spin);
+}
+
+const struct dlm_lockspace_ops gdlm_lockspace_ops = {
+ .recover_prep = gdlm_recover_prep,
+ .recover_slot = gdlm_recover_slot,
+ .recover_done = gdlm_recover_done,
+};
+
+static int gdlm_mount(struct gfs2_sbd *sdp, const char *table)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ char cluster[GFS2_LOCKNAME_LEN];
+ const char *fsname;
+ uint32_t flags;
+ int error, ops_result;
+
+ /*
+ * initialize everything
+ */
+
+ INIT_DELAYED_WORK(&sdp->sd_control_work, gfs2_control_func);
+ spin_lock_init(&ls->ls_recover_spin);
+ ls->ls_recover_flags = 0;
+ ls->ls_recover_mount = 0;
+ ls->ls_recover_start = 0;
+ ls->ls_recover_block = 0;
+ ls->ls_recover_size = 0;
+ ls->ls_recover_submit = NULL;
+ ls->ls_recover_result = NULL;
+
+ error = set_recover_size(sdp, NULL, 0);
+ if (error)
+ goto fail;
+
+ /*
+ * prepare dlm_new_lockspace args
+ */
+
+ fsname = strchr(table, ':');
+ if (!fsname) {
+ fs_info(sdp, "no fsname found\n");
+ error = -EINVAL;
+ goto fail_free;
+ }
+ memset(cluster, 0, sizeof(cluster));
+ memcpy(cluster, table, strlen(table) - strlen(fsname));
+ fsname++;
+
+ flags = DLM_LSFL_FS | DLM_LSFL_NEWEXCL;
+ if (ls->ls_nodir)
+ flags |= DLM_LSFL_NODIR;
+
+ /*
+ * create/join lockspace
+ */
+
+ error = dlm_new_lockspace(fsname, cluster, flags, GDLM_LVB_SIZE,
+ &gdlm_lockspace_ops, sdp, &ops_result,
+ &ls->ls_dlm);
+ if (error) {
+ fs_err(sdp, "dlm_new_lockspace error %d\n", error);
+ goto fail_free;
+ }
+
+ if (ops_result < 0) {
+ /*
+ * dlm does not support ops callbacks,
+ * old dlm_controld/gfs_controld are used, try without ops.
+ */
+ fs_info(sdp, "dlm lockspace ops not used\n");
+ free_recover_size(ls);
+ set_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags);
+ return 0;
+ }
+
+ if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags)) {
+ fs_err(sdp, "dlm lockspace ops disallow jid preset\n");
+ error = -EINVAL;
+ goto fail_release;
+ }
+
+ /*
+ * control_mount() uses control_lock to determine first mounter,
+ * and for later mounts, waits for any recoveries to be cleared.
+ */
+
+ error = control_mount(sdp);
+ if (error) {
+ fs_err(sdp, "mount control error %d\n", error);
+ goto fail_release;
+ }
+
+ ls->ls_first = !!test_bit(DFL_FIRST_MOUNT, &ls->ls_recover_flags);
+ clear_bit(SDF_NOJOURNALID, &sdp->sd_flags);
+ smp_mb__after_clear_bit();
+ wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
+ return 0;
+
+fail_release:
+ dlm_release_lockspace(ls->ls_dlm, 2);
+fail_free:
+ free_recover_size(ls);
+fail:
+ return error;
+}
+
+static void gdlm_first_done(struct gfs2_sbd *sdp)
+{
+ struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ int error;
+
+ if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags))
+ return;
+
+ error = control_first_done(sdp);
+ if (error)
+ fs_err(sdp, "mount first_done error %d\n", error);
+}
+
static void gdlm_unmount(struct gfs2_sbd *sdp)
{
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+ if (test_bit(DFL_NO_DLM_OPS, &ls->ls_recover_flags))
+ goto release;
+
+ /* wait for gfs2_control_wq to be done with this mount */
+
+ spin_lock(&ls->ls_recover_spin);
+ set_bit(DFL_UNMOUNT, &ls->ls_recover_flags);
+ spin_unlock(&ls->ls_recover_spin);
+ flush_delayed_work_sync(&sdp->sd_control_work);
+
+ /* mounted_lock and control_lock will be purged in dlm recovery */
+release:
if (ls->ls_dlm) {
dlm_release_lockspace(ls->ls_dlm, 2);
ls->ls_dlm = NULL;
}
+
+ free_recover_size(ls);
}
static const match_table_t dlm_tokens = {
@@ -226,6 +1197,8 @@ static const match_table_t dlm_tokens = {
const struct lm_lockops gfs2_dlm_ops = {
.lm_proto_name = "lock_dlm",
.lm_mount = gdlm_mount,
+ .lm_first_done = gdlm_first_done,
+ .lm_recovery_result = gdlm_recovery_result,
.lm_unmount = gdlm_unmount,
.lm_put_lock = gdlm_put_lock,
.lm_lock = gdlm_lock,
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index c150298e2d8e..a8d9bcd0e19c 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -28,6 +28,8 @@
#include "recovery.h"
#include "dir.h"
+struct workqueue_struct *gfs2_control_wq;
+
static struct shrinker qd_shrinker = {
.shrink = gfs2_shrink_qd_memory,
.seeks = DEFAULT_SEEKS,
@@ -146,12 +148,19 @@ static int __init init_gfs2_fs(void)
if (!gfs_recovery_wq)
goto fail_wq;
+ gfs2_control_wq = alloc_workqueue("gfs2_control",
+ WQ_NON_REENTRANT | WQ_UNBOUND | WQ_FREEZABLE, 0);
+ if (!gfs2_control_wq)
+ goto fail_control;
+
gfs2_register_debugfs();
printk("GFS2 installed\n");
return 0;
+fail_control:
+ destroy_workqueue(gfs_recovery_wq);
fail_wq:
unregister_filesystem(&gfs2meta_fs_type);
fail_unregister:
@@ -195,6 +204,7 @@ static void __exit exit_gfs2_fs(void)
unregister_filesystem(&gfs2_fs_type);
unregister_filesystem(&gfs2meta_fs_type);
destroy_workqueue(gfs_recovery_wq);
+ destroy_workqueue(gfs2_control_wq);
rcu_barrier();
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c
index fe72e79e6ff9..6aacf3f230a2 100644
--- a/fs/gfs2/ops_fstype.c
+++ b/fs/gfs2/ops_fstype.c
@@ -562,8 +562,12 @@ static void gfs2_others_may_mount(struct gfs2_sbd *sdp)
{
char *message = "FIRSTMOUNT=Done";
char *envp[] = { message, NULL };
- struct lm_lockstruct *ls = &sdp->sd_lockstruct;
- ls->ls_first_done = 1;
+
+ fs_info(sdp, "first mount done, others may mount\n");
+
+ if (sdp->sd_lockstruct.ls_ops->lm_first_done)
+ sdp->sd_lockstruct.ls_ops->lm_first_done(sdp);
+
kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp);
}
@@ -944,7 +948,6 @@ static int gfs2_lm_mount(struct gfs2_sbd *sdp, int silent)
struct gfs2_args *args = &sdp->sd_args;
const char *proto = sdp->sd_proto_name;
const char *table = sdp->sd_table_name;
- const char *fsname;
char *o, *options;
int ret;
@@ -1004,21 +1007,12 @@ hostdata_error:
}
}
- if (sdp->sd_args.ar_spectator)
- snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s.s", table);
- else
- snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s.%u", table,
- sdp->sd_lockstruct.ls_jid);
-
- fsname = strchr(table, ':');
- if (fsname)
- fsname++;
if (lm->lm_mount == NULL) {
fs_info(sdp, "Now mounting FS...\n");
complete_all(&sdp->sd_locking_init);
return 0;
}
- ret = lm->lm_mount(sdp, fsname);
+ ret = lm->lm_mount(sdp, table);
if (ret == 0)
fs_info(sdp, "Joined cluster. Now mounting FS...\n");
complete_all(&sdp->sd_locking_init);
@@ -1084,7 +1078,7 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
if (sdp->sd_args.ar_spectator) {
sb->s_flags |= MS_RDONLY;
- set_bit(SDF_NORECOVERY, &sdp->sd_flags);
+ set_bit(SDF_RORECOVERY, &sdp->sd_flags);
}
if (sdp->sd_args.ar_posix_acl)
sb->s_flags |= MS_POSIXACL;
@@ -1124,6 +1118,8 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
if (error)
goto fail;
+ snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s", sdp->sd_table_name);
+
gfs2_create_debugfs_file(sdp);
error = gfs2_sys_fs_add(sdp);
@@ -1160,6 +1156,13 @@ static int fill_super(struct super_block *sb, struct gfs2_args *args, int silent
goto fail_sb;
}
+ if (sdp->sd_args.ar_spectator)
+ snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s.s",
+ sdp->sd_table_name);
+ else
+ snprintf(sdp->sd_fsname, GFS2_FSNAME_LEN, "%s.%u",
+ sdp->sd_table_name, sdp->sd_lockstruct.ls_jid);
+
error = init_inodes(sdp, DO);
if (error)
goto fail_sb;
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index f2a02edcac8f..963b2d75200c 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -436,12 +436,16 @@ static void gfs2_recovery_done(struct gfs2_sbd *sdp, unsigned int jid,
char env_status[20];
char *envp[] = { env_jid, env_status, NULL };
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
+
ls->ls_recover_jid_done = jid;
ls->ls_recover_jid_status = message;
sprintf(env_jid, "JID=%d", jid);
sprintf(env_status, "RECOVERY=%s",
message == LM_RD_SUCCESS ? "Done" : "Failed");
kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp);
+
+ if (sdp->sd_lockstruct.ls_ops->lm_recovery_result)
+ sdp->sd_lockstruct.ls_ops->lm_recovery_result(sdp, jid, message);
}
void gfs2_recover_func(struct work_struct *work)
@@ -512,7 +516,9 @@ void gfs2_recover_func(struct work_struct *work)
if (error)
goto fail_gunlock_ji;
- if (test_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags)) {
+ if (test_bit(SDF_RORECOVERY, &sdp->sd_flags)) {
+ ro = 1;
+ } else if (test_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags)) {
if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
ro = 1;
} else {
@@ -577,6 +583,7 @@ fail_gunlock_j:
fs_info(sdp, "jid=%u: %s\n", jd->jd_jid, (error) ? "Failed" : "Done");
fail:
+ jd->jd_recover_error = error;
gfs2_recovery_done(sdp, jd->jd_jid, LM_RD_GAVEUP);
done:
clear_bit(JDF_RECOVERY, &jd->jd_flags);
@@ -605,6 +612,6 @@ int gfs2_recover_journal(struct gfs2_jdesc *jd, bool wait)
wait_on_bit(&jd->jd_flags, JDF_RECOVERY, gfs2_recovery_wait,
TASK_UNINTERRUPTIBLE);
- return 0;
+ return wait ? jd->jd_recover_error : 0;
}
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 22234627f684..981bfa32121a 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -1108,9 +1108,9 @@ void gfs2_inplace_release(struct gfs2_inode *ip)
{
struct gfs2_blkreserv *rs = ip->i_res;
- gfs2_blkrsv_put(ip);
if (rs->rs_rgd_gh.gh_gl)
gfs2_glock_dq_uninit(&rs->rs_rgd_gh);
+ gfs2_blkrsv_put(ip);
}
/**
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c
index 443cabcfcd23..d33172c291ba 100644
--- a/fs/gfs2/sys.c
+++ b/fs/gfs2/sys.c
@@ -298,7 +298,7 @@ static ssize_t block_show(struct gfs2_sbd *sdp, char *buf)
ssize_t ret;
int val = 0;
- if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_flags))
+ if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))
val = 1;
ret = sprintf(buf, "%d\n", val);
return ret;
@@ -313,9 +313,9 @@ static ssize_t block_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
val = simple_strtol(buf, NULL, 0);
if (val == 1)
- set_bit(DFL_BLOCK_LOCKS, &ls->ls_flags);
+ set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
else if (val == 0) {
- clear_bit(DFL_BLOCK_LOCKS, &ls->ls_flags);
+ clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
smp_mb__after_clear_bit();
gfs2_glock_thaw(sdp);
} else {
@@ -350,8 +350,8 @@ static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
goto out;
if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
goto out;
- sdp->sd_lockstruct.ls_first = first;
- rv = 0;
+ sdp->sd_lockstruct.ls_first = first;
+ rv = 0;
out:
spin_unlock(&sdp->sd_jindex_spin);
return rv ? rv : len;
@@ -360,19 +360,14 @@ out:
static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
{
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
- return sprintf(buf, "%d\n", ls->ls_first_done);
+ return sprintf(buf, "%d\n", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags));
}
-static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
+int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid)
{
- unsigned jid;
struct gfs2_jdesc *jd;
int rv;
- rv = sscanf(buf, "%u", &jid);
- if (rv != 1)
- return -EINVAL;
-
rv = -ESHUTDOWN;
spin_lock(&sdp->sd_jindex_spin);
if (test_bit(SDF_NORECOVERY, &sdp->sd_flags))
@@ -389,6 +384,20 @@ static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
}
out:
spin_unlock(&sdp->sd_jindex_spin);
+ return rv;
+}
+
+static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
+{
+ unsigned jid;
+ int rv;
+
+ rv = sscanf(buf, "%u", &jid);
+ if (rv != 1)
+ return -EINVAL;
+
+ rv = gfs2_recover_set(sdp, jid);
+
return rv ? rv : len;
}
diff --git a/fs/gfs2/sys.h b/fs/gfs2/sys.h
index e94560e836d7..79182d6ad6ac 100644
--- a/fs/gfs2/sys.h
+++ b/fs/gfs2/sys.h
@@ -19,5 +19,7 @@ void gfs2_sys_fs_del(struct gfs2_sbd *sdp);
int gfs2_sys_init(void);
void gfs2_sys_uninit(void);
+int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid);
+
#endif /* __SYS_DOT_H__ */
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c
index 23d7451b2938..65ba36b80a9e 100644
--- a/fs/lockd/mon.c
+++ b/fs/lockd/mon.c
@@ -55,7 +55,7 @@ static DEFINE_SPINLOCK(nsm_lock);
* Local NSM state
*/
u32 __read_mostly nsm_local_state;
-int __read_mostly nsm_use_hostnames;
+bool __read_mostly nsm_use_hostnames;
static inline struct sockaddr *nsm_addr(const struct nsm_handle *nsm)
{
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 277dfaf2e99a..31778f74357d 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -84,7 +84,7 @@ retry:
/*
* Turn off NFSv4 uid/gid mapping when using AUTH_SYS
*/
-static int nfs4_disable_idmapping = 1;
+static bool nfs4_disable_idmapping = true;
/*
* RPC cruft for NFS
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 25c3bfad7953..f649fba8c384 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -57,7 +57,7 @@
#define NFS_64_BIT_INODE_NUMBERS_ENABLED 1
/* Default is to see 64-bit inode numbers */
-static int enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;
+static bool enable_ino64 = NFS_64_BIT_INODE_NUMBERS_ENABLED;
static void nfs_invalidate_inode(struct inode *);
static int nfs_update_inode(struct inode *, struct nfs_fattr *);
diff --git a/fs/nfsd/Kconfig b/fs/nfsd/Kconfig
index 10e6366608f2..8df1ea4a6ff9 100644
--- a/fs/nfsd/Kconfig
+++ b/fs/nfsd/Kconfig
@@ -80,3 +80,13 @@ config NFSD_V4
available from http://linux-nfs.org/.
If unsure, say N.
+
+config NFSD_FAULT_INJECTION
+ bool "NFS server manual fault injection"
+ depends on NFSD_V4 && DEBUG_KERNEL
+ help
+ This option enables support for manually injecting faults
+ into the NFS server. This is intended to be used for
+ testing error recovery on the NFS client.
+
+ If unsure, say N.
diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile
index 9b118ee20193..af32ef06b4fe 100644
--- a/fs/nfsd/Makefile
+++ b/fs/nfsd/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_NFSD) += nfsd.o
nfsd-y := nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \
export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o
+nfsd-$(CONFIG_NFSD_FAULT_INJECTION) += fault_inject.o
nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o
nfsd-$(CONFIG_NFSD_V3) += nfs3proc.o nfs3xdr.o
nfsd-$(CONFIG_NFSD_V3_ACL) += nfs3acl.o
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 62f3b9074e84..cf8a6bd062fa 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -87,7 +87,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
struct svc_expkey key;
struct svc_expkey *ek = NULL;
- if (mesg[mlen-1] != '\n')
+ if (mlen < 1 || mesg[mlen-1] != '\n')
return -EINVAL;
mesg[mlen-1] = 0;
@@ -1226,12 +1226,12 @@ nfsd_export_init(void)
int rv;
dprintk("nfsd: initializing export module.\n");
- rv = cache_register(&svc_export_cache);
+ rv = cache_register_net(&svc_export_cache, &init_net);
if (rv)
return rv;
- rv = cache_register(&svc_expkey_cache);
+ rv = cache_register_net(&svc_expkey_cache, &init_net);
if (rv)
- cache_unregister(&svc_export_cache);
+ cache_unregister_net(&svc_export_cache, &init_net);
return rv;
}
@@ -1255,8 +1255,8 @@ nfsd_export_shutdown(void)
dprintk("nfsd: shutting down export module.\n");
- cache_unregister(&svc_expkey_cache);
- cache_unregister(&svc_export_cache);
+ cache_unregister_net(&svc_expkey_cache, &init_net);
+ cache_unregister_net(&svc_export_cache, &init_net);
svcauth_unix_purge();
dprintk("nfsd: export shutdown complete.\n");
diff --git a/fs/nfsd/fault_inject.c b/fs/nfsd/fault_inject.c
new file mode 100644
index 000000000000..ce7f0758d84c
--- /dev/null
+++ b/fs/nfsd/fault_inject.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2011 Bryan Schumaker <bjschuma@netapp.com>
+ *
+ * Uses debugfs to create fault injection points for client testing
+ */
+
+#include <linux/types.h>
+#include <linux/fs.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+
+#include "state.h"
+#include "fault_inject.h"
+
+struct nfsd_fault_inject_op {
+ char *file;
+ void (*func)(u64);
+};
+
+static struct nfsd_fault_inject_op inject_ops[] = {
+ {
+ .file = "forget_clients",
+ .func = nfsd_forget_clients,
+ },
+ {
+ .file = "forget_locks",
+ .func = nfsd_forget_locks,
+ },
+ {
+ .file = "forget_openowners",
+ .func = nfsd_forget_openowners,
+ },
+ {
+ .file = "forget_delegations",
+ .func = nfsd_forget_delegations,
+ },
+ {
+ .file = "recall_delegations",
+ .func = nfsd_recall_delegations,
+ },
+};
+
+static long int NUM_INJECT_OPS = sizeof(inject_ops) / sizeof(struct nfsd_fault_inject_op);
+static struct dentry *debug_dir;
+
+static int nfsd_inject_set(void *op_ptr, u64 val)
+{
+ struct nfsd_fault_inject_op *op = op_ptr;
+
+ if (val == 0)
+ printk(KERN_INFO "NFSD Fault Injection: %s (all)", op->file);
+ else
+ printk(KERN_INFO "NFSD Fault Injection: %s (n = %llu)", op->file, val);
+
+ op->func(val);
+ return 0;
+}
+
+static int nfsd_inject_get(void *data, u64 *val)
+{
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(fops_nfsd, nfsd_inject_get, nfsd_inject_set, "%llu\n");
+
+void nfsd_fault_inject_cleanup(void)
+{
+ debugfs_remove_recursive(debug_dir);
+}
+
+int nfsd_fault_inject_init(void)
+{
+ unsigned int i;
+ struct nfsd_fault_inject_op *op;
+ mode_t mode = S_IFREG | S_IRUSR | S_IWUSR;
+
+ debug_dir = debugfs_create_dir("nfsd", NULL);
+ if (!debug_dir)
+ goto fail;
+
+ for (i = 0; i < NUM_INJECT_OPS; i++) {
+ op = &inject_ops[i];
+ if (!debugfs_create_file(op->file, mode, debug_dir, op, &fops_nfsd))
+ goto fail;
+ }
+ return 0;
+
+fail:
+ nfsd_fault_inject_cleanup();
+ return -ENOMEM;
+}
diff --git a/fs/nfsd/fault_inject.h b/fs/nfsd/fault_inject.h
new file mode 100644
index 000000000000..90bd0570956c
--- /dev/null
+++ b/fs/nfsd/fault_inject.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011 Bryan Schumaker <bjschuma@netapp.com>
+ *
+ * Function definitions for fault injection
+ */
+
+#ifndef LINUX_NFSD_FAULT_INJECT_H
+#define LINUX_NFSD_FAULT_INJECT_H
+
+#ifdef CONFIG_NFSD_FAULT_INJECTION
+int nfsd_fault_inject_init(void);
+void nfsd_fault_inject_cleanup(void);
+void nfsd_forget_clients(u64);
+void nfsd_forget_locks(u64);
+void nfsd_forget_openowners(u64);
+void nfsd_forget_delegations(u64);
+void nfsd_recall_delegations(u64);
+#else /* CONFIG_NFSD_FAULT_INJECTION */
+static inline int nfsd_fault_inject_init(void) { return 0; }
+static inline void nfsd_fault_inject_cleanup(void) {}
+static inline void nfsd_forget_clients(u64 num) {}
+static inline void nfsd_forget_locks(u64 num) {}
+static inline void nfsd_forget_openowners(u64 num) {}
+static inline void nfsd_forget_delegations(u64 num) {}
+static inline void nfsd_recall_delegations(u64 num) {}
+#endif /* CONFIG_NFSD_FAULT_INJECTION */
+
+#endif /* LINUX_NFSD_FAULT_INJECT_H */
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 55780a22fdbd..94096273cd6c 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -36,6 +36,7 @@
#include <linux/seq_file.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <net/net_namespace.h>
#include "idmap.h"
#include "nfsd.h"
@@ -466,20 +467,20 @@ nfsd_idmap_init(void)
{
int rv;
- rv = cache_register(&idtoname_cache);
+ rv = cache_register_net(&idtoname_cache, &init_net);
if (rv)
return rv;
- rv = cache_register(&nametoid_cache);
+ rv = cache_register_net(&nametoid_cache, &init_net);
if (rv)
- cache_unregister(&idtoname_cache);
+ cache_unregister_net(&idtoname_cache, &init_net);
return rv;
}
void
nfsd_idmap_shutdown(void)
{
- cache_unregister(&idtoname_cache);
- cache_unregister(&nametoid_cache);
+ cache_unregister_net(&idtoname_cache, &init_net);
+ cache_unregister_net(&nametoid_cache, &init_net);
}
static int
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index c5e28ed8bca0..896da74ec563 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -266,10 +266,6 @@ do_open_fhandle(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_
{
__be32 status;
- /* Only reclaims from previously confirmed clients are valid */
- if ((status = nfs4_check_open_reclaim(&open->op_clientid)))
- return status;
-
/* We don't know the target directory, and therefore can not
* set the change info
*/
@@ -373,6 +369,9 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
break;
case NFS4_OPEN_CLAIM_PREVIOUS:
open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED;
+ status = nfs4_check_open_reclaim(&open->op_clientid);
+ if (status)
+ goto out;
case NFS4_OPEN_CLAIM_FH:
case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
status = do_open_fhandle(rqstp, &cstate->current_fh,
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 80a0be9ed008..0b3e875d1abd 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -117,8 +117,7 @@ out_no_tfm:
return status;
}
-int
-nfsd4_create_clid_dir(struct nfs4_client *clp)
+void nfsd4_create_clid_dir(struct nfs4_client *clp)
{
const struct cred *original_cred;
char *dname = clp->cl_recdir;
@@ -127,13 +126,14 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
dprintk("NFSD: nfsd4_create_clid_dir for \"%s\"\n", dname);
- if (!rec_file || clp->cl_firststate)
- return 0;
-
+ if (clp->cl_firststate)
+ return;
clp->cl_firststate = 1;
+ if (!rec_file)
+ return;
status = nfs4_save_creds(&original_cred);
if (status < 0)
- return status;
+ return;
dir = rec_file->f_path.dentry;
/* lock the parent */
@@ -144,8 +144,15 @@ nfsd4_create_clid_dir(struct nfs4_client *clp)
status = PTR_ERR(dentry);
goto out_unlock;
}
- status = -EEXIST;
if (dentry->d_inode)
+ /*
+ * In the 4.1 case, where we're called from
+ * reclaim_complete(), records from the previous reboot
+ * may still be left, so this is OK.
+ *
+ * In the 4.0 case, we should never get here; but we may
+ * as well be forgiving and just succeed silently.
+ */
goto out_put;
status = mnt_want_write_file(rec_file);
if (status)
@@ -164,7 +171,6 @@ out_unlock:
" and is writeable", status,
user_recovery_dirname);
nfs4_reset_creds(original_cred);
- return status;
}
typedef int (recdir_func)(struct dentry *, struct dentry *);
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9ca16dc09e04..e8c98f009670 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -49,12 +49,20 @@
time_t nfsd4_lease = 90; /* default lease time */
time_t nfsd4_grace = 90;
static time_t boot_time;
-static stateid_t zerostateid; /* bits all 0 */
-static stateid_t onestateid; /* bits all 1 */
+
+#define all_ones {{~0,~0},~0}
+static const stateid_t one_stateid = {
+ .si_generation = ~0,
+ .si_opaque = all_ones,
+};
+static const stateid_t zero_stateid = {
+ /* all fields zero */
+};
+
static u64 current_sessionid = 1;
-#define ZERO_STATEID(stateid) (!memcmp((stateid), &zerostateid, sizeof(stateid_t)))
-#define ONE_STATEID(stateid) (!memcmp((stateid), &onestateid, sizeof(stateid_t)))
+#define ZERO_STATEID(stateid) (!memcmp((stateid), &zero_stateid, sizeof(stateid_t)))
+#define ONE_STATEID(stateid) (!memcmp((stateid), &one_stateid, sizeof(stateid_t)))
/* forward declarations */
static int check_for_locks(struct nfs4_file *filp, struct nfs4_lockowner *lowner);
@@ -133,21 +141,21 @@ unsigned int max_delegations;
* Open owner state (share locks)
*/
-/* hash tables for open owners */
-#define OPEN_OWNER_HASH_BITS 8
-#define OPEN_OWNER_HASH_SIZE (1 << OPEN_OWNER_HASH_BITS)
-#define OPEN_OWNER_HASH_MASK (OPEN_OWNER_HASH_SIZE - 1)
+/* hash tables for lock and open owners */
+#define OWNER_HASH_BITS 8
+#define OWNER_HASH_SIZE (1 << OWNER_HASH_BITS)
+#define OWNER_HASH_MASK (OWNER_HASH_SIZE - 1)
-static unsigned int open_ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername)
+static unsigned int ownerstr_hashval(u32 clientid, struct xdr_netobj *ownername)
{
unsigned int ret;
ret = opaque_hashval(ownername->data, ownername->len);
ret += clientid;
- return ret & OPEN_OWNER_HASH_MASK;
+ return ret & OWNER_HASH_MASK;
}
-static struct list_head open_ownerstr_hashtbl[OPEN_OWNER_HASH_SIZE];
+static struct list_head ownerstr_hashtbl[OWNER_HASH_SIZE];
/* hash table for nfs4_file */
#define FILE_HASH_BITS 8
@@ -514,6 +522,7 @@ static void unhash_lockowner(struct nfs4_lockowner *lo)
list_del(&lo->lo_owner.so_strhash);
list_del(&lo->lo_perstateid);
+ list_del(&lo->lo_owner_ino_hash);
while (!list_empty(&lo->lo_owner.so_stateids)) {
stp = list_first_entry(&lo->lo_owner.so_stateids,
struct nfs4_ol_stateid, st_perstateowner);
@@ -985,12 +994,11 @@ static struct nfs4_client *alloc_client(struct xdr_netobj name)
clp = kzalloc(sizeof(struct nfs4_client), GFP_KERNEL);
if (clp == NULL)
return NULL;
- clp->cl_name.data = kmalloc(name.len, GFP_KERNEL);
+ clp->cl_name.data = kmemdup(name.data, name.len, GFP_KERNEL);
if (clp->cl_name.data == NULL) {
kfree(clp);
return NULL;
}
- memcpy(clp->cl_name.data, name.data, name.len);
clp->cl_name.len = name.len;
return clp;
}
@@ -1058,7 +1066,6 @@ expire_client(struct nfs4_client *clp)
spin_unlock(&recall_lock);
while (!list_empty(&reaplist)) {
dp = list_entry(reaplist.next, struct nfs4_delegation, dl_recall_lru);
- list_del_init(&dp->dl_recall_lru);
unhash_delegation(dp);
}
while (!list_empty(&clp->cl_openowners)) {
@@ -2301,7 +2308,7 @@ nfsd4_free_slabs(void)
nfsd4_free_slab(&deleg_slab);
}
-static int
+int
nfsd4_init_slabs(void)
{
openowner_slab = kmem_cache_create("nfsd4_openowners",
@@ -2373,7 +2380,7 @@ static inline void *alloc_stateowner(struct kmem_cache *slab, struct xdr_netobj
static void hash_openowner(struct nfs4_openowner *oo, struct nfs4_client *clp, unsigned int strhashval)
{
- list_add(&oo->oo_owner.so_strhash, &open_ownerstr_hashtbl[strhashval]);
+ list_add(&oo->oo_owner.so_strhash, &ownerstr_hashtbl[strhashval]);
list_add(&oo->oo_perclient, &clp->cl_openowners);
}
@@ -2436,7 +2443,9 @@ find_openstateowner_str(unsigned int hashval, struct nfsd4_open *open)
struct nfs4_stateowner *so;
struct nfs4_openowner *oo;
- list_for_each_entry(so, &open_ownerstr_hashtbl[hashval], so_strhash) {
+ list_for_each_entry(so, &ownerstr_hashtbl[hashval], so_strhash) {
+ if (!so->so_is_open_owner)
+ continue;
if (same_owner_str(so, &open->op_owner, &open->op_clientid)) {
oo = openowner(so);
renew_client(oo->oo_owner.so_client);
@@ -2580,7 +2589,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
if (open->op_file == NULL)
return nfserr_jukebox;
- strhashval = open_ownerstr_hashval(clientid->cl_id, &open->op_owner);
+ strhashval = ownerstr_hashval(clientid->cl_id, &open->op_owner);
oo = find_openstateowner_str(strhashval, open);
open->op_openowner = oo;
if (!oo) {
@@ -3123,7 +3132,6 @@ nfs4_laundromat(void)
spin_unlock(&recall_lock);
list_for_each_safe(pos, next, &reaplist) {
dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
- list_del_init(&dp->dl_recall_lru);
unhash_delegation(dp);
}
test_val = nfsd4_lease;
@@ -3718,13 +3726,11 @@ out:
}
-/*
- * Lock owner state (byte-range locks)
- */
#define LOFF_OVERFLOW(start, len) ((u64)(len) > ~(u64)(start))
-#define LOCK_HASH_BITS 8
-#define LOCK_HASH_SIZE (1 << LOCK_HASH_BITS)
-#define LOCK_HASH_MASK (LOCK_HASH_SIZE - 1)
+
+#define LOCKOWNER_INO_HASH_BITS 8
+#define LOCKOWNER_INO_HASH_SIZE (1 << LOCKOWNER_INO_HASH_BITS)
+#define LOCKOWNER_INO_HASH_MASK (LOCKOWNER_INO_HASH_SIZE - 1)
static inline u64
end_offset(u64 start, u64 len)
@@ -3746,16 +3752,14 @@ last_byte_offset(u64 start, u64 len)
return end > start ? end - 1: NFS4_MAX_UINT64;
}
-static inline unsigned int
-lock_ownerstr_hashval(struct inode *inode, u32 cl_id,
- struct xdr_netobj *ownername)
+static unsigned int lockowner_ino_hashval(struct inode *inode, u32 cl_id, struct xdr_netobj *ownername)
{
return (file_hashval(inode) + cl_id
+ opaque_hashval(ownername->data, ownername->len))
- & LOCK_HASH_MASK;
+ & LOCKOWNER_INO_HASH_MASK;
}
-static struct list_head lock_ownerstr_hashtbl[LOCK_HASH_SIZE];
+static struct list_head lockowner_ino_hashtbl[LOCKOWNER_INO_HASH_SIZE];
/*
* TODO: Linux file offsets are _signed_ 64-bit quantities, which means that
@@ -3809,23 +3813,39 @@ nevermind:
deny->ld_type = NFS4_WRITE_LT;
}
+static bool same_lockowner_ino(struct nfs4_lockowner *lo, struct inode *inode, clientid_t *clid, struct xdr_netobj *owner)
+{
+ struct nfs4_ol_stateid *lst;
+
+ if (!same_owner_str(&lo->lo_owner, owner, clid))
+ return false;
+ lst = list_first_entry(&lo->lo_owner.so_stateids,
+ struct nfs4_ol_stateid, st_perstateowner);
+ return lst->st_file->fi_inode == inode;
+}
+
static struct nfs4_lockowner *
find_lockowner_str(struct inode *inode, clientid_t *clid,
struct xdr_netobj *owner)
{
- unsigned int hashval = lock_ownerstr_hashval(inode, clid->cl_id, owner);
- struct nfs4_stateowner *op;
+ unsigned int hashval = lockowner_ino_hashval(inode, clid->cl_id, owner);
+ struct nfs4_lockowner *lo;
- list_for_each_entry(op, &lock_ownerstr_hashtbl[hashval], so_strhash) {
- if (same_owner_str(op, owner, clid))
- return lockowner(op);
+ list_for_each_entry(lo, &lockowner_ino_hashtbl[hashval], lo_owner_ino_hash) {
+ if (same_lockowner_ino(lo, inode, clid, owner))
+ return lo;
}
return NULL;
}
static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, struct nfs4_client *clp, struct nfs4_ol_stateid *open_stp)
{
- list_add(&lo->lo_owner.so_strhash, &lock_ownerstr_hashtbl[strhashval]);
+ struct inode *inode = open_stp->st_file->fi_inode;
+ unsigned int inohash = lockowner_ino_hashval(inode,
+ clp->cl_clientid.cl_id, &lo->lo_owner.so_owner);
+
+ list_add(&lo->lo_owner.so_strhash, &ownerstr_hashtbl[strhashval]);
+ list_add(&lo->lo_owner_ino_hash, &lockowner_ino_hashtbl[inohash]);
list_add(&lo->lo_perstateid, &open_stp->st_lockowners);
}
@@ -3834,7 +3854,7 @@ static void hash_lockowner(struct nfs4_lockowner *lo, unsigned int strhashval, s
* Called in nfsd4_lock - therefore, OPEN and OPEN_CONFIRM (if needed) has
* occurred.
*
- * strhashval = lock_ownerstr_hashval
+ * strhashval = ownerstr_hashval
*/
static struct nfs4_lockowner *
@@ -3892,6 +3912,37 @@ static void get_lock_access(struct nfs4_ol_stateid *lock_stp, u32 access)
__set_bit(access, &lock_stp->st_access_bmap);
}
+__be32 lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, struct nfs4_ol_stateid *ost, struct nfsd4_lock *lock, struct nfs4_ol_stateid **lst, bool *new)
+{
+ struct nfs4_file *fi = ost->st_file;
+ struct nfs4_openowner *oo = openowner(ost->st_stateowner);
+ struct nfs4_client *cl = oo->oo_owner.so_client;
+ struct nfs4_lockowner *lo;
+ unsigned int strhashval;
+
+ lo = find_lockowner_str(fi->fi_inode, &cl->cl_clientid, &lock->v.new.owner);
+ if (lo) {
+ if (!cstate->minorversion)
+ return nfserr_bad_seqid;
+ /* XXX: a lockowner always has exactly one stateid: */
+ *lst = list_first_entry(&lo->lo_owner.so_stateids,
+ struct nfs4_ol_stateid, st_perstateowner);
+ return nfs_ok;
+ }
+ strhashval = ownerstr_hashval(cl->cl_clientid.cl_id,
+ &lock->v.new.owner);
+ lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock);
+ if (lo == NULL)
+ return nfserr_jukebox;
+ *lst = alloc_init_lock_stateid(lo, fi, ost);
+ if (*lst == NULL) {
+ release_lockowner(lo);
+ return nfserr_jukebox;
+ }
+ *new = true;
+ return nfs_ok;
+}
+
/*
* LOCK operation
*/
@@ -3907,7 +3958,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
struct file_lock file_lock;
struct file_lock conflock;
__be32 status = 0;
- unsigned int strhashval;
+ bool new_state = false;
int lkflg;
int err;
@@ -3933,10 +3984,15 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
* lock stateid.
*/
struct nfs4_ol_stateid *open_stp = NULL;
-
+
+ if (nfsd4_has_session(cstate))
+ /* See rfc 5661 18.10.3: given clientid is ignored: */
+ memcpy(&lock->v.new.clientid,
+ &cstate->session->se_client->cl_clientid,
+ sizeof(clientid_t));
+
status = nfserr_stale_clientid;
- if (!nfsd4_has_session(cstate) &&
- STALE_CLIENTID(&lock->lk_new_clientid))
+ if (STALE_CLIENTID(&lock->lk_new_clientid))
goto out;
/* validate and update open stateid and open seqid */
@@ -3948,25 +4004,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
goto out;
open_sop = openowner(open_stp->st_stateowner);
status = nfserr_bad_stateid;
- if (!nfsd4_has_session(cstate) &&
- !same_clid(&open_sop->oo_owner.so_client->cl_clientid,
+ if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
&lock->v.new.clientid))
goto out;
- /* create lockowner and lock stateid */
- fp = open_stp->st_file;
- strhashval = lock_ownerstr_hashval(fp->fi_inode,
- open_sop->oo_owner.so_client->cl_clientid.cl_id,
- &lock->v.new.owner);
- /* XXX: Do we need to check for duplicate stateowners on
- * the same file, or should they just be allowed (and
- * create new stateids)? */
- status = nfserr_jukebox;
- lock_sop = alloc_init_lock_stateowner(strhashval,
- open_sop->oo_owner.so_client, open_stp, lock);
- if (lock_sop == NULL)
- goto out;
- lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
- if (lock_stp == NULL)
+ status = lookup_or_create_lock_state(cstate, open_stp, lock,
+ &lock_stp, &new_state);
+ if (status)
goto out;
} else {
/* lock (lock owner + lock stateid) already exists */
@@ -3976,10 +4019,9 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
NFS4_LOCK_STID, &lock_stp);
if (status)
goto out;
- lock_sop = lockowner(lock_stp->st_stateowner);
- fp = lock_stp->st_file;
}
- /* lock_sop and lock_stp have been created or found */
+ lock_sop = lockowner(lock_stp->st_stateowner);
+ fp = lock_stp->st_file;
lkflg = setlkflg(lock->lk_type);
status = nfs4_check_openmode(lock_stp, lkflg);
@@ -4054,7 +4096,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
break;
}
out:
- if (status && lock->lk_is_new && lock_sop)
+ if (status && new_state)
release_lockowner(lock_sop);
if (!cstate->replay_owner)
nfs4_unlock_state();
@@ -4251,7 +4293,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
struct nfs4_ol_stateid *stp;
struct xdr_netobj *owner = &rlockowner->rl_owner;
struct list_head matches;
- int i;
+ unsigned int hashval = ownerstr_hashval(clid->cl_id, owner);
__be32 status;
dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
@@ -4266,22 +4308,19 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
nfs4_lock_state();
status = nfserr_locks_held;
- /* XXX: we're doing a linear search through all the lockowners.
- * Yipes! For now we'll just hope clients aren't really using
- * release_lockowner much, but eventually we have to fix these
- * data structures. */
INIT_LIST_HEAD(&matches);
- for (i = 0; i < LOCK_HASH_SIZE; i++) {
- list_for_each_entry(sop, &lock_ownerstr_hashtbl[i], so_strhash) {
- if (!same_owner_str(sop, owner, clid))
- continue;
- list_for_each_entry(stp, &sop->so_stateids,
- st_perstateowner) {
- lo = lockowner(sop);
- if (check_for_locks(stp->st_file, lo))
- goto out;
- list_add(&lo->lo_list, &matches);
- }
+
+ list_for_each_entry(sop, &ownerstr_hashtbl[hashval], so_strhash) {
+ if (sop->so_is_open_owner)
+ continue;
+ if (!same_owner_str(sop, owner, clid))
+ continue;
+ list_for_each_entry(stp, &sop->so_stateids,
+ st_perstateowner) {
+ lo = lockowner(sop);
+ if (check_for_locks(stp->st_file, lo))
+ goto out;
+ list_add(&lo->lo_list, &matches);
}
}
/* Clients probably won't expect us to return with some (but not all)
@@ -4394,16 +4433,127 @@ nfs4_check_open_reclaim(clientid_t *clid)
return nfs4_find_reclaim_client(clid) ? nfs_ok : nfserr_reclaim_bad;
}
+#ifdef CONFIG_NFSD_FAULT_INJECTION
+
+void nfsd_forget_clients(u64 num)
+{
+ struct nfs4_client *clp, *next;
+ int count = 0;
+
+ nfs4_lock_state();
+ list_for_each_entry_safe(clp, next, &client_lru, cl_lru) {
+ nfsd4_remove_clid_dir(clp);
+ expire_client(clp);
+ if (++count == num)
+ break;
+ }
+ nfs4_unlock_state();
+
+ printk(KERN_INFO "NFSD: Forgot %d clients", count);
+}
+
+static void release_lockowner_sop(struct nfs4_stateowner *sop)
+{
+ release_lockowner(lockowner(sop));
+}
+
+static void release_openowner_sop(struct nfs4_stateowner *sop)
+{
+ release_openowner(openowner(sop));
+}
+
+static int nfsd_release_n_owners(u64 num, bool is_open_owner,
+ void (*release_sop)(struct nfs4_stateowner *))
+{
+ int i, count = 0;
+ struct nfs4_stateowner *sop, *next;
+
+ for (i = 0; i < OWNER_HASH_SIZE; i++) {
+ list_for_each_entry_safe(sop, next, &ownerstr_hashtbl[i], so_strhash) {
+ if (sop->so_is_open_owner != is_open_owner)
+ continue;
+ release_sop(sop);
+ if (++count == num)
+ return count;
+ }
+ }
+ return count;
+}
+
+void nfsd_forget_locks(u64 num)
+{
+ int count;
+
+ nfs4_lock_state();
+ count = nfsd_release_n_owners(num, false, release_lockowner_sop);
+ nfs4_unlock_state();
+
+ printk(KERN_INFO "NFSD: Forgot %d locks", count);
+}
+
+void nfsd_forget_openowners(u64 num)
+{
+ int count;
+
+ nfs4_lock_state();
+ count = nfsd_release_n_owners(num, true, release_openowner_sop);
+ nfs4_unlock_state();
+
+ printk(KERN_INFO "NFSD: Forgot %d open owners", count);
+}
+
+int nfsd_process_n_delegations(u64 num, void (*deleg_func)(struct nfs4_delegation *))
+{
+ int i, count = 0;
+ struct nfs4_file *fp, *fnext;
+ struct nfs4_delegation *dp, *dnext;
+
+ for (i = 0; i < FILE_HASH_SIZE; i++) {
+ list_for_each_entry_safe(fp, fnext, &file_hashtbl[i], fi_hash) {
+ list_for_each_entry_safe(dp, dnext, &fp->fi_delegations, dl_perfile) {
+ deleg_func(dp);
+ if (++count == num)
+ return count;
+ }
+ }
+ }
+
+ return count;
+}
+
+void nfsd_forget_delegations(u64 num)
+{
+ unsigned int count;
+
+ nfs4_lock_state();
+ count = nfsd_process_n_delegations(num, unhash_delegation);
+ nfs4_unlock_state();
+
+ printk(KERN_INFO "NFSD: Forgot %d delegations", count);
+}
+
+void nfsd_recall_delegations(u64 num)
+{
+ unsigned int count;
+
+ nfs4_lock_state();
+ spin_lock(&recall_lock);
+ count = nfsd_process_n_delegations(num, nfsd_break_one_deleg);
+ spin_unlock(&recall_lock);
+ nfs4_unlock_state();
+
+ printk(KERN_INFO "NFSD: Recalled %d delegations", count);
+}
+
+#endif /* CONFIG_NFSD_FAULT_INJECTION */
+
/* initialization to perform at module load time: */
-int
+void
nfs4_state_init(void)
{
- int i, status;
+ int i;
- status = nfsd4_init_slabs();
- if (status)
- return status;
for (i = 0; i < CLIENT_HASH_SIZE; i++) {
INIT_LIST_HEAD(&conf_id_hashtbl[i]);
INIT_LIST_HEAD(&conf_str_hashtbl[i]);
@@ -4416,18 +4566,15 @@ nfs4_state_init(void)
for (i = 0; i < FILE_HASH_SIZE; i++) {
INIT_LIST_HEAD(&file_hashtbl[i]);
}
- for (i = 0; i < OPEN_OWNER_HASH_SIZE; i++) {
- INIT_LIST_HEAD(&open_ownerstr_hashtbl[i]);
- }
- for (i = 0; i < LOCK_HASH_SIZE; i++) {
- INIT_LIST_HEAD(&lock_ownerstr_hashtbl[i]);
+ for (i = 0; i < OWNER_HASH_SIZE; i++) {
+ INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
}
- memset(&onestateid, ~0, sizeof(stateid_t));
+ for (i = 0; i < LOCKOWNER_INO_HASH_SIZE; i++)
+ INIT_LIST_HEAD(&lockowner_ino_hashtbl[i]);
INIT_LIST_HEAD(&close_lru);
INIT_LIST_HEAD(&client_lru);
INIT_LIST_HEAD(&del_recall_lru);
reclaim_str_hashtbl_size = 0;
- return 0;
}
static void
@@ -4526,7 +4673,6 @@ __nfs4_state_shutdown(void)
spin_unlock(&recall_lock);
list_for_each_safe(pos, next, &reaplist) {
dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
- list_del_init(&dp->dl_recall_lru);
unhash_delegation(dp);
}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index b6fa792d6b85..0ec5a1b9700e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -215,10 +215,9 @@ defer_free(struct nfsd4_compoundargs *argp,
static char *savemem(struct nfsd4_compoundargs *argp, __be32 *p, int nbytes)
{
if (p == argp->tmp) {
- p = kmalloc(nbytes, GFP_KERNEL);
+ p = kmemdup(argp->tmp, nbytes, GFP_KERNEL);
if (!p)
return NULL;
- memcpy(p, argp->tmp, nbytes);
} else {
BUG_ON(p != argp->tmpp);
argp->tmpp = NULL;
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index bb4a11d58a5a..748eda93ce59 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -18,6 +18,7 @@
#include "idmap.h"
#include "nfsd.h"
#include "cache.h"
+#include "fault_inject.h"
/*
* We have a single directory with several nodes in it.
@@ -1128,9 +1129,13 @@ static int __init init_nfsd(void)
int retval;
printk(KERN_INFO "Installing knfsd (copyright (C) 1996 okir@monad.swb.de).\n");
- retval = nfs4_state_init(); /* nfs4 locking state */
+ retval = nfsd4_init_slabs();
if (retval)
return retval;
+ nfs4_state_init();
+ retval = nfsd_fault_inject_init(); /* nfsd fault injection controls */
+ if (retval)
+ goto out_free_slabs;
nfsd_stat_init(); /* Statistics */
retval = nfsd_reply_cache_init();
if (retval)
@@ -1161,6 +1166,8 @@ out_free_cache:
nfsd_reply_cache_shutdown();
out_free_stat:
nfsd_stat_shutdown();
+ nfsd_fault_inject_cleanup();
+out_free_slabs:
nfsd4_free_slabs();
return retval;
}
@@ -1175,6 +1182,7 @@ static void __exit exit_nfsd(void)
nfsd_lockd_shutdown();
nfsd_idmap_shutdown();
nfsd4_free_slabs();
+ nfsd_fault_inject_cleanup();
unregister_filesystem(&nfsd_fs_type);
}
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h
index 58134a23fdfb..1d1e8589b4ce 100644
--- a/fs/nfsd/nfsd.h
+++ b/fs/nfsd/nfsd.h
@@ -104,14 +104,16 @@ static inline int nfsd_v4client(struct svc_rqst *rq)
*/
#ifdef CONFIG_NFSD_V4
extern unsigned int max_delegations;
-int nfs4_state_init(void);
+void nfs4_state_init(void);
+int nfsd4_init_slabs(void);
void nfsd4_free_slabs(void);
int nfs4_state_start(void);
void nfs4_state_shutdown(void);
void nfs4_reset_lease(time_t leasetime);
int nfs4_reset_recoverydir(char *recdir);
#else
-static inline int nfs4_state_init(void) { return 0; }
+static inline void nfs4_state_init(void) { }
+static inline int nfsd4_init_slabs(void) { return 0; }
static inline void nfsd4_free_slabs(void) { }
static inline int nfs4_state_start(void) { return 0; }
static inline void nfs4_state_shutdown(void) { }
@@ -338,15 +340,15 @@ static inline u32 nfsd_suppattrs2(u32 minorversion)
}
/* These will return ERR_INVAL if specified in GETATTR or READDIR. */
-#define NFSD_WRITEONLY_ATTRS_WORD1 \
-(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
+#define NFSD_WRITEONLY_ATTRS_WORD1 \
+ (FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
/* These are the only attrs allowed in CREATE/OPEN/SETATTR. */
-#define NFSD_WRITEABLE_ATTRS_WORD0 \
-(FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL )
-#define NFSD_WRITEABLE_ATTRS_WORD1 \
-(FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
- | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
+#define NFSD_WRITEABLE_ATTRS_WORD0 \
+ (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL)
+#define NFSD_WRITEABLE_ATTRS_WORD1 \
+ (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \
+ | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)
#define NFSD_WRITEABLE_ATTRS_WORD2 0
#define NFSD_SUPPATTR_EXCLCREAT_WORD0 \
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index a3cf38476a1b..ffb5df1db94f 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -366,6 +366,7 @@ struct nfs4_openowner {
struct nfs4_lockowner {
struct nfs4_stateowner lo_owner; /* must be first element */
+ struct list_head lo_owner_ino_hash; /* hash by owner,file */
struct list_head lo_perstateid; /* for lockowners only */
struct list_head lo_list; /* for temporary uses */
};
@@ -482,7 +483,7 @@ extern void nfsd4_shutdown_recdir(void);
extern int nfs4_client_to_reclaim(const char *name);
extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id);
extern void nfsd4_recdir_purge_old(void);
-extern int nfsd4_create_clid_dir(struct nfs4_client *clp);
+extern void nfsd4_create_clid_dir(struct nfs4_client *clp);
extern void nfsd4_remove_clid_dir(struct nfs4_client *clp);
extern void release_session_client(struct nfsd4_session *);
extern __be32 nfs4_validate_stateid(struct nfs4_client *, stateid_t *);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index d25a723b68ad..edf6d3ed8777 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -594,8 +594,19 @@ nfsd4_get_nfs4_acl(struct svc_rqst *rqstp, struct dentry *dentry, struct nfs4_ac
return error;
}
-#define NFSD_XATTR_JUNCTION_PREFIX XATTR_TRUSTED_PREFIX "junction."
-#define NFSD_XATTR_JUNCTION_TYPE NFSD_XATTR_JUNCTION_PREFIX "type"
+/*
+ * NFS junction information is stored in an extended attribute.
+ */
+#define NFSD_JUNCTION_XATTR_NAME XATTR_TRUSTED_PREFIX "junction.nfs"
+
+/**
+ * nfsd4_is_junction - Test if an object could be an NFS junction
+ *
+ * @dentry: object to test
+ *
+ * Returns 1 if "dentry" appears to contain NFS junction information.
+ * Otherwise 0 is returned.
+ */
int nfsd4_is_junction(struct dentry *dentry)
{
struct inode *inode = dentry->d_inode;
@@ -606,7 +617,7 @@ int nfsd4_is_junction(struct dentry *dentry)
return 0;
if (!(inode->i_mode & S_ISVTX))
return 0;
- if (vfs_getxattr(dentry, NFSD_XATTR_JUNCTION_TYPE, NULL, 0) <= 0)
+ if (vfs_getxattr(dentry, NFSD_JUNCTION_XATTR_NAME, NULL, 0) <= 0)
return 0;
return 1;
}
diff --git a/fs/notify/mark.c b/fs/notify/mark.c
index e14587d55689..f104d565b682 100644
--- a/fs/notify/mark.c
+++ b/fs/notify/mark.c
@@ -135,9 +135,6 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
mark->flags &= ~FSNOTIFY_MARK_FLAG_ALIVE;
- /* 1 from caller and 1 for being on i_list/g_list */
- BUG_ON(atomic_read(&mark->refcnt) < 2);
-
spin_lock(&group->mark_lock);
if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
@@ -182,6 +179,11 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark)
iput(inode);
/*
+ * We don't necessarily have a ref on mark from caller so the above iput
+ * may have already destroyed it. Don't touch from now on.
+ */
+
+ /*
* it's possible that this group tried to destroy itself, but this
* this mark was simultaneously being freed by inode. If that's the
* case, we finish freeing the group here.
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 608be4516091..5a4a8af5c406 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -3198,7 +3198,7 @@ MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2011 Anton Altaparm
MODULE_VERSION(NTFS_VERSION);
MODULE_LICENSE("GPL");
#ifdef DEBUG
-module_param(debug_msgs, bool, 0);
+module_param(debug_msgs, bint, 0);
MODULE_PARM_DESC(debug_msgs, "Enable debug messages.");
#endif
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 9252ee3b71e3..c602b8d20f06 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -380,7 +380,7 @@ static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
state = *get_task_state(task);
vsize = eip = esp = 0;
- permitted = ptrace_may_access(task, PTRACE_MODE_READ);
+ permitted = ptrace_may_access(task, PTRACE_MODE_READ | PTRACE_MODE_NOAUDIT);
mm = get_task_mm(task);
if (mm) {
vsize = task_vsize(mm);
diff --git a/fs/squashfs/cache.c b/fs/squashfs/cache.c
index f744be98cd5a..af0b73802592 100644
--- a/fs/squashfs/cache.c
+++ b/fs/squashfs/cache.c
@@ -70,11 +70,15 @@ struct squashfs_cache_entry *squashfs_cache_get(struct super_block *sb,
spin_lock(&cache->lock);
while (1) {
- for (i = 0; i < cache->entries; i++)
- if (cache->entry[i].block == block)
+ for (i = cache->curr_blk, n = 0; n < cache->entries; n++) {
+ if (cache->entry[i].block == block) {
+ cache->curr_blk = i;
break;
+ }
+ i = (i + 1) % cache->entries;
+ }
- if (i == cache->entries) {
+ if (n == cache->entries) {
/*
* Block not in cache, if all cache entries are used
* go to sleep waiting for one to become available.
@@ -245,6 +249,7 @@ struct squashfs_cache *squashfs_cache_init(char *name, int entries,
goto cleanup;
}
+ cache->curr_blk = 0;
cache->next_blk = 0;
cache->unused = entries;
cache->entries = entries;
@@ -332,17 +337,20 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer,
u64 *block, int *offset, int length)
{
struct squashfs_sb_info *msblk = sb->s_fs_info;
- int bytes, copied = length;
+ int bytes, res = length;
struct squashfs_cache_entry *entry;
TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset);
while (length) {
entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0);
- if (entry->error)
- return entry->error;
- else if (*offset >= entry->length)
- return -EIO;
+ if (entry->error) {
+ res = entry->error;
+ goto error;
+ } else if (*offset >= entry->length) {
+ res = -EIO;
+ goto error;
+ }
bytes = squashfs_copy_data(buffer, entry, *offset, length);
if (buffer)
@@ -358,7 +366,11 @@ int squashfs_read_metadata(struct super_block *sb, void *buffer,
squashfs_cache_put(entry);
}
- return copied;
+ return res;
+
+error:
+ squashfs_cache_put(entry);
+ return res;
}
diff --git a/fs/squashfs/inode.c b/fs/squashfs/inode.c
index fd7b3b3bda13..81afbccfa843 100644
--- a/fs/squashfs/inode.c
+++ b/fs/squashfs/inode.c
@@ -208,8 +208,8 @@ int squashfs_read_inode(struct inode *inode, long long ino)
inode->i_op = &squashfs_inode_ops;
inode->i_fop = &generic_ro_fops;
inode->i_mode |= S_IFREG;
- inode->i_blocks = ((inode->i_size -
- le64_to_cpu(sqsh_ino->sparse) - 1) >> 9) + 1;
+ inode->i_blocks = (inode->i_size -
+ le64_to_cpu(sqsh_ino->sparse) + 511) >> 9;
squashfs_i(inode)->fragment_block = frag_blk;
squashfs_i(inode)->fragment_size = frag_size;
diff --git a/fs/squashfs/squashfs_fs_sb.h b/fs/squashfs/squashfs_fs_sb.h
index 651f0b31d296..52934a22f296 100644
--- a/fs/squashfs/squashfs_fs_sb.h
+++ b/fs/squashfs/squashfs_fs_sb.h
@@ -28,6 +28,7 @@
struct squashfs_cache {
char *name;
int entries;
+ int curr_blk;
int next_blk;
int num_waiters;
int unused;
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c
index d0858c2d9a47..ecaa2f7bdb8f 100644
--- a/fs/squashfs/super.c
+++ b/fs/squashfs/super.c
@@ -290,7 +290,7 @@ handle_fragments:
check_directory_table:
/* Sanity check directory_table */
- if (msblk->directory_table >= next_table) {
+ if (msblk->directory_table > next_table) {
err = -EINVAL;
goto failed_mount;
}
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h
index f554a9313b43..7762bc2d8404 100644
--- a/include/acpi/acpixf.h
+++ b/include/acpi/acpixf.h
@@ -66,7 +66,7 @@ extern u8 acpi_gbl_create_osi_method;
extern u8 acpi_gbl_use_default_register_widths;
extern acpi_name acpi_gbl_trace_method_name;
extern u32 acpi_gbl_trace_flags;
-extern u32 acpi_gbl_enable_aml_debug_object;
+extern bool acpi_gbl_enable_aml_debug_object;
extern u8 acpi_gbl_copy_dsdt_locally;
extern u8 acpi_gbl_truncate_io_addresses;
extern u8 acpi_gbl_disable_auto_repair;
diff --git a/include/acpi/apei.h b/include/acpi/apei.h
index 51a527d24a8a..04f349d8da73 100644
--- a/include/acpi/apei.h
+++ b/include/acpi/apei.h
@@ -16,10 +16,10 @@
#ifdef __KERNEL__
-extern int hest_disable;
+extern bool hest_disable;
extern int erst_disable;
#ifdef CONFIG_ACPI_APEI_GHES
-extern int ghes_disable;
+extern bool ghes_disable;
#else
#define ghes_disable 1
#endif
diff --git a/include/asm-generic/gpio.h b/include/asm-generic/gpio.h
index d466c8d8826d..1ff4e221cb4d 100644
--- a/include/asm-generic/gpio.h
+++ b/include/asm-generic/gpio.h
@@ -177,6 +177,10 @@ extern int gpio_request_one(unsigned gpio, unsigned long flags, const char *labe
extern int gpio_request_array(const struct gpio *array, size_t num);
extern void gpio_free_array(const struct gpio *array, size_t num);
+/* bindings for managed devices that want to request gpios */
+int devm_gpio_request(struct device *dev, unsigned gpio, const char *label);
+void devm_gpio_free(struct device *dev, unsigned int gpio);
+
#ifdef CONFIG_GPIO_SYSFS
/*
diff --git a/include/asm-generic/param.h b/include/asm-generic/param.h
index cdf8251bfb6c..835632a3b468 100644
--- a/include/asm-generic/param.h
+++ b/include/asm-generic/param.h
@@ -1,12 +1,6 @@
#ifndef __ASM_GENERIC_PARAM_H
#define __ASM_GENERIC_PARAM_H
-#ifdef __KERNEL__
-# define HZ CONFIG_HZ /* Internal kernel timer frequency */
-# define USER_HZ 100 /* some user interfaces are */
-# define CLOCKS_PER_SEC (USER_HZ) /* in "ticks" like times() */
-#endif
-
#ifndef HZ
#define HZ 100
#endif
@@ -21,4 +15,11 @@
#define MAXHOSTNAMELEN 64 /* max length of hostname */
+#ifdef __KERNEL__
+# undef HZ
+# define HZ CONFIG_HZ /* Internal kernel timer frequency */
+# define USER_HZ 100 /* some user interfaces are */
+# define CLOCKS_PER_SEC (USER_HZ) /* in "ticks" like times() */
+#endif
+
#endif /* __ASM_GENERIC_PARAM_H */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index 63e4fce67288..4cd4be26722c 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -453,7 +453,7 @@ struct drm_encoder_funcs {
#define DRM_CONNECTOR_MAX_UMODES 16
#define DRM_CONNECTOR_MAX_PROPERTY 16
#define DRM_CONNECTOR_LEN 32
-#define DRM_CONNECTOR_MAX_ENCODER 2
+#define DRM_CONNECTOR_MAX_ENCODER 3
/**
* drm_encoder - central DRM encoder structure
diff --git a/include/linux/acct.h b/include/linux/acct.h
index 3e4737fa6cce..d537aa0ec414 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -146,6 +146,9 @@ extern void acct_exit_ns(struct pid_namespace *);
*
*/
+#undef ACCT_VERSION
+#undef AHZ
+
#ifdef CONFIG_BSD_PROCESS_ACCT_V3
#define ACCT_VERSION 3
#define AHZ 100
diff --git a/include/linux/amba/mmci.h b/include/linux/amba/mmci.h
index 21114810c7c0..0101e9c17fa1 100644
--- a/include/linux/amba/mmci.h
+++ b/include/linux/amba/mmci.h
@@ -30,6 +30,7 @@ struct dma_chan;
* @cd_invert: true if the gpio_cd pin value is active low
* @capabilities: the capabilities of the block as implemented in
* this platform, signify anything MMC_CAP_* from mmc/host.h
+ * @capabilities2: more capabilities, MMC_CAP2_* from mmc/host.h
* @dma_filter: function used to select an appropriate RX and TX
* DMA channel to be used for DMA, if and only if you're deploying the
* generic DMA engine
@@ -52,6 +53,7 @@ struct mmci_platform_data {
int gpio_cd;
bool cd_invert;
unsigned long capabilities;
+ unsigned long capabilities2;
bool (*dma_filter)(struct dma_chan *chan, void *filter_param);
void *dma_rx_param;
void *dma_tx_param;
diff --git a/include/linux/amba/pl061.h b/include/linux/amba/pl061.h
index 2412af944f1f..fb83c0453489 100644
--- a/include/linux/amba/pl061.h
+++ b/include/linux/amba/pl061.h
@@ -7,7 +7,7 @@ struct pl061_platform_data {
unsigned gpio_base;
/* number of the first IRQ.
- * If the IRQ functionality in not desired this must be set to NO_IRQ.
+ * If the IRQ functionality in not desired this must be set to 0.
*/
unsigned irq_base;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 94acd8172b5b..0ed1eb062313 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -675,6 +675,9 @@ extern int blk_insert_cloned_request(struct request_queue *q,
struct request *rq);
extern void blk_delay_queue(struct request_queue *, unsigned long);
extern void blk_recount_segments(struct request_queue *, struct bio *);
+extern int scsi_verify_blk_ioctl(struct block_device *, unsigned int);
+extern int scsi_cmd_blk_ioctl(struct block_device *, fmode_t,
+ unsigned int, void __user *);
extern int scsi_cmd_ioctl(struct request_queue *, struct gendisk *, fmode_t,
unsigned int, void __user *);
extern int sg_scsi_ioctl(struct request_queue *, struct gendisk *, fmode_t,
diff --git a/include/linux/capability.h b/include/linux/capability.h
index a63d13d84ad8..12d52dedb229 100644
--- a/include/linux/capability.h
+++ b/include/linux/capability.h
@@ -380,7 +380,6 @@ struct user_namespace;
struct user_namespace *current_user_ns(void);
extern const kernel_cap_t __cap_empty_set;
-extern const kernel_cap_t __cap_full_set;
extern const kernel_cap_t __cap_init_eff_set;
/*
@@ -544,9 +543,10 @@ extern bool has_capability(struct task_struct *t, int cap);
extern bool has_ns_capability(struct task_struct *t,
struct user_namespace *ns, int cap);
extern bool has_capability_noaudit(struct task_struct *t, int cap);
+extern bool has_ns_capability_noaudit(struct task_struct *t,
+ struct user_namespace *ns, int cap);
extern bool capable(int cap);
extern bool ns_capable(struct user_namespace *ns, int cap);
-extern bool task_ns_capable(struct task_struct *t, int cap);
extern bool nsown_capable(int cap);
/* audit system wants to get cap info from files as well */
diff --git a/include/linux/console.h b/include/linux/console.h
index 7453cfd593c8..7201ce4280ca 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -152,7 +152,7 @@ extern int braille_register_console(struct console *, int index,
char *console_options, char *braille_options);
extern int braille_unregister_console(struct console *);
extern void console_sysfs_notify(void);
-extern int console_suspend_enabled;
+extern bool console_suspend_enabled;
/* Suspend and resume console messages over PM events */
extern void suspend_console(void);
diff --git a/include/linux/cred.h b/include/linux/cred.h
index 40308969ed00..adadf71a7327 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -358,10 +358,12 @@ static inline void put_cred(const struct cred *_cred)
#define current_security() (current_cred_xxx(security))
#ifdef CONFIG_USER_NS
-#define current_user_ns() (current_cred_xxx(user_ns))
+#define current_user_ns() (current_cred_xxx(user_ns))
+#define task_user_ns(task) (task_cred_xxx((task), user_ns))
#else
extern struct user_namespace init_user_ns;
-#define current_user_ns() (&init_user_ns)
+#define current_user_ns() (&init_user_ns)
+#define task_user_ns(task) (&init_user_ns)
#endif
diff --git a/include/linux/cuda.h b/include/linux/cuda.h
index 6a3e6385d3f3..9f9865ff781e 100644
--- a/include/linux/cuda.h
+++ b/include/linux/cuda.h
@@ -5,6 +5,9 @@
* Copyright (C) 1996 Paul Mackerras.
*/
+#ifndef _LINUX_CUDA_H
+#define _LINUX_CUDA_H
+
/* CUDA commands (2nd byte) */
#define CUDA_WARM_START 0
#define CUDA_AUTOPOLL 1
@@ -34,3 +37,5 @@ extern int cuda_request(struct adb_request *req,
extern void cuda_poll(void);
#endif /* __KERNEL */
+
+#endif /* _LINUX_CUDA_H */
diff --git a/include/linux/display.h b/include/linux/display.h
deleted file mode 100644
index 3bf70d639728..000000000000
--- a/include/linux/display.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2006 James Simmons <jsimmons@infradead.org>
- *
- * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, 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 _LINUX_DISPLAY_H
-#define _LINUX_DISPLAY_H
-
-#include <linux/device.h>
-
-struct display_device;
-
-/* This structure defines all the properties of a Display. */
-struct display_driver {
- int (*set_contrast)(struct display_device *, unsigned int);
- int (*get_contrast)(struct display_device *);
- void (*suspend)(struct display_device *, pm_message_t state);
- void (*resume)(struct display_device *);
- int (*probe)(struct display_device *, void *);
- int (*remove)(struct display_device *);
- int max_contrast;
-};
-
-struct display_device {
- struct module *owner; /* Owner module */
- struct display_driver *driver;
- struct device *parent; /* This is the parent */
- struct device *dev; /* This is this display device */
- struct mutex lock;
- void *priv_data;
- char type[16];
- char *name;
- int idx;
-};
-
-extern struct display_device *display_device_register(struct display_driver *driver,
- struct device *dev, void *devdata);
-extern void display_device_unregister(struct display_device *dev);
-
-extern int probe_edid(struct display_device *dev, void *devdata);
-
-#define to_display_device(obj) container_of(obj, struct display_device, class_dev)
-
-#endif
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 31f0508d7da7..999b4f52e8e5 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -7,15 +7,6 @@
#include <asm/elf.h>
#endif
-struct file;
-
-#ifndef elf_read_implies_exec
- /* Executables for which elf_read_implies_exec() returns TRUE will
- have the READ_IMPLIES_EXEC personality flag set automatically.
- Override in asm/elf.h as needed. */
-# define elf_read_implies_exec(ex, have_pt_gnu_stack) 0
-#endif
-
/* 32-bit ELF base types. */
typedef __u32 Elf32_Addr;
typedef __u16 Elf32_Half;
@@ -414,6 +405,13 @@ typedef struct elf64_note {
} Elf64_Nhdr;
#ifdef __KERNEL__
+#ifndef elf_read_implies_exec
+ /* Executables for which elf_read_implies_exec() returns TRUE will
+ have the READ_IMPLIES_EXEC personality flag set automatically.
+ Override in asm/elf.h as needed. */
+# define elf_read_implies_exec(ex, have_pt_gnu_stack) 0
+#endif
+
#if ELF_CLASS == ELFCLASS32
extern Elf32_Dyn _DYNAMIC [];
@@ -437,6 +435,8 @@ extern Elf64_Dyn _DYNAMIC [];
#endif
/* Optional callbacks to write extra ELF notes. */
+struct file;
+
#ifndef ARCH_HAVE_EXTRA_ELF_NOTES
static inline int elf_coredump_extra_notes_size(void) { return 0; }
static inline int elf_coredump_extra_notes_write(struct file *file,
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 1d6836c498dd..c18122f40543 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -45,6 +45,7 @@
#define FB_TYPE_INTERLEAVED_PLANES 2 /* Interleaved planes */
#define FB_TYPE_TEXT 3 /* Text/attributes */
#define FB_TYPE_VGA_PLANES 4 /* EGA/VGA planes */
+#define FB_TYPE_FOURCC 5 /* Type identified by a V4L2 FOURCC */
#define FB_AUX_TEXT_MDA 0 /* Monochrome text */
#define FB_AUX_TEXT_CGA 1 /* CGA/EGA/VGA Color text */
@@ -69,6 +70,7 @@
#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
#define FB_VISUAL_DIRECTCOLOR 4 /* Direct color */
#define FB_VISUAL_STATIC_PSEUDOCOLOR 5 /* Pseudo color readonly */
+#define FB_VISUAL_FOURCC 6 /* Visual identified by a V4L2 FOURCC */
#define FB_ACCEL_NONE 0 /* no hardware accelerator */
#define FB_ACCEL_ATARIBLITT 1 /* Atari Blitter */
@@ -154,6 +156,8 @@
#define FB_ACCEL_PUV3_UNIGFX 0xa0 /* PKUnity-v3 Unigfx */
+#define FB_CAP_FOURCC 1 /* Device supports FOURCC-based formats */
+
struct fb_fix_screeninfo {
char id[16]; /* identification string eg "TT Builtin" */
unsigned long smem_start; /* Start of frame buffer mem */
@@ -171,7 +175,8 @@ struct fb_fix_screeninfo {
__u32 mmio_len; /* Length of Memory Mapped I/O */
__u32 accel; /* Indicate to driver which */
/* specific chip/card we have */
- __u16 reserved[3]; /* Reserved for future compatibility */
+ __u16 capabilities; /* see FB_CAP_* */
+ __u16 reserved[2]; /* Reserved for future compatibility */
};
/* Interpretation of offset for color fields: All offsets are from the right,
@@ -246,8 +251,8 @@ struct fb_var_screeninfo {
__u32 yoffset; /* resolution */
__u32 bits_per_pixel; /* guess what */
- __u32 grayscale; /* != 0 Graylevels instead of colors */
-
+ __u32 grayscale; /* 0 = color, 1 = grayscale, */
+ /* >1 = FOURCC */
struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
@@ -273,7 +278,8 @@ struct fb_var_screeninfo {
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 rotate; /* angle we rotate counter clockwise */
- __u32 reserved[5]; /* Reserved for future compatibility */
+ __u32 colorspace; /* colorspace for FOURCC-based modes */
+ __u32 reserved[4]; /* Reserved for future compatibility */
};
struct fb_cmap {
diff --git a/include/linux/gfs2_ondisk.h b/include/linux/gfs2_ondisk.h
index 4f4462974c14..b148087f49a6 100644
--- a/include/linux/gfs2_ondisk.h
+++ b/include/linux/gfs2_ondisk.h
@@ -22,6 +22,8 @@
#define GFS2_LIVE_LOCK 1
#define GFS2_TRANS_LOCK 2
#define GFS2_RENAME_LOCK 3
+#define GFS2_CONTROL_LOCK 4
+#define GFS2_MOUNTED_LOCK 5
/* Format numbers for various metadata types */
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index 114c0f6fc63d..78d3465251d6 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -652,10 +652,12 @@ struct twl4030_power_data {
unsigned num;
struct twl4030_resconfig *resource_config;
#define TWL4030_RESCONFIG_UNDEF ((u8)-1)
+ bool use_poweroff; /* Board is wired for TWL poweroff */
};
extern void twl4030_power_init(struct twl4030_power_data *triton2_scripts);
extern int twl4030_remove_script(u8 flags);
+extern void twl4030_power_off(void);
struct twl4030_codec_data {
unsigned int digimic_delay; /* in ms */
diff --git a/include/linux/init.h b/include/linux/init.h
index 9146f39cdddf..6b951095a42f 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -2,6 +2,7 @@
#define _LINUX_INIT_H
#include <linux/compiler.h>
+#include <linux/types.h>
/* These macros are used to mark some functions or
* initialized data (doesn't apply to uninitialized data)
@@ -156,7 +157,7 @@ void prepare_namespace(void);
extern void (*late_time_init)(void);
-extern int initcall_debug;
+extern bool initcall_debug;
#endif
diff --git a/include/linux/isdn_divertif.h b/include/linux/isdn_divertif.h
index 07821ca5955f..a5a50f523807 100644
--- a/include/linux/isdn_divertif.h
+++ b/include/linux/isdn_divertif.h
@@ -10,6 +10,8 @@
*
*/
+#ifndef _LINUX_ISDN_DIVERTIF_H
+#define _LINUX_ISDN_DIVERTIF_H
/***********************************************************/
/* magic value is also used to control version information */
@@ -45,3 +47,5 @@ typedef struct
/*********************/
extern int DIVERT_REG_NAME(isdn_divert_if *);
#endif
+
+#endif /* _LINUX_ISDN_DIVERTIF_H */
diff --git a/include/linux/kmemleak.h b/include/linux/kmemleak.h
index 99d9a6766f7e..2a5e5548a1d2 100644
--- a/include/linux/kmemleak.h
+++ b/include/linux/kmemleak.h
@@ -26,8 +26,10 @@
extern void kmemleak_init(void) __ref;
extern void kmemleak_alloc(const void *ptr, size_t size, int min_count,
gfp_t gfp) __ref;
+extern void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size) __ref;
extern void kmemleak_free(const void *ptr) __ref;
extern void kmemleak_free_part(const void *ptr, size_t size) __ref;
+extern void kmemleak_free_percpu(const void __percpu *ptr) __ref;
extern void kmemleak_padding(const void *ptr, unsigned long offset,
size_t size) __ref;
extern void kmemleak_not_leak(const void *ptr) __ref;
@@ -68,6 +70,9 @@ static inline void kmemleak_alloc_recursive(const void *ptr, size_t size,
gfp_t gfp)
{
}
+static inline void kmemleak_alloc_percpu(const void __percpu *ptr, size_t size)
+{
+}
static inline void kmemleak_free(const void *ptr)
{
}
@@ -77,6 +82,9 @@ static inline void kmemleak_free_part(const void *ptr, size_t size)
static inline void kmemleak_free_recursive(const void *ptr, unsigned long flags)
{
}
+static inline void kmemleak_free_percpu(const void __percpu *ptr)
+{
+}
static inline void kmemleak_not_leak(const void *ptr)
{
}
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 90b0656a869e..88a114fce477 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -195,7 +195,7 @@ extern struct svc_procedure nlmsvc_procedures4[];
#endif
extern int nlmsvc_grace_period;
extern unsigned long nlmsvc_timeout;
-extern int nsm_use_hostnames;
+extern bool nsm_use_hostnames;
extern u32 nsm_local_state;
/*
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index 63b4fb8e3b6f..92be3476c9f5 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -297,10 +297,11 @@ enum {
struct pm860x_chip {
struct device *dev;
- struct mutex io_lock;
struct mutex irq_lock;
struct i2c_client *client;
struct i2c_client *companion; /* companion chip client */
+ struct regmap *regmap;
+ struct regmap *regmap_companion;
int buck3_double; /* DVC ramp slope double */
unsigned short companion_addr;
diff --git a/include/linux/mfd/ab5500/ab5500.h b/include/linux/mfd/abx500/ab5500.h
index a720051ae933..a720051ae933 100644
--- a/include/linux/mfd/ab5500/ab5500.h
+++ b/include/linux/mfd/abx500/ab5500.h
diff --git a/include/linux/mfd/ab8500/gpadc.h b/include/linux/mfd/abx500/ab8500-gpadc.h
index 252966769d93..252966769d93 100644
--- a/include/linux/mfd/ab8500/gpadc.h
+++ b/include/linux/mfd/abx500/ab8500-gpadc.h
diff --git a/include/linux/mfd/ab8500/gpio.h b/include/linux/mfd/abx500/ab8500-gpio.h
index 488a8c920a29..488a8c920a29 100644
--- a/include/linux/mfd/ab8500/gpio.h
+++ b/include/linux/mfd/abx500/ab8500-gpio.h
diff --git a/include/linux/mfd/ab8500/sysctrl.h b/include/linux/mfd/abx500/ab8500-sysctrl.h
index 10da0291f8f8..10da0291f8f8 100644
--- a/include/linux/mfd/ab8500/sysctrl.h
+++ b/include/linux/mfd/abx500/ab8500-sysctrl.h
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 838c6b487cc5..838c6b487cc5 100644
--- a/include/linux/mfd/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h
index b8e6d9449086..15b2392a56fb 100644
--- a/include/linux/mfd/max8925.h
+++ b/include/linux/mfd/max8925.h
@@ -203,6 +203,8 @@ struct max8925_chip {
int irq_base;
int core_irq;
int tsc_irq;
+
+ unsigned int wakeup_flag;
};
struct max8925_backlight_pdata {
diff --git a/include/linux/mfd/max8997.h b/include/linux/mfd/max8997.h
index 0bbd13dbe336..fff590521e50 100644
--- a/include/linux/mfd/max8997.h
+++ b/include/linux/mfd/max8997.h
@@ -77,6 +77,82 @@ struct max8997_regulator_data {
struct regulator_init_data *initdata;
};
+enum max8997_muic_usb_type {
+ MAX8997_USB_HOST,
+ MAX8997_USB_DEVICE,
+};
+
+enum max8997_muic_charger_type {
+ MAX8997_CHARGER_TYPE_NONE = 0,
+ MAX8997_CHARGER_TYPE_USB,
+ MAX8997_CHARGER_TYPE_DOWNSTREAM_PORT,
+ MAX8997_CHARGER_TYPE_DEDICATED_CHG,
+ MAX8997_CHARGER_TYPE_500MA,
+ MAX8997_CHARGER_TYPE_1A,
+ MAX8997_CHARGER_TYPE_DEAD_BATTERY = 7,
+};
+
+struct max8997_muic_reg_data {
+ u8 addr;
+ u8 data;
+};
+
+/**
+ * struct max8997_muic_platform_data
+ * @usb_callback: callback function for USB
+ * inform callee of USB type (HOST or DEVICE)
+ * and attached state(true or false)
+ * @charger_callback: callback function for charger
+ * inform callee of charger_type
+ * and attached state(true or false)
+ * @deskdock_callback: callback function for desk dock
+ * inform callee of attached state(true or false)
+ * @cardock_callback: callback function for car dock
+ * inform callee of attached state(true or false)
+ * @mhl_callback: callback function for MHL (Mobile High-definition Link)
+ * inform callee of attached state(true or false)
+ * @uart_callback: callback function for JIG UART
+ * inform callee of attached state(true or false)
+ * @init_data: array of max8997_muic_reg_data
+ * used for initializing registers of MAX8997 MUIC device
+ * @num_init_data: array size of init_data
+ */
+struct max8997_muic_platform_data {
+ void (*usb_callback)(enum max8997_muic_usb_type usb_type,
+ bool attached);
+ void (*charger_callback)(bool attached,
+ enum max8997_muic_charger_type charger_type);
+ void (*deskdock_callback) (bool attached);
+ void (*cardock_callback) (bool attached);
+ void (*mhl_callback) (bool attached);
+ void (*uart_callback) (bool attached);
+
+ struct max8997_muic_reg_data *init_data;
+ int num_init_data;
+};
+
+enum max8997_led_mode {
+ MAX8997_NONE,
+ MAX8997_FLASH_MODE,
+ MAX8997_MOVIE_MODE,
+ MAX8997_FLASH_PIN_CONTROL_MODE,
+ MAX8997_MOVIE_PIN_CONTROL_MODE,
+};
+
+/**
+ * struct max8997_led_platform_data
+ * The number of LED devices for MAX8997 is two
+ * @mode: LED mode for each LED device
+ * @brightness: initial brightness for each LED device
+ * range:
+ * [0 - 31]: MAX8997_FLASH_MODE and MAX8997_FLASH_PIN_CONTROL_MODE
+ * [0 - 15]: MAX8997_MOVIE_MODE and MAX8997_MOVIE_PIN_CONTROL_MODE
+ */
+struct max8997_led_platform_data {
+ enum max8997_led_mode mode[2];
+ u8 brightness[2];
+};
+
struct max8997_platform_data {
/* IRQ */
int irq_base;
@@ -113,10 +189,13 @@ struct max8997_platform_data {
/* charge Full Timeout */
int timeout; /* 0 (no timeout), 5, 6, 7 hours */
- /* MUIC: Not implemented */
+ /* ---- MUIC ---- */
+ struct max8997_muic_platform_data *muic_pdata;
+
/* HAPTIC: Not implemented */
/* RTC: Not implemented */
- /* Flash: Not implemented */
+ /* ---- LED ---- */
+ struct max8997_led_platform_data *led_pdata;
};
#endif /* __LINUX_MFD_MAX8998_H */
diff --git a/include/linux/mfd/mc13xxx.h b/include/linux/mfd/mc13xxx.h
index a98e2a316d1f..b86ee45c8b03 100644
--- a/include/linux/mfd/mc13xxx.h
+++ b/include/linux/mfd/mc13xxx.h
@@ -174,6 +174,9 @@ struct mc13xxx_platform_data {
#define MC13XXX_ADC_MODE_MULT_CHAN 3
#define MC13XXX_ADC0 43
+#define MC13XXX_ADC0_LICELLCON (1 << 0)
+#define MC13XXX_ADC0_CHRGICON (1 << 1)
+#define MC13XXX_ADC0_BATICON (1 << 2)
#define MC13XXX_ADC0_ADREFEN (1 << 10)
#define MC13XXX_ADC0_TSMOD0 (1 << 12)
#define MC13XXX_ADC0_TSMOD1 (1 << 13)
@@ -185,4 +188,9 @@ struct mc13xxx_platform_data {
MC13XXX_ADC0_TSMOD1 | \
MC13XXX_ADC0_TSMOD2)
+#define MC13XXX_ADC0_CONFIG_MASK (MC13XXX_ADC0_TSMOD_MASK | \
+ MC13XXX_ADC0_LICELLCON | \
+ MC13XXX_ADC0_CHRGICON | \
+ MC13XXX_ADC0_BATICON)
+
#endif /* ifndef __LINUX_MFD_MC13XXX_H */
diff --git a/include/linux/mfd/mcp.h b/include/linux/mfd/mcp.h
index ee496708e38b..1515e64e3663 100644
--- a/include/linux/mfd/mcp.h
+++ b/include/linux/mfd/mcp.h
@@ -10,6 +10,7 @@
#ifndef MCP_H
#define MCP_H
+#include <linux/mod_devicetable.h>
#include <mach/dma.h>
struct mcp_ops;
@@ -26,7 +27,7 @@ struct mcp {
dma_device_t dma_telco_rd;
dma_device_t dma_telco_wr;
struct device attached_device;
- int gpio_base;
+ const char *codec;
};
struct mcp_ops {
@@ -44,10 +45,11 @@ void mcp_reg_write(struct mcp *, unsigned int, unsigned int);
unsigned int mcp_reg_read(struct mcp *, unsigned int);
void mcp_enable(struct mcp *);
void mcp_disable(struct mcp *);
+const struct mcp_device_id *mcp_get_device_id(const struct mcp *mcp);
#define mcp_get_sclk_rate(mcp) ((mcp)->sclk_rate)
struct mcp *mcp_host_alloc(struct device *, size_t);
-int mcp_host_register(struct mcp *);
+int mcp_host_register(struct mcp *, void *);
void mcp_host_unregister(struct mcp *);
struct mcp_driver {
@@ -56,6 +58,7 @@ struct mcp_driver {
void (*remove)(struct mcp *);
int (*suspend)(struct mcp *, pm_message_t);
int (*resume)(struct mcp *);
+ const struct mcp_device_id *id_table;
};
int mcp_driver_register(struct mcp_driver *);
diff --git a/include/linux/mfd/s5m87xx/s5m-core.h b/include/linux/mfd/s5m87xx/s5m-core.h
new file mode 100644
index 000000000000..a7480b57f92d
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-core.h
@@ -0,0 +1,373 @@
+/*
+ * s5m-core.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_CORE_H
+#define __LINUX_MFD_S5M_CORE_H
+
+#define NUM_IRQ_REGS 4
+
+enum s5m_device_type {
+ S5M8751X,
+ S5M8763X,
+ S5M8767X,
+};
+
+/* S5M8767 registers */
+enum s5m8767_reg {
+ S5M8767_REG_ID,
+ S5M8767_REG_INT1,
+ S5M8767_REG_INT2,
+ S5M8767_REG_INT3,
+ S5M8767_REG_INT1M,
+ S5M8767_REG_INT2M,
+ S5M8767_REG_INT3M,
+ S5M8767_REG_STATUS1,
+ S5M8767_REG_STATUS2,
+ S5M8767_REG_STATUS3,
+ S5M8767_REG_CTRL1,
+ S5M8767_REG_CTRL2,
+ S5M8767_REG_LOWBAT1,
+ S5M8767_REG_LOWBAT2,
+ S5M8767_REG_BUCHG,
+ S5M8767_REG_DVSRAMP,
+ S5M8767_REG_DVSTIMER2 = 0x10,
+ S5M8767_REG_DVSTIMER3,
+ S5M8767_REG_DVSTIMER4,
+ S5M8767_REG_LDO1,
+ S5M8767_REG_LDO2,
+ S5M8767_REG_LDO3,
+ S5M8767_REG_LDO4,
+ S5M8767_REG_LDO5,
+ S5M8767_REG_LDO6,
+ S5M8767_REG_LDO7,
+ S5M8767_REG_LDO8,
+ S5M8767_REG_LDO9,
+ S5M8767_REG_LDO10,
+ S5M8767_REG_LDO11,
+ S5M8767_REG_LDO12,
+ S5M8767_REG_LDO13,
+ S5M8767_REG_LDO14 = 0x20,
+ S5M8767_REG_LDO15,
+ S5M8767_REG_LDO16,
+ S5M8767_REG_LDO17,
+ S5M8767_REG_LDO18,
+ S5M8767_REG_LDO19,
+ S5M8767_REG_LDO20,
+ S5M8767_REG_LDO21,
+ S5M8767_REG_LDO22,
+ S5M8767_REG_LDO23,
+ S5M8767_REG_LDO24,
+ S5M8767_REG_LDO25,
+ S5M8767_REG_LDO26,
+ S5M8767_REG_LDO27,
+ S5M8767_REG_LDO28,
+ S5M8767_REG_UVLO = 0x31,
+ S5M8767_REG_BUCK1CTRL1,
+ S5M8767_REG_BUCK1CTRL2,
+ S5M8767_REG_BUCK2CTRL,
+ S5M8767_REG_BUCK2DVS1,
+ S5M8767_REG_BUCK2DVS2,
+ S5M8767_REG_BUCK2DVS3,
+ S5M8767_REG_BUCK2DVS4,
+ S5M8767_REG_BUCK2DVS5,
+ S5M8767_REG_BUCK2DVS6,
+ S5M8767_REG_BUCK2DVS7,
+ S5M8767_REG_BUCK2DVS8,
+ S5M8767_REG_BUCK3CTRL,
+ S5M8767_REG_BUCK3DVS1,
+ S5M8767_REG_BUCK3DVS2,
+ S5M8767_REG_BUCK3DVS3,
+ S5M8767_REG_BUCK3DVS4,
+ S5M8767_REG_BUCK3DVS5,
+ S5M8767_REG_BUCK3DVS6,
+ S5M8767_REG_BUCK3DVS7,
+ S5M8767_REG_BUCK3DVS8,
+ S5M8767_REG_BUCK4CTRL,
+ S5M8767_REG_BUCK4DVS1,
+ S5M8767_REG_BUCK4DVS2,
+ S5M8767_REG_BUCK4DVS3,
+ S5M8767_REG_BUCK4DVS4,
+ S5M8767_REG_BUCK4DVS5,
+ S5M8767_REG_BUCK4DVS6,
+ S5M8767_REG_BUCK4DVS7,
+ S5M8767_REG_BUCK4DVS8,
+ S5M8767_REG_BUCK5CTRL1,
+ S5M8767_REG_BUCK5CTRL2,
+ S5M8767_REG_BUCK5CTRL3,
+ S5M8767_REG_BUCK5CTRL4,
+ S5M8767_REG_BUCK5CTRL5,
+ S5M8767_REG_BUCK6CTRL1,
+ S5M8767_REG_BUCK6CTRL2,
+ S5M8767_REG_BUCK7CTRL1,
+ S5M8767_REG_BUCK7CTRL2,
+ S5M8767_REG_BUCK8CTRL1,
+ S5M8767_REG_BUCK8CTRL2,
+ S5M8767_REG_BUCK9CTRL1,
+ S5M8767_REG_BUCK9CTRL2,
+ S5M8767_REG_LDO1CTRL,
+ S5M8767_REG_LDO2_1CTRL,
+ S5M8767_REG_LDO2_2CTRL,
+ S5M8767_REG_LDO2_3CTRL,
+ S5M8767_REG_LDO2_4CTRL,
+ S5M8767_REG_LDO3CTRL,
+ S5M8767_REG_LDO4CTRL,
+ S5M8767_REG_LDO5CTRL,
+ S5M8767_REG_LDO6CTRL,
+ S5M8767_REG_LDO7CTRL,
+ S5M8767_REG_LDO8CTRL,
+ S5M8767_REG_LDO9CTRL,
+ S5M8767_REG_LDO10CTRL,
+ S5M8767_REG_LDO11CTRL,
+ S5M8767_REG_LDO12CTRL,
+ S5M8767_REG_LDO13CTRL,
+ S5M8767_REG_LDO14CTRL,
+ S5M8767_REG_LDO15CTRL,
+ S5M8767_REG_LDO16CTRL,
+ S5M8767_REG_LDO17CTRL,
+ S5M8767_REG_LDO18CTRL,
+ S5M8767_REG_LDO19CTRL,
+ S5M8767_REG_LDO20CTRL,
+ S5M8767_REG_LDO21CTRL,
+ S5M8767_REG_LDO22CTRL,
+ S5M8767_REG_LDO23CTRL,
+ S5M8767_REG_LDO24CTRL,
+ S5M8767_REG_LDO25CTRL,
+ S5M8767_REG_LDO26CTRL,
+ S5M8767_REG_LDO27CTRL,
+ S5M8767_REG_LDO28CTRL,
+};
+
+/* S5M8763 registers */
+enum s5m8763_reg {
+ S5M8763_REG_IRQ1,
+ S5M8763_REG_IRQ2,
+ S5M8763_REG_IRQ3,
+ S5M8763_REG_IRQ4,
+ S5M8763_REG_IRQM1,
+ S5M8763_REG_IRQM2,
+ S5M8763_REG_IRQM3,
+ S5M8763_REG_IRQM4,
+ S5M8763_REG_STATUS1,
+ S5M8763_REG_STATUS2,
+ S5M8763_REG_STATUSM1,
+ S5M8763_REG_STATUSM2,
+ S5M8763_REG_CHGR1,
+ S5M8763_REG_CHGR2,
+ S5M8763_REG_LDO_ACTIVE_DISCHARGE1,
+ S5M8763_REG_LDO_ACTIVE_DISCHARGE2,
+ S5M8763_REG_BUCK_ACTIVE_DISCHARGE3,
+ S5M8763_REG_ONOFF1,
+ S5M8763_REG_ONOFF2,
+ S5M8763_REG_ONOFF3,
+ S5M8763_REG_ONOFF4,
+ S5M8763_REG_BUCK1_VOLTAGE1,
+ S5M8763_REG_BUCK1_VOLTAGE2,
+ S5M8763_REG_BUCK1_VOLTAGE3,
+ S5M8763_REG_BUCK1_VOLTAGE4,
+ S5M8763_REG_BUCK2_VOLTAGE1,
+ S5M8763_REG_BUCK2_VOLTAGE2,
+ S5M8763_REG_BUCK3,
+ S5M8763_REG_BUCK4,
+ S5M8763_REG_LDO1_LDO2,
+ S5M8763_REG_LDO3,
+ S5M8763_REG_LDO4,
+ S5M8763_REG_LDO5,
+ S5M8763_REG_LDO6,
+ S5M8763_REG_LDO7,
+ S5M8763_REG_LDO7_LDO8,
+ S5M8763_REG_LDO9_LDO10,
+ S5M8763_REG_LDO11,
+ S5M8763_REG_LDO12,
+ S5M8763_REG_LDO13,
+ S5M8763_REG_LDO14,
+ S5M8763_REG_LDO15,
+ S5M8763_REG_LDO16,
+ S5M8763_REG_BKCHR,
+ S5M8763_REG_LBCNFG1,
+ S5M8763_REG_LBCNFG2,
+};
+
+enum s5m8767_irq {
+ S5M8767_IRQ_PWRR,
+ S5M8767_IRQ_PWRF,
+ S5M8767_IRQ_PWR1S,
+ S5M8767_IRQ_JIGR,
+ S5M8767_IRQ_JIGF,
+ S5M8767_IRQ_LOWBAT2,
+ S5M8767_IRQ_LOWBAT1,
+
+ S5M8767_IRQ_MRB,
+ S5M8767_IRQ_DVSOK2,
+ S5M8767_IRQ_DVSOK3,
+ S5M8767_IRQ_DVSOK4,
+
+ S5M8767_IRQ_RTC60S,
+ S5M8767_IRQ_RTCA1,
+ S5M8767_IRQ_RTCA2,
+ S5M8767_IRQ_SMPL,
+ S5M8767_IRQ_RTC1S,
+ S5M8767_IRQ_WTSR,
+
+ S5M8767_IRQ_NR,
+};
+
+#define S5M8767_IRQ_PWRR_MASK (1 << 0)
+#define S5M8767_IRQ_PWRF_MASK (1 << 1)
+#define S5M8767_IRQ_PWR1S_MASK (1 << 3)
+#define S5M8767_IRQ_JIGR_MASK (1 << 4)
+#define S5M8767_IRQ_JIGF_MASK (1 << 5)
+#define S5M8767_IRQ_LOWBAT2_MASK (1 << 6)
+#define S5M8767_IRQ_LOWBAT1_MASK (1 << 7)
+
+#define S5M8767_IRQ_MRB_MASK (1 << 2)
+#define S5M8767_IRQ_DVSOK2_MASK (1 << 3)
+#define S5M8767_IRQ_DVSOK3_MASK (1 << 4)
+#define S5M8767_IRQ_DVSOK4_MASK (1 << 5)
+
+#define S5M8767_IRQ_RTC60S_MASK (1 << 0)
+#define S5M8767_IRQ_RTCA1_MASK (1 << 1)
+#define S5M8767_IRQ_RTCA2_MASK (1 << 2)
+#define S5M8767_IRQ_SMPL_MASK (1 << 3)
+#define S5M8767_IRQ_RTC1S_MASK (1 << 4)
+#define S5M8767_IRQ_WTSR_MASK (1 << 5)
+
+enum s5m8763_irq {
+ S5M8763_IRQ_DCINF,
+ S5M8763_IRQ_DCINR,
+ S5M8763_IRQ_JIGF,
+ S5M8763_IRQ_JIGR,
+ S5M8763_IRQ_PWRONF,
+ S5M8763_IRQ_PWRONR,
+
+ S5M8763_IRQ_WTSREVNT,
+ S5M8763_IRQ_SMPLEVNT,
+ S5M8763_IRQ_ALARM1,
+ S5M8763_IRQ_ALARM0,
+
+ S5M8763_IRQ_ONKEY1S,
+ S5M8763_IRQ_TOPOFFR,
+ S5M8763_IRQ_DCINOVPR,
+ S5M8763_IRQ_CHGRSTF,
+ S5M8763_IRQ_DONER,
+ S5M8763_IRQ_CHGFAULT,
+
+ S5M8763_IRQ_LOBAT1,
+ S5M8763_IRQ_LOBAT2,
+
+ S5M8763_IRQ_NR,
+};
+
+#define S5M8763_IRQ_DCINF_MASK (1 << 2)
+#define S5M8763_IRQ_DCINR_MASK (1 << 3)
+#define S5M8763_IRQ_JIGF_MASK (1 << 4)
+#define S5M8763_IRQ_JIGR_MASK (1 << 5)
+#define S5M8763_IRQ_PWRONF_MASK (1 << 6)
+#define S5M8763_IRQ_PWRONR_MASK (1 << 7)
+
+#define S5M8763_IRQ_WTSREVNT_MASK (1 << 0)
+#define S5M8763_IRQ_SMPLEVNT_MASK (1 << 1)
+#define S5M8763_IRQ_ALARM1_MASK (1 << 2)
+#define S5M8763_IRQ_ALARM0_MASK (1 << 3)
+
+#define S5M8763_IRQ_ONKEY1S_MASK (1 << 0)
+#define S5M8763_IRQ_TOPOFFR_MASK (1 << 2)
+#define S5M8763_IRQ_DCINOVPR_MASK (1 << 3)
+#define S5M8763_IRQ_CHGRSTF_MASK (1 << 4)
+#define S5M8763_IRQ_DONER_MASK (1 << 5)
+#define S5M8763_IRQ_CHGFAULT_MASK (1 << 7)
+
+#define S5M8763_IRQ_LOBAT1_MASK (1 << 0)
+#define S5M8763_IRQ_LOBAT2_MASK (1 << 1)
+
+#define S5M8763_ENRAMP (1 << 4)
+
+/**
+ * struct s5m87xx_dev - s5m87xx master device for sub-drivers
+ * @dev: master device of the chip (can be used to access platform data)
+ * @i2c: i2c client private data for regulator
+ * @rtc: i2c client private data for rtc
+ * @iolock: mutex for serializing io access
+ * @irqlock: mutex for buslock
+ * @irq_base: base IRQ number for s5m87xx, required for IRQs
+ * @irq: generic IRQ number for s5m87xx
+ * @ono: power onoff IRQ number for s5m87xx
+ * @irq_masks_cur: currently active value
+ * @irq_masks_cache: cached hardware value
+ * @type: indicate which s5m87xx "variant" is used
+ */
+struct s5m87xx_dev {
+ struct device *dev;
+ struct regmap *regmap;
+ struct i2c_client *i2c;
+ struct i2c_client *rtc;
+ struct mutex iolock;
+ struct mutex irqlock;
+
+ int device_type;
+ int irq_base;
+ int irq;
+ int ono;
+ u8 irq_masks_cur[NUM_IRQ_REGS];
+ u8 irq_masks_cache[NUM_IRQ_REGS];
+ int type;
+ bool wakeup;
+};
+
+int s5m_irq_init(struct s5m87xx_dev *s5m87xx);
+void s5m_irq_exit(struct s5m87xx_dev *s5m87xx);
+int s5m_irq_resume(struct s5m87xx_dev *s5m87xx);
+
+extern int s5m_reg_read(struct s5m87xx_dev *s5m87xx, u8 reg, void *dest);
+extern int s5m_bulk_read(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf);
+extern int s5m_reg_write(struct s5m87xx_dev *s5m87xx, u8 reg, u8 value);
+extern int s5m_bulk_write(struct s5m87xx_dev *s5m87xx, u8 reg, int count, u8 *buf);
+extern int s5m_reg_update(struct s5m87xx_dev *s5m87xx, u8 reg, u8 val, u8 mask);
+
+struct s5m_platform_data {
+ struct s5m_regulator_data *regulators;
+ int device_type;
+ int num_regulators;
+
+ int irq_base;
+ int (*cfg_pmic_irq)(void);
+
+ int ono;
+ bool wakeup;
+ bool buck_voltage_lock;
+
+ int buck_gpios[3];
+ int buck2_voltage[8];
+ bool buck2_gpiodvs;
+ int buck3_voltage[8];
+ bool buck3_gpiodvs;
+ int buck4_voltage[8];
+ bool buck4_gpiodvs;
+
+ int buck_set1;
+ int buck_set2;
+ int buck_set3;
+ int buck2_enable;
+ int buck3_enable;
+ int buck4_enable;
+ int buck_default_idx;
+ int buck2_default_idx;
+ int buck3_default_idx;
+ int buck4_default_idx;
+
+ int buck_ramp_delay;
+ bool buck2_ramp_enable;
+ bool buck3_ramp_enable;
+ bool buck4_ramp_enable;
+};
+
+#endif /* __LINUX_MFD_S5M_CORE_H */
diff --git a/include/linux/mfd/s5m87xx/s5m-pmic.h b/include/linux/mfd/s5m87xx/s5m-pmic.h
new file mode 100644
index 000000000000..a72a5d27e62e
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-pmic.h
@@ -0,0 +1,100 @@
+/* s5m87xx.h
+ *
+ * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#ifndef __LINUX_MFD_S5M_PMIC_H
+#define __LINUX_MFD_S5M_PMIC_H
+
+#include <linux/regulator/machine.h>
+
+/* S5M8767 regulator ids */
+enum s5m8767_regulators {
+ S5M8767_LDO1,
+ S5M8767_LDO2,
+ S5M8767_LDO3,
+ S5M8767_LDO4,
+ S5M8767_LDO5,
+ S5M8767_LDO6,
+ S5M8767_LDO7,
+ S5M8767_LDO8,
+ S5M8767_LDO9,
+ S5M8767_LDO10,
+ S5M8767_LDO11,
+ S5M8767_LDO12,
+ S5M8767_LDO13,
+ S5M8767_LDO14,
+ S5M8767_LDO15,
+ S5M8767_LDO16,
+ S5M8767_LDO17,
+ S5M8767_LDO18,
+ S5M8767_LDO19,
+ S5M8767_LDO20,
+ S5M8767_LDO21,
+ S5M8767_LDO22,
+ S5M8767_LDO23,
+ S5M8767_LDO24,
+ S5M8767_LDO25,
+ S5M8767_LDO26,
+ S5M8767_LDO27,
+ S5M8767_LDO28,
+ S5M8767_BUCK1,
+ S5M8767_BUCK2,
+ S5M8767_BUCK3,
+ S5M8767_BUCK4,
+ S5M8767_BUCK5,
+ S5M8767_BUCK6,
+ S5M8767_BUCK7,
+ S5M8767_BUCK8,
+ S5M8767_BUCK9,
+ S5M8767_AP_EN32KHZ,
+ S5M8767_CP_EN32KHZ,
+
+ S5M8767_REG_MAX,
+};
+
+/* S5M8763 regulator ids */
+enum s5m8763_regulators {
+ S5M8763_LDO1,
+ S5M8763_LDO2,
+ S5M8763_LDO3,
+ S5M8763_LDO4,
+ S5M8763_LDO5,
+ S5M8763_LDO6,
+ S5M8763_LDO7,
+ S5M8763_LDO8,
+ S5M8763_LDO9,
+ S5M8763_LDO10,
+ S5M8763_LDO11,
+ S5M8763_LDO12,
+ S5M8763_LDO13,
+ S5M8763_LDO14,
+ S5M8763_LDO15,
+ S5M8763_LDO16,
+ S5M8763_BUCK1,
+ S5M8763_BUCK2,
+ S5M8763_BUCK3,
+ S5M8763_BUCK4,
+ S5M8763_AP_EN32KHZ,
+ S5M8763_CP_EN32KHZ,
+ S5M8763_ENCHGVI,
+ S5M8763_ESAFEUSB1,
+ S5M8763_ESAFEUSB2,
+};
+
+/**
+ * s5m87xx_regulator_data - regulator data
+ * @id: regulator id
+ * @initdata: regulator init data (contraints, supplies, ...)
+ */
+struct s5m_regulator_data {
+ int id;
+ struct regulator_init_data *initdata;
+};
+
+#endif /* __LINUX_MFD_S5M_PMIC_H */
diff --git a/include/linux/mfd/s5m87xx/s5m-rtc.h b/include/linux/mfd/s5m87xx/s5m-rtc.h
new file mode 100644
index 000000000000..6ce8da264cec
--- /dev/null
+++ b/include/linux/mfd/s5m87xx/s5m-rtc.h
@@ -0,0 +1,84 @@
+/*
+ * s5m-rtc.h
+ *
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd
+ * http://www.samsung.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#ifndef __LINUX_MFD_S5M_RTC_H
+#define __LINUX_MFD_S5M_RTC_H
+
+enum s5m87xx_rtc_reg {
+ S5M87XX_RTC_SEC,
+ S5M87XX_RTC_MIN,
+ S5M87XX_RTC_HOUR,
+ S5M87XX_RTC_WEEKDAY,
+ S5M87XX_RTC_DATE,
+ S5M87XX_RTC_MONTH,
+ S5M87XX_RTC_YEAR1,
+ S5M87XX_RTC_YEAR2,
+ S5M87XX_ALARM0_SEC,
+ S5M87XX_ALARM0_MIN,
+ S5M87XX_ALARM0_HOUR,
+ S5M87XX_ALARM0_WEEKDAY,
+ S5M87XX_ALARM0_DATE,
+ S5M87XX_ALARM0_MONTH,
+ S5M87XX_ALARM0_YEAR1,
+ S5M87XX_ALARM0_YEAR2,
+ S5M87XX_ALARM1_SEC,
+ S5M87XX_ALARM1_MIN,
+ S5M87XX_ALARM1_HOUR,
+ S5M87XX_ALARM1_WEEKDAY,
+ S5M87XX_ALARM1_DATE,
+ S5M87XX_ALARM1_MONTH,
+ S5M87XX_ALARM1_YEAR1,
+ S5M87XX_ALARM1_YEAR2,
+ S5M87XX_ALARM0_CONF,
+ S5M87XX_ALARM1_CONF,
+ S5M87XX_RTC_STATUS,
+ S5M87XX_WTSR_SMPL_CNTL,
+ S5M87XX_RTC_UDR_CON,
+};
+
+#define RTC_I2C_ADDR (0x0C >> 1)
+
+#define HOUR_12 (1 << 7)
+#define HOUR_AMPM (1 << 6)
+#define HOUR_PM (1 << 5)
+#define ALARM0_STATUS (1 << 1)
+#define ALARM1_STATUS (1 << 2)
+#define UPDATE_AD (1 << 0)
+
+/* RTC Control Register */
+#define BCD_EN_SHIFT 0
+#define BCD_EN_MASK (1 << BCD_EN_SHIFT)
+#define MODEL24_SHIFT 1
+#define MODEL24_MASK (1 << MODEL24_SHIFT)
+/* RTC Update Register1 */
+#define RTC_UDR_SHIFT 0
+#define RTC_UDR_MASK (1 << RTC_UDR_SHIFT)
+/* RTC Hour register */
+#define HOUR_PM_SHIFT 6
+#define HOUR_PM_MASK (1 << HOUR_PM_SHIFT)
+/* RTC Alarm Enable */
+#define ALARM_ENABLE_SHIFT 7
+#define ALARM_ENABLE_MASK (1 << ALARM_ENABLE_SHIFT)
+
+enum {
+ RTC_SEC = 0,
+ RTC_MIN,
+ RTC_HOUR,
+ RTC_WEEKDAY,
+ RTC_DATE,
+ RTC_MONTH,
+ RTC_YEAR1,
+ RTC_YEAR2,
+};
+
+#endif /* __LINUX_MFD_S5M_RTC_H */
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index be1af7c42e57..ca1d7a347600 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -20,6 +20,8 @@ enum stmpe_block {
};
enum stmpe_partnum {
+ STMPE610,
+ STMPE801,
STMPE811,
STMPE1601,
STMPE2401,
@@ -50,17 +52,20 @@ enum {
struct stmpe_variant_info;
+struct stmpe_client_info;
/**
* struct stmpe - STMPE MFD structure
* @lock: lock protecting I/O operations
* @irq_lock: IRQ bus lock
* @dev: device, mostly for dev_dbg()
- * @i2c: i2c client
+ * @client: client - i2c or spi
+ * @ci: client specific information
* @partnum: part number
* @variant: the detected STMPE model number
* @regs: list of addresses of registers which are at different addresses on
* different variants. Indexed by one of STMPE_IDX_*.
+ * @irq: irq number for stmpe
* @irq_base: starting IRQ number for internal IRQs
* @num_gpios: number of gpios, differs for variants
* @ier: cache of IER registers for bus_lock
@@ -71,11 +76,13 @@ struct stmpe {
struct mutex lock;
struct mutex irq_lock;
struct device *dev;
- struct i2c_client *i2c;
+ void *client;
+ struct stmpe_client_info *ci;
enum stmpe_partnum partnum;
struct stmpe_variant_info *variant;
const u8 *regs;
+ int irq;
int irq_base;
int num_gpios;
u8 ier[2];
@@ -183,6 +190,9 @@ struct stmpe_ts_platform_data {
* @autosleep_timeout: inactivity timeout in milliseconds for autosleep
* @irq_base: base IRQ number. %STMPE_NR_IRQS irqs will be used, or
* %STMPE_NR_INTERNAL_IRQS if the GPIO driver is not used.
+ * @irq_over_gpio: true if gpio is used to get irq
+ * @irq_gpio: gpio number over which irq will be requested (significant only if
+ * irq_over_gpio is true)
* @gpio: GPIO-specific platform data
* @keypad: keypad-specific platform data
* @ts: touchscreen-specific platform data
@@ -194,6 +204,8 @@ struct stmpe_platform_data {
unsigned int irq_trigger;
bool irq_invert_polarity;
bool autosleep;
+ bool irq_over_gpio;
+ int irq_gpio;
int autosleep_timeout;
struct stmpe_gpio_platform_data *gpio;
diff --git a/include/linux/mfd/ucb1x00.h b/include/linux/mfd/ucb1x00.h
index 4321f044d1e4..bc19e5fb7ea8 100644
--- a/include/linux/mfd/ucb1x00.h
+++ b/include/linux/mfd/ucb1x00.h
@@ -104,6 +104,9 @@
#define UCB_MODE_DYN_VFLAG_ENA (1 << 12)
#define UCB_MODE_AUD_OFF_CAN (1 << 13)
+struct ucb1x00_plat_data {
+ int gpio_base;
+};
struct ucb1x00_irq {
void *devid;
@@ -116,7 +119,7 @@ struct ucb1x00 {
unsigned int irq;
struct semaphore adc_sem;
spinlock_t io_lock;
- u16 id;
+ const struct mcp_device_id *id;
u16 io_dir;
u16 io_out;
u16 adc_cr;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index c8ef9bc54d50..9f22ba572de0 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -71,6 +71,8 @@ struct mmc_ext_csd {
bool hpi_en; /* HPI enablebit */
bool hpi; /* HPI support bit */
unsigned int hpi_cmd; /* cmd used as HPI */
+ unsigned int boot_ro_lock; /* ro lock support */
+ bool boot_ro_lockable;
u8 raw_partition_support; /* 160 */
u8 raw_erased_mem_count; /* 181 */
u8 raw_ext_csd_structure; /* 194 */
@@ -110,6 +112,7 @@ struct sd_ssr {
struct sd_switch_caps {
unsigned int hs_max_dtr;
unsigned int uhs_max_dtr;
+#define HIGH_SPEED_MAX_DTR 50000000
#define UHS_SDR104_MAX_DTR 208000000
#define UHS_SDR50_MAX_DTR 100000000
#define UHS_DDR50_MAX_DTR 50000000
@@ -117,11 +120,13 @@ struct sd_switch_caps {
#define UHS_SDR12_MAX_DTR 25000000
unsigned int sd3_bus_mode;
#define UHS_SDR12_BUS_SPEED 0
+#define HIGH_SPEED_BUS_SPEED 1
#define UHS_SDR25_BUS_SPEED 1
#define UHS_SDR50_BUS_SPEED 2
#define UHS_SDR104_BUS_SPEED 3
#define UHS_DDR50_BUS_SPEED 4
+#define SD_MODE_HIGH_SPEED (1 << HIGH_SPEED_BUS_SPEED)
#define SD_MODE_UHS_SDR12 (1 << UHS_SDR12_BUS_SPEED)
#define SD_MODE_UHS_SDR25 (1 << UHS_SDR25_BUS_SPEED)
#define SD_MODE_UHS_SDR50 (1 << UHS_SDR50_BUS_SPEED)
@@ -184,6 +189,10 @@ struct mmc_part {
unsigned int part_cfg; /* partition type */
char name[MAX_MMC_PART_NAME_LEN];
bool force_ro; /* to make boot parts RO by default */
+ unsigned int area_type;
+#define MMC_BLK_DATA_AREA_MAIN (1<<0)
+#define MMC_BLK_DATA_AREA_BOOT (1<<1)
+#define MMC_BLK_DATA_AREA_GP (1<<2)
};
/*
@@ -206,6 +215,8 @@ struct mmc_card {
#define MMC_STATE_HIGHSPEED_DDR (1<<4) /* card is in high speed mode */
#define MMC_STATE_ULTRAHIGHSPEED (1<<5) /* card is in ultra high speed mode */
#define MMC_CARD_SDXC (1<<6) /* card is SDXC */
+#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
+#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
@@ -261,12 +272,14 @@ struct mmc_card {
* This function fill contents in mmc_part.
*/
static inline void mmc_part_add(struct mmc_card *card, unsigned int size,
- unsigned int part_cfg, char *name, int idx, bool ro)
+ unsigned int part_cfg, char *name, int idx, bool ro,
+ int area_type)
{
card->part[card->nr_parts].size = size;
card->part[card->nr_parts].part_cfg = part_cfg;
sprintf(card->part[card->nr_parts].name, name, idx);
card->part[card->nr_parts].force_ro = ro;
+ card->part[card->nr_parts].area_type = area_type;
card->nr_parts++;
}
@@ -362,18 +375,24 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)
#define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT)
#define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY)
#define mmc_card_highspeed(c) ((c)->state & MMC_STATE_HIGHSPEED)
+#define mmc_card_hs200(c) ((c)->state & MMC_STATE_HIGHSPEED_200)
#define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR)
#define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR)
-#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
+#define mmc_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
+#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
+#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
#define mmc_card_set_highspeed(c) ((c)->state |= MMC_STATE_HIGHSPEED)
+#define mmc_card_set_hs200(c) ((c)->state |= MMC_STATE_HIGHSPEED_200)
#define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
#define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR)
+#define mmc_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
+#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
/*
* Quirk add/remove for MMC products.
diff --git a/include/linux/mmc/cd-gpio.h b/include/linux/mmc/cd-gpio.h
new file mode 100644
index 000000000000..a8e469783318
--- /dev/null
+++ b/include/linux/mmc/cd-gpio.h
@@ -0,0 +1,19 @@
+/*
+ * Generic GPIO card-detect helper header
+ *
+ * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MMC_CD_GPIO_H
+#define MMC_CD_GPIO_H
+
+struct mmc_host;
+int mmc_cd_gpio_request(struct mmc_host *host, unsigned int gpio,
+ unsigned int irq, unsigned long flags);
+void mmc_cd_gpio_free(struct mmc_host *host);
+
+#endif
diff --git a/include/linux/mmc/core.h b/include/linux/mmc/core.h
index 174a844a5dda..87a976cc5654 100644
--- a/include/linux/mmc/core.h
+++ b/include/linux/mmc/core.h
@@ -180,6 +180,8 @@ extern int mmc_try_claim_host(struct mmc_host *host);
extern int mmc_flush_cache(struct mmc_card *);
+extern int mmc_detect_card_removed(struct mmc_host *host);
+
/**
* mmc_claim_host - exclusively claim a host
* @host: mmc host to claim
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 6dc9b80568a0..e8779c6d1759 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -214,6 +214,7 @@ struct dw_mci_board {
unsigned int bus_hz; /* Bus speed */
unsigned int caps; /* Capabilities */
+ unsigned int caps2; /* More capabilities */
/*
* Override fifo depth. If 0, autodetect it from the FIFOTH register,
* but note that this may not be reliable after a bootloader has used
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index a3ac9c48e5de..0beba1e5e1ed 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -56,10 +56,13 @@ struct mmc_ios {
#define MMC_TIMING_UHS_SDR50 3
#define MMC_TIMING_UHS_SDR104 4
#define MMC_TIMING_UHS_DDR50 5
+#define MMC_TIMING_MMC_HS200 6
#define MMC_SDR_MODE 0
#define MMC_1_2V_DDR_MODE 1
#define MMC_1_8V_DDR_MODE 2
+#define MMC_1_2V_SDR_MODE 3
+#define MMC_1_8V_SDR_MODE 4
unsigned char signal_voltage; /* signalling voltage (1.8V or 3.3V) */
@@ -148,7 +151,9 @@ struct mmc_host_ops {
void (*init_card)(struct mmc_host *host, struct mmc_card *card);
int (*start_signal_voltage_switch)(struct mmc_host *host, struct mmc_ios *ios);
- int (*execute_tuning)(struct mmc_host *host);
+
+ /* The tuning command opcode value is different for SD and eMMC cards */
+ int (*execute_tuning)(struct mmc_host *host, u32 opcode);
void (*enable_preset_value)(struct mmc_host *host, bool enable);
int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
void (*hw_reset)(struct mmc_host *host);
@@ -167,6 +172,11 @@ struct mmc_async_req {
int (*err_check) (struct mmc_card *, struct mmc_async_req *);
};
+struct mmc_hotplug {
+ unsigned int irq;
+ void *handler_priv;
+};
+
struct mmc_host {
struct device *parent;
struct device class_dev;
@@ -242,6 +252,11 @@ struct mmc_host {
#define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */
#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */
#define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */
+#define MMC_CAP2_NO_SLEEP_CMD (1 << 4) /* Don't allow sleep command */
+#define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */
+#define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */
+#define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \
+ MMC_CAP2_HS200_1_2V_SDR)
mmc_pm_flag_t pm_caps; /* supported pm features */
unsigned int power_notify_type;
@@ -253,10 +268,12 @@ struct mmc_host {
int clk_requests; /* internal reference counter */
unsigned int clk_delay; /* number of MCI clk hold cycles */
bool clk_gated; /* clock gated */
- struct work_struct clk_gate_work; /* delayed clock gate */
+ struct delayed_work clk_gate_work; /* delayed clock gate */
unsigned int clk_old; /* old clock value cache */
spinlock_t clk_lock; /* lock for clk fields */
struct mutex clk_gate_mutex; /* mutex for clock gating */
+ struct device_attribute clkgate_delay_attr;
+ unsigned long clkgate_delay;
#endif
/* host specific block data */
@@ -297,6 +314,8 @@ struct mmc_host {
int claim_cnt; /* "claim" nesting count */
struct delayed_work detect;
+ int detect_change; /* card detect flag */
+ struct mmc_hotplug hotplug;
const struct mmc_bus_ops *bus_ops; /* current bus driver */
unsigned int bus_refs; /* reference counter */
@@ -323,6 +342,8 @@ struct mmc_host {
struct fault_attr fail_mmc_request;
#endif
+ unsigned int actual_clock; /* Actual HC clock rate */
+
unsigned long private[0] ____cacheline_aligned;
};
@@ -396,7 +417,7 @@ static inline void mmc_set_disable_delay(struct mmc_host *host,
}
/* Module parameter */
-extern int mmc_assume_removable;
+extern bool mmc_assume_removable;
static inline int mmc_card_is_removable(struct mmc_host *host)
{
diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h
index 0e7135697d11..fb9f6e116e1c 100644
--- a/include/linux/mmc/mmc.h
+++ b/include/linux/mmc/mmc.h
@@ -51,6 +51,7 @@
#define MMC_READ_SINGLE_BLOCK 17 /* adtc [31:0] data addr R1 */
#define MMC_READ_MULTIPLE_BLOCK 18 /* adtc [31:0] data addr R1 */
#define MMC_SEND_TUNING_BLOCK 19 /* adtc R1 */
+#define MMC_SEND_TUNING_BLOCK_HS200 21 /* adtc R1 */
/* class 3 */
#define MMC_WRITE_DAT_UNTIL_STOP 20 /* adtc [31:0] data addr R1 */
@@ -280,6 +281,7 @@ struct _mmc_csd {
#define EXT_CSD_RST_N_FUNCTION 162 /* R/W */
#define EXT_CSD_SANITIZE_START 165 /* W */
#define EXT_CSD_WR_REL_PARAM 166 /* RO */
+#define EXT_CSD_BOOT_WP 173 /* R/W */
#define EXT_CSD_ERASE_GROUP_DEF 175 /* R/W */
#define EXT_CSD_PART_CONFIG 179 /* R/W */
#define EXT_CSD_ERASED_MEM_CONT 181 /* RO */
@@ -321,6 +323,11 @@ struct _mmc_csd {
#define EXT_CSD_WR_REL_PARAM_EN (1<<2)
+#define EXT_CSD_BOOT_WP_B_PWR_WP_DIS (0x40)
+#define EXT_CSD_BOOT_WP_B_PERM_WP_DIS (0x10)
+#define EXT_CSD_BOOT_WP_B_PERM_WP_EN (0x04)
+#define EXT_CSD_BOOT_WP_B_PWR_WP_EN (0x01)
+
#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
#define EXT_CSD_PART_CONFIG_ACC_GP0 (0x4)
@@ -333,13 +340,76 @@ struct _mmc_csd {
#define EXT_CSD_CARD_TYPE_26 (1<<0) /* Card can run at 26MHz */
#define EXT_CSD_CARD_TYPE_52 (1<<1) /* Card can run at 52MHz */
-#define EXT_CSD_CARD_TYPE_MASK 0xF /* Mask out reserved bits */
+#define EXT_CSD_CARD_TYPE_MASK 0x3F /* Mask out reserved bits */
#define EXT_CSD_CARD_TYPE_DDR_1_8V (1<<2) /* Card can run at 52MHz */
/* DDR mode @1.8V or 3V I/O */
#define EXT_CSD_CARD_TYPE_DDR_1_2V (1<<3) /* Card can run at 52MHz */
/* DDR mode @1.2V I/O */
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| EXT_CSD_CARD_TYPE_DDR_1_2V)
+#define EXT_CSD_CARD_TYPE_SDR_1_8V (1<<4) /* Card can run at 200MHz */
+#define EXT_CSD_CARD_TYPE_SDR_1_2V (1<<5) /* Card can run at 200MHz */
+ /* SDR mode @1.2V I/O */
+
+#define EXT_CSD_CARD_TYPE_SDR_200 (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_SDR_1_2V)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_ALL (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_ALL (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_2V_DDR_52 (EXT_CSD_CARD_TYPE_SDR_1_2V | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_1_8V_DDR_52 (EXT_CSD_CARD_TYPE_SDR_1_8V | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_8V (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_1_8V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_1_2V (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_1_2V | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
+
+#define EXT_CSD_CARD_TYPE_SDR_ALL_DDR_52 (EXT_CSD_CARD_TYPE_SDR_200 | \
+ EXT_CSD_CARD_TYPE_DDR_52 | \
+ EXT_CSD_CARD_TYPE_52 | \
+ EXT_CSD_CARD_TYPE_26)
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
diff --git a/include/linux/mmc/sdhci-pci-data.h b/include/linux/mmc/sdhci-pci-data.h
new file mode 100644
index 000000000000..8959604a13d3
--- /dev/null
+++ b/include/linux/mmc/sdhci-pci-data.h
@@ -0,0 +1,18 @@
+#ifndef LINUX_MMC_SDHCI_PCI_DATA_H
+#define LINUX_MMC_SDHCI_PCI_DATA_H
+
+struct pci_dev;
+
+struct sdhci_pci_data {
+ struct pci_dev *pdev;
+ int slotno;
+ int rst_n_gpio; /* Set to -EINVAL if unused */
+ int cd_gpio; /* Set to -EINVAL if unused */
+ int (*setup)(struct sdhci_pci_data *data);
+ void (*cleanup)(struct sdhci_pci_data *data);
+};
+
+extern struct sdhci_pci_data *(*sdhci_pci_get_data)(struct pci_dev *pdev,
+ int slotno);
+
+#endif
diff --git a/include/linux/mmc/sdhci.h b/include/linux/mmc/sdhci.h
index e4b69353678d..c750f85177d9 100644
--- a/include/linux/mmc/sdhci.h
+++ b/include/linux/mmc/sdhci.h
@@ -90,8 +90,6 @@ struct sdhci_host {
unsigned int quirks2; /* More deviations from spec. */
-#define SDHCI_QUIRK2_OWN_CARD_DETECTION (1<<0)
-
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
@@ -121,6 +119,7 @@ struct sdhci_host {
#define SDHCI_AUTO_CMD23 (1<<7) /* Auto CMD23 support */
#define SDHCI_PV_ENABLED (1<<8) /* Preset value enabled */
#define SDHCI_SDIO_IRQ_ENABLED (1<<9) /* SDIO irq enabled */
+#define SDHCI_HS200_NEEDS_TUNING (1<<10) /* HS200 needs tuning */
unsigned int version; /* SDHCI spec. version */
diff --git a/include/linux/mmc/sdio.h b/include/linux/mmc/sdio.h
index e0b1123497b9..c9fe66c58f8f 100644
--- a/include/linux/mmc/sdio.h
+++ b/include/linux/mmc/sdio.h
@@ -38,6 +38,7 @@
* [8:0] Byte/block count
*/
+#define R4_18V_PRESENT (1<<24)
#define R4_MEMORY_PRESENT (1 << 27)
/*
@@ -85,6 +86,7 @@
#define SDIO_SD_REV_1_01 0 /* SD Physical Spec Version 1.01 */
#define SDIO_SD_REV_1_10 1 /* SD Physical Spec Version 1.10 */
#define SDIO_SD_REV_2_00 2 /* SD Physical Spec Version 2.00 */
+#define SDIO_SD_REV_3_00 3 /* SD Physical Spev Version 3.00 */
#define SDIO_CCCR_IOEx 0x02
#define SDIO_CCCR_IORx 0x03
@@ -134,8 +136,31 @@
#define SDIO_CCCR_SPEED 0x13
#define SDIO_SPEED_SHS 0x01 /* Supports High-Speed mode */
-#define SDIO_SPEED_EHS 0x02 /* Enable High-Speed mode */
-
+#define SDIO_SPEED_BSS_SHIFT 1
+#define SDIO_SPEED_BSS_MASK (7<<SDIO_SPEED_BSS_SHIFT)
+#define SDIO_SPEED_SDR12 (0<<SDIO_SPEED_BSS_SHIFT)
+#define SDIO_SPEED_SDR25 (1<<SDIO_SPEED_BSS_SHIFT)
+#define SDIO_SPEED_SDR50 (2<<SDIO_SPEED_BSS_SHIFT)
+#define SDIO_SPEED_SDR104 (3<<SDIO_SPEED_BSS_SHIFT)
+#define SDIO_SPEED_DDR50 (4<<SDIO_SPEED_BSS_SHIFT)
+#define SDIO_SPEED_EHS SDIO_SPEED_SDR25 /* Enable High-Speed */
+
+#define SDIO_CCCR_UHS 0x14
+#define SDIO_UHS_SDR50 0x01
+#define SDIO_UHS_SDR104 0x02
+#define SDIO_UHS_DDR50 0x04
+
+#define SDIO_CCCR_DRIVE_STRENGTH 0x15
+#define SDIO_SDTx_MASK 0x07
+#define SDIO_DRIVE_SDTA (1<<0)
+#define SDIO_DRIVE_SDTC (1<<1)
+#define SDIO_DRIVE_SDTD (1<<2)
+#define SDIO_DRIVE_DTSx_MASK 0x03
+#define SDIO_DRIVE_DTSx_SHIFT 4
+#define SDIO_DTSx_SET_TYPE_B (0 << SDIO_DRIVE_DTSx_SHIFT)
+#define SDIO_DTSx_SET_TYPE_A (1 << SDIO_DRIVE_DTSx_SHIFT)
+#define SDIO_DTSx_SET_TYPE_C (2 << SDIO_DRIVE_DTSx_SHIFT)
+#define SDIO_DTSx_SET_TYPE_D (3 << SDIO_DRIVE_DTSx_SHIFT)
/*
* Function Basic Registers (FBR)
*/
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 83ac0713ed0a..b29e7f6f8fa5 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -436,6 +436,17 @@ struct spi_device_id {
__attribute__((aligned(sizeof(kernel_ulong_t))));
};
+/* mcp */
+
+#define MCP_NAME_SIZE 20
+#define MCP_MODULE_PREFIX "mcp:"
+
+struct mcp_device_id {
+ char name[MCP_NAME_SIZE];
+ kernel_ulong_t driver_data /* Data private to the driver */
+ __attribute__((aligned(sizeof(kernel_ulong_t))));
+};
+
/* dmi */
enum dmi_field {
DMI_NONE,
diff --git a/include/linux/module.h b/include/linux/module.h
index 3cb7839a60b9..4598bf03e98b 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -205,6 +205,20 @@ enum module_state
MODULE_STATE_GOING,
};
+/**
+ * struct module_ref - per cpu module reference counts
+ * @incs: number of module get on this cpu
+ * @decs: number of module put on this cpu
+ *
+ * We force an alignment on 8 or 16 bytes, so that alloc_percpu()
+ * put @incs/@decs in same cache line, with no extra memory cost,
+ * since alloc_percpu() is fine grained.
+ */
+struct module_ref {
+ unsigned long incs;
+ unsigned long decs;
+} __attribute((aligned(2 * sizeof(unsigned long))));
+
struct module
{
enum module_state state;
@@ -347,10 +361,7 @@ struct module
/* Destruction function. */
void (*exit)(void);
- struct module_ref {
- unsigned int incs;
- unsigned int decs;
- } __percpu *refptr;
+ struct module_ref __percpu *refptr;
#endif
#ifdef CONFIG_CONSTRUCTORS
@@ -434,7 +445,7 @@ extern void __module_put_and_exit(struct module *mod, long code)
#define module_put_and_exit(code) __module_put_and_exit(THIS_MODULE, code);
#ifdef CONFIG_MODULE_UNLOAD
-unsigned int module_refcount(struct module *mod);
+unsigned long module_refcount(struct module *mod);
void __symbol_put(const char *symbol);
#define symbol_put(x) __symbol_put(MODULE_SYMBOL_PREFIX #x)
void symbol_put_addr(void *addr);
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 7939f636c8ba..c47f4d60db0b 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -350,23 +350,23 @@ extern int param_set_charp(const char *val, const struct kernel_param *kp);
extern int param_get_charp(char *buffer, const struct kernel_param *kp);
#define param_check_charp(name, p) __param_check(name, p, char *)
-/* For historical reasons "bool" parameters can be (unsigned) "int". */
+/* We used to allow int as well as bool. We're taking that away! */
extern struct kernel_param_ops param_ops_bool;
extern int param_set_bool(const char *val, const struct kernel_param *kp);
extern int param_get_bool(char *buffer, const struct kernel_param *kp);
-#define param_check_bool(name, p) \
- static inline void __check_##name(void) \
- { \
- BUILD_BUG_ON(!__same_type((p), bool *) && \
- !__same_type((p), unsigned int *) && \
- !__same_type((p), int *)); \
- }
+#define param_check_bool(name, p) __param_check(name, p, bool)
extern struct kernel_param_ops param_ops_invbool;
extern int param_set_invbool(const char *val, const struct kernel_param *kp);
extern int param_get_invbool(char *buffer, const struct kernel_param *kp);
#define param_check_invbool(name, p) __param_check(name, p, bool)
+/* An int, which can only be set like a bool (though it shows as an int). */
+extern struct kernel_param_ops param_ops_bint;
+extern int param_set_bint(const char *val, const struct kernel_param *kp);
+#define param_get_bint param_get_int
+#define param_check_bint param_check_int
+
/**
* module_param_array - a parameter which is an array of some type
* @name: the name of the array variable
@@ -395,6 +395,7 @@ extern int param_get_invbool(char *buffer, const struct kernel_param *kp);
* module_param_named() for why this might be necessary.
*/
#define module_param_array_named(name, array, type, nump, perm) \
+ param_check_##type(name, &(array)[0]); \
static const struct kparam_array __param_arr_##name \
= { .max = ARRAY_SIZE(array), .num = nump, \
.ops = &param_ops_##type, \
diff --git a/include/linux/mroute6.h b/include/linux/mroute6.h
index a3759cb0ac10..6d8c7251eb8d 100644
--- a/include/linux/mroute6.h
+++ b/include/linux/mroute6.h
@@ -43,9 +43,11 @@ typedef unsigned short mifi_t;
typedef __u32 if_mask;
#define NIFBITS (sizeof(if_mask) * 8) /* bits per mask */
-#if !defined(__KERNEL__) && !defined(DIV_ROUND_UP)
+#if !defined(__KERNEL__)
+#if !defined(DIV_ROUND_UP)
#define DIV_ROUND_UP(x,y) (((x) + ((y) - 1)) / (y))
#endif
+#endif
typedef struct if_set {
if_mask ifs_bits[DIV_ROUND_UP(IF_SETSIZE, NIFBITS)];
diff --git a/include/linux/patchkey.h b/include/linux/patchkey.h
index d974a6e92372..aefda0ec6e62 100644
--- a/include/linux/patchkey.h
+++ b/include/linux/patchkey.h
@@ -32,7 +32,8 @@
# else
# error "could not determine byte order"
# endif
-#elif defined(__BYTE_ORDER)
+#else
+#if defined(__BYTE_ORDER)
# if __BYTE_ORDER == __BIG_ENDIAN
# define _PATCHKEY(id) (0xfd00|id)
# elif __BYTE_ORDER == __LITTLE_ENDIAN
@@ -41,5 +42,6 @@
# error "could not determine byte order"
# endif
#endif
+#endif
#endif /* _LINUX_PATCHKEY_H */
diff --git a/include/linux/pmu.h b/include/linux/pmu.h
index cafe98d96948..84e6a55a1202 100644
--- a/include/linux/pmu.h
+++ b/include/linux/pmu.h
@@ -6,6 +6,8 @@
* Copyright (C) 1998 Paul Mackerras.
*/
+#ifndef _LINUX_PMU_H
+#define _LINUX_PMU_H
#define PMU_DRIVER_VERSION 2
@@ -207,3 +209,5 @@ extern int pmu_sys_suspended;
#endif
#endif /* __KERNEL__ */
+
+#endif /* _LINUX_PMU_H */
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
index 800f113bea66..a27e56ca41a4 100644
--- a/include/linux/ptrace.h
+++ b/include/linux/ptrace.h
@@ -127,8 +127,9 @@ extern void __ptrace_link(struct task_struct *child,
struct task_struct *new_parent);
extern void __ptrace_unlink(struct task_struct *child);
extern void exit_ptrace(struct task_struct *tracer);
-#define PTRACE_MODE_READ 1
-#define PTRACE_MODE_ATTACH 2
+#define PTRACE_MODE_READ 0x01
+#define PTRACE_MODE_ATTACH 0x02
+#define PTRACE_MODE_NOAUDIT 0x04
/* Returns 0 on success, -errno on denial. */
extern int __ptrace_may_access(struct task_struct *task, unsigned int mode);
/* Returns true on success, false on denial. */
diff --git a/include/linux/security.h b/include/linux/security.h
index 0ccceb9b1046..83c18e8c846d 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -54,8 +54,8 @@ struct user_namespace;
* These functions are in security/capability.c and are used
* as the default capabilities functions
*/
-extern int cap_capable(struct task_struct *tsk, const struct cred *cred,
- struct user_namespace *ns, int cap, int audit);
+extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
+ int cap, int audit);
extern int cap_settime(const struct timespec *ts, const struct timezone *tz);
extern int cap_ptrace_access_check(struct task_struct *child, unsigned int mode);
extern int cap_ptrace_traceme(struct task_struct *parent);
@@ -96,7 +96,6 @@ struct xfrm_user_sec_ctx;
struct seq_file;
extern int cap_netlink_send(struct sock *sk, struct sk_buff *skb);
-extern int cap_netlink_recv(struct sk_buff *skb, int cap);
void reset_security_ops(void);
@@ -799,12 +798,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @skb contains the sk_buff structure for the netlink message.
* Return 0 if the information was successfully saved and message
* is allowed to be transmitted.
- * @netlink_recv:
- * Check permission before processing the received netlink message in
- * @skb.
- * @skb contains the sk_buff structure for the netlink message.
- * @cap indicates the capability required
- * Return 0 if permission is granted.
*
* Security hooks for Unix domain networking.
*
@@ -1268,7 +1261,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* @capable:
* Check whether the @tsk process has the @cap capability in the indicated
* credentials.
- * @tsk contains the task_struct for the process.
* @cred contains the credentials to use.
* @ns contains the user namespace we want the capability in
* @cap contains the capability <include/linux/capability.h>.
@@ -1392,8 +1384,8 @@ struct security_operations {
const kernel_cap_t *effective,
const kernel_cap_t *inheritable,
const kernel_cap_t *permitted);
- int (*capable) (struct task_struct *tsk, const struct cred *cred,
- struct user_namespace *ns, int cap, int audit);
+ int (*capable) (const struct cred *cred, struct user_namespace *ns,
+ int cap, int audit);
int (*quotactl) (int cmds, int type, int id, struct super_block *sb);
int (*quota_on) (struct dentry *dentry);
int (*syslog) (int type);
@@ -1563,7 +1555,6 @@ struct security_operations {
struct sembuf *sops, unsigned nsops, int alter);
int (*netlink_send) (struct sock *sk, struct sk_buff *skb);
- int (*netlink_recv) (struct sk_buff *skb, int cap);
void (*d_instantiate) (struct dentry *dentry, struct inode *inode);
@@ -1675,12 +1666,10 @@ int security_capset(struct cred *new, const struct cred *old,
const kernel_cap_t *effective,
const kernel_cap_t *inheritable,
const kernel_cap_t *permitted);
-int security_capable(struct user_namespace *ns, const struct cred *cred,
- int cap);
-int security_real_capable(struct task_struct *tsk, struct user_namespace *ns,
+int security_capable(const struct cred *cred, struct user_namespace *ns,
int cap);
-int security_real_capable_noaudit(struct task_struct *tsk,
- struct user_namespace *ns, int cap);
+int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns,
+ int cap);
int security_quotactl(int cmds, int type, int id, struct super_block *sb);
int security_quota_on(struct dentry *dentry);
int security_syslog(int type);
@@ -1817,7 +1806,6 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode);
int security_getprocattr(struct task_struct *p, char *name, char **value);
int security_setprocattr(struct task_struct *p, char *name, void *value, size_t size);
int security_netlink_send(struct sock *sk, struct sk_buff *skb);
-int security_netlink_recv(struct sk_buff *skb, int cap);
int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
void security_release_secctx(char *secdata, u32 seclen);
@@ -1875,32 +1863,15 @@ static inline int security_capset(struct cred *new,
return cap_capset(new, old, effective, inheritable, permitted);
}
-static inline int security_capable(struct user_namespace *ns,
- const struct cred *cred, int cap)
-{
- return cap_capable(current, cred, ns, cap, SECURITY_CAP_AUDIT);
-}
-
-static inline int security_real_capable(struct task_struct *tsk, struct user_namespace *ns, int cap)
+static inline int security_capable(const struct cred *cred,
+ struct user_namespace *ns, int cap)
{
- int ret;
-
- rcu_read_lock();
- ret = cap_capable(tsk, __task_cred(tsk), ns, cap, SECURITY_CAP_AUDIT);
- rcu_read_unlock();
- return ret;
+ return cap_capable(cred, ns, cap, SECURITY_CAP_AUDIT);
}
-static inline
-int security_real_capable_noaudit(struct task_struct *tsk, struct user_namespace *ns, int cap)
-{
- int ret;
-
- rcu_read_lock();
- ret = cap_capable(tsk, __task_cred(tsk), ns, cap,
- SECURITY_CAP_NOAUDIT);
- rcu_read_unlock();
- return ret;
+static inline int security_capable_noaudit(const struct cred *cred,
+ struct user_namespace *ns, int cap) {
+ return cap_capable(cred, ns, cap, SECURITY_CAP_NOAUDIT);
}
static inline int security_quotactl(int cmds, int type, int id,
@@ -2517,11 +2488,6 @@ static inline int security_netlink_send(struct sock *sk, struct sk_buff *skb)
return cap_netlink_send(sk, skb);
}
-static inline int security_netlink_recv(struct sk_buff *skb, int cap)
-{
- return cap_netlink_recv(skb, cap);
-}
-
static inline int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
{
return -EOPNOTSUPP;
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index b67305e3ad57..c91ace70c21d 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -207,6 +207,10 @@
/* Xilinx PSS UART */
#define PORT_XUARTPS 98
+/* Atheros AR933X SoC */
+#define PORT_AR933X 99
+
+
#ifdef __KERNEL__
#include <linux/compiler.h>
diff --git a/include/linux/sound.h b/include/linux/sound.h
index 44dcf0570432..fae20ba01fbf 100644
--- a/include/linux/sound.h
+++ b/include/linux/sound.h
@@ -1,3 +1,5 @@
+#ifndef _LINUX_SOUND_H
+#define _LINUX_SOUND_H
/*
* Minor numbers for the sound driver.
@@ -42,3 +44,5 @@ extern void unregister_sound_mixer(int unit);
extern void unregister_sound_midi(int unit);
extern void unregister_sound_dsp(int unit);
#endif /* __KERNEL__ */
+
+#endif /* _LINUX_SOUND_H */
diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h
index fe204fe39f7c..dfcf86f013a9 100644
--- a/include/linux/soundcard.h
+++ b/include/linux/soundcard.h
@@ -198,7 +198,8 @@ typedef struct seq_event_rec {
# else
# error "could not determine byte order"
# endif
-#elif defined(__BYTE_ORDER)
+#else
+# if defined(__BYTE_ORDER)
# if __BYTE_ORDER == __BIG_ENDIAN
# define AFMT_S16_NE AFMT_S16_BE
# elif __BYTE_ORDER == __LITTLE_ENDIAN
@@ -206,6 +207,7 @@ typedef struct seq_event_rec {
# else
# error "could not determine byte order"
# endif
+# endif
#endif
/*
diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
index 8620f79658d4..dfa900948af7 100644
--- a/include/linux/sunrpc/svc_xprt.h
+++ b/include/linux/sunrpc/svc_xprt.h
@@ -109,7 +109,7 @@ static inline int register_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u
int svc_reg_xprt_class(struct svc_xprt_class *);
void svc_unreg_xprt_class(struct svc_xprt_class *);
-void svc_xprt_init(struct svc_xprt_class *, struct svc_xprt *,
+void svc_xprt_init(struct net *, struct svc_xprt_class *, struct svc_xprt *,
struct svc_serv *);
int svc_create_xprt(struct svc_serv *, const char *, struct net *,
const int, const unsigned short, int);
@@ -118,7 +118,6 @@ void svc_xprt_received(struct svc_xprt *);
void svc_xprt_put(struct svc_xprt *xprt);
void svc_xprt_copy_addrs(struct svc_rqst *rqstp, struct svc_xprt *xprt);
void svc_close_xprt(struct svc_xprt *xprt);
-void svc_delete_xprt(struct svc_xprt *xprt);
int svc_port_is_privileged(struct sockaddr *sin);
int svc_print_xprts(char *buf, int maxlen);
struct svc_xprt *svc_find_xprt(struct svc_serv *serv, const char *xcl_name,
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index 85c50b40759d..c84e9741cb2a 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -34,7 +34,7 @@ struct svc_sock {
/*
* Function prototypes.
*/
-void svc_close_all(struct list_head *);
+void svc_close_all(struct svc_serv *);
int svc_recv(struct svc_rqst *, long);
int svc_send(struct svc_rqst *);
void svc_drop(struct svc_rqst *);
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 4b752d5ee80e..d2f74f8e3fe3 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -343,6 +343,8 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_NV21 v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */
#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
+#define V4L2_PIX_FMT_NV24 v4l2_fourcc('N', 'V', '2', '4') /* 24 Y/CbCr 4:4:4 */
+#define V4L2_PIX_FMT_NV42 v4l2_fourcc('N', 'V', '4', '2') /* 24 Y/CrCb 4:4:4 */
/* two non contiguous planes - one Y, one Cr + Cb interleaved */
#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */
diff --git a/include/linux/zorro_ids.h b/include/linux/zorro_ids.h
index 7e749088910d..74bc53bcfdcf 100644
--- a/include/linux/zorro_ids.h
+++ b/include/linux/zorro_ids.h
@@ -360,8 +360,8 @@
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM ZORRO_ID(VILLAGE_TRONIC, 0x0B, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG ZORRO_ID(VILLAGE_TRONIC, 0x0C, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_SEGMENTED_MODE ZORRO_ID(VILLAGE_TRONIC, 0x0D, 0)
-#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0)
-#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_MEM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM1 ZORRO_ID(VILLAGE_TRONIC, 0x15, 0)
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_RAM2 ZORRO_ID(VILLAGE_TRONIC, 0x16, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z2_REG ZORRO_ID(VILLAGE_TRONIC, 0x17, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 ZORRO_ID(VILLAGE_TRONIC, 0x18, 0)
#define ZORRO_PROD_VILLAGE_TRONIC_ARIADNE ZORRO_ID(VILLAGE_TRONIC, 0xC9, 0)
diff --git a/include/video/edid.h b/include/video/edid.h
index 928c342b33d6..c5f198704912 100644
--- a/include/video/edid.h
+++ b/include/video/edid.h
@@ -1,16 +1,14 @@
#ifndef __linux_video_edid_h__
#define __linux_video_edid_h__
-#if !defined(__KERNEL__) || defined(CONFIG_X86)
-
struct edid_info {
unsigned char dummy[128];
};
#ifdef __KERNEL__
+#ifdef CONFIG_X86
extern struct edid_info edid_info;
-#endif /* __KERNEL__ */
-
+#endif
#endif
#endif /* __linux_video_edid_h__ */
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 378c7ed6760b..062b3b24ff10 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -200,6 +200,10 @@ enum omap_dss_clk_source {
OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI, /* OMAP4: PLL2_CLK2 */
};
+enum omap_hdmi_flags {
+ OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
+};
+
/* RFBI */
struct rfbi_timings {
@@ -294,8 +298,8 @@ int dsi_vc_set_max_rx_packet_size(struct omap_dss_device *dssdev, int channel,
u16 len);
int dsi_vc_send_null(struct omap_dss_device *dssdev, int channel);
int dsi_vc_send_bta_sync(struct omap_dss_device *dssdev, int channel);
-int dsi_video_mode_enable(struct omap_dss_device *dssdev, int channel);
-void dsi_video_mode_disable(struct omap_dss_device *dssdev, int channel);
+int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel);
+void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel);
/* Board specific data */
struct omap_dss_board_info {
@@ -309,6 +313,8 @@ struct omap_dss_board_info {
/* Init with the board info */
extern int omap_display_init(struct omap_dss_board_info *board_data);
+/* HDMI mux init*/
+extern int omap_hdmi_init(enum omap_hdmi_flags flags);
struct omap_display_platform_data {
struct omap_dss_board_info *board_data;
@@ -352,8 +358,6 @@ struct omap_dss_cpr_coefs {
};
struct omap_overlay_info {
- bool enabled;
-
u32 paddr;
u32 p_uv_addr; /* for NV12 format */
u16 screen_width;
@@ -385,11 +389,21 @@ struct omap_overlay {
/* dynamic fields */
struct omap_overlay_manager *manager;
- struct omap_overlay_info info;
- bool manager_changed;
- /* if true, info has been changed, but not applied() yet */
- bool info_dirty;
+ /*
+ * The following functions do not block:
+ *
+ * is_enabled
+ * set_overlay_info
+ * get_overlay_info
+ *
+ * The rest of the functions may block and cannot be called from
+ * interrupt context
+ */
+
+ int (*enable)(struct omap_overlay *ovl);
+ int (*disable)(struct omap_overlay *ovl);
+ bool (*is_enabled)(struct omap_overlay *ovl);
int (*set_manager)(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr);
@@ -418,23 +432,27 @@ struct omap_overlay_manager_info {
struct omap_overlay_manager {
struct kobject kobj;
- struct list_head list;
/* static fields */
const char *name;
enum omap_channel id;
enum omap_overlay_manager_caps caps;
- int num_overlays;
- struct omap_overlay **overlays;
+ struct list_head overlays;
enum omap_display_type supported_displays;
/* dynamic fields */
struct omap_dss_device *device;
- struct omap_overlay_manager_info info;
- bool device_changed;
- /* if true, info has been changed but not applied() yet */
- bool info_dirty;
+ /*
+ * The following functions do not block:
+ *
+ * set_manager_info
+ * get_manager_info
+ * apply
+ *
+ * The rest of the functions may block and cannot be called from
+ * interrupt context
+ */
int (*set_device)(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev);
@@ -448,9 +466,6 @@ struct omap_overlay_manager {
int (*apply)(struct omap_overlay_manager *mgr);
int (*wait_for_go)(struct omap_overlay_manager *mgr);
int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
-
- int (*enable)(struct omap_overlay_manager *mgr);
- int (*disable)(struct omap_overlay_manager *mgr);
};
struct omap_dss_device {
@@ -662,12 +677,7 @@ void omapdss_dsi_vc_enable_hs(struct omap_dss_device *dssdev, int channel,
bool enable);
int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable);
-int omap_dsi_prepare_update(struct omap_dss_device *dssdev,
- u16 *x, u16 *y, u16 *w, u16 *h,
- bool enlarge_update_area);
-int omap_dsi_update(struct omap_dss_device *dssdev,
- int channel,
- u16 x, u16 y, u16 w, u16 h,
+int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
void (*callback)(int, void *), void *data);
int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel);
int omap_dsi_set_vc_id(struct omap_dss_device *dssdev, int channel, int vc_id);
diff --git a/include/video/sh_mipi_dsi.h b/include/video/sh_mipi_dsi.h
index 6cb95c977de9..434d56b4a1a5 100644
--- a/include/video/sh_mipi_dsi.h
+++ b/include/video/sh_mipi_dsi.h
@@ -28,14 +28,33 @@ enum sh_mipi_dsi_data_fmt {
struct sh_mobile_lcdc_chan_cfg;
#define SH_MIPI_DSI_HSABM (1 << 0)
-#define SH_MIPI_DSI_HSPBM (1 << 1)
+#define SH_MIPI_DSI_HBPBM (1 << 1)
+#define SH_MIPI_DSI_HFPBM (1 << 2)
+#define SH_MIPI_DSI_BL2E (1 << 3)
+#define SH_MIPI_DSI_VSEE (1 << 4)
+#define SH_MIPI_DSI_HSEE (1 << 5)
+#define SH_MIPI_DSI_HSAE (1 << 6)
+
+#define SH_MIPI_DSI_HSbyteCLK (1 << 24)
+#define SH_MIPI_DSI_HS6divCLK (1 << 25)
+#define SH_MIPI_DSI_HS4divCLK (1 << 26)
+
+#define SH_MIPI_DSI_SYNC_PULSES_MODE (SH_MIPI_DSI_VSEE | \
+ SH_MIPI_DSI_HSEE | \
+ SH_MIPI_DSI_HSAE)
+#define SH_MIPI_DSI_SYNC_EVENTS_MODE (0)
+#define SH_MIPI_DSI_SYNC_BURST_MODE (SH_MIPI_DSI_BL2E)
struct sh_mipi_dsi_info {
enum sh_mipi_dsi_data_fmt data_format;
struct sh_mobile_lcdc_chan_cfg *lcd_chan;
+ int lane;
unsigned long flags;
u32 clksrc;
unsigned int vsynw_offset;
+ int (*set_dot_clock)(struct platform_device *pdev,
+ void __iomem *base,
+ int enable);
};
#endif
diff --git a/include/video/sh_mobile_lcdc.h b/include/video/sh_mobile_lcdc.h
index 8101b726b48a..fe30b759c51e 100644
--- a/include/video/sh_mobile_lcdc.h
+++ b/include/video/sh_mobile_lcdc.h
@@ -174,7 +174,8 @@ struct sh_mobile_lcdc_bl_info {
struct sh_mobile_lcdc_chan_cfg {
int chan;
- int bpp;
+ int fourcc;
+ int colorspace;
int interface_type; /* selects RGBn or SYSn I/F, see above */
int clock_divider;
unsigned long flags; /* LCDC_FLAGS_... */
@@ -184,7 +185,6 @@ struct sh_mobile_lcdc_chan_cfg {
struct sh_mobile_lcdc_board_cfg board_cfg;
struct sh_mobile_lcdc_bl_info bl_info;
struct sh_mobile_lcdc_sys_bus_cfg sys_bus_cfg; /* only for SYSn I/F */
- int nonstd;
struct sh_mobile_meram_cfg *meram_cfg;
};
diff --git a/init/main.c b/init/main.c
index 415548e808d2..ff49a6dacfbb 100644
--- a/init/main.c
+++ b/init/main.c
@@ -648,7 +648,7 @@ static void __init do_ctors(void)
#endif
}
-int initcall_debug;
+bool initcall_debug;
core_param(initcall_debug, initcall_debug, bool, 0644);
static char msgbuf[64];
diff --git a/kernel/async.c b/kernel/async.c
index 80b74b88fefe..bd0c168a3bbe 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -78,8 +78,6 @@ static DECLARE_WAIT_QUEUE_HEAD(async_done);
static atomic_t entry_count;
-extern int initcall_debug;
-
/*
* MUST be called with the lock held!
diff --git a/kernel/audit.c b/kernel/audit.c
index 2c1d6ab7106e..57e3f5107937 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -601,13 +601,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
case AUDIT_TTY_SET:
case AUDIT_TRIM:
case AUDIT_MAKE_EQUIV:
- if (security_netlink_recv(skb, CAP_AUDIT_CONTROL))
+ if (!capable(CAP_AUDIT_CONTROL))
err = -EPERM;
break;
case AUDIT_USER:
case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG:
case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2:
- if (security_netlink_recv(skb, CAP_AUDIT_WRITE))
+ if (!capable(CAP_AUDIT_WRITE))
err = -EPERM;
break;
default: /* bad msg */
diff --git a/kernel/capability.c b/kernel/capability.c
index b463871a4e69..0fcf1c14a297 100644
--- a/kernel/capability.c
+++ b/kernel/capability.c
@@ -287,74 +287,84 @@ error:
}
/**
- * has_capability - Does a task have a capability in init_user_ns
+ * has_ns_capability - Does a task have a capability in a specific user ns
* @t: The task in question
+ * @ns: target user namespace
* @cap: The capability to be tested for
*
* Return true if the specified task has the given superior capability
- * currently in effect to the initial user namespace, false if not.
+ * currently in effect to the specified user namespace, false if not.
*
* Note that this does not set PF_SUPERPRIV on the task.
*/
-bool has_capability(struct task_struct *t, int cap)
+bool has_ns_capability(struct task_struct *t,
+ struct user_namespace *ns, int cap)
{
- int ret = security_real_capable(t, &init_user_ns, cap);
+ int ret;
+
+ rcu_read_lock();
+ ret = security_capable(__task_cred(t), ns, cap);
+ rcu_read_unlock();
return (ret == 0);
}
/**
- * has_capability - Does a task have a capability in a specific user ns
+ * has_capability - Does a task have a capability in init_user_ns
* @t: The task in question
- * @ns: target user namespace
* @cap: The capability to be tested for
*
* Return true if the specified task has the given superior capability
- * currently in effect to the specified user namespace, false if not.
+ * currently in effect to the initial user namespace, false if not.
*
* Note that this does not set PF_SUPERPRIV on the task.
*/
-bool has_ns_capability(struct task_struct *t,
- struct user_namespace *ns, int cap)
+bool has_capability(struct task_struct *t, int cap)
{
- int ret = security_real_capable(t, ns, cap);
-
- return (ret == 0);
+ return has_ns_capability(t, &init_user_ns, cap);
}
/**
- * has_capability_noaudit - Does a task have a capability (unaudited)
+ * has_ns_capability_noaudit - Does a task have a capability (unaudited)
+ * in a specific user ns.
* @t: The task in question
+ * @ns: target user namespace
* @cap: The capability to be tested for
*
* Return true if the specified task has the given superior capability
- * currently in effect to init_user_ns, false if not. Don't write an
- * audit message for the check.
+ * currently in effect to the specified user namespace, false if not.
+ * Do not write an audit message for the check.
*
* Note that this does not set PF_SUPERPRIV on the task.
*/
-bool has_capability_noaudit(struct task_struct *t, int cap)
+bool has_ns_capability_noaudit(struct task_struct *t,
+ struct user_namespace *ns, int cap)
{
- int ret = security_real_capable_noaudit(t, &init_user_ns, cap);
+ int ret;
+
+ rcu_read_lock();
+ ret = security_capable_noaudit(__task_cred(t), ns, cap);
+ rcu_read_unlock();
return (ret == 0);
}
/**
- * capable - Determine if the current task has a superior capability in effect
+ * has_capability_noaudit - Does a task have a capability (unaudited) in the
+ * initial user ns
+ * @t: The task in question
* @cap: The capability to be tested for
*
- * Return true if the current task has the given superior capability currently
- * available for use, false if not.
+ * Return true if the specified task has the given superior capability
+ * currently in effect to init_user_ns, false if not. Don't write an
+ * audit message for the check.
*
- * This sets PF_SUPERPRIV on the task if the capability is available on the
- * assumption that it's about to be used.
+ * Note that this does not set PF_SUPERPRIV on the task.
*/
-bool capable(int cap)
+bool has_capability_noaudit(struct task_struct *t, int cap)
{
- return ns_capable(&init_user_ns, cap);
+ return has_ns_capability_noaudit(t, &init_user_ns, cap);
}
-EXPORT_SYMBOL(capable);
/**
* ns_capable - Determine if the current task has a superior capability in effect
@@ -374,7 +384,7 @@ bool ns_capable(struct user_namespace *ns, int cap)
BUG();
}
- if (security_capable(ns, current_cred(), cap) == 0) {
+ if (has_ns_capability(current, ns, cap)) {
current->flags |= PF_SUPERPRIV;
return true;
}
@@ -383,18 +393,20 @@ bool ns_capable(struct user_namespace *ns, int cap)
EXPORT_SYMBOL(ns_capable);
/**
- * task_ns_capable - Determine whether current task has a superior
- * capability targeted at a specific task's user namespace.
- * @t: The task whose user namespace is targeted.
- * @cap: The capability in question.
+ * capable - Determine if the current task has a superior capability in effect
+ * @cap: The capability to be tested for
+ *
+ * Return true if the current task has the given superior capability currently
+ * available for use, false if not.
*
- * Return true if it does, false otherwise.
+ * This sets PF_SUPERPRIV on the task if the capability is available on the
+ * assumption that it's about to be used.
*/
-bool task_ns_capable(struct task_struct *t, int cap)
+bool capable(int cap)
{
- return ns_capable(task_cred_xxx(t, user)->user_ns, cap);
+ return ns_capable(&init_user_ns, cap);
}
-EXPORT_SYMBOL(task_ns_capable);
+EXPORT_SYMBOL(capable);
/**
* nsown_capable - Check superior capability to one's own user_ns
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c
index 63786e71a3cd..e2ae7349437f 100644
--- a/kernel/debug/kdb/kdb_main.c
+++ b/kernel/debug/kdb/kdb_main.c
@@ -1982,7 +1982,7 @@ static int kdb_lsmod(int argc, const char **argv)
kdb_printf("%-20s%8u 0x%p ", mod->name,
mod->core_size, (void *)mod);
#ifdef CONFIG_MODULE_UNLOAD
- kdb_printf("%4d ", module_refcount(mod));
+ kdb_printf("%4ld ", module_refcount(mod));
#endif
if (mod->state == MODULE_STATE_GOING)
kdb_printf(" (Unloading)");
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index a73dd6c7372d..b7952316016a 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -15,7 +15,7 @@
#define istate core_internal_state__do_not_mess_with_it
-extern int noirqdebug;
+extern bool noirqdebug;
/*
* Bits used by threaded handlers:
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index dc813a948be2..611cd6003c45 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -325,7 +325,7 @@ void note_interrupt(unsigned int irq, struct irq_desc *desc,
desc->irqs_unhandled = 0;
}
-int noirqdebug __read_mostly;
+bool noirqdebug __read_mostly;
int noirqdebug_setup(char *str)
{
diff --git a/kernel/module.c b/kernel/module.c
index 178333c48d1e..acf6ed3ebe81 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -62,12 +62,6 @@
#define CREATE_TRACE_POINTS
#include <trace/events/module.h>
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt , a...)
-#endif
-
#ifndef ARCH_SHF_SMALL
#define ARCH_SHF_SMALL 0
#endif
@@ -138,7 +132,6 @@ struct load_info {
unsigned long len;
Elf_Shdr *sechdrs;
char *secstrings, *strtab;
- unsigned long *strmap;
unsigned long symoffs, stroffs;
struct _ddebug *debug;
unsigned int num_debug;
@@ -410,7 +403,7 @@ const struct kernel_symbol *find_symbol(const char *name,
return fsa.sym;
}
- DEBUGP("Failed to find symbol %s\n", name);
+ pr_debug("Failed to find symbol %s\n", name);
return NULL;
}
EXPORT_SYMBOL_GPL(find_symbol);
@@ -600,11 +593,11 @@ static int already_uses(struct module *a, struct module *b)
list_for_each_entry(use, &b->source_list, source_list) {
if (use->source == a) {
- DEBUGP("%s uses %s!\n", a->name, b->name);
+ pr_debug("%s uses %s!\n", a->name, b->name);
return 1;
}
}
- DEBUGP("%s does not use %s!\n", a->name, b->name);
+ pr_debug("%s does not use %s!\n", a->name, b->name);
return 0;
}
@@ -619,7 +612,7 @@ static int add_module_usage(struct module *a, struct module *b)
{
struct module_use *use;
- DEBUGP("Allocating new usage for %s.\n", a->name);
+ pr_debug("Allocating new usage for %s.\n", a->name);
use = kmalloc(sizeof(*use), GFP_ATOMIC);
if (!use) {
printk(KERN_WARNING "%s: out of memory loading\n", a->name);
@@ -663,7 +656,7 @@ static void module_unload_free(struct module *mod)
mutex_lock(&module_mutex);
list_for_each_entry_safe(use, tmp, &mod->target_list, target_list) {
struct module *i = use->target;
- DEBUGP("%s unusing %s\n", mod->name, i->name);
+ pr_debug("%s unusing %s\n", mod->name, i->name);
module_put(i);
list_del(&use->source_list);
list_del(&use->target_list);
@@ -726,9 +719,9 @@ static int try_stop_module(struct module *mod, int flags, int *forced)
}
}
-unsigned int module_refcount(struct module *mod)
+unsigned long module_refcount(struct module *mod)
{
- unsigned int incs = 0, decs = 0;
+ unsigned long incs = 0, decs = 0;
int cpu;
for_each_possible_cpu(cpu)
@@ -761,7 +754,7 @@ static void wait_for_zero_refcount(struct module *mod)
/* Since we might sleep for some time, release the mutex first */
mutex_unlock(&module_mutex);
for (;;) {
- DEBUGP("Looking at refcount...\n");
+ pr_debug("Looking at refcount...\n");
set_current_state(TASK_UNINTERRUPTIBLE);
if (module_refcount(mod) == 0)
break;
@@ -804,7 +797,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
if (mod->state != MODULE_STATE_LIVE) {
/* FIXME: if (force), slam module count and wake up
waiter --RR */
- DEBUGP("%s already dying\n", mod->name);
+ pr_debug("%s already dying\n", mod->name);
ret = -EBUSY;
goto out;
}
@@ -849,12 +842,32 @@ out:
return ret;
}
+static size_t module_flags_taint(struct module *mod, char *buf)
+{
+ size_t l = 0;
+
+ if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
+ buf[l++] = 'P';
+ if (mod->taints & (1 << TAINT_OOT_MODULE))
+ buf[l++] = 'O';
+ if (mod->taints & (1 << TAINT_FORCED_MODULE))
+ buf[l++] = 'F';
+ if (mod->taints & (1 << TAINT_CRAP))
+ buf[l++] = 'C';
+ /*
+ * TAINT_FORCED_RMMOD: could be added.
+ * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
+ * apply to modules.
+ */
+ return l;
+}
+
static inline void print_unload_info(struct seq_file *m, struct module *mod)
{
struct module_use *use;
int printed_something = 0;
- seq_printf(m, " %u ", module_refcount(mod));
+ seq_printf(m, " %lu ", module_refcount(mod));
/* Always include a trailing , so userspace can differentiate
between this and the old multi-field proc format. */
@@ -904,13 +917,11 @@ EXPORT_SYMBOL_GPL(symbol_put_addr);
static ssize_t show_refcnt(struct module_attribute *mattr,
struct module_kobject *mk, char *buffer)
{
- return sprintf(buffer, "%u\n", module_refcount(mk->mod));
+ return sprintf(buffer, "%lu\n", module_refcount(mk->mod));
}
-static struct module_attribute refcnt = {
- .attr = { .name = "refcnt", .mode = 0444 },
- .show = show_refcnt,
-};
+static struct module_attribute modinfo_refcnt =
+ __ATTR(refcnt, 0444, show_refcnt, NULL);
void module_put(struct module *module)
{
@@ -970,10 +981,8 @@ static ssize_t show_initstate(struct module_attribute *mattr,
return sprintf(buffer, "%s\n", state);
}
-static struct module_attribute initstate = {
- .attr = { .name = "initstate", .mode = 0444 },
- .show = show_initstate,
-};
+static struct module_attribute modinfo_initstate =
+ __ATTR(initstate, 0444, show_initstate, NULL);
static ssize_t store_uevent(struct module_attribute *mattr,
struct module_kobject *mk,
@@ -986,18 +995,50 @@ static ssize_t store_uevent(struct module_attribute *mattr,
return count;
}
-struct module_attribute module_uevent = {
- .attr = { .name = "uevent", .mode = 0200 },
- .store = store_uevent,
-};
+struct module_attribute module_uevent =
+ __ATTR(uevent, 0200, NULL, store_uevent);
+
+static ssize_t show_coresize(struct module_attribute *mattr,
+ struct module_kobject *mk, char *buffer)
+{
+ return sprintf(buffer, "%u\n", mk->mod->core_size);
+}
+
+static struct module_attribute modinfo_coresize =
+ __ATTR(coresize, 0444, show_coresize, NULL);
+
+static ssize_t show_initsize(struct module_attribute *mattr,
+ struct module_kobject *mk, char *buffer)
+{
+ return sprintf(buffer, "%u\n", mk->mod->init_size);
+}
+
+static struct module_attribute modinfo_initsize =
+ __ATTR(initsize, 0444, show_initsize, NULL);
+
+static ssize_t show_taint(struct module_attribute *mattr,
+ struct module_kobject *mk, char *buffer)
+{
+ size_t l;
+
+ l = module_flags_taint(mk->mod, buffer);
+ buffer[l++] = '\n';
+ return l;
+}
+
+static struct module_attribute modinfo_taint =
+ __ATTR(taint, 0444, show_taint, NULL);
static struct module_attribute *modinfo_attrs[] = {
+ &module_uevent,
&modinfo_version,
&modinfo_srcversion,
- &initstate,
- &module_uevent,
+ &modinfo_initstate,
+ &modinfo_coresize,
+ &modinfo_initsize,
+ &modinfo_taint,
#ifdef CONFIG_MODULE_UNLOAD
- &refcnt,
+ &modinfo_refcnt,
#endif
NULL,
};
@@ -1057,7 +1098,7 @@ static int check_version(Elf_Shdr *sechdrs,
if (versions[i].crc == maybe_relocated(*crc, crc_owner))
return 1;
- DEBUGP("Found checksum %lX vs module %lX\n",
+ pr_debug("Found checksum %lX vs module %lX\n",
maybe_relocated(*crc, crc_owner), versions[i].crc);
goto bad_version;
}
@@ -1834,7 +1875,7 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
case SHN_COMMON:
/* We compiled with -fno-common. These are not
supposed to happen. */
- DEBUGP("Common symbol: %s\n", name);
+ pr_debug("Common symbol: %s\n", name);
printk("%s: please compile with -fno-common\n",
mod->name);
ret = -ENOEXEC;
@@ -1842,7 +1883,7 @@ static int simplify_symbols(struct module *mod, const struct load_info *info)
case SHN_ABS:
/* Don't need to do anything */
- DEBUGP("Absolute symbol: 0x%08lx\n",
+ pr_debug("Absolute symbol: 0x%08lx\n",
(long)sym[i].st_value);
break;
@@ -1966,7 +2007,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
for (i = 0; i < info->hdr->e_shnum; i++)
info->sechdrs[i].sh_entsize = ~0UL;
- DEBUGP("Core section allocation order:\n");
+ pr_debug("Core section allocation order:\n");
for (m = 0; m < ARRAY_SIZE(masks); ++m) {
for (i = 0; i < info->hdr->e_shnum; ++i) {
Elf_Shdr *s = &info->sechdrs[i];
@@ -1978,7 +2019,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
|| strstarts(sname, ".init"))
continue;
s->sh_entsize = get_offset(mod, &mod->core_size, s, i);
- DEBUGP("\t%s\n", name);
+ pr_debug("\t%s\n", sname);
}
switch (m) {
case 0: /* executable */
@@ -1995,7 +2036,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
}
}
- DEBUGP("Init section allocation order:\n");
+ pr_debug("Init section allocation order:\n");
for (m = 0; m < ARRAY_SIZE(masks); ++m) {
for (i = 0; i < info->hdr->e_shnum; ++i) {
Elf_Shdr *s = &info->sechdrs[i];
@@ -2008,7 +2049,7 @@ static void layout_sections(struct module *mod, struct load_info *info)
continue;
s->sh_entsize = (get_offset(mod, &mod->init_size, s, i)
| INIT_OFFSET_MASK);
- DEBUGP("\t%s\n", sname);
+ pr_debug("\t%s\n", sname);
}
switch (m) {
case 0: /* executable */
@@ -2178,45 +2219,46 @@ static bool is_core_symbol(const Elf_Sym *src, const Elf_Shdr *sechdrs,
return true;
}
+/*
+ * We only allocate and copy the strings needed by the parts of symtab
+ * we keep. This is simple, but has the effect of making multiple
+ * copies of duplicates. We could be more sophisticated, see
+ * linux-kernel thread starting with
+ * <73defb5e4bca04a6431392cc341112b1@localhost>.
+ */
static void layout_symtab(struct module *mod, struct load_info *info)
{
Elf_Shdr *symsect = info->sechdrs + info->index.sym;
Elf_Shdr *strsect = info->sechdrs + info->index.str;
const Elf_Sym *src;
- unsigned int i, nsrc, ndst;
+ unsigned int i, nsrc, ndst, strtab_size;
/* Put symbol section at end of init part of module. */
symsect->sh_flags |= SHF_ALLOC;
symsect->sh_entsize = get_offset(mod, &mod->init_size, symsect,
info->index.sym) | INIT_OFFSET_MASK;
- DEBUGP("\t%s\n", info->secstrings + symsect->sh_name);
+ pr_debug("\t%s\n", info->secstrings + symsect->sh_name);
src = (void *)info->hdr + symsect->sh_offset;
nsrc = symsect->sh_size / sizeof(*src);
- for (ndst = i = 1; i < nsrc; ++i, ++src)
- if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
- unsigned int j = src->st_name;
- while (!__test_and_set_bit(j, info->strmap)
- && info->strtab[j])
- ++j;
- ++ndst;
+ /* Compute total space required for the core symbols' strtab. */
+ for (ndst = i = strtab_size = 1; i < nsrc; ++i, ++src)
+ if (is_core_symbol(src, info->sechdrs, info->hdr->e_shnum)) {
+ strtab_size += strlen(&info->strtab[src->st_name]) + 1;
+ ndst++;
}
/* Append room for core symbols at end of core part. */
info->symoffs = ALIGN(mod->core_size, symsect->sh_addralign ?: 1);
- mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym);
+ info->stroffs = mod->core_size = info->symoffs + ndst * sizeof(Elf_Sym);
+ mod->core_size += strtab_size;
/* Put string table section at end of init part of module. */
strsect->sh_flags |= SHF_ALLOC;
strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
info->index.str) | INIT_OFFSET_MASK;
- DEBUGP("\t%s\n", info->secstrings + strsect->sh_name);
-
- /* Append room for core symbols' strings at end of core part. */
- info->stroffs = mod->core_size;
- __set_bit(0, info->strmap);
- mod->core_size += bitmap_weight(info->strmap, strsect->sh_size);
+ pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
}
static void add_kallsyms(struct module *mod, const struct load_info *info)
@@ -2237,22 +2279,19 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
mod->core_symtab = dst = mod->module_core + info->symoffs;
+ mod->core_strtab = s = mod->module_core + info->stroffs;
src = mod->symtab;
*dst = *src;
+ *s++ = 0;
for (ndst = i = 1; i < mod->num_symtab; ++i, ++src) {
if (!is_core_symbol(src, info->sechdrs, info->hdr->e_shnum))
continue;
+
dst[ndst] = *src;
- dst[ndst].st_name = bitmap_weight(info->strmap,
- dst[ndst].st_name);
- ++ndst;
+ dst[ndst++].st_name = s - mod->core_strtab;
+ s += strlcpy(s, &mod->strtab[src->st_name], KSYM_NAME_LEN) + 1;
}
mod->core_num_syms = ndst;
-
- mod->core_strtab = s = mod->module_core + info->stroffs;
- for (*s = 0, i = 1; i < info->sechdrs[info->index.str].sh_size; ++i)
- if (test_bit(i, info->strmap))
- *++s = mod->strtab[i];
}
#else
static inline void layout_symtab(struct module *mod, struct load_info *info)
@@ -2621,7 +2660,7 @@ static int move_module(struct module *mod, struct load_info *info)
mod->module_init = ptr;
/* Transfer each section which specifies SHF_ALLOC */
- DEBUGP("final section addresses:\n");
+ pr_debug("final section addresses:\n");
for (i = 0; i < info->hdr->e_shnum; i++) {
void *dest;
Elf_Shdr *shdr = &info->sechdrs[i];
@@ -2639,8 +2678,8 @@ static int move_module(struct module *mod, struct load_info *info)
memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
/* Update sh_addr to point to copy in image. */
shdr->sh_addr = (unsigned long)dest;
- DEBUGP("\t0x%lx %s\n",
- shdr->sh_addr, info->secstrings + shdr->sh_name);
+ pr_debug("\t0x%lx %s\n",
+ (long)shdr->sh_addr, info->secstrings + shdr->sh_name);
}
return 0;
@@ -2742,27 +2781,18 @@ static struct module *layout_and_allocate(struct load_info *info)
this is done generically; there doesn't appear to be any
special cases for the architectures. */
layout_sections(mod, info);
-
- info->strmap = kzalloc(BITS_TO_LONGS(info->sechdrs[info->index.str].sh_size)
- * sizeof(long), GFP_KERNEL);
- if (!info->strmap) {
- err = -ENOMEM;
- goto free_percpu;
- }
layout_symtab(mod, info);
/* Allocate and move to the final place */
err = move_module(mod, info);
if (err)
- goto free_strmap;
+ goto free_percpu;
/* Module has been copied to its final place now: return it. */
mod = (void *)info->sechdrs[info->index.mod].sh_addr;
kmemleak_load_module(mod, info);
return mod;
-free_strmap:
- kfree(info->strmap);
free_percpu:
percpu_modfree(mod);
out:
@@ -2772,7 +2802,6 @@ out:
/* mod is no longer valid after this! */
static void module_deallocate(struct module *mod, struct load_info *info)
{
- kfree(info->strmap);
percpu_modfree(mod);
module_free(mod, mod->module_init);
module_free(mod, mod->module_core);
@@ -2811,7 +2840,7 @@ static struct module *load_module(void __user *umod,
struct module *mod;
long err;
- DEBUGP("load_module: umod=%p, len=%lu, uargs=%p\n",
+ pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n",
umod, len, uargs);
/* Copy in the blobs from userspace, check they are vaguely sane. */
@@ -2902,8 +2931,7 @@ static struct module *load_module(void __user *umod,
if (err < 0)
goto unlink;
- /* Get rid of temporary copy and strmap. */
- kfree(info.strmap);
+ /* Get rid of temporary copy. */
free_copy(&info);
/* Done! */
@@ -3256,20 +3284,7 @@ static char *module_flags(struct module *mod, char *buf)
mod->state == MODULE_STATE_GOING ||
mod->state == MODULE_STATE_COMING) {
buf[bx++] = '(';
- if (mod->taints & (1 << TAINT_PROPRIETARY_MODULE))
- buf[bx++] = 'P';
- else if (mod->taints & (1 << TAINT_OOT_MODULE))
- buf[bx++] = 'O';
- if (mod->taints & (1 << TAINT_FORCED_MODULE))
- buf[bx++] = 'F';
- if (mod->taints & (1 << TAINT_CRAP))
- buf[bx++] = 'C';
- /*
- * TAINT_FORCED_RMMOD: could be added.
- * TAINT_UNSAFE_SMP, TAINT_MACHINE_CHECK, TAINT_BAD_PAGE don't
- * apply to modules.
- */
-
+ bx += module_flags_taint(mod, buf + bx);
/* Show a - for module-is-being-unloaded */
if (mod->state == MODULE_STATE_GOING)
buf[bx++] = '-';
diff --git a/kernel/params.c b/kernel/params.c
index 65aae11eb93f..32ee04308285 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -25,12 +25,6 @@
#include <linux/slab.h>
#include <linux/ctype.h>
-#if 0
-#define DEBUGP printk
-#else
-#define DEBUGP(fmt, a...)
-#endif
-
/* Protects all parameters, and incidentally kmalloced_param list. */
static DEFINE_MUTEX(param_lock);
@@ -105,7 +99,7 @@ static int parse_one(char *param,
/* No one handled NULL, so do it here. */
if (!val && params[i].ops->set != param_set_bool)
return -EINVAL;
- DEBUGP("They are equal! Calling %p\n",
+ pr_debug("They are equal! Calling %p\n",
params[i].ops->set);
mutex_lock(&param_lock);
err = params[i].ops->set(val, &params[i]);
@@ -115,11 +109,11 @@ static int parse_one(char *param,
}
if (handle_unknown) {
- DEBUGP("Unknown argument: calling %p\n", handle_unknown);
+ pr_debug("Unknown argument: calling %p\n", handle_unknown);
return handle_unknown(param, val);
}
- DEBUGP("Unknown argument `%s'\n", param);
+ pr_debug("Unknown argument `%s'\n", param);
return -ENOENT;
}
@@ -184,7 +178,7 @@ int parse_args(const char *name,
{
char *param, *val;
- DEBUGP("Parsing ARGS: %s\n", args);
+ pr_debug("Parsing ARGS: %s\n", args);
/* Chew leading spaces */
args = skip_spaces(args);
@@ -369,6 +363,30 @@ struct kernel_param_ops param_ops_invbool = {
};
EXPORT_SYMBOL(param_ops_invbool);
+int param_set_bint(const char *val, const struct kernel_param *kp)
+{
+ struct kernel_param boolkp;
+ bool v;
+ int ret;
+
+ /* Match bool exactly, by re-using it. */
+ boolkp = *kp;
+ boolkp.arg = &v;
+ boolkp.flags |= KPARAM_ISBOOL;
+
+ ret = param_set_bool(val, &boolkp);
+ if (ret == 0)
+ *(int *)kp->arg = v;
+ return ret;
+}
+EXPORT_SYMBOL(param_set_bint);
+
+struct kernel_param_ops param_ops_bint = {
+ .set = param_set_bint,
+ .get = param_get_int,
+};
+EXPORT_SYMBOL(param_ops_bint);
+
/* We break the rule and mangle the string. */
static int param_array(const char *name,
const char *val,
diff --git a/kernel/printk.c b/kernel/printk.c
index 989e4a52da76..13c0a1143f49 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -521,7 +521,7 @@ static void __call_console_drivers(unsigned start, unsigned end)
}
}
-static int __read_mostly ignore_loglevel;
+static bool __read_mostly ignore_loglevel;
static int __init ignore_loglevel_setup(char *str)
{
@@ -532,7 +532,7 @@ static int __init ignore_loglevel_setup(char *str)
}
early_param("ignore_loglevel", ignore_loglevel_setup);
-module_param_named(ignore_loglevel, ignore_loglevel, bool, S_IRUGO | S_IWUSR);
+module_param(ignore_loglevel, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ignore_loglevel, "ignore loglevel setting, to"
"print all kernel messages to the console.");
@@ -696,9 +696,9 @@ static void zap_locks(void)
}
#if defined(CONFIG_PRINTK_TIME)
-static int printk_time = 1;
+static bool printk_time = 1;
#else
-static int printk_time = 0;
+static bool printk_time = 0;
#endif
module_param_named(time, printk_time, bool, S_IRUGO | S_IWUSR);
@@ -1098,7 +1098,7 @@ int update_console_cmdline(char *name, int idx, char *name_new, int idx_new, cha
return -1;
}
-int console_suspend_enabled = 1;
+bool console_suspend_enabled = 1;
EXPORT_SYMBOL(console_suspend_enabled);
static int __init console_suspend_disable(char *str)
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 78ab24a7b0e4..00ab2ca5ed11 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -172,6 +172,14 @@ int ptrace_check_attach(struct task_struct *child, bool ignore_state)
return ret;
}
+static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
+{
+ if (mode & PTRACE_MODE_NOAUDIT)
+ return has_ns_capability_noaudit(current, ns, CAP_SYS_PTRACE);
+ else
+ return has_ns_capability(current, ns, CAP_SYS_PTRACE);
+}
+
int __ptrace_may_access(struct task_struct *task, unsigned int mode)
{
const struct cred *cred = current_cred(), *tcred;
@@ -198,7 +206,7 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
cred->gid == tcred->sgid &&
cred->gid == tcred->gid))
goto ok;
- if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE))
+ if (ptrace_has_cap(tcred->user->user_ns, mode))
goto ok;
rcu_read_unlock();
return -EPERM;
@@ -207,7 +215,7 @@ ok:
smp_rmb();
if (task->mm)
dumpable = get_dumpable(task->mm);
- if (!dumpable && !task_ns_capable(task, CAP_SYS_PTRACE))
+ if (!dumpable && !ptrace_has_cap(task_user_ns(task), mode))
return -EPERM;
return security_ptrace_access_check(task, mode);
@@ -277,7 +285,7 @@ static int ptrace_attach(struct task_struct *task, long request,
task->ptrace = PT_PTRACED;
if (seize)
task->ptrace |= PT_SEIZED;
- if (task_ns_capable(task, CAP_SYS_PTRACE))
+ if (ns_capable(task_user_ns(task), CAP_SYS_PTRACE))
task->ptrace |= PT_PTRACE_CAP;
__ptrace_link(task, current);
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index fd7b25e90079..df00cb09263e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -4330,7 +4330,7 @@ long sched_setaffinity(pid_t pid, const struct cpumask *in_mask)
goto out_free_cpus_allowed;
}
retval = -EPERM;
- if (!check_same_owner(p) && !task_ns_capable(p, CAP_SYS_NICE))
+ if (!check_same_owner(p) && !ns_capable(task_user_ns(p), CAP_SYS_NICE))
goto out_unlock;
retval = security_task_setscheduler(p);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 82928f5ea049..8745ac7d1f75 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -414,7 +414,7 @@ config SLUB_STATS
config DEBUG_KMEMLEAK
bool "Kernel memory leak detector"
- depends on DEBUG_KERNEL && EXPERIMENTAL && !MEMORY_HOTPLUG && \
+ depends on DEBUG_KERNEL && EXPERIMENTAL && \
(X86 || ARM || PPC || MIPS || S390 || SPARC64 || SUPERH || MICROBLAZE || TILE)
select DEBUG_FS
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index f3b2a00fe9c1..c833addd94d7 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -100,6 +100,7 @@
#include <linux/kmemcheck.h>
#include <linux/kmemleak.h>
+#include <linux/memory_hotplug.h>
/*
* Kmemleak configuration and common defines.
@@ -196,7 +197,9 @@ static atomic_t kmemleak_enabled = ATOMIC_INIT(0);
static atomic_t kmemleak_initialized = ATOMIC_INIT(0);
/* enables or disables early logging of the memory operations */
static atomic_t kmemleak_early_log = ATOMIC_INIT(1);
-/* set if a fata kmemleak error has occurred */
+/* set if a kmemleak warning was issued */
+static atomic_t kmemleak_warning = ATOMIC_INIT(0);
+/* set if a fatal kmemleak error has occurred */
static atomic_t kmemleak_error = ATOMIC_INIT(0);
/* minimum and maximum address that may be valid pointers */
@@ -228,8 +231,10 @@ static int kmemleak_skip_disable;
/* kmemleak operation type for early logging */
enum {
KMEMLEAK_ALLOC,
+ KMEMLEAK_ALLOC_PERCPU,
KMEMLEAK_FREE,
KMEMLEAK_FREE_PART,
+ KMEMLEAK_FREE_PERCPU,
KMEMLEAK_NOT_LEAK,
KMEMLEAK_IGNORE,
KMEMLEAK_SCAN_AREA,
@@ -259,9 +264,10 @@ static void kmemleak_disable(void);
/*
* Print a warning and dump the stack trace.
*/
-#define kmemleak_warn(x...) do { \
- pr_warning(x); \
- dump_stack(); \
+#define kmemleak_warn(x...) do { \
+ pr_warning(x); \
+ dump_stack(); \
+ atomic_set(&kmemleak_warning, 1); \
} while (0)
/*
@@ -403,8 +409,8 @@ static struct kmemleak_object *lookup_object(unsigned long ptr, int alias)
object = prio_tree_entry(node, struct kmemleak_object,
tree_node);
if (!alias && object->pointer != ptr) {
- pr_warning("Found object by alias at 0x%08lx\n", ptr);
- dump_stack();
+ kmemleak_warn("Found object by alias at 0x%08lx\n",
+ ptr);
dump_object_info(object);
object = NULL;
}
@@ -794,9 +800,13 @@ static void __init log_early(int op_type, const void *ptr, size_t size,
unsigned long flags;
struct early_log *log;
+ if (atomic_read(&kmemleak_error)) {
+ /* kmemleak stopped recording, just count the requests */
+ crt_early_log++;
+ return;
+ }
+
if (crt_early_log >= ARRAY_SIZE(early_log)) {
- pr_warning("Early log buffer exceeded, "
- "please increase DEBUG_KMEMLEAK_EARLY_LOG_SIZE\n");
kmemleak_disable();
return;
}
@@ -811,8 +821,7 @@ static void __init log_early(int op_type, const void *ptr, size_t size,
log->ptr = ptr;
log->size = size;
log->min_count = min_count;
- if (op_type == KMEMLEAK_ALLOC)
- log->trace_len = __save_stack_trace(log->trace);
+ log->trace_len = __save_stack_trace(log->trace);
crt_early_log++;
local_irq_restore(flags);
}
@@ -846,6 +855,20 @@ out:
rcu_read_unlock();
}
+/*
+ * Log an early allocated block and populate the stack trace.
+ */
+static void early_alloc_percpu(struct early_log *log)
+{
+ unsigned int cpu;
+ const void __percpu *ptr = log->ptr;
+
+ for_each_possible_cpu(cpu) {
+ log->ptr = per_cpu_ptr(ptr, cpu);
+ early_alloc(log);
+ }
+}
+
/**
* kmemleak_alloc - register a newly allocated object
* @ptr: pointer to beginning of the object
@@ -873,6 +896,34 @@ void __ref kmemleak_alloc(const void *ptr, size_t size, int min_count,
EXPORT_SYMBOL_GPL(kmemleak_alloc);
/**
+ * kmemleak_alloc_percpu - register a newly allocated __percpu object
+ * @ptr: __percpu pointer to beginning of the object
+ * @size: size of the object
+ *
+ * This function is called from the kernel percpu allocator when a new object
+ * (memory block) is allocated (alloc_percpu). It assumes GFP_KERNEL
+ * allocation.
+ */
+void __ref kmemleak_alloc_percpu(const void __percpu *ptr, size_t size)
+{
+ unsigned int cpu;
+
+ pr_debug("%s(0x%p, %zu)\n", __func__, ptr, size);
+
+ /*
+ * Percpu allocations are only scanned and not reported as leaks
+ * (min_count is set to 0).
+ */
+ if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr))
+ for_each_possible_cpu(cpu)
+ create_object((unsigned long)per_cpu_ptr(ptr, cpu),
+ size, 0, GFP_KERNEL);
+ else if (atomic_read(&kmemleak_early_log))
+ log_early(KMEMLEAK_ALLOC_PERCPU, ptr, size, 0);
+}
+EXPORT_SYMBOL_GPL(kmemleak_alloc_percpu);
+
+/**
* kmemleak_free - unregister a previously registered object
* @ptr: pointer to beginning of the object
*
@@ -911,6 +962,28 @@ void __ref kmemleak_free_part(const void *ptr, size_t size)
EXPORT_SYMBOL_GPL(kmemleak_free_part);
/**
+ * kmemleak_free_percpu - unregister a previously registered __percpu object
+ * @ptr: __percpu pointer to beginning of the object
+ *
+ * This function is called from the kernel percpu allocator when an object
+ * (memory block) is freed (free_percpu).
+ */
+void __ref kmemleak_free_percpu(const void __percpu *ptr)
+{
+ unsigned int cpu;
+
+ pr_debug("%s(0x%p)\n", __func__, ptr);
+
+ if (atomic_read(&kmemleak_enabled) && ptr && !IS_ERR(ptr))
+ for_each_possible_cpu(cpu)
+ delete_object_full((unsigned long)per_cpu_ptr(ptr,
+ cpu));
+ else if (atomic_read(&kmemleak_early_log))
+ log_early(KMEMLEAK_FREE_PERCPU, ptr, 0, 0);
+}
+EXPORT_SYMBOL_GPL(kmemleak_free_percpu);
+
+/**
* kmemleak_not_leak - mark an allocated object as false positive
* @ptr: pointer to beginning of the object
*
@@ -1220,9 +1293,9 @@ static void kmemleak_scan(void)
#endif
/*
- * Struct page scanning for each node. The code below is not yet safe
- * with MEMORY_HOTPLUG.
+ * Struct page scanning for each node.
*/
+ lock_memory_hotplug();
for_each_online_node(i) {
pg_data_t *pgdat = NODE_DATA(i);
unsigned long start_pfn = pgdat->node_start_pfn;
@@ -1241,6 +1314,7 @@ static void kmemleak_scan(void)
scan_block(page, page + 1, NULL, 1);
}
}
+ unlock_memory_hotplug();
/*
* Scanning the task stacks (may introduce false negatives).
@@ -1467,9 +1541,6 @@ static const struct seq_operations kmemleak_seq_ops = {
static int kmemleak_open(struct inode *inode, struct file *file)
{
- if (!atomic_read(&kmemleak_enabled))
- return -EBUSY;
-
return seq_open(file, &kmemleak_seq_ops);
}
@@ -1543,6 +1614,9 @@ static ssize_t kmemleak_write(struct file *file, const char __user *user_buf,
int buf_size;
int ret;
+ if (!atomic_read(&kmemleak_enabled))
+ return -EBUSY;
+
buf_size = min(size, (sizeof(buf) - 1));
if (strncpy_from_user(buf, user_buf, buf_size) < 0)
return -EFAULT;
@@ -1602,20 +1676,24 @@ static const struct file_operations kmemleak_fops = {
};
/*
- * Perform the freeing of the kmemleak internal objects after waiting for any
- * current memory scan to complete.
+ * Stop the memory scanning thread and free the kmemleak internal objects if
+ * no previous scan thread (otherwise, kmemleak may still have some useful
+ * information on memory leaks).
*/
static void kmemleak_do_cleanup(struct work_struct *work)
{
struct kmemleak_object *object;
+ bool cleanup = scan_thread == NULL;
mutex_lock(&scan_mutex);
stop_scan_thread();
- rcu_read_lock();
- list_for_each_entry_rcu(object, &object_list, object_list)
- delete_object_full(object->pointer);
- rcu_read_unlock();
+ if (cleanup) {
+ rcu_read_lock();
+ list_for_each_entry_rcu(object, &object_list, object_list)
+ delete_object_full(object->pointer);
+ rcu_read_unlock();
+ }
mutex_unlock(&scan_mutex);
}
@@ -1632,7 +1710,6 @@ static void kmemleak_disable(void)
return;
/* stop any memory operation tracing */
- atomic_set(&kmemleak_early_log, 0);
atomic_set(&kmemleak_enabled, 0);
/* check whether it is too early for a kernel thread */
@@ -1659,6 +1736,17 @@ static int kmemleak_boot_config(char *str)
}
early_param("kmemleak", kmemleak_boot_config);
+static void __init print_log_trace(struct early_log *log)
+{
+ struct stack_trace trace;
+
+ trace.nr_entries = log->trace_len;
+ trace.entries = log->trace;
+
+ pr_notice("Early log backtrace:\n");
+ print_stack_trace(&trace, 2);
+}
+
/*
* Kmemleak initialization.
*/
@@ -1681,12 +1769,18 @@ void __init kmemleak_init(void)
scan_area_cache = KMEM_CACHE(kmemleak_scan_area, SLAB_NOLEAKTRACE);
INIT_PRIO_TREE_ROOT(&object_tree_root);
+ if (crt_early_log >= ARRAY_SIZE(early_log))
+ pr_warning("Early log buffer exceeded (%d), please increase "
+ "DEBUG_KMEMLEAK_EARLY_LOG_SIZE\n", crt_early_log);
+
/* the kernel is still in UP mode, so disabling the IRQs is enough */
local_irq_save(flags);
- if (!atomic_read(&kmemleak_error)) {
+ atomic_set(&kmemleak_early_log, 0);
+ if (atomic_read(&kmemleak_error)) {
+ local_irq_restore(flags);
+ return;
+ } else
atomic_set(&kmemleak_enabled, 1);
- atomic_set(&kmemleak_early_log, 0);
- }
local_irq_restore(flags);
/*
@@ -1701,12 +1795,18 @@ void __init kmemleak_init(void)
case KMEMLEAK_ALLOC:
early_alloc(log);
break;
+ case KMEMLEAK_ALLOC_PERCPU:
+ early_alloc_percpu(log);
+ break;
case KMEMLEAK_FREE:
kmemleak_free(log->ptr);
break;
case KMEMLEAK_FREE_PART:
kmemleak_free_part(log->ptr, log->size);
break;
+ case KMEMLEAK_FREE_PERCPU:
+ kmemleak_free_percpu(log->ptr);
+ break;
case KMEMLEAK_NOT_LEAK:
kmemleak_not_leak(log->ptr);
break;
@@ -1720,7 +1820,13 @@ void __init kmemleak_init(void)
kmemleak_no_scan(log->ptr);
break;
default:
- WARN_ON(1);
+ kmemleak_warn("Unknown early log operation: %d\n",
+ log->op_type);
+ }
+
+ if (atomic_read(&kmemleak_warning)) {
+ print_log_trace(log);
+ atomic_set(&kmemleak_warning, 0);
}
}
}
diff --git a/mm/percpu.c b/mm/percpu.c
index 716eb4acf2fc..f47af9123af7 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -67,6 +67,7 @@
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
+#include <linux/kmemleak.h>
#include <asm/cacheflush.h>
#include <asm/sections.h>
@@ -710,6 +711,7 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved)
const char *err;
int slot, off, new_alloc;
unsigned long flags;
+ void __percpu *ptr;
if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE)) {
WARN(true, "illegal size (%zu) or align (%zu) for "
@@ -802,7 +804,9 @@ area_found:
mutex_unlock(&pcpu_alloc_mutex);
/* return address relative to base address */
- return __addr_to_pcpu_ptr(chunk->base_addr + off);
+ ptr = __addr_to_pcpu_ptr(chunk->base_addr + off);
+ kmemleak_alloc_percpu(ptr, size);
+ return ptr;
fail_unlock:
spin_unlock_irqrestore(&pcpu_lock, flags);
@@ -916,6 +920,8 @@ void free_percpu(void __percpu *ptr)
if (!ptr)
return;
+ kmemleak_free_percpu(ptr);
+
addr = __pcpu_ptr_to_addr(ptr);
spin_lock_irqsave(&pcpu_lock, flags);
@@ -1639,6 +1645,8 @@ int __init pcpu_embed_first_chunk(size_t reserved_size, size_t dyn_size,
rc = -ENOMEM;
goto out_free_areas;
}
+ /* kmemleak tracks the percpu allocations separately */
+ kmemleak_free(ptr);
areas[group] = ptr;
base = min(ptr, base);
@@ -1753,6 +1761,8 @@ int __init pcpu_page_first_chunk(size_t reserved_size,
"for cpu%u\n", psize_str, cpu);
goto enomem;
}
+ /* kmemleak tracks the percpu allocations separately */
+ kmemleak_free(ptr);
pages[j++] = virt_to_page(ptr);
}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index dbf2ddafd52d..f16444bc6cbb 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1960,7 +1960,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
sz_idx = type>>2;
kind = type&3;
- if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN))
+ if (kind != 2 && !capable(CAP_NET_ADMIN))
return -EPERM;
if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c
index 69975e0bcdea..1531135130db 100644
--- a/net/decnet/netfilter/dn_rtmsg.c
+++ b/net/decnet/netfilter/dn_rtmsg.c
@@ -108,7 +108,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb)
if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
return;
- if (security_netlink_recv(skb, CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
RCV_SKB_FAIL(-EPERM);
/* Eventually we might send routing messages too */
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index a057fe64debd..94d45e1f8882 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -431,7 +431,7 @@ __ipq_rcv_skb(struct sk_buff *skb)
if (type <= IPQM_BASE)
return;
- if (security_netlink_recv(skb, CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
RCV_SKB_FAIL(-EPERM);
spin_lock_bh(&queue_lock);
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c
index fb80a23c6640..a34c9e4c792c 100644
--- a/net/ipv6/netfilter/ip6_queue.c
+++ b/net/ipv6/netfilter/ip6_queue.c
@@ -432,7 +432,7 @@ __ipq_rcv_skb(struct sk_buff *skb)
if (type <= IPQM_BASE)
return;
- if (security_netlink_recv(skb, CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
RCV_SKB_FAIL(-EPERM);
spin_lock_bh(&queue_lock);
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index b4f8d849480c..4d70785b953d 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -130,7 +130,7 @@ static int nfnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
const struct nfnetlink_subsystem *ss;
int type, err;
- if (security_netlink_recv(skb, CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
/* All the messages must at least contain nfgenmsg */
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index a403b618faa5..c29d2568c9e0 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -524,7 +524,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
return -EOPNOTSUPP;
if ((ops->flags & GENL_ADMIN_PERM) &&
- security_netlink_recv(skb, CAP_NET_ADMIN))
+ !capable(CAP_NET_ADMIN))
return -EPERM;
if (nlh->nlmsg_flags & NLM_F_DUMP) {
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 03b56bc3b659..465df9ae1046 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -1641,6 +1641,7 @@ int cache_register_net(struct cache_detail *cd, struct net *net)
sunrpc_destroy_cache_detail(cd);
return ret;
}
+EXPORT_SYMBOL_GPL(cache_register_net);
int cache_register(struct cache_detail *cd)
{
@@ -1653,6 +1654,7 @@ void cache_unregister_net(struct cache_detail *cd, struct net *net)
remove_cache_proc_entries(cd, net);
sunrpc_destroy_cache_detail(cd);
}
+EXPORT_SYMBOL_GPL(cache_unregister_net);
void cache_unregister(struct cache_detail *cd)
{
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 9d01d46b05f3..e4aabc02368b 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -167,6 +167,7 @@ svc_pool_map_alloc_arrays(struct svc_pool_map *m, unsigned int maxpools)
fail_free:
kfree(m->to_pool);
+ m->to_pool = NULL;
fail:
return -ENOMEM;
}
@@ -285,9 +286,10 @@ svc_pool_map_put(void)
mutex_lock(&svc_pool_map_mutex);
if (!--m->count) {
- m->mode = SVC_POOL_DEFAULT;
kfree(m->to_pool);
+ m->to_pool = NULL;
kfree(m->pool_to);
+ m->pool_to = NULL;
m->npools = 0;
}
@@ -527,17 +529,20 @@ svc_destroy(struct svc_serv *serv)
printk("svc_destroy: no threads for serv=%p!\n", serv);
del_timer_sync(&serv->sv_temptimer);
-
- svc_close_all(&serv->sv_tempsocks);
+ /*
+ * The set of xprts (contained in the sv_tempsocks and
+ * sv_permsocks lists) is now constant, since it is modified
+ * only by accepting new sockets (done by service threads in
+ * svc_recv) or aging old ones (done by sv_temptimer), or
+ * configuration changes (excluded by whatever locking the
+ * caller is using--nfsd_mutex in the case of nfsd). So it's
+ * safe to traverse those lists and shut everything down:
+ */
+ svc_close_all(serv);
if (serv->sv_shutdown)
serv->sv_shutdown(serv);
- svc_close_all(&serv->sv_permsocks);
-
- BUG_ON(!list_empty(&serv->sv_permsocks));
- BUG_ON(!list_empty(&serv->sv_tempsocks));
-
cache_clean_deferred(serv);
if (svc_serv_is_pooled(serv))
@@ -683,8 +688,8 @@ found_pool:
* Create or destroy enough new threads to make the number
* of threads the given number. If `pool' is non-NULL, applies
* only to threads in that pool, otherwise round-robins between
- * all pools. Must be called with a svc_get() reference and
- * the BKL or another lock to protect access to svc_serv fields.
+ * all pools. Caller must ensure that mutual exclusion between this and
+ * server startup or shutdown.
*
* Destroying threads relies on the service threads filling in
* rqstp->rq_task, which only the nfs ones do. Assumes the serv
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
index 38649cfa4e81..74cb0d8e9ca1 100644
--- a/net/sunrpc/svc_xprt.c
+++ b/net/sunrpc/svc_xprt.c
@@ -22,6 +22,7 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt);
static int svc_deferred_recv(struct svc_rqst *rqstp);
static struct cache_deferred_req *svc_defer(struct cache_req *req);
static void svc_age_temp_xprts(unsigned long closure);
+static void svc_delete_xprt(struct svc_xprt *xprt);
/* apparently the "standard" is that clients close
* idle connections after 5 minutes, servers after
@@ -147,8 +148,8 @@ EXPORT_SYMBOL_GPL(svc_xprt_put);
* Called by transport drivers to initialize the transport independent
* portion of the transport instance.
*/
-void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
- struct svc_serv *serv)
+void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
+ struct svc_xprt *xprt, struct svc_serv *serv)
{
memset(xprt, 0, sizeof(*xprt));
xprt->xpt_class = xcl;
@@ -163,7 +164,7 @@ void svc_xprt_init(struct svc_xprt_class *xcl, struct svc_xprt *xprt,
spin_lock_init(&xprt->xpt_lock);
set_bit(XPT_BUSY, &xprt->xpt_flags);
rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending");
- xprt->xpt_net = get_net(&init_net);
+ xprt->xpt_net = get_net(net);
}
EXPORT_SYMBOL_GPL(svc_xprt_init);
@@ -878,7 +879,7 @@ static void call_xpt_users(struct svc_xprt *xprt)
/*
* Remove a dead transport
*/
-void svc_delete_xprt(struct svc_xprt *xprt)
+static void svc_delete_xprt(struct svc_xprt *xprt)
{
struct svc_serv *serv = xprt->xpt_server;
struct svc_deferred_req *dr;
@@ -893,14 +894,7 @@ void svc_delete_xprt(struct svc_xprt *xprt)
spin_lock_bh(&serv->sv_lock);
if (!test_and_set_bit(XPT_DETACHED, &xprt->xpt_flags))
list_del_init(&xprt->xpt_list);
- /*
- * The only time we're called while xpt_ready is still on a list
- * is while the list itself is about to be destroyed (in
- * svc_destroy). BUT svc_xprt_enqueue could still be attempting
- * to add new entries to the sp_sockets list, so we can't leave
- * a freed xprt on it.
- */
- list_del_init(&xprt->xpt_ready);
+ BUG_ON(!list_empty(&xprt->xpt_ready));
if (test_bit(XPT_TEMP, &xprt->xpt_flags))
serv->sv_tmpcnt--;
spin_unlock_bh(&serv->sv_lock);
@@ -928,22 +922,48 @@ void svc_close_xprt(struct svc_xprt *xprt)
}
EXPORT_SYMBOL_GPL(svc_close_xprt);
-void svc_close_all(struct list_head *xprt_list)
+static void svc_close_list(struct list_head *xprt_list)
+{
+ struct svc_xprt *xprt;
+
+ list_for_each_entry(xprt, xprt_list, xpt_list) {
+ set_bit(XPT_CLOSE, &xprt->xpt_flags);
+ set_bit(XPT_BUSY, &xprt->xpt_flags);
+ }
+}
+
+void svc_close_all(struct svc_serv *serv)
{
+ struct svc_pool *pool;
struct svc_xprt *xprt;
struct svc_xprt *tmp;
+ int i;
+
+ svc_close_list(&serv->sv_tempsocks);
+ svc_close_list(&serv->sv_permsocks);
+ for (i = 0; i < serv->sv_nrpools; i++) {
+ pool = &serv->sv_pools[i];
+
+ spin_lock_bh(&pool->sp_lock);
+ while (!list_empty(&pool->sp_sockets)) {
+ xprt = list_first_entry(&pool->sp_sockets, struct svc_xprt, xpt_ready);
+ list_del_init(&xprt->xpt_ready);
+ }
+ spin_unlock_bh(&pool->sp_lock);
+ }
/*
- * The server is shutting down, and no more threads are running.
- * svc_xprt_enqueue() might still be running, but at worst it
- * will re-add the xprt to sp_sockets, which will soon get
- * freed. So we don't bother with any more locking, and don't
- * leave the close to the (nonexistent) server threads:
+ * At this point the sp_sockets lists will stay empty, since
+ * svc_enqueue will not add new entries without taking the
+ * sp_lock and checking XPT_BUSY.
*/
- list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) {
- set_bit(XPT_CLOSE, &xprt->xpt_flags);
+ list_for_each_entry_safe(xprt, tmp, &serv->sv_tempsocks, xpt_list)
svc_delete_xprt(xprt);
- }
+ list_for_each_entry_safe(xprt, tmp, &serv->sv_permsocks, xpt_list)
+ svc_delete_xprt(xprt);
+
+ BUG_ON(!list_empty(&serv->sv_permsocks));
+ BUG_ON(!list_empty(&serv->sv_tempsocks));
}
/*
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index 4653286fcc9e..464570906f80 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -739,7 +739,8 @@ static void svc_udp_init(struct svc_sock *svsk, struct svc_serv *serv)
{
int err, level, optname, one = 1;
- svc_xprt_init(&svc_udp_class, &svsk->sk_xprt, serv);
+ svc_xprt_init(sock_net(svsk->sk_sock->sk), &svc_udp_class,
+ &svsk->sk_xprt, serv);
clear_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags);
svsk->sk_sk->sk_data_ready = svc_udp_data_ready;
svsk->sk_sk->sk_write_space = svc_write_space;
@@ -1343,7 +1344,8 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
{
struct sock *sk = svsk->sk_sk;
- svc_xprt_init(&svc_tcp_class, &svsk->sk_xprt, serv);
+ svc_xprt_init(sock_net(svsk->sk_sock->sk), &svc_tcp_class,
+ &svsk->sk_xprt, serv);
set_bit(XPT_CACHE_AUTH, &svsk->sk_xprt.xpt_flags);
if (sk->sk_state == TCP_LISTEN) {
dprintk("setting up TCP socket for listening\n");
@@ -1659,7 +1661,7 @@ static struct svc_xprt *svc_bc_create_socket(struct svc_serv *serv,
return ERR_PTR(-ENOMEM);
xprt = &svsk->sk_xprt;
- svc_xprt_init(&svc_tcp_bc_class, xprt, serv);
+ svc_xprt_init(net, &svc_tcp_bc_class, xprt, serv);
serv->sv_bc_xprt = xprt;
diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
index ba1296d88de0..894cb42db91d 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
@@ -453,7 +453,7 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
if (!cma_xprt)
return NULL;
- svc_xprt_init(&svc_rdma_class, &cma_xprt->sc_xprt, serv);
+ svc_xprt_init(&init_net, &svc_rdma_class, &cma_xprt->sc_xprt, serv);
INIT_LIST_HEAD(&cma_xprt->sc_accept_q);
INIT_LIST_HEAD(&cma_xprt->sc_dto_q);
INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q);
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 637f11a1e4df..66b84fbf2746 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -2290,7 +2290,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
link = &xfrm_dispatch[type];
/* All operations require privileges, even GET */
- if (security_netlink_recv(skb, CAP_NET_ADMIN))
+ if (!capable(CAP_NET_ADMIN))
return -EPERM;
if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) ||
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl
index ec7afce4c88d..bccf07ddd0b6 100644
--- a/scripts/kconfig/streamline_config.pl
+++ b/scripts/kconfig/streamline_config.pl
@@ -250,33 +250,61 @@ if ($kconfig) {
read_kconfig($kconfig);
}
+sub convert_vars {
+ my ($line, %vars) = @_;
+
+ my $process = "";
+
+ while ($line =~ s/^(.*?)(\$\((.*?)\))//) {
+ my $start = $1;
+ my $variable = $2;
+ my $var = $3;
+
+ if (defined($vars{$var})) {
+ $process .= $start . $vars{$var};
+ } else {
+ $process .= $start . $variable;
+ }
+ }
+
+ $process .= $line;
+
+ return $process;
+}
+
# Read all Makefiles to map the configs to the objects
foreach my $makefile (@makefiles) {
- my $cont = 0;
+ my $line = "";
+ my %make_vars;
open(MIN,$makefile) || die "Can't open $makefile";
while (<MIN>) {
+ # if this line ends with a backslash, continue
+ chomp;
+ if (/^(.*)\\$/) {
+ $line .= $1;
+ next;
+ }
+
+ $line .= $_;
+ $_ = $line;
+ $line = "";
+
my $objs;
- # is this a line after a line with a backslash?
- if ($cont && /(\S.*)$/) {
- $objs = $1;
- }
- $cont = 0;
+ $_ = convert_vars($_, %make_vars);
# collect objects after obj-$(CONFIG_FOO_BAR)
if (/obj-\$\((CONFIG_[^\)]*)\)\s*[+:]?=\s*(.*)/) {
$var = $1;
$objs = $2;
+
+ # check if variables are set
+ } elsif (/^\s*(\S+)\s*[:]?=\s*(.*\S)/) {
+ $make_vars{$1} = $2;
}
if (defined($objs)) {
- # test if the line ends with a backslash
- if ($objs =~ m,(.*)\\$,) {
- $objs = $1;
- $cont = 1;
- }
-
foreach my $obj (split /\s+/,$objs) {
$obj =~ s/-/_/g;
if ($obj =~ /(.*)\.o$/) {
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
index 363ab4666b17..c0e14b3f2306 100644
--- a/scripts/mod/file2alias.c
+++ b/scripts/mod/file2alias.c
@@ -28,6 +28,7 @@ typedef Elf64_Addr kernel_ulong_t;
#endif
#include <ctype.h>
+#include <stdbool.h>
typedef uint32_t __u32;
typedef uint16_t __u16;
@@ -38,6 +39,35 @@ typedef unsigned char __u8;
* we handle those differences explicitly below */
#include "../../include/linux/mod_devicetable.h"
+/* This array collects all instances that use the generic do_table */
+struct devtable {
+ const char *device_id; /* name of table, __mod_<name>_device_table. */
+ unsigned long id_size;
+ void *function;
+};
+
+/* 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)
+
+#if __GNUC__ == 3 && __GNUC_MINOR__ < 3
+# define __used __attribute__((__unused__))
+#else
+# define __used __attribute__((__used__))
+#endif
+
+/* Add a table entry. We test function type matches while we're here. */
+#define ADD_TO_DEVTABLE(device_id, type, function) \
+ static struct devtable __cat(devtable,__LINE__) = { \
+ device_id + 0*sizeof((function)((const char *)NULL, \
+ (type *)NULL, \
+ (char *)NULL)), \
+ sizeof(type), (function) }; \
+ static struct devtable *__attribute__((section("__devtable"))) \
+ __used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
+
#define ADD(str, sep, cond, field) \
do { \
strcat(str, sep); \
@@ -289,6 +319,7 @@ static int do_hid_entry(const char *filename,
return 1;
}
+ADD_TO_DEVTABLE("hid", struct hid_device_id, do_hid_entry);
/* Looks like: ieee1394:venNmoNspNverN */
static int do_ieee1394_entry(const char *filename,
@@ -313,6 +344,7 @@ static int do_ieee1394_entry(const char *filename,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("ieee1394", struct ieee1394_device_id, do_ieee1394_entry);
/* Looks like: pci:vNdNsvNsdNbcNscNiN. */
static int do_pci_entry(const char *filename,
@@ -356,6 +388,7 @@ static int do_pci_entry(const char *filename,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("pci", struct pci_device_id, do_pci_entry);
/* looks like: "ccw:tNmNdtNdmN" */
static int do_ccw_entry(const char *filename,
@@ -379,6 +412,7 @@ static int do_ccw_entry(const char *filename,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("ccw", struct ccw_device_id, do_ccw_entry);
/* looks like: "ap:tN" */
static int do_ap_entry(const char *filename,
@@ -387,6 +421,7 @@ static int do_ap_entry(const char *filename,
sprintf(alias, "ap:t%02X*", id->dev_type);
return 1;
}
+ADD_TO_DEVTABLE("ap", struct ap_device_id, do_ap_entry);
/* looks like: "css:tN" */
static int do_css_entry(const char *filename,
@@ -395,6 +430,7 @@ static int do_css_entry(const char *filename,
sprintf(alias, "css:t%01X", id->type);
return 1;
}
+ADD_TO_DEVTABLE("css", struct css_device_id, do_css_entry);
/* Looks like: "serio:tyNprNidNexN" */
static int do_serio_entry(const char *filename,
@@ -414,6 +450,7 @@ static int do_serio_entry(const char *filename,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("serio", struct serio_device_id, do_serio_entry);
/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
static int do_acpi_entry(const char *filename,
@@ -422,6 +459,7 @@ static int do_acpi_entry(const char *filename,
sprintf(alias, "acpi*:%s:*", id->id);
return 1;
}
+ADD_TO_DEVTABLE("acpi", struct acpi_device_id, do_acpi_entry);
/* looks like: "pnp:dD" */
static void do_pnp_device_entry(void *symval, unsigned long size,
@@ -544,8 +582,7 @@ static int do_pcmcia_entry(const char *filename,
add_wildcard(alias);
return 1;
}
-
-
+ADD_TO_DEVTABLE("pcmcia", struct pcmcia_device_id, do_pcmcia_entry);
static int do_of_entry (const char *filename, struct of_device_id *of, char *alias)
{
@@ -568,6 +605,7 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("of", struct of_device_id, do_of_entry);
static int do_vio_entry(const char *filename, struct vio_device_id *vio,
char *alias)
@@ -585,6 +623,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("vio", struct vio_device_id, do_vio_entry);
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
@@ -640,6 +679,7 @@ static int do_input_entry(const char *filename, struct input_device_id *id,
do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX);
return 1;
}
+ADD_TO_DEVTABLE("input", struct input_device_id, do_input_entry);
static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
char *alias)
@@ -650,6 +690,7 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
strcat(alias, "*");
return 1;
}
+ADD_TO_DEVTABLE("eisa", struct eisa_device_id, do_eisa_entry);
/* Looks like: parisc:tNhvNrevNsvN */
static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
@@ -669,6 +710,7 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("parisc", struct parisc_device_id, do_parisc_entry);
/* Looks like: sdio:cNvNdN. */
static int do_sdio_entry(const char *filename,
@@ -685,6 +727,7 @@ static int do_sdio_entry(const char *filename,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("sdio", struct sdio_device_id, do_sdio_entry);
/* Looks like: ssb:vNidNrevN. */
static int do_ssb_entry(const char *filename,
@@ -701,6 +744,7 @@ static int do_ssb_entry(const char *filename,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("ssb", struct ssb_device_id, do_ssb_entry);
/* Looks like: bcma:mNidNrevNclN. */
static int do_bcma_entry(const char *filename,
@@ -719,6 +763,7 @@ static int do_bcma_entry(const char *filename,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("bcma", struct bcma_device_id, do_bcma_entry);
/* Looks like: virtio:dNvN */
static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
@@ -734,6 +779,7 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
add_wildcard(alias);
return 1;
}
+ADD_TO_DEVTABLE("virtio", struct virtio_device_id, do_virtio_entry);
/*
* Looks like: vmbus:guid
@@ -755,6 +801,7 @@ static int do_vmbus_entry(const char *filename, struct hv_vmbus_device_id *id,
return 1;
}
+ADD_TO_DEVTABLE("vmbus", struct hv_vmbus_device_id, do_vmbus_entry);
/* Looks like: i2c:S */
static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
@@ -764,6 +811,7 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
return 1;
}
+ADD_TO_DEVTABLE("i2c", struct i2c_device_id, do_i2c_entry);
/* Looks like: spi:S */
static int do_spi_entry(const char *filename, struct spi_device_id *id,
@@ -773,6 +821,17 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id,
return 1;
}
+ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry);
+
+/* Looks like: mcp:S */
+static int do_mcp_entry(const char *filename, struct mcp_device_id *id,
+ char *alias)
+{
+ sprintf(alias, MCP_MODULE_PREFIX "%s", id->name);
+
+ return 1;
+}
+ADD_TO_DEVTABLE("mcp", struct mcp_device_id, do_mcp_entry);
static const struct dmifield {
const char *prefix;
@@ -827,6 +886,7 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
strcat(alias, ":");
return 1;
}
+ADD_TO_DEVTABLE("dmi", struct dmi_system_id, do_dmi_entry);
static int do_platform_entry(const char *filename,
struct platform_device_id *id, char *alias)
@@ -834,6 +894,7 @@ static int do_platform_entry(const char *filename,
sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name);
return 1;
}
+ADD_TO_DEVTABLE("platform", struct platform_device_id, do_platform_entry);
static int do_mdio_entry(const char *filename,
struct mdio_device_id *id, char *alias)
@@ -856,6 +917,7 @@ static int do_mdio_entry(const char *filename,
return 1;
}
+ADD_TO_DEVTABLE("mdio", struct mdio_device_id, do_mdio_entry);
/* Looks like: zorro:iN. */
static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
@@ -866,6 +928,7 @@ static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
return 1;
}
+ADD_TO_DEVTABLE("zorro", struct zorro_device_id, do_zorro_entry);
/* looks like: "pnp:dD" */
static int do_isapnp_entry(const char *filename,
@@ -879,6 +942,7 @@ static int do_isapnp_entry(const char *filename,
(id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
return 1;
}
+ADD_TO_DEVTABLE("isa", struct isapnp_device_id, do_isapnp_entry);
/*
* Append a match expression for a single masked hex digit.
@@ -947,16 +1011,15 @@ static int do_amba_entry(const char *filename,
return 1;
}
+ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry);
-/* Ignore any prefix, eg. some architectures prepend _ */
-static inline int sym_is(const char *symbol, const char *name)
+/* Does namelen bytes of name exactly match the symbol? */
+static bool sym_is(const char *name, unsigned namelen, const char *symbol)
{
- const char *match;
+ if (namelen != strlen(symbol))
+ return false;
- match = strstr(symbol, name);
- if (!match)
- return 0;
- return match[strlen(name)] == '\0';
+ return memcmp(name, symbol, namelen) == 0;
}
static void do_table(void *symval, unsigned long size,
@@ -989,11 +1052,25 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
{
void *symval;
char *zeros = NULL;
+ const char *name;
+ unsigned int namelen;
/* We're looking for a section relative symbol */
if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
return;
+ /* All our symbols are of form <prefix>__mod_XXX_device_table. */
+ name = strstr(symname, "__mod_");
+ if (!name)
+ return;
+ name += strlen("__mod_");
+ namelen = strlen(name);
+ if (namelen < strlen("_device_table"))
+ return;
+ if (strcmp(name + namelen - strlen("_device_table"), "_device_table"))
+ return;
+ namelen -= strlen("_device_table");
+
/* Handle all-NULL symbols allocated into .bss */
if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
zeros = calloc(1, sym->st_size);
@@ -1004,121 +1081,24 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
+ sym->st_value;
}
- if (sym_is(symname, "__mod_pci_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct pci_device_id), "pci",
- do_pci_entry, mod);
- else if (sym_is(symname, "__mod_usb_device_table"))
- /* special case to handle bcdDevice ranges */
+ /* First handle the "special" cases */
+ if (sym_is(name, namelen, "usb"))
do_usb_table(symval, sym->st_size, mod);
- else if (sym_is(symname, "__mod_hid_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct hid_device_id), "hid",
- do_hid_entry, mod);
- else if (sym_is(symname, "__mod_ieee1394_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct ieee1394_device_id), "ieee1394",
- do_ieee1394_entry, mod);
- else if (sym_is(symname, "__mod_ccw_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct ccw_device_id), "ccw",
- do_ccw_entry, mod);
- else if (sym_is(symname, "__mod_ap_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct ap_device_id), "ap",
- do_ap_entry, mod);
- else if (sym_is(symname, "__mod_css_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct css_device_id), "css",
- do_css_entry, mod);
- else if (sym_is(symname, "__mod_serio_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct serio_device_id), "serio",
- do_serio_entry, mod);
- else if (sym_is(symname, "__mod_acpi_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct acpi_device_id), "acpi",
- do_acpi_entry, mod);
- else if (sym_is(symname, "__mod_pnp_device_table"))
+ else if (sym_is(name, namelen, "pnp"))
do_pnp_device_entry(symval, sym->st_size, mod);
- else if (sym_is(symname, "__mod_pnp_card_device_table"))
+ else if (sym_is(name, namelen, "pnp_card"))
do_pnp_card_entries(symval, sym->st_size, mod);
- else if (sym_is(symname, "__mod_pcmcia_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct pcmcia_device_id), "pcmcia",
- do_pcmcia_entry, mod);
- else if (sym_is(symname, "__mod_of_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct of_device_id), "of",
- do_of_entry, mod);
- else if (sym_is(symname, "__mod_vio_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct vio_device_id), "vio",
- do_vio_entry, mod);
- else if (sym_is(symname, "__mod_input_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct input_device_id), "input",
- do_input_entry, mod);
- else if (sym_is(symname, "__mod_eisa_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct eisa_device_id), "eisa",
- do_eisa_entry, mod);
- else if (sym_is(symname, "__mod_parisc_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct parisc_device_id), "parisc",
- do_parisc_entry, mod);
- else if (sym_is(symname, "__mod_sdio_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct sdio_device_id), "sdio",
- do_sdio_entry, mod);
- else if (sym_is(symname, "__mod_ssb_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct ssb_device_id), "ssb",
- do_ssb_entry, mod);
- else if (sym_is(symname, "__mod_bcma_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct bcma_device_id), "bcma",
- do_bcma_entry, mod);
- else if (sym_is(symname, "__mod_virtio_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct virtio_device_id), "virtio",
- do_virtio_entry, mod);
- else if (sym_is(symname, "__mod_vmbus_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct hv_vmbus_device_id), "vmbus",
- do_vmbus_entry, mod);
- else if (sym_is(symname, "__mod_i2c_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct i2c_device_id), "i2c",
- do_i2c_entry, mod);
- else if (sym_is(symname, "__mod_spi_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct spi_device_id), "spi",
- do_spi_entry, mod);
- else if (sym_is(symname, "__mod_dmi_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct dmi_system_id), "dmi",
- do_dmi_entry, mod);
- else if (sym_is(symname, "__mod_platform_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct platform_device_id), "platform",
- do_platform_entry, mod);
- else if (sym_is(symname, "__mod_mdio_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct mdio_device_id), "mdio",
- do_mdio_entry, mod);
- else if (sym_is(symname, "__mod_zorro_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct zorro_device_id), "zorro",
- do_zorro_entry, mod);
- else if (sym_is(symname, "__mod_isapnp_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct isapnp_device_id), "isa",
- do_isapnp_entry, mod);
- else if (sym_is(symname, "__mod_amba_device_table"))
- do_table(symval, sym->st_size,
- sizeof(struct amba_id), "amba",
- do_amba_entry, mod);
+ else {
+ struct devtable **p;
+
+ for (p = __start___devtable; p < __stop___devtable; p++) {
+ if (sym_is(name, namelen, (*p)->device_id)) {
+ do_table(symval, sym->st_size, (*p)->id_size,
+ (*p)->device_id, (*p)->function, mod);
+ break;
+ }
+ }
+ }
free(zeros);
}
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h
index 38ccaea08204..df3649560818 100644
--- a/security/apparmor/include/apparmor.h
+++ b/security/apparmor/include/apparmor.h
@@ -21,11 +21,11 @@
/* Control parameters settable through module/boot flags */
extern enum audit_mode aa_g_audit;
-extern int aa_g_audit_header;
-extern int aa_g_debug;
-extern int aa_g_lock_policy;
-extern int aa_g_logsyscall;
-extern int aa_g_paranoid_load;
+extern bool aa_g_audit_header;
+extern bool aa_g_debug;
+extern bool aa_g_lock_policy;
+extern bool aa_g_logsyscall;
+extern bool aa_g_paranoid_load;
extern unsigned int aa_g_path_max;
/*
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index d7f06f8b2837..97ce8fae49b3 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -136,16 +136,16 @@ static int apparmor_capget(struct task_struct *target, kernel_cap_t *effective,
return 0;
}
-static int apparmor_capable(struct task_struct *task, const struct cred *cred,
- struct user_namespace *ns, int cap, int audit)
+static int apparmor_capable(const struct cred *cred, struct user_namespace *ns,
+ int cap, int audit)
{
struct aa_profile *profile;
/* cap_capable returns 0 on success, else -EPERM */
- int error = cap_capable(task, cred, ns, cap, audit);
+ int error = cap_capable(cred, ns, cap, audit);
if (!error) {
profile = aa_cred_profile(cred);
if (!unconfined(profile))
- error = aa_capable(task, profile, cap, audit);
+ error = aa_capable(current, profile, cap, audit);
}
return error;
}
@@ -708,7 +708,7 @@ module_param_call(mode, param_set_mode, param_get_mode,
&aa_g_profile_mode, S_IRUSR | S_IWUSR);
/* Debug mode */
-int aa_g_debug;
+bool aa_g_debug;
module_param_named(debug, aa_g_debug, aabool, S_IRUSR | S_IWUSR);
/* Audit mode */
@@ -719,7 +719,7 @@ module_param_call(audit, param_set_audit, param_get_audit,
/* Determines if audit header is included in audited messages. This
* provides more context if the audit daemon is not running
*/
-int aa_g_audit_header = 1;
+bool aa_g_audit_header = 1;
module_param_named(audit_header, aa_g_audit_header, aabool,
S_IRUSR | S_IWUSR);
@@ -727,12 +727,12 @@ module_param_named(audit_header, aa_g_audit_header, aabool,
* TODO: add in at boot loading of policy, which is the only way to
* load policy, if lock_policy is set
*/
-int aa_g_lock_policy;
+bool aa_g_lock_policy;
module_param_named(lock_policy, aa_g_lock_policy, aalockpolicy,
S_IRUSR | S_IWUSR);
/* Syscall logging mode */
-int aa_g_logsyscall;
+bool aa_g_logsyscall;
module_param_named(logsyscall, aa_g_logsyscall, aabool, S_IRUSR | S_IWUSR);
/* Maximum pathname length before accesses will start getting rejected */
@@ -742,12 +742,12 @@ module_param_named(path_max, aa_g_path_max, aauint, S_IRUSR | S_IWUSR);
/* Determines how paranoid loading of policy is and how much verification
* on the loaded policy is done.
*/
-int aa_g_paranoid_load = 1;
+bool aa_g_paranoid_load = 1;
module_param_named(paranoid_load, aa_g_paranoid_load, aabool,
S_IRUSR | S_IWUSR);
/* Boot time disable flag */
-static unsigned int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
+static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
module_param_named(enabled, apparmor_enabled, aabool, S_IRUSR);
static int __init apparmor_enabled_setup(char *str)
diff --git a/security/capability.c b/security/capability.c
index 3b5883b7179f..2f680eb02b59 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -998,7 +998,6 @@ void __init security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null(ops, sem_semctl);
set_to_cap_if_null(ops, sem_semop);
set_to_cap_if_null(ops, netlink_send);
- set_to_cap_if_null(ops, netlink_recv);
set_to_cap_if_null(ops, d_instantiate);
set_to_cap_if_null(ops, getprocattr);
set_to_cap_if_null(ops, setprocattr);
diff --git a/security/commoncap.c b/security/commoncap.c
index ee4f8486e5f5..7ce191ea29a0 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -56,17 +56,8 @@ int cap_netlink_send(struct sock *sk, struct sk_buff *skb)
return 0;
}
-int cap_netlink_recv(struct sk_buff *skb, int cap)
-{
- if (!cap_raised(current_cap(), cap))
- return -EPERM;
- return 0;
-}
-EXPORT_SYMBOL(cap_netlink_recv);
-
/**
* cap_capable - Determine whether a task has a particular effective capability
- * @tsk: The task to query
* @cred: The credentials to use
* @ns: The user namespace in which we need the capability
* @cap: The capability to check for
@@ -80,8 +71,8 @@ EXPORT_SYMBOL(cap_netlink_recv);
* cap_has_capability() returns 0 when a task has a capability, but the
* kernel's capable() and has_capability() returns 1 for this case.
*/
-int cap_capable(struct task_struct *tsk, const struct cred *cred,
- struct user_namespace *targ_ns, int cap, int audit)
+int cap_capable(const struct cred *cred, struct user_namespace *targ_ns,
+ int cap, int audit)
{
for (;;) {
/* The creator of the user namespace has all caps. */
@@ -222,9 +213,8 @@ static inline int cap_inh_is_capped(void)
/* they are so limited unless the current task has the CAP_SETPCAP
* capability
*/
- if (cap_capable(current, current_cred(),
- current_cred()->user->user_ns, CAP_SETPCAP,
- SECURITY_CAP_AUDIT) == 0)
+ if (cap_capable(current_cred(), current_cred()->user->user_ns,
+ CAP_SETPCAP, SECURITY_CAP_AUDIT) == 0)
return 0;
return 1;
}
@@ -874,7 +864,7 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
& (new->securebits ^ arg2)) /*[1]*/
|| ((new->securebits & SECURE_ALL_LOCKS & ~arg2)) /*[2]*/
|| (arg2 & ~(SECURE_ALL_LOCKS | SECURE_ALL_BITS)) /*[3]*/
- || (cap_capable(current, current_cred(),
+ || (cap_capable(current_cred(),
current_cred()->user->user_ns, CAP_SETPCAP,
SECURITY_CAP_AUDIT) != 0) /*[4]*/
/*
@@ -940,7 +930,7 @@ int cap_vm_enough_memory(struct mm_struct *mm, long pages)
{
int cap_sys_admin = 0;
- if (cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_ADMIN,
+ if (cap_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,
SECURITY_CAP_NOAUDIT) == 0)
cap_sys_admin = 1;
return __vm_enough_memory(mm, pages, cap_sys_admin);
@@ -967,7 +957,7 @@ int cap_file_mmap(struct file *file, unsigned long reqprot,
int ret = 0;
if (addr < dac_mmap_min_addr) {
- ret = cap_capable(current, current_cred(), &init_user_ns, CAP_SYS_RAWIO,
+ ret = cap_capable(current_cred(), &init_user_ns, CAP_SYS_RAWIO,
SECURITY_CAP_AUDIT);
/* set PF_SUPERPRIV if it turns out we allow the low mmap */
if (ret == 0)
diff --git a/security/security.c b/security/security.c
index 214502c772ab..d7542493454d 100644
--- a/security/security.c
+++ b/security/security.c
@@ -155,35 +155,16 @@ int security_capset(struct cred *new, const struct cred *old,
effective, inheritable, permitted);
}
-int security_capable(struct user_namespace *ns, const struct cred *cred,
+int security_capable(const struct cred *cred, struct user_namespace *ns,
int cap)
{
- return security_ops->capable(current, cred, ns, cap,
- SECURITY_CAP_AUDIT);
+ return security_ops->capable(cred, ns, cap, SECURITY_CAP_AUDIT);
}
-int security_real_capable(struct task_struct *tsk, struct user_namespace *ns,
- int cap)
+int security_capable_noaudit(const struct cred *cred, struct user_namespace *ns,
+ int cap)
{
- const struct cred *cred;
- int ret;
-
- cred = get_task_cred(tsk);
- ret = security_ops->capable(tsk, cred, ns, cap, SECURITY_CAP_AUDIT);
- put_cred(cred);
- return ret;
-}
-
-int security_real_capable_noaudit(struct task_struct *tsk,
- struct user_namespace *ns, int cap)
-{
- const struct cred *cred;
- int ret;
-
- cred = get_task_cred(tsk);
- ret = security_ops->capable(tsk, cred, ns, cap, SECURITY_CAP_NOAUDIT);
- put_cred(cred);
- return ret;
+ return security_ops->capable(cred, ns, cap, SECURITY_CAP_NOAUDIT);
}
int security_quotactl(int cmds, int type, int id, struct super_block *sb)
@@ -994,12 +975,6 @@ int security_netlink_send(struct sock *sk, struct sk_buff *skb)
return security_ops->netlink_send(sk, skb);
}
-int security_netlink_recv(struct sk_buff *skb, int cap)
-{
- return security_ops->netlink_recv(skb, cap);
-}
-EXPORT_SYMBOL(security_netlink_recv);
-
int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen)
{
return security_ops->secid_to_secctx(secid, secdata, seclen);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7cd4c3affac8..6a3683e28426 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1415,8 +1415,7 @@ static int current_has_perm(const struct task_struct *tsk,
#endif
/* Check whether a task is allowed to use a capability. */
-static int task_has_capability(struct task_struct *tsk,
- const struct cred *cred,
+static int cred_has_capability(const struct cred *cred,
int cap, int audit)
{
struct common_audit_data ad;
@@ -1427,7 +1426,7 @@ static int task_has_capability(struct task_struct *tsk,
int rc;
COMMON_AUDIT_DATA_INIT(&ad, CAP);
- ad.tsk = tsk;
+ ad.tsk = current;
ad.u.cap = cap;
switch (CAP_TO_INDEX(cap)) {
@@ -1811,7 +1810,7 @@ static int selinux_ptrace_access_check(struct task_struct *child,
if (rc)
return rc;
- if (mode == PTRACE_MODE_READ) {
+ if (mode & PTRACE_MODE_READ) {
u32 sid = current_sid();
u32 csid = task_sid(child);
return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL);
@@ -1868,16 +1867,16 @@ static int selinux_capset(struct cred *new, const struct cred *old,
* the CAP_SETUID and CAP_SETGID capabilities using the capable hook.
*/
-static int selinux_capable(struct task_struct *tsk, const struct cred *cred,
- struct user_namespace *ns, int cap, int audit)
+static int selinux_capable(const struct cred *cred, struct user_namespace *ns,
+ int cap, int audit)
{
int rc;
- rc = cap_capable(tsk, cred, ns, cap, audit);
+ rc = cap_capable(cred, ns, cap, audit);
if (rc)
return rc;
- return task_has_capability(tsk, cred, cap, audit);
+ return cred_has_capability(cred, cap, audit);
}
static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb)
@@ -1954,8 +1953,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
{
int rc, cap_sys_admin = 0;
- rc = selinux_capable(current, current_cred(),
- &init_user_ns, CAP_SYS_ADMIN,
+ rc = selinux_capable(current_cred(), &init_user_ns, CAP_SYS_ADMIN,
SECURITY_CAP_NOAUDIT);
if (rc == 0)
cap_sys_admin = 1;
@@ -2859,8 +2857,7 @@ static int selinux_inode_getsecurity(const struct inode *inode, const char *name
* and lack of permission just means that we fall back to the
* in-core context value, not a denial.
*/
- error = selinux_capable(current, current_cred(),
- &init_user_ns, CAP_MAC_ADMIN,
+ error = selinux_capable(current_cred(), &init_user_ns, CAP_MAC_ADMIN,
SECURITY_CAP_NOAUDIT);
if (!error)
error = security_sid_to_context_force(isec->sid, &context,
@@ -2993,8 +2990,8 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd,
case KDSKBENT:
case KDSKBSENT:
- error = task_has_capability(current, cred, CAP_SYS_TTY_CONFIG,
- SECURITY_CAP_AUDIT);
+ error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG,
+ SECURITY_CAP_AUDIT);
break;
/* default case assumes that the command will go
@@ -4718,24 +4715,6 @@ static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
return selinux_nlmsg_perm(sk, skb);
}
-static int selinux_netlink_recv(struct sk_buff *skb, int capability)
-{
- int err;
- struct common_audit_data ad;
- u32 sid;
-
- err = cap_netlink_recv(skb, capability);
- if (err)
- return err;
-
- COMMON_AUDIT_DATA_INIT(&ad, CAP);
- ad.u.cap = capability;
-
- security_task_getsecid(current, &sid);
- return avc_has_perm(sid, sid, SECCLASS_CAPABILITY,
- CAP_TO_MASK(capability), &ad);
-}
-
static int ipc_alloc_security(struct task_struct *task,
struct kern_ipc_perm *perm,
u16 sclass)
@@ -5464,7 +5443,6 @@ static struct security_operations selinux_ops = {
.vm_enough_memory = selinux_vm_enough_memory,
.netlink_send = selinux_netlink_send,
- .netlink_recv = selinux_netlink_recv,
.bprm_set_creds = selinux_bprm_set_creds,
.bprm_committing_creds = selinux_bprm_committing_creds,
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index 40b181bab930..9f3b01bb72c8 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -95,13 +95,13 @@ module_param(ac97_quirk, charp, 0444);
MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware.");
module_param(buggy_semaphore, bool, 0444);
MODULE_PARM_DESC(buggy_semaphore, "Enable workaround for hardwares with problematic codec semaphores.");
-module_param(buggy_irq, bool, 0444);
+module_param(buggy_irq, bint, 0444);
MODULE_PARM_DESC(buggy_irq, "Enable workaround for buggy interrupts on some motherboards.");
module_param(xbox, bool, 0444);
MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 codec detection.");
module_param(spdif_aclink, int, 0444);
MODULE_PARM_DESC(spdif_aclink, "S/PDIF over AC-link.");
-module_param(inside_vm, bool, 0444);
+module_param(inside_vm, bint, 0444);
MODULE_PARM_DESC(inside_vm, "KVM/Parallels optimization.");
/* just for backward compatibility */
diff --git a/sound/soc/au1x/Kconfig b/sound/soc/au1x/Kconfig
index e908a8123110..a56104040e83 100644
--- a/sound/soc/au1x/Kconfig
+++ b/sound/soc/au1x/Kconfig
@@ -1,13 +1,13 @@
##
-## Au1200/Au1550 PSC + DBDMA
+## Au1200/Au1550/Au1300 PSC + DBDMA
##
config SND_SOC_AU1XPSC
- tristate "SoC Audio for Au1200/Au1250/Au1550"
+ tristate "SoC Audio for Au12xx/Au13xx/Au1550"
depends on MIPS_ALCHEMY
help
This option enables support for the Programmable Serial
Controllers in AC97 and I2S mode, and the Descriptor-Based DMA
- Controller (DBDMA) as found on the Au1200/Au1250/Au1550 SoC.
+ Controller (DBDMA) as found on the Au12xx/Au13xx/Au1550 SoC.
config SND_SOC_AU1XPSC_I2S
tristate
@@ -51,12 +51,14 @@ config SND_SOC_DB1000
of boards (DB1000/DB1500/DB1100).
config SND_SOC_DB1200
- tristate "DB1200 AC97+I2S audio support"
+ tristate "DB1200/DB1300/DB1550 Audio support"
depends on SND_SOC_AU1XPSC
select SND_SOC_AU1XPSC_AC97
select SND_SOC_AC97_CODEC
+ select SND_SOC_WM9712
select SND_SOC_AU1XPSC_I2S
select SND_SOC_WM8731
help
- Select this option to enable audio (AC97 or I2S) on the
- Alchemy/AMD/RMI DB1200 demoboard.
+ Select this option to enable audio (AC97 and I2S) on the
+ Alchemy/AMD/RMI/NetLogic Db1200, Db1550 and Db1300 evaluation boards.
+ If you need Db1300 touchscreen support, you definitely want to say Y.
diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c
index 1c629393df78..30ea513d81d7 100644
--- a/sound/soc/au1x/db1200.c
+++ b/sound/soc/au1x/db1200.c
@@ -1,5 +1,5 @@
/*
- * DB1200 ASoC audio fabric support code.
+ * DB1200/DB1300/DB1550 ASoC audio fabric support code.
*
* (c) 2008-2011 Manuel Lauss <manuel.lauss@googlemail.com>
*
@@ -28,6 +28,18 @@ static struct platform_device_id db1200_pids[] = {
}, {
.name = "db1200-i2s",
.driver_data = 1,
+ }, {
+ .name = "db1300-ac97",
+ .driver_data = 2,
+ }, {
+ .name = "db1300-i2s",
+ .driver_data = 3,
+ }, {
+ .name = "db1550-ac97",
+ .driver_data = 4,
+ }, {
+ .name = "db1550-i2s",
+ .driver_data = 5,
},
{},
};
@@ -50,6 +62,27 @@ static struct snd_soc_card db1200_ac97_machine = {
.num_links = 1,
};
+static struct snd_soc_dai_link db1300_ac97_dai = {
+ .name = "AC97",
+ .stream_name = "AC97 HiFi",
+ .codec_dai_name = "wm9712-hifi",
+ .cpu_dai_name = "au1xpsc_ac97.1",
+ .platform_name = "au1xpsc-pcm.1",
+ .codec_name = "wm9712-codec.1",
+};
+
+static struct snd_soc_card db1300_ac97_machine = {
+ .name = "DB1300_AC97",
+ .dai_link = &db1300_ac97_dai,
+ .num_links = 1,
+};
+
+static struct snd_soc_card db1550_ac97_machine = {
+ .name = "DB1550_AC97",
+ .dai_link = &db1200_ac97_dai,
+ .num_links = 1,
+};
+
/*------------------------- I2S PART ---------------------------*/
static int db1200_i2s_startup(struct snd_pcm_substream *substream)
@@ -100,11 +133,47 @@ static struct snd_soc_card db1200_i2s_machine = {
.num_links = 1,
};
+static struct snd_soc_dai_link db1300_i2s_dai = {
+ .name = "WM8731",
+ .stream_name = "WM8731 PCM",
+ .codec_dai_name = "wm8731-hifi",
+ .cpu_dai_name = "au1xpsc_i2s.2",
+ .platform_name = "au1xpsc-pcm.2",
+ .codec_name = "wm8731.0-001b",
+ .ops = &db1200_i2s_wm8731_ops,
+};
+
+static struct snd_soc_card db1300_i2s_machine = {
+ .name = "DB1300_I2S",
+ .dai_link = &db1300_i2s_dai,
+ .num_links = 1,
+};
+
+static struct snd_soc_dai_link db1550_i2s_dai = {
+ .name = "WM8731",
+ .stream_name = "WM8731 PCM",
+ .codec_dai_name = "wm8731-hifi",
+ .cpu_dai_name = "au1xpsc_i2s.3",
+ .platform_name = "au1xpsc-pcm.3",
+ .codec_name = "wm8731.0-001b",
+ .ops = &db1200_i2s_wm8731_ops,
+};
+
+static struct snd_soc_card db1550_i2s_machine = {
+ .name = "DB1550_I2S",
+ .dai_link = &db1550_i2s_dai,
+ .num_links = 1,
+};
+
/*------------------------- COMMON PART ---------------------------*/
static struct snd_soc_card *db1200_cards[] __devinitdata = {
&db1200_ac97_machine,
&db1200_i2s_machine,
+ &db1300_ac97_machine,
+ &db1300_i2s_machine,
+ &db1550_ac97_machine,
+ &db1550_i2s_machine,
};
static int __devinit db1200_audio_probe(struct platform_device *pdev)
@@ -138,5 +207,5 @@ static struct platform_driver db1200_audio_driver = {
module_platform_driver(db1200_audio_driver);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("DB1200 ASoC audio support");
+MODULE_DESCRIPTION("DB1200/DB1300/DB1550 ASoC audio support");
MODULE_AUTHOR("Manuel Lauss");
diff --git a/tools/nfsd/inject_fault.sh b/tools/nfsd/inject_fault.sh
new file mode 100755
index 000000000000..06a399ac8b2f
--- /dev/null
+++ b/tools/nfsd/inject_fault.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+#
+# Copyright (c) 2011 Bryan Schumaker <bjschuma@netapp.com>
+#
+# Script for easier NFSD fault injection
+
+# Check that debugfs has been mounted
+DEBUGFS=`cat /proc/mounts | grep debugfs`
+if [ "$DEBUGFS" == "" ]; then
+ echo "debugfs does not appear to be mounted!"
+ echo "Please mount debugfs and try again"
+ exit 1
+fi
+
+# Check that the fault injection directory exists
+DEBUGDIR=`echo $DEBUGFS | awk '{print $2}'`/nfsd
+if [ ! -d "$DEBUGDIR" ]; then
+ echo "$DEBUGDIR does not exist"
+ echo "Check that your .config selects CONFIG_NFSD_FAULT_INJECTION"
+ exit 1
+fi
+
+function help()
+{
+ echo "Usage $0 injection_type [count]"
+ echo ""
+ echo "Injection types are:"
+ ls $DEBUGDIR
+ exit 1
+}
+
+if [ $# == 0 ]; then
+ help
+elif [ ! -f $DEBUGDIR/$1 ]; then
+ help
+elif [ $# != 2 ]; then
+ COUNT=0
+else
+ COUNT=$2
+fi
+
+BEFORE=`mktemp`
+AFTER=`mktemp`
+dmesg > $BEFORE
+echo $COUNT > $DEBUGDIR/$1
+dmesg > $AFTER
+# Capture lines that only exist in the $AFTER file
+diff $BEFORE $AFTER | grep ">"
+rm -f $BEFORE $AFTER
diff --git a/virt/kvm/iommu.c b/virt/kvm/iommu.c
index 0fb448e6a1a3..a457d2138f49 100644
--- a/virt/kvm/iommu.c
+++ b/virt/kvm/iommu.c
@@ -32,7 +32,7 @@
#include <linux/iommu.h>
#include <linux/intel-iommu.h>
-static int allow_unsafe_assigned_interrupts;
+static bool allow_unsafe_assigned_interrupts;
module_param_named(allow_unsafe_assigned_interrupts,
allow_unsafe_assigned_interrupts, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(allow_unsafe_assigned_interrupts,